From accd31895eff6d7a916025b0a5a54be95db09fe2 Mon Sep 17 00:00:00 2001 From: Robert MacGregor Date: Sun, 30 Aug 2015 02:30:29 -0400 Subject: [PATCH] Brought up to date with the newest T2BoL I've located --- JTLdelDSO.bat | 8 +- console_end.cs | 1380 +-- data/Info.dat | 14 +- data/RPGPreferences.txt | 18 +- data/SavedData.cs | 416 - .../pdaApplications/Clan Management.cs | 28 +- data/bolContent/pdaApplications/EMail.cs | 28 +- data/bolContent/pdaApplications/Save.cs | 38 +- data/campaigns/Tribes 2.dat | 64 +- data/creditsText.txt | 122 +- data/encyclopedia/Encyclopedia.conf | 20 +- data/encyclopedia/characters/Beast.txt | 8 +- data/encyclopedia/characters/Cobra.txt | 8 +- .../characters/Commander Jackson.txt | 8 +- .../characters/Corperal Jones.txt | 8 +- .../characters/Cynthia Fisher.txt | 8 +- .../encyclopedia/characters/Dalaila Hayes.txt | 8 +- data/encyclopedia/characters/Diamond Back.txt | 8 +- data/encyclopedia/characters/Dolosus.txt | 8 +- data/encyclopedia/characters/Eva.txt | 8 +- data/encyclopedia/characters/Gecko.txt | 8 +- data/encyclopedia/characters/Gerex Chol.txt | 8 +- data/encyclopedia/characters/Gila.txt | 8 +- data/encyclopedia/characters/Iguana.txt | 8 +- data/encyclopedia/characters/Lore.txt | 8 +- data/encyclopedia/characters/Raptor.txt | 8 +- data/encyclopedia/characters/Rex.txt | 8 +- data/encyclopedia/characters/Rragh Zhek.txt | 8 +- data/encyclopedia/characters/Sharp Tooth.txt | 8 +- data/encyclopedia/characters/Snake.txt | 8 +- data/encyclopedia/characters/Viper.txt | 8 +- data/encyclopedia/factions/Alpha Viper.txt | 16 +- data/encyclopedia/factions/Blood Eagle.txt | 16 +- data/encyclopedia/factions/Diamond Sword.txt | 16 +- data/encyclopedia/factions/Horde.txt | 16 +- data/encyclopedia/factions/Phoenix.txt | 16 +- data/encyclopedia/factions/Star Wolf.txt | 20 +- data/encyclopedia/factions/Storm.txt | 16 +- data/encyclopedia/packs/Dampening Field.txt | 14 +- data/encyclopedia/packs/Mining Tool.txt | 14 +- data/encyclopedia/planets/Earth.txt | 10 +- data/encyclopedia/planets/Xeron.txt | 10 +- data/encyclopedia/races/BioDerm.txt | 18 +- data/encyclopedia/races/Criollos.txt | 16 +- data/encyclopedia/races/Draakan.txt | 48 +- data/encyclopedia/races/Human.txt | 16 +- data/encyclopedia/vehicles/Shrike.txt | 14 +- data/encyclopedia/weapons/ELF Projector.txt | 14 +- .../encyclopedia/weapons/Grenade Launcher.txt | 14 +- data/encyclopedia/weapons/Laser Rifle.txt | 14 +- .../encyclopedia/weapons/Missile Launcher.txt | 14 +- data/encyclopedia/weapons/Mortar.txt | 14 +- data/encyclopedia/weapons/Plasma Rifle.txt | 14 +- data/encyclopedia/weapons/Shock Lance.txt | 14 +- data/encyclopedia/weapons/Spinfusor.txt | 16 +- data/game/Encyclopedia_Intro.des | 10 +- data/game/ammunition.txt | 88 +- data/game/encyclopediaData.txt | 20 +- data/game/gems.txt | 60 +- data/game/items.txt | 8 +- data/game/ores.txt | 30 +- data/game/saves/IceRidge_nef/427694980.txt | 62 +- data/game/saves/earth/427694980.txt | 62 +- data/game/structures/BBunk.txt | 18 +- data/game/structures/SMLCabin.cs | 184 +- data/game/structures/SMLCabin.txt | 18 +- data/game/vehicles.txt | 74 +- data/game/weapons.txt | 124 +- data/http/templates/403.html | 18 +- data/http/templates/404.html | 18 +- data/http/templates/Copy of 404.html | 18 +- data/http/templates/Directory.html | 20 +- data/http/test.cs | 14 +- data/http/test.html | 20 +- data/survivalPreferences.txt | 22 +- doc/races.txt | 46 + doc/versions.txt | 14 + gui/DebriefGui.gui | 504 +- gui/InputDLG.gui | 182 +- gui/LANAccountCreationDLG.gui | 244 +- gui/LaunchToolbarDlg.gui | 152 +- gui/MP3PlayerDLG.gui | 250 +- gui/MessageBoxFileTransfer.gui | 150 +- gui/OptionsDlg.gui | 5430 ++++++------ gui/RPGBrowserGui.gui | 684 +- gui/TrainingGui.gui | 588 +- gui/guiProfiles.cs | 3312 +++---- missions/AlphaSector.cs | 74 +- missions/AlphaSector.mis | 3296 +++---- missions/Beginning.cs | 830 +- missions/Beginning.mis | 6518 +++++++------- missions/Deployment.cs | 740 +- missions/Deployment.mis | 2408 ++--- missions/Earth.cs | 88 +- missions/Earth.mis | 3128 +++---- missions/Example_MapScript.cs | 72 +- missions/HotZone.cs | 740 +- missions/Hotzone.mis | 3856 ++++---- missions/KatabaticSV.mis | 1770 ++-- missions/Mission1.mis | 5508 ++++++------ missions/Mission2.mis | 5508 ++++++------ missions/SlapDashSV.mis | 2524 +++--- missions/Training.mis | 590 +- missions/rpg_new.mis | 1248 +-- prefs/Bot Profiles.conf | 42 + prefs/WebServer.conf | 14 + scripts/CTFGame.cs | 4192 ++++----- scripts/CnHGame.cs | 936 +- scripts/DMGame.cs | 760 +- scripts/DnDGame.cs | 2666 +++--- scripts/GameGui.cs | 4308 +++++---- scripts/HuntersGame.cs | 3492 ++++---- scripts/Importer/Building.cs | 476 +- scripts/Importer/BuildingDatablocks.cs | 266 +- scripts/Importer/BuildingGroups.cs | 306 +- scripts/Importer/Converter.cs | 266 +- scripts/LaunchLanGui.cs | 774 +- scripts/NSGame.cs | 1254 +-- scripts/OptionsDlg.cs | 5362 +++++------ scripts/PracticeCTFGame.cs | 6200 ++++++------- scripts/RPGGame.cs | 1050 +-- scripts/SVGame.cs | 1494 ++-- scripts/SiegeGame.cs | 2448 ++--- scripts/SinglePlayerGame.cs | 2630 +++--- scripts/Training.cs | 494 +- scripts/TrainingGui.cs | 626 +- scripts/admin.cs | 858 +- scripts/ai.cs | 1824 ++-- scripts/aiBotProfiles.cs | 556 +- scripts/aiDeathMatch.cs | 50 +- scripts/aiDebug.cs | 2106 ++--- scripts/aiInventory.cs | 2950 +++---- scripts/aiNS.cs | 52 +- scripts/aiObjectives.cs | 7836 ++++++++--------- scripts/aiPracticeCtf.cs | 234 +- scripts/aiRPG.cs | 52 +- scripts/aiSurvival.cs | 86 +- scripts/autoexec/FixRemap.cs | 152 +- scripts/autoexec/GUIMLWorkaround.cs | 72 +- scripts/autoexec/TCmini-client.cs | 2159 ++--- scripts/autoexec/TerrainUEPrevent.cs | 66 +- scripts/autoexec/cleanDSO.cs | 56 +- scripts/autoexec/debugLog.cs | 132 +- scripts/autoexec/minivstationx.cs | 90 +- scripts/autoexec/safeMode.cs | 104 +- scripts/autoexec/staticWaypointFix.cs | 74 +- scripts/camera.cs | 722 ++ scripts/chatMenuHud.cs | 466 +- scripts/client.cs | 4364 ++++----- scripts/commanderMap.cs | 1990 ++--- scripts/commonDialogs.cs | 450 +- scripts/creditsGui.cs | 266 +- scripts/creditsText.cs | 28 +- scripts/creditsText_default.cs | 3218 +++---- scripts/damageTypes.cs | 1440 +-- scripts/deathMessages.cs | 806 +- scripts/defaultGame.cs | 7624 ++++++++-------- scripts/deployables.cs | 2880 +++--- scripts/hud.cs | 3700 ++++---- scripts/inventory.cs | 1250 +-- scripts/inventoryHud.cs | 2226 ++--- scripts/item.cs | 1514 ++-- scripts/loadingGui.cs | 894 +- scripts/message.cs | 953 +- scripts/modScripts/Note.txt | 2 - scripts/modScripts/server/RPG/GameTriggers.cs | 81 - scripts/modScripts/server/initialise.cs | 15 - scripts/modScripts/shared/initialise.cs | 11 - .../{modScripts => modscripts}/AICharacter.cs | 0 .../client/RPGBrowserGui.cs | 0 .../client/clientFunctions.cs | 0 .../client/initialise.cs | 0 .../client/initialize.cs | 0 .../client/serverRequestHandler.cs | 0 .../modscripts/server/HTTP/ActivePlayers.cs | 1 + scripts/modscripts/server/HTTP/Index.cs | 21 + .../modscripts/server/HTTP/PlayerDirectory.cs | 0 .../server/HTTPServer.cs | 685 +- .../modscripts/server/RPG/ClientFunctions.cs | 49 + scripts/modscripts/server/RPG/GameTriggers.cs | 31 + scripts/modscripts/server/RPG/Interact.cs | 63 + scripts/modscripts/server/RPG/PDA.cs | 268 + .../server/RPG/PDAApplication.cs | 62 +- scripts/modscripts/server/RPG/RadioChat.cs | 1 + scripts/modscripts/server/RPG/RangedVoice.cs | 98 + scripts/modscripts/server/RPG/dataImport.cs | 302 + scripts/modscripts/server/RPG/initialise.cs | 1 + .../server/RPG}/looting.cs | 212 +- .../server/RPG}/mining.cs | 77 +- .../server/RPG/propertyOwning.cs | 0 .../server/RPG}/serverNetworking.cs | 99 +- .../server/TCPServer.cs | 355 +- .../server/bloodbioderm.cs | 810 +- .../server/bloodhuman.cs | 426 +- .../server/dataImport.cs | 0 .../server/initialize.cs | 0 .../RPG => modscripts/server}/looting.cs | 0 .../RPG => modscripts/server}/mining.cs | 0 .../server/propData.cs | 120 +- .../server/propertyOwning.cs | 0 .../server/serverFunctions.cs | 0 .../server}/serverNetworking.cs | 0 .../server/torqueExServer.cs | 514 +- .../shared/Array.cs | 156 +- scripts/modscripts/shared/BasicData.cs | 276 + scripts/modscripts/shared/FileFunctions.cs | 80 + .../shared/StringFunctions.cs} | 392 +- .../shared/basicDataStorage.cs | 0 .../shared/fileProcessing.cs | 0 .../shared/initialize.cs | 2 +- .../shared/putback/basicDataStorage.cs | 0 scripts/mpbTeleporter.cs | 590 +- scripts/objectiveHud.cs | 3054 +++---- scripts/pack.cs | 184 +- scripts/packs/ELFbarrelPack.cs | 120 +- scripts/packs/aabarrelPack.cs | 124 +- scripts/packs/buildingconstructor.cs | 258 +- scripts/packs/c4.cs | 628 +- scripts/packs/cloakingpack.cs | 330 +- scripts/packs/miningTool.cs | 1234 +-- scripts/packs/missilebarrelPack.cs | 128 +- scripts/packs/mortarBarrelPack.cs | 124 +- scripts/packs/plasmabarrelPack.cs | 120 +- scripts/packs/repairpack.cs | 1284 +-- scripts/packs/satchelCharge.cs | 1686 ++-- scripts/packs/sensorjammerpack.cs | 292 +- scripts/player.cs | 7257 ++++++++------- scripts/practice.cs | 822 +- scripts/projectiles.cs | 1518 ++-- scripts/scoreList.cs | 262 +- scripts/scoreScreen.cs | 194 +- scripts/server.cs | 6340 +++++++------ scripts/serverCommanderMap.cs | 598 +- scripts/serverDefaults.cs | 306 +- scripts/shapes/MoneyBag.dts | Bin 4926 -> 0 bytes scripts/simGroup.cs | 21 + scripts/spdialog.cs | 1446 +-- scripts/staticShape.cs | 2860 +++--- scripts/station.cs | 2318 ++--- scripts/supportClassic.cs | 430 +- scripts/turret.cs | 713 +- scripts/turrets/ELFBarrelLarge.cs | 312 +- scripts/turrets/aaBarrelLarge.cs | 526 +- scripts/turrets/indoorDeployableBarrel.cs | 650 +- scripts/turrets/missileBarrelLarge.cs | 352 +- scripts/turrets/mortarBarrelLarge.cs | 322 +- scripts/turrets/outdoorDeployableBarrel.cs | 502 +- scripts/turrets/plasmaBarrelLarge.cs | 648 +- scripts/vehicles/serverVehicleHud.cs | 648 +- scripts/vehicles/vehicle.cs | 3242 +++---- scripts/vehicles/vehicle_bomber.cs | 1944 ++-- scripts/vehicles/vehicle_havoc.cs | 454 +- scripts/vehicles/vehicle_mpb.cs | 610 +- scripts/vehicles/vehicle_shrike.cs | 680 +- scripts/vehicles/vehicle_tank.cs | 1364 +-- scripts/vehicles/vehicle_wildcat.cs | 754 +- scripts/weapTurretCode.cs | 1854 ++-- scripts/weapons.cs | 724 +- scripts/weapons/DrakeFlame.cs | 712 +- scripts/weapons/ELFGun.cs | 408 +- scripts/weapons/R700.cs | 330 +- scripts/weapons/cameraGrenade.cs | 386 +- scripts/weapons/chaingun.cs | 1352 +-- scripts/weapons/disc.cs | 966 +- scripts/weapons/flashGrenade.cs | 138 +- scripts/weapons/grenadeLauncher.cs | 1574 ++-- scripts/weapons/mine.cs | 680 +- scripts/weapons/missileLauncher.cs | 1590 ++-- scripts/weapons/mortar.cs | 1596 ++-- scripts/weapons/plasma.cs | 986 +-- scripts/weapons/shockLance.cs | 594 +- scripts/weapons/targetingLaser.cs | 432 +- {scripts/shapes => shapes}/MoneyBagC.png | Bin .../shapes => shapes}/PutBack/Drake_Poly.dts | Bin .../PutBack/Drake_Poly_Huge.dts | Bin textures/Bonus/Thumbs.db | Bin 55296 -> 0 bytes textures/GUI/Thumbs.db | Bin 15872 -> 0 bytes textures/Keldrin/Thumbs.db | Bin 7680 -> 0 bytes textures/Kmines/Thumbs.db | Bin 8704 -> 0 bytes textures/LiquidTiles/Thumbs.db | Bin 7680 -> 0 bytes textures/Thumbs.db | Bin 12288 -> 0 bytes textures/UrbanAssault/Thumbs.db | Bin 264192 -> 0 bytes textures/inttext/Thumbs.db | Bin 213504 -> 0 bytes textures/skins/Thumbs.db | Bin 58880 -> 0 bytes textures/terrain/Thumbs.db | Bin 32256 -> 0 bytes textures/texticons/Thumbs.db | Bin 61952 -> 0 bytes textures/texticons/Trophies/Thumbs.db | Bin 17408 -> 0 bytes 287 files changed, 108557 insertions(+), 107608 deletions(-) delete mode 100644 data/SavedData.cs create mode 100644 doc/races.txt create mode 100644 doc/versions.txt create mode 100644 prefs/Bot Profiles.conf create mode 100644 prefs/WebServer.conf create mode 100644 scripts/camera.cs delete mode 100644 scripts/modScripts/Note.txt delete mode 100644 scripts/modScripts/server/RPG/GameTriggers.cs delete mode 100644 scripts/modScripts/server/initialise.cs delete mode 100644 scripts/modScripts/shared/initialise.cs rename scripts/{modScripts => modscripts}/AICharacter.cs (100%) rename scripts/{modScripts => modscripts}/client/RPGBrowserGui.cs (100%) rename scripts/{modScripts => modscripts}/client/clientFunctions.cs (100%) rename scripts/{modScripts => modscripts}/client/initialise.cs (100%) rename scripts/{modScripts => modscripts}/client/initialize.cs (100%) rename scripts/{modScripts => modscripts}/client/serverRequestHandler.cs (100%) create mode 100644 scripts/modscripts/server/HTTP/ActivePlayers.cs create mode 100644 scripts/modscripts/server/HTTP/Index.cs create mode 100644 scripts/modscripts/server/HTTP/PlayerDirectory.cs rename scripts/{modScripts => modscripts}/server/HTTPServer.cs (92%) create mode 100644 scripts/modscripts/server/RPG/ClientFunctions.cs create mode 100644 scripts/modscripts/server/RPG/GameTriggers.cs create mode 100644 scripts/modscripts/server/RPG/Interact.cs create mode 100644 scripts/modscripts/server/RPG/PDA.cs rename scripts/{modScripts => modscripts}/server/RPG/PDAApplication.cs (90%) create mode 100644 scripts/modscripts/server/RPG/RadioChat.cs create mode 100644 scripts/modscripts/server/RPG/RangedVoice.cs create mode 100644 scripts/modscripts/server/RPG/dataImport.cs create mode 100644 scripts/modscripts/server/RPG/initialise.cs rename scripts/{modScripts/server => modscripts/server/RPG}/looting.cs (96%) rename scripts/{modScripts/server => modscripts/server/RPG}/mining.cs (93%) rename scripts/{modScripts => modscripts}/server/RPG/propertyOwning.cs (100%) rename scripts/{modScripts/server => modscripts/server/RPG}/serverNetworking.cs (91%) rename scripts/{modScripts => modscripts}/server/TCPServer.cs (93%) rename scripts/{modScripts => modscripts}/server/bloodbioderm.cs (96%) rename scripts/{modScripts => modscripts}/server/bloodhuman.cs (96%) rename scripts/{modScripts => modscripts}/server/dataImport.cs (100%) rename scripts/{modScripts => modscripts}/server/initialize.cs (100%) rename scripts/{modScripts/server/RPG => modscripts/server}/looting.cs (100%) rename scripts/{modScripts/server/RPG => modscripts/server}/mining.cs (100%) rename scripts/{modScripts => modscripts}/server/propData.cs (59%) rename scripts/{modScripts => modscripts}/server/propertyOwning.cs (100%) rename scripts/{modScripts => modscripts}/server/serverFunctions.cs (100%) rename scripts/{modScripts/server/RPG => modscripts/server}/serverNetworking.cs (100%) rename scripts/{modScripts => modscripts}/server/torqueExServer.cs (74%) rename scripts/{modScripts => modscripts}/shared/Array.cs (84%) create mode 100644 scripts/modscripts/shared/BasicData.cs create mode 100644 scripts/modscripts/shared/FileFunctions.cs rename scripts/{modScripts/shared/stringProcessing.cs => modscripts/shared/StringFunctions.cs} (90%) rename scripts/{modScripts => modscripts}/shared/basicDataStorage.cs (100%) rename scripts/{modScripts => modscripts}/shared/fileProcessing.cs (100%) rename scripts/{modScripts => modscripts}/shared/initialize.cs (86%) rename scripts/{modScripts => modscripts}/shared/putback/basicDataStorage.cs (100%) delete mode 100644 scripts/shapes/MoneyBag.dts create mode 100644 scripts/simGroup.cs rename {scripts/shapes => shapes}/MoneyBagC.png (100%) rename {scripts/shapes => shapes}/PutBack/Drake_Poly.dts (100%) rename {scripts/shapes => shapes}/PutBack/Drake_Poly_Huge.dts (100%) delete mode 100644 textures/Bonus/Thumbs.db delete mode 100644 textures/GUI/Thumbs.db delete mode 100644 textures/Keldrin/Thumbs.db delete mode 100644 textures/Kmines/Thumbs.db delete mode 100644 textures/LiquidTiles/Thumbs.db delete mode 100644 textures/Thumbs.db delete mode 100644 textures/UrbanAssault/Thumbs.db delete mode 100644 textures/inttext/Thumbs.db delete mode 100644 textures/skins/Thumbs.db delete mode 100644 textures/terrain/Thumbs.db delete mode 100644 textures/texticons/Thumbs.db delete mode 100644 textures/texticons/Trophies/Thumbs.db diff --git a/JTLdelDSO.bat b/JTLdelDSO.bat index 4eabc47..1f882ac 100644 --- a/JTLdelDSO.bat +++ b/JTLdelDSO.bat @@ -1,4 +1,4 @@ -del /s /q "..\base\*.dso" -del /s /q "*.dso" -del /s /q "fonts\*.gft" -del /s /q "editor\*.cs" +del /s /q "..\base\*.dso" +del /s /q "*.dso" +del /s /q "fonts\*.gft" +del /s /q "editor\*.cs" diff --git a/console_end.cs b/console_end.cs index 5a4ac63..a54c547 100644 --- a/console_end.cs +++ b/console_end.cs @@ -1,690 +1,690 @@ -if ( $pref::Shell::lastBackground > 4 ) - $pref::Shell::lastBackground = 0; -else - $pref::Shell::lastBackground++; - -// load default controls: -exec("scripts/controlDefaults.cs"); - -// override with control settings -if ( $pref::Input::ActiveConfig !$= "" ) - exec( "prefs/" @ $pref::Input::ActiveConfig @ ".cs", false, true ); - -// --------------------------------------------------------------------------------- -// z0dd - ZOD, 5/8/02. Moved here so scripters can use the message callback feature. -// message.cs is loaded so autoexec can add new message callbacks -exec("scripts/message.cs"); - -//exec any user created .cs files found in scripts/autoexec (order is that returned by the OS) -function loadCustomScripts() -{ - %path = "scripts/autoexec/*.cs"; - for( %file = findFirstFile( %path ); %file !$= ""; %file = findNextFile( %path ) ) - exec( %file ); -} -loadCustomScripts(); - -// override settings from autoexec.cs -exec("autoexec.cs"); -$LoginName = ""; - $LoginPassword = ""; - -//TINMAN hack to add a command line option for starting a bot match... -if ($CmdLineBotCount !$= "") -{ - $Host::BotCount = $CmdLineBotCount; -} - -// message.cs is loaded so autoexec can add new message callbacks -// z0dd - ZOD, 5/8/02. Moved so scripters can use the message callback feature. -//exec("scripts/message.cs"); - -//function to be called when the game exits -function onExit() -{ - if ( !isDemo() && isObject($IRCClient.tcp) ) - IRCClient::quit(); - - echo("exporting pref::* to ClientPrefs.cs"); - export("$pref::*", "prefs/ClientPrefs.cs", False); - BanList::Export("prefs/banlist.cs"); - if ( $PlayingOnline ) - savePlayerDatabase(); -} - - -//-------------------------------------------------------------------------- - -exec("scripts/LaunchLanGui.cs"); -exec("scripts/GameGui.cs"); -exec("scripts/ChooseFilterDlg.cs"); -exec("scripts/TrainingGui.cs"); -exec("scripts/webstuff.cs"); -exec("scripts/webemail.cs"); -exec("scripts/webbrowser.cs"); -exec("scripts/webtest.cs"); -exec("scripts/weblinks.cs"); -exec("scripts/OptionsDlg.cs"); -exec("scripts/EditChatMenuGui.cs"); -exec("scripts/scoreList.cs"); -exec("scripts/LobbyGui.cs"); -exec("scripts/DebriefGui.cs"); -exec("scripts/commonDialogs.cs"); -exec("scripts/client.cs"); -exec("scripts/clientFunctions.cs"); -exec("scripts/server.cs"); -exec("scripts/hud.cs"); -exec("scripts/objectiveHud.cs"); -exec("scripts/vehicles/clientVehicleHud.cs"); -exec("scripts/inventoryHud.cs"); -exec("scripts/chatMenuHud.cs"); -exec("scripts/scoreScreen.cs"); -exec("scripts/loadingGui.cs"); -exec("scripts/helpGuiText.cs"); -exec("scripts/voiceChat.cs"); -exec("scripts/clientTasks.cs"); -exec("scripts/targetManager.cs"); -exec("scripts/gameCanvas.cs"); -exec("scripts/centerPrint.cs"); -exec("scripts/CreditsGui.cs"); -exec("serverControl.cs"); - -//Init Shared & Client scripts -exec("scripts/modScripts/shared/initialise.cs"); -exec("scripts/modScripts/client/initialise.cs"); -if (isDemo()) - exec("scripts/DemoEndGui.cs"); -exec("scripts/ChatGui.cs"); - -// see if the mission and type are valid -// if they are they will be assigned into $Host::Map and $Host::MissionType -if($mission !$= "" && $missionType !$= "") - validateMissionAndType($mission, $missionType); - -if($LaunchMode $= "DedicatedServer") -{ - enableWinConsole(true); - $Host::Dedicated = true; - $HostGameType = "Online"; - $ServerName = $Host::GameName; - setNetPort($Host::Port); - CreateServer($Host::Map, $Host::MissionType); - return; -} -else if($LaunchMode $= "Console") -{ - enableWinConsole(true); - $Host::Dedicated = true; - return; -} -else if($LaunchMode $= "NavBuild") -{ - enableWinConsole(true); - $Host::Dedicated = true; - $ServerName = $Host::GameName; - $Host::MissionType = $missionType; - $Host::Map = $Mission; - setNetPort($Host::Port); - CreateServer($Mission, $missionType); - return; -} -else if($LaunchMode $= "SpnBuild") -{ - enableWinConsole(true); - $Host::Dedicated = true; - $ServerName = $Host::GameName; - $Host::MissionType = $missionType; - $Host::Map = $Mission; - setNetPort($Host::Port); - CreateServer($Mission, $missionType); - return; -} - -function recordMovie(%movieName, %fps) -{ - $timeAdvance = 1000 / %fps; - $screenGrabThread = schedule("movieGrabScreen(" @ %movieName @ ", 0);", $timeAdvance); -} - -function movieGrabScreen(%movieName, %frameNumber) -{ - if(%frameNumber < 10) - %frameNumber = "0" @ %frameNumber; - if(%frameNumber < 100) - %frameNumber = "0" @ %frameNumber; - if(%frameNumber < 1000) - %frameNumber = "0" @ %frameNumber; - if(%frameNumber < 10000) - %frameNumber = "0" @ %frameNumber; - screenshot(%movieName @ %frameNumber @ ".png"); - $screenGrabThread = schedule("movieGrabScreen(" @ %movieName @ "," @ %frameNumber + 1 @ ");", $timeAdvance); -} - -function stopMovie() -{ - cancel($screenGrabThread); -} - -function loadGui(%gui) -{ - exec("gui/" @ %gui @ ".gui"); -} - -exec("scripts/clientAudio.cs"); -exec("gui/guiProfiles.cs"); -exec("scripts/recordings.cs"); - -// tool guis -loadGui("GuiEditorGui"); -loadGui("consoleDlg"); -loadGui("InspectDlg"); -loadGui("CommonLoadDlg"); -loadGui("CommonSaveDlg"); -loadGui("FrameOverlayGui"); -loadGui("TribeAdminMemberDlg"); -loadGui("TSShowGui"); -loadGui("TSShowLoadDlg"); -loadGui("TSShowMiscDlg"); -loadGui("TSShowThreadControlDlg"); -loadGui("TSShowEditScale"); -loadGui("TSShowLightDlg"); -loadGui("TSShowTransitionDlg"); -loadGui("TSShowTranDurEditDlg"); -loadGui("TSShowDetailControlDlg"); - -// debugger GUI's -function Debugger() -{ - if(!$DebuggerLoaded) - { - loadGui("debuggerGui"); - loadGui("DebuggerBreakConditionDlg"); - loadGui("DebuggerConnectDlg"); - loadGui("DebuggerEditWatchDlg"); - loadGui("DebuggerWatchDlg"); - loadGui("DebuggerFindDlg"); - exec("scripts/debuggerGui.cs"); - $DebuggerLoaded = true; - } - Canvas.setContent(DebuggerGui); -} - -// test GUIs -loadGui("GuiTestGui"); - -// common shell dialogs: -loadGui("MessageBoxDlg"); -loadGui("MessagePopupDlg"); -loadGui("ShellLoadFileDlg"); -loadGui("ShellSaveFileDlg"); - -// menus -loadGui("AddressDlg"); -loadGui("GenDialog"); -loadGui("LaunchGui"); -loadGui("LaunchToolbarDlg"); -loadGui("GameGui"); -loadGui("ChooseFilterDlg"); -loadGui("ServerInfoDlg"); -loadGui("EnterIPDlg"); -loadGui("FindServerDlg"); -loadGui("AdvancedHostDlg"); -loadGui("NewWarriorDlg"); -loadGui("JoinChatDlg"); -loadGui("ChannelKeyDlg"); -loadGui("ChatOptionsDlg"); -loadGui("ChannelOptionsDlg"); -loadGui("ChannelBanDlg"); -loadGui("FilterEditDlg"); -loadGui("PasswordDlg"); -loadGui("OptionsDlg"); -loadGui("DriverInfoDlg"); -loadGui("RemapDlg"); -loadGui("MouseConfigDlg"); -loadGui("JoystickConfigDlg"); -loadGui("EditChatMenuGui"); -loadGui("EditChatMenuDlg"); -loadGui("EditChatCommandDlg"); -loadGui("ChatGui"); -loadGui("EmailGui"); -loadGui("EmailBlockDlg"); -loadGui("EmailComposeDlg"); -loadGui("TribeAndWarriorBrowserGui"); -loadGui("TribePropertiesDlg"); -loadGui("WarriorPropertiesDlg"); -loadGui("BrowserSearchDlg"); -loadGui("BrowserEditInfoDlg"); -loadGui("CreateTribeDlg"); -loadGui("RecordingsDlg"); -loadGui("DemoLoadProgressDlg"); -loadGui("DemoRenameFileDlg"); -loadGui("DemoPlaybackDlg"); -loadGui("TrainingGui"); -loadGui("SinglePlayerEscapeDlg"); -loadGui("LobbyGui"); -loadGui("DebriefGui"); -loadGui("CreditsGui"); -loadGui("InputDLG"); -loadGui("MessageBoxFileTransfer"); -loadGui("LANAccountCreationDLG"); -if (isDemo()) - loadGui("DemoEndGui"); -loadGui("MoveThreadDlg"); -loadGui("NewMissionGui"); -loadGui("ChatDlg"); -loadGui("PlayGui"); -loadGui("PanoramaGui"); -loadGui("LoadingGui"); -loadGui("TestGui"); - -// HUD GUI's: -loadGui("HUDDlgs"); - -// TR2 Huds -exec("prefs/TR2HudPrefs.cs"); -exec("scripts/TR2BonusHud.cs"); -exec("scripts/TR2EventHud.cs"); -exec("scripts/TR2FlagToss.cs"); - -// terraformer GUI's -loadGui("helpTextGui"); - -// - -loadGui("InteriorPreviewGui"); -loadGui("InteriorDebug"); -exec("scripts/editor.cs"); -loadGui("SceneLightingGui"); -loadGui("InspectAddFieldDlg"); - -loadGui("PickTeamDlg"); - -loadGui("DetailSetDlg"); - -loadGui("IHVTest"); - -loadGui("RPGBrowserGui"); - -// Load material properties -echo("Load Material Properties:"); -//exec("textures/badlands/badlandsPropMap.cs"); -//exec("textures/desert/desertPropMap.cs"); -//exec("textures/ice/icePropMap.cs"); -//exec("textures/lava/lavaPropMap.cs"); -//exec("textures/lush/lushPropMap.cs"); -exec("scripts/badlandsPropMap.cs"); -exec("scripts/desertPropMap.cs"); -exec("scripts/icePropMap.cs"); -exec("scripts/lavaPropMap.cs"); -exec("scripts/lushPropMap.cs"); - -// commander map -exec("scripts/commanderProfiles.cs"); -exec("scripts/commanderMap.cs"); -exec("scripts/commanderMapHelpText.cs"); - -loadGui(CommanderMapGui); -loadGui(cmdMapHelpText); -loadGui(TaskHudDlg); - - -function frameCounter() -{ - return " FPS: " @ $fps::real @ - " mspf: " @ 1000 / $fps::real; -} - -function terrMetrics() -{ - return frameCounter() @ - " L0: " @ $T2::levelZeroCount @ - " FMC: " @ $T2::fullMipCount @ - " DTC: " @ $T2::dynamicTextureCount @ - " UNU: " @ $T2::unusedTextureCount @ - " STC: " @ $T2::staticTextureCount @ - " DTSU: " @ $T2::textureSpaceUsed @ - " STSU: " @ $T2::staticTSU @ - " FRB: " @ $T2::FogRejections; -} - -function triMetrics() -{ - return frameCounter() @ - " TC: " @ $OpenGL::triCount0 + $OpenGL::triCount1 + $OpenGL::triCount2 + $OpenGL::triCount3 @ - " PC: " @ $OpenGL::primCount0 + $OpenGL::primCount1 + $OpenGL::primCount2 + $OpenGL::primCount3 @ - " T_T: " @ $OpenGL::triCount1 @ - " T_P: " @ $OpenGL::primCount1 @ - " I_T: " @ $OpenGL::triCount2 @ - " I_P: " @ $OpenGL::primCount2 @ - " TS_T: " @ $OpenGL::triCount3 @ - " TS_P: " @ $OpenGL::primCount3 @ - " ?_T: " @ $OpenGL::triCount0 @ - " ?_P: " @ $OpenGL::primCount0; -} - -function interiorMetrics() -{ - return frameCounter() @ - " NTL: " @ $Video::numTexelsLoaded @ - " TRP: " @ $Video::texResidentPercentage @ - " INP: " @ $Metrics::Interior::numPrimitives @ - " INT: " @ $Matrics::Interior::numTexturesUsed @ - " INO: " @ $Metrics::Interior::numInteriors; -} - -function textureMetrics() -{ - return frameCounter() @ - " NTL: " @ $Video::numTexelsLoaded @ - " TRP: " @ $Video::texResidentPercentage @ - " TCM: " @ $Video::textureCacheMisses; -} - -function waterMetrics() -{ - return frameCounter() @ - " Tri#: " @ $T2::waterTriCount @ - " Pnt#: " @ $T2::waterPointCount @ - " Hz#: " @ $T2::waterHazePointCount; -} - -function timeMetrics() -{ - return frameCounter() @ " Time: " @ getSimTime() @ " Mod: " @ getSimTime() % 32; -} - -function vehicleMetrics() -{ - return frameCounter() @ - " R: " @ $Vehicle::retryCount @ - " C: " @ $Vehicle::searchCount @ - " P: " @ $Vehicle::polyCount @ - " V: " @ $Vehicle::vertexCount; -} - -function audioMetrics() -{ - return frameCounter() @ - " OH: " @ $Audio::numOpenHandles @ - " OLH: " @ $Audio::numOpenLoopingHandles @ - " OVH: " @ $Audio::numOpenVoiceHandles @ - " AS: " @ $Audio::numActiveStreams @ - " NAS: " @ $Audio::numNullActiveStreams @ - " LAS: " @ $Audio::numActiveLoopingStreams @ - " VAS: " @ $Audio::numActiveVoiceStreams @ - " LS: " @ $Audio::numLoopingStreams @ - " ILS: " @ $Audio::numInactiveLoopingStreams @ - " CLS: " @ $Audio::numCulledLoopingStreams @ - " MEM: " @ $Audio::memUsage @ - " DYN: " @ $Audio::dynamicMemUsage @ - " / " @ $Audio::dynamicMemSize @ - " CNT: " @ $Audio::dynamicBufferCount @ - " / " @ $Audio::bufferCount; -} - -function DebugMetrics() -{ - return frameCounter() @ - " NTL: " @ $Video::numTexelsLoaded @ - " TRP: " @ $Video::texResidentPercentage @ - " NP: " @ $Metrics::numPrimitives @ - " NT: " @ $Metrics::numTexturesUsed @ - " NO: " @ $Metrics::numObjectsRendered; -} - -function showMapperMetrics( %expr ) -{ - GLEnableMetrics( %expr ); - - if( Canvas.getContent() != PlayGui.getId() ) - metricsIMain.setVisible( %expr ); - else - metricsMain.setVisible( %expr ); -} - -function showTerr() -{ - show("terrMetrics()"); -} - -function showTri() -{ - GLEnableMetrics(true); - show("triMetrics()"); -} - -function showTime() -{ - show("timeMetrics()"); -} - -function showWater() -{ - show("waterMetrics()"); -} - -function showTexture() -{ - show("textureMetrics()"); -} - -function showInterior() -{ - $fps::virtual = 0; - $Interior::numPolys = 0; - $Interior::numTextures = 0; - $Interior::numTexels = 0; - $Interior::numLightmaps = 0; - $Interior::numLumels = 0; - show("interiorMetrics()"); -} - -function showVehicle() -{ - show("vehicleMetrics()"); -} - -function showAudio() -{ - show("audioMetrics()"); -} - -function showDebug() -{ - show("DebugMetrics()"); -} - - -function show(%expr) -{ - if(%expr $= "") - { - GLEnableMetrics(false); - Canvas.popDialog(FrameOverlayGui); - } - else - { - Canvas.pushDialog(FrameOverlayGui, 1000); - TextOverlayControl.setValue(%expr); - } -} -//showInterior(); - -// check the launch mode: - -Canvas.setCursor("DefaultCursor"); - -function dumpFile(%fileName) -{ - %file = new FileObject(); - if(%file.openForRead(%fileName)) - { - while(!%file.isEOF()) - echo(%file.readLine()); - } - %file.delete(); -} - -function doScreenShot(%val) -{ - $pref::interior::showdetailmaps = false; - if(!%val) - screenShot("screen" @ $screenshotnum++ @ ".png"); -} - -// set up the movement action map -GlobalActionMap.bind(keyboard, "print", doScreenShot); -GlobalActionMap.bindCmd(keyboard, "alt enter", "", "toggleFullScreen();"); - -// Get the joystick binding functions: -exec( "scripts/joystickBind.cs" ); - -function clientCMDgetManagerID(%client) -{ - $client = %client; -} -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- // - -function abs(%val) -{ - if (%val < 0) - return %val * -1; - else - return %val; -} - -//############################################################################## -//CreateServer(testmission); -//LocalConnect(UberBob); -//############################################################################## - -function ServerConnectionAccepted() -{ - if ( !isDemo() ) - { - %info = GMJ_Browser.getServerInfoString(); - %desc = "joined a" SPC getField(%info,4) @ " game (" @ getField(%info,3) @ ") on the \"" @ getField(%info,0) @ "\" server."; - - IRCClient::onJoinGame($JoinGameAddress,%desc); - - if ( !$pref::Net::CheckEmail ) - CancelEmailCheck(); - - // if($pref::Net::DisconnectChat) - // IRCClient::quit(); - } - - checkGotLoadInfo(); -} - -function LocalConnectionAccepted() -{ - if ( !isDemo() ) - { - %desc = $pref::IRCClient::hostmsg; - - IRCClient::onJoinGame("", %desc); - - if ( !$pref::Net::CheckEmail ) - CancelEmailCheck(); - - // if($pref::Net::DisconnectChat) - // IRCClient::quit(); //this is screwed up right now ^^ - } - - checkGotLoadInfo(); -} - -function checkGotLoadInfo() -{ - if ( LoadingGui.gotLoadInfo ) - Canvas.setContent( LoadingGui ); - else - LoadingGui.checkSchedule = schedule( 500, 0, checkGotLoadInfo ); -} - -function cancelLoadInfoCheck() -{ - if ( LoadingGui.checkSchedule ) - { - cancel( LoadingGui.checkSchedule ); - LoadingGui.checkSchedule = ""; - } -} - -function DispatchLaunchMode() -{ - switch$($LaunchMode) - { - case "InteriorView": - if ( isFile( "missions/interiorTest.mis" ) ) - { - $InteriorArgument = $TestObjectFileName; - $extension = fileExt( $TestObjectFileName ); - if ( stricmp( $extension, ".dif\"" ) == 0 ) - { - // Have to adjust for quotes: - $TestObjectFileName = getSubStr( $TestObjectFileName, - 1, strlen( $TestObjectFileName ) - 2 ); - } - - if ( getSubStr( $TestObjectFileName, strlen( $TestObjectFileName ) - 6, 1 ) $= "_" ) - { - // Strip the detail part off... - $TestObjectFileName = getSubStr( $TestObjectFileName, 0, strlen( $TestObjectFileName ) - 6 ) @ ".dif"; - } - - echo( $TestObjectFileName @ " is the file loaded" ); - - $ServerName = $Host::GameName; - $Host::TimeLimit = 60; - CreateServer( "interiorTest", "InteriorTest" ); - localConnect( "TestGuy" ); - } - else - MessageBoxOK( "FILE NOT FOUND", "You do not have the interior test mission in your mission folder.\nTalk to Brad or Tom to get it.", "quit();" ); - case "Connect": - OnlineLogIn(); - setNetPort(0); - JoinGame($JoinGameAddress); - case "HostGame": - $ServerName = $Host::GameName; - $Host::MissionType = $MissionType; - $Host::Map = $Mission; - CreateServer($Mission, $MissionType); - localConnect(); - case "Normal": - OnlineLogIn(); - case "Offline": - PlayOffline(); - case "TSShow": - startShow(); - case "SceneLight": - CreateServer($Mission); - localConnect(); - case "Demo": - LoopDemos(); - } - - if ($Host::Dedicated) //Server doesn't need to initialize client Startup - return; - - //If we're offline, check if the user has a LAN account setup.. - if (!$PlayingOnline && $Pref::LANAccount::Name $= "" || $Pref::LANAccount::PassWord $= "" && $Pref::FirstRan) - canvas.pushDialog(LANAccountCreationDLG); - - if (!$Pref::FirstRan) //Technically the gameMode is included, but the BETA maps are not there - { - $Pref::FirstRan = true; - if (!$PlayingOnline && $Pref::LANAccount::Name $= "" || $Pref::LANAccount::PassWord $= "") - messageBoxOk("WARNING","This version of T2Bol ("@$ModVersionText@") does not include the RPG gamemode. If possible, please update the mod.",canvas.pushDialog(LANAccountCreationDLG)); - else - messageBoxOk("WARNING","This version of T2Bol ("@$ModVersionText@") does not include the RPG gamemode. If possible, please update the mod."); - } -} - -// if($LaunchMode !$= "Demo") -// VerifyCDCheck(DispatchLaunchMode); -// else - DispatchLaunchMode(); - setPerfCounterEnable(0); //Nobody needs the damn perf counter anymore ... +if ( $pref::Shell::lastBackground > 4 ) + $pref::Shell::lastBackground = 0; +else + $pref::Shell::lastBackground++; + +// load default controls: +exec("scripts/controlDefaults.cs"); + +// override with control settings +if ( $pref::Input::ActiveConfig !$= "" ) + exec( "prefs/" @ $pref::Input::ActiveConfig @ ".cs", false, true ); + +// --------------------------------------------------------------------------------- +// z0dd - ZOD, 5/8/02. Moved here so scripters can use the message callback feature. +// message.cs is loaded so autoexec can add new message callbacks +exec("scripts/message.cs"); + +//exec any user created .cs files found in scripts/autoexec (order is that returned by the OS) +function loadCustomScripts() +{ + %path = "scripts/autoexec/*.cs"; + for( %file = findFirstFile( %path ); %file !$= ""; %file = findNextFile( %path ) ) + exec( %file ); +} +loadCustomScripts(); + +// override settings from autoexec.cs +exec("autoexec.cs"); +$LoginName = ""; + $LoginPassword = ""; + +//TINMAN hack to add a command line option for starting a bot match... +if ($CmdLineBotCount !$= "") +{ + $Host::BotCount = $CmdLineBotCount; +} + +// message.cs is loaded so autoexec can add new message callbacks +// z0dd - ZOD, 5/8/02. Moved so scripters can use the message callback feature. +//exec("scripts/message.cs"); + +//function to be called when the game exits +function onExit() +{ + if ( !isDemo() && isObject($IRCClient.tcp) ) + IRCClient::quit(); + + echo("exporting pref::* to ClientPrefs.cs"); + export("$pref::*", "prefs/ClientPrefs.cs", False); + BanList::Export("prefs/banlist.cs"); + if ( $PlayingOnline ) + savePlayerDatabase(); +} + + +//-------------------------------------------------------------------------- + +exec("scripts/LaunchLanGui.cs"); +exec("scripts/GameGui.cs"); +exec("scripts/ChooseFilterDlg.cs"); +exec("scripts/TrainingGui.cs"); +exec("scripts/webstuff.cs"); +exec("scripts/webemail.cs"); +exec("scripts/webbrowser.cs"); +exec("scripts/webtest.cs"); +exec("scripts/weblinks.cs"); +exec("scripts/OptionsDlg.cs"); +exec("scripts/EditChatMenuGui.cs"); +exec("scripts/scoreList.cs"); +exec("scripts/LobbyGui.cs"); +exec("scripts/DebriefGui.cs"); +exec("scripts/commonDialogs.cs"); +exec("scripts/client.cs"); +exec("scripts/clientFunctions.cs"); +exec("scripts/server.cs"); +exec("scripts/hud.cs"); +exec("scripts/objectiveHud.cs"); +exec("scripts/vehicles/clientVehicleHud.cs"); +exec("scripts/inventoryHud.cs"); +exec("scripts/chatMenuHud.cs"); +exec("scripts/scoreScreen.cs"); +exec("scripts/loadingGui.cs"); +exec("scripts/helpGuiText.cs"); +exec("scripts/voiceChat.cs"); +exec("scripts/clientTasks.cs"); +exec("scripts/targetManager.cs"); +exec("scripts/gameCanvas.cs"); +exec("scripts/centerPrint.cs"); +exec("scripts/CreditsGui.cs"); +exec("serverControl.cs"); + +//Init Shared & Client scripts +exec("scripts/modscripts/shared/initialize.cs"); +exec("scripts/modscripts/client/initialize.cs"); +if (isDemo()) + exec("scripts/DemoEndGui.cs"); +exec("scripts/ChatGui.cs"); + +// see if the mission and type are valid +// if they are they will be assigned into $Host::Map and $Host::MissionType +if($mission !$= "" && $missionType !$= "") + validateMissionAndType($mission, $missionType); + +if($LaunchMode $= "DedicatedServer") +{ + enableWinConsole(true); + $Host::Dedicated = true; + $HostGameType = "Online"; + $ServerName = $Host::GameName; + setNetPort($Host::Port); + CreateServer($Host::Map, $Host::MissionType); + return; +} +else if($LaunchMode $= "Console") +{ + enableWinConsole(true); + $Host::Dedicated = true; + return; +} +else if($LaunchMode $= "NavBuild") +{ + enableWinConsole(true); + $Host::Dedicated = true; + $ServerName = $Host::GameName; + $Host::MissionType = $missionType; + $Host::Map = $Mission; + setNetPort($Host::Port); + CreateServer($Mission, $missionType); + return; +} +else if($LaunchMode $= "SpnBuild") +{ + enableWinConsole(true); + $Host::Dedicated = true; + $ServerName = $Host::GameName; + $Host::MissionType = $missionType; + $Host::Map = $Mission; + setNetPort($Host::Port); + CreateServer($Mission, $missionType); + return; +} + +function recordMovie(%movieName, %fps) +{ + $timeAdvance = 1000 / %fps; + $screenGrabThread = schedule("movieGrabScreen(" @ %movieName @ ", 0);", $timeAdvance); +} + +function movieGrabScreen(%movieName, %frameNumber) +{ + if(%frameNumber < 10) + %frameNumber = "0" @ %frameNumber; + if(%frameNumber < 100) + %frameNumber = "0" @ %frameNumber; + if(%frameNumber < 1000) + %frameNumber = "0" @ %frameNumber; + if(%frameNumber < 10000) + %frameNumber = "0" @ %frameNumber; + screenshot(%movieName @ %frameNumber @ ".png"); + $screenGrabThread = schedule("movieGrabScreen(" @ %movieName @ "," @ %frameNumber + 1 @ ");", $timeAdvance); +} + +function stopMovie() +{ + cancel($screenGrabThread); +} + +function loadGui(%gui) +{ + exec("gui/" @ %gui @ ".gui"); +} + +exec("scripts/clientAudio.cs"); +exec("gui/guiProfiles.cs"); +exec("scripts/recordings.cs"); + +// tool guis +loadGui("GuiEditorGui"); +loadGui("consoleDlg"); +loadGui("InspectDlg"); +loadGui("CommonLoadDlg"); +loadGui("CommonSaveDlg"); +loadGui("FrameOverlayGui"); +loadGui("TribeAdminMemberDlg"); +loadGui("TSShowGui"); +loadGui("TSShowLoadDlg"); +loadGui("TSShowMiscDlg"); +loadGui("TSShowThreadControlDlg"); +loadGui("TSShowEditScale"); +loadGui("TSShowLightDlg"); +loadGui("TSShowTransitionDlg"); +loadGui("TSShowTranDurEditDlg"); +loadGui("TSShowDetailControlDlg"); + +// debugger GUI's +function Debugger() +{ + if(!$DebuggerLoaded) + { + loadGui("debuggerGui"); + loadGui("DebuggerBreakConditionDlg"); + loadGui("DebuggerConnectDlg"); + loadGui("DebuggerEditWatchDlg"); + loadGui("DebuggerWatchDlg"); + loadGui("DebuggerFindDlg"); + exec("scripts/debuggerGui.cs"); + $DebuggerLoaded = true; + } + Canvas.setContent(DebuggerGui); +} + +// test GUIs +loadGui("GuiTestGui"); + +// common shell dialogs: +loadGui("MessageBoxDlg"); +loadGui("MessagePopupDlg"); +loadGui("ShellLoadFileDlg"); +loadGui("ShellSaveFileDlg"); + +// menus +loadGui("AddressDlg"); +loadGui("GenDialog"); +loadGui("LaunchGui"); +loadGui("LaunchToolbarDlg"); +loadGui("GameGui"); +loadGui("ChooseFilterDlg"); +loadGui("ServerInfoDlg"); +loadGui("EnterIPDlg"); +loadGui("FindServerDlg"); +loadGui("AdvancedHostDlg"); +loadGui("NewWarriorDlg"); +loadGui("JoinChatDlg"); +loadGui("ChannelKeyDlg"); +loadGui("ChatOptionsDlg"); +loadGui("ChannelOptionsDlg"); +loadGui("ChannelBanDlg"); +loadGui("FilterEditDlg"); +loadGui("PasswordDlg"); +loadGui("OptionsDlg"); +loadGui("DriverInfoDlg"); +loadGui("RemapDlg"); +loadGui("MouseConfigDlg"); +loadGui("JoystickConfigDlg"); +loadGui("EditChatMenuGui"); +loadGui("EditChatMenuDlg"); +loadGui("EditChatCommandDlg"); +loadGui("ChatGui"); +loadGui("EmailGui"); +loadGui("EmailBlockDlg"); +loadGui("EmailComposeDlg"); +loadGui("TribeAndWarriorBrowserGui"); +loadGui("TribePropertiesDlg"); +loadGui("WarriorPropertiesDlg"); +loadGui("BrowserSearchDlg"); +loadGui("BrowserEditInfoDlg"); +loadGui("CreateTribeDlg"); +loadGui("RecordingsDlg"); +loadGui("DemoLoadProgressDlg"); +loadGui("DemoRenameFileDlg"); +loadGui("DemoPlaybackDlg"); +loadGui("TrainingGui"); +loadGui("SinglePlayerEscapeDlg"); +loadGui("LobbyGui"); +loadGui("DebriefGui"); +loadGui("CreditsGui"); +loadGui("InputDLG"); +loadGui("MessageBoxFileTransfer"); +loadGui("LANAccountCreationDLG"); +if (isDemo()) + loadGui("DemoEndGui"); +loadGui("MoveThreadDlg"); +loadGui("NewMissionGui"); +loadGui("ChatDlg"); +loadGui("PlayGui"); +loadGui("PanoramaGui"); +loadGui("LoadingGui"); +loadGui("TestGui"); + +// HUD GUI's: +loadGui("HUDDlgs"); + +// TR2 Huds +exec("prefs/TR2HudPrefs.cs"); +exec("scripts/TR2BonusHud.cs"); +exec("scripts/TR2EventHud.cs"); +exec("scripts/TR2FlagToss.cs"); + +// terraformer GUI's +loadGui("helpTextGui"); + +// + +loadGui("InteriorPreviewGui"); +loadGui("InteriorDebug"); +exec("scripts/editor.cs"); +loadGui("SceneLightingGui"); +loadGui("InspectAddFieldDlg"); + +loadGui("PickTeamDlg"); + +loadGui("DetailSetDlg"); + +loadGui("IHVTest"); + +loadGui("RPGBrowserGui"); + +// Load material properties +echo("Load Material Properties:"); +//exec("textures/badlands/badlandsPropMap.cs"); +//exec("textures/desert/desertPropMap.cs"); +//exec("textures/ice/icePropMap.cs"); +//exec("textures/lava/lavaPropMap.cs"); +//exec("textures/lush/lushPropMap.cs"); +exec("scripts/badlandsPropMap.cs"); +exec("scripts/desertPropMap.cs"); +exec("scripts/icePropMap.cs"); +exec("scripts/lavaPropMap.cs"); +exec("scripts/lushPropMap.cs"); + +// commander map +exec("scripts/commanderProfiles.cs"); +exec("scripts/commanderMap.cs"); +exec("scripts/commanderMapHelpText.cs"); + +loadGui(CommanderMapGui); +loadGui(cmdMapHelpText); +loadGui(TaskHudDlg); + + +function frameCounter() +{ + return " FPS: " @ $fps::real @ + " mspf: " @ 1000 / $fps::real; +} + +function terrMetrics() +{ + return frameCounter() @ + " L0: " @ $T2::levelZeroCount @ + " FMC: " @ $T2::fullMipCount @ + " DTC: " @ $T2::dynamicTextureCount @ + " UNU: " @ $T2::unusedTextureCount @ + " STC: " @ $T2::staticTextureCount @ + " DTSU: " @ $T2::textureSpaceUsed @ + " STSU: " @ $T2::staticTSU @ + " FRB: " @ $T2::FogRejections; +} + +function triMetrics() +{ + return frameCounter() @ + " TC: " @ $OpenGL::triCount0 + $OpenGL::triCount1 + $OpenGL::triCount2 + $OpenGL::triCount3 @ + " PC: " @ $OpenGL::primCount0 + $OpenGL::primCount1 + $OpenGL::primCount2 + $OpenGL::primCount3 @ + " T_T: " @ $OpenGL::triCount1 @ + " T_P: " @ $OpenGL::primCount1 @ + " I_T: " @ $OpenGL::triCount2 @ + " I_P: " @ $OpenGL::primCount2 @ + " TS_T: " @ $OpenGL::triCount3 @ + " TS_P: " @ $OpenGL::primCount3 @ + " ?_T: " @ $OpenGL::triCount0 @ + " ?_P: " @ $OpenGL::primCount0; +} + +function interiorMetrics() +{ + return frameCounter() @ + " NTL: " @ $Video::numTexelsLoaded @ + " TRP: " @ $Video::texResidentPercentage @ + " INP: " @ $Metrics::Interior::numPrimitives @ + " INT: " @ $Matrics::Interior::numTexturesUsed @ + " INO: " @ $Metrics::Interior::numInteriors; +} + +function textureMetrics() +{ + return frameCounter() @ + " NTL: " @ $Video::numTexelsLoaded @ + " TRP: " @ $Video::texResidentPercentage @ + " TCM: " @ $Video::textureCacheMisses; +} + +function waterMetrics() +{ + return frameCounter() @ + " Tri#: " @ $T2::waterTriCount @ + " Pnt#: " @ $T2::waterPointCount @ + " Hz#: " @ $T2::waterHazePointCount; +} + +function timeMetrics() +{ + return frameCounter() @ " Time: " @ getSimTime() @ " Mod: " @ getSimTime() % 32; +} + +function vehicleMetrics() +{ + return frameCounter() @ + " R: " @ $Vehicle::retryCount @ + " C: " @ $Vehicle::searchCount @ + " P: " @ $Vehicle::polyCount @ + " V: " @ $Vehicle::vertexCount; +} + +function audioMetrics() +{ + return frameCounter() @ + " OH: " @ $Audio::numOpenHandles @ + " OLH: " @ $Audio::numOpenLoopingHandles @ + " OVH: " @ $Audio::numOpenVoiceHandles @ + " AS: " @ $Audio::numActiveStreams @ + " NAS: " @ $Audio::numNullActiveStreams @ + " LAS: " @ $Audio::numActiveLoopingStreams @ + " VAS: " @ $Audio::numActiveVoiceStreams @ + " LS: " @ $Audio::numLoopingStreams @ + " ILS: " @ $Audio::numInactiveLoopingStreams @ + " CLS: " @ $Audio::numCulledLoopingStreams @ + " MEM: " @ $Audio::memUsage @ + " DYN: " @ $Audio::dynamicMemUsage @ + " / " @ $Audio::dynamicMemSize @ + " CNT: " @ $Audio::dynamicBufferCount @ + " / " @ $Audio::bufferCount; +} + +function DebugMetrics() +{ + return frameCounter() @ + " NTL: " @ $Video::numTexelsLoaded @ + " TRP: " @ $Video::texResidentPercentage @ + " NP: " @ $Metrics::numPrimitives @ + " NT: " @ $Metrics::numTexturesUsed @ + " NO: " @ $Metrics::numObjectsRendered; +} + +function showMapperMetrics( %expr ) +{ + GLEnableMetrics( %expr ); + + if( Canvas.getContent() != PlayGui.getId() ) + metricsIMain.setVisible( %expr ); + else + metricsMain.setVisible( %expr ); +} + +function showTerr() +{ + show("terrMetrics()"); +} + +function showTri() +{ + GLEnableMetrics(true); + show("triMetrics()"); +} + +function showTime() +{ + show("timeMetrics()"); +} + +function showWater() +{ + show("waterMetrics()"); +} + +function showTexture() +{ + show("textureMetrics()"); +} + +function showInterior() +{ + $fps::virtual = 0; + $Interior::numPolys = 0; + $Interior::numTextures = 0; + $Interior::numTexels = 0; + $Interior::numLightmaps = 0; + $Interior::numLumels = 0; + show("interiorMetrics()"); +} + +function showVehicle() +{ + show("vehicleMetrics()"); +} + +function showAudio() +{ + show("audioMetrics()"); +} + +function showDebug() +{ + show("DebugMetrics()"); +} + + +function show(%expr) +{ + if(%expr $= "") + { + GLEnableMetrics(false); + Canvas.popDialog(FrameOverlayGui); + } + else + { + Canvas.pushDialog(FrameOverlayGui, 1000); + TextOverlayControl.setValue(%expr); + } +} +//showInterior(); + +// check the launch mode: + +Canvas.setCursor("DefaultCursor"); + +function dumpFile(%fileName) +{ + %file = new FileObject(); + if(%file.openForRead(%fileName)) + { + while(!%file.isEOF()) + echo(%file.readLine()); + } + %file.delete(); +} + +function doScreenShot(%val) +{ + $pref::interior::showdetailmaps = false; + if(!%val) + screenShot("screen" @ $screenshotnum++ @ ".png"); +} + +// set up the movement action map +GlobalActionMap.bind(keyboard, "print", doScreenShot); +GlobalActionMap.bindCmd(keyboard, "alt enter", "", "toggleFullScreen();"); + +// Get the joystick binding functions: +exec( "scripts/joystickBind.cs" ); + +function clientCMDgetManagerID(%client) +{ + $client = %client; +} +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- // + +function abs(%val) +{ + if (%val < 0) + return %val * -1; + else + return %val; +} + +//############################################################################## +//CreateServer(testmission); +//LocalConnect(UberBob); +//############################################################################## + +function ServerConnectionAccepted() +{ + if ( !isDemo() ) + { + %info = GMJ_Browser.getServerInfoString(); + %desc = "joined a" SPC getField(%info,4) @ " game (" @ getField(%info,3) @ ") on the \"" @ getField(%info,0) @ "\" server."; + + IRCClient::onJoinGame($JoinGameAddress,%desc); + + if ( !$pref::Net::CheckEmail ) + CancelEmailCheck(); + + // if($pref::Net::DisconnectChat) + // IRCClient::quit(); + } + + checkGotLoadInfo(); +} + +function LocalConnectionAccepted() +{ + if ( !isDemo() ) + { + %desc = $pref::IRCClient::hostmsg; + + IRCClient::onJoinGame("", %desc); + + if ( !$pref::Net::CheckEmail ) + CancelEmailCheck(); + + // if($pref::Net::DisconnectChat) + // IRCClient::quit(); //this is screwed up right now ^^ + } + + checkGotLoadInfo(); +} + +function checkGotLoadInfo() +{ + if ( LoadingGui.gotLoadInfo ) + Canvas.setContent( LoadingGui ); + else + LoadingGui.checkSchedule = schedule( 500, 0, checkGotLoadInfo ); +} + +function cancelLoadInfoCheck() +{ + if ( LoadingGui.checkSchedule ) + { + cancel( LoadingGui.checkSchedule ); + LoadingGui.checkSchedule = ""; + } +} + +function DispatchLaunchMode() +{ + switch$($LaunchMode) + { + case "InteriorView": + if ( isFile( "missions/interiorTest.mis" ) ) + { + $InteriorArgument = $TestObjectFileName; + $extension = fileExt( $TestObjectFileName ); + if ( stricmp( $extension, ".dif\"" ) == 0 ) + { + // Have to adjust for quotes: + $TestObjectFileName = getSubStr( $TestObjectFileName, + 1, strlen( $TestObjectFileName ) - 2 ); + } + + if ( getSubStr( $TestObjectFileName, strlen( $TestObjectFileName ) - 6, 1 ) $= "_" ) + { + // Strip the detail part off... + $TestObjectFileName = getSubStr( $TestObjectFileName, 0, strlen( $TestObjectFileName ) - 6 ) @ ".dif"; + } + + echo( $TestObjectFileName @ " is the file loaded" ); + + $ServerName = $Host::GameName; + $Host::TimeLimit = 60; + CreateServer( "interiorTest", "InteriorTest" ); + localConnect( "TestGuy" ); + } + else + MessageBoxOK( "FILE NOT FOUND", "You do not have the interior test mission in your mission folder.\nTalk to Brad or Tom to get it.", "quit();" ); + case "Connect": + OnlineLogIn(); + setNetPort(0); + JoinGame($JoinGameAddress); + case "HostGame": + $ServerName = $Host::GameName; + $Host::MissionType = $MissionType; + $Host::Map = $Mission; + CreateServer($Mission, $MissionType); + localConnect(); + case "Normal": + OnlineLogIn(); + case "Offline": + PlayOffline(); + case "TSShow": + startShow(); + case "SceneLight": + CreateServer($Mission); + localConnect(); + case "Demo": + LoopDemos(); + } + + if ($Host::Dedicated) //Server doesn't need to initialize client Startup + return; + + //If we're offline, check if the user has a LAN account setup.. + if (!$PlayingOnline && $Pref::LANAccount::Name $= "" || $Pref::LANAccount::PassWord $= "" && $Pref::FirstRan) + canvas.pushDialog(LANAccountCreationDLG); + + if (!$Pref::FirstRan) //Technically the gameMode is included, but the BETA maps are not there + { + $Pref::FirstRan = true; + if (!$PlayingOnline && $Pref::LANAccount::Name $= "" || $Pref::LANAccount::PassWord $= "") + messageBoxOk("WARNING","This version of T2Bol ("@$ModVersionText@") does not include the RPG gamemode. If possible, please update the mod.",canvas.pushDialog(LANAccountCreationDLG)); + else + messageBoxOk("WARNING","This version of T2Bol ("@$ModVersionText@") does not include the RPG gamemode. If possible, please update the mod."); + } +} + +// if($LaunchMode !$= "Demo") +// VerifyCDCheck(DispatchLaunchMode); +// else + DispatchLaunchMode(); + setPerfCounterEnable(0); //Nobody needs the damn perf counter anymore ... diff --git a/data/Info.dat b/data/Info.dat index 81e3596..c06cf73 100644 --- a/data/Info.dat +++ b/data/Info.dat @@ -1,8 +1,8 @@ -Info.dat -Information about this version of BoL used by servers and clients (pretty much compatability checks and updates) -Copyright (c) 2012 The DarkDragonDX - -[Version] -Major = 1; -Minor = 1; +Info.dat +Information about this version of BoL used by servers and clients (pretty much compatability checks and updates) +Copyright (c) 2012 The DarkDragonDX + +[Version] +Major = 1; +Minor = 1; Codename = Ragora; \ No newline at end of file diff --git a/data/RPGPreferences.txt b/data/RPGPreferences.txt index aee572b..e2ff285 100644 --- a/data/RPGPreferences.txt +++ b/data/RPGPreferences.txt @@ -1,10 +1,10 @@ -[RPG] -keepCorpses = true; -maxCorpses = 6; - -[PawsAreNice] -Indeed = true; - -[Server] -SpaceServer = "192.168.1.5"; +[RPG] +keepCorpses = true; +maxCorpses = 6; + +[PawsAreNice] +Indeed = true; + +[Server] +SpaceServer = "192.168.1.5"; EarthServer = "192.168.1.5"; \ No newline at end of file diff --git a/data/SavedData.cs b/data/SavedData.cs deleted file mode 100644 index 499e0d5..0000000 --- a/data/SavedData.cs +++ /dev/null @@ -1,416 +0,0 @@ -$Data::Ammo1836101295_0_AlphaSector = "100"; -$Data::Ammo1836101295_0_Earth = "100"; -$Data::Ammo1836101295_1_AlphaSector = "15"; -$Data::Ammo1836101295_1_Earth = "15"; -$Data::Ammo2003098_1_Earth = "15"; -$Data::Ammo2003098_1_rpg_new = "17"; -$Data::Ammo2003098_2_Earth = "100"; -$Data::Ammo2003098_2_rpg_new = "100"; -$Data::Ammo427694980_1_AlphaSector = "15"; -$Data::Ammo427694980_1_Earth = "12"; -$Data::Ammo427694980_2_AlphaSector = "100"; -$Data::Ammo427694980_2_Earth = "0"; -$Data::Armor1836101295_AlphaSector = "Light"; -$Data::Armor1836101295_Earth = "Light"; -$Data::Armor2003098_Earth = "LIGHT"; -$Data::Armor2003098_rpg_new = "LIGHT"; -$Data::Armor427694980_AlphaSector = "LIGHT"; -$Data::Armor427694980_Earth = "LIGHT"; -$Data::Caps = 3; -$Data::Caps0 = 0; -$Data::Caps1682851961 = 0; -$Data::Caps1836101295 = 0; -$Data::Caps2003098 = 5; -$Data::Caps2485526 = 0; -$Data::Caps3738647 = 0; -$Data::Caps427694980 = 2; -$Data::Caps960691562 = 0; -$Data::ClanCount = 3; -$Data::ClanDesc0 = "We do what we must because we can."; -$Data::ClanDesc1 = "A test.."; -$Data::ClanID1836101295 = "0"; -$Data::ClanID2003098 = "2"; -$Data::ClanID427694980 = "1"; -$Data::ClanLeader0 = "DarkDragonDX"; -$Data::ClanLeader1 = "Dark Dragon DX"; -$Data::ClanLeader2 = "DarkDragonDX"; -$Data::ClanLeaderGUID0 = "1836101295"; -$Data::ClanLeaderGUID1 = "427694980"; -$Data::ClanLeaderGUID2 = "2003098"; -$Data::ClanMember0_0 = "1836101295"; -$Data::ClanMember1_0 = "427694980"; -$Data::ClanMember2_0 = "2003098"; -$Data::ClanName0 = "Draakan Militia"; -$Data::ClanName1 = "Draakan Militia"; -$Data::ClanName2 = "Alpha Viper"; -$Data::ClanTag0 = "|-{DRK}-|"; -$Data::ClanTag1 = "|-{DRK}-|"; -$Data::ClanTag2 = "-|{VPR}|-"; -$Data::Client0 = "427694980"; -$Data::ClientCount = 4; -$Data::ClientGUID1 = "2003098"; -$Data::ClientGUID2 = "2485526"; -$Data::ClientGUID3 = "0"; -$Data::ClientName0 = "Dark Dragon DX"; -$Data::ClientName1 = "DarkDragonDX"; -$Data::ClientName2 = "Dayuppy"; -$Data::ClientName3 = "DarkDragonDX"; -$Data::DamageFlash1836101295_AlphaSector = "0"; -$Data::DamageFlash1836101295_Earth = "0"; -$Data::DamageFlash2003098_Earth = "0"; -$Data::DamageFlash2003098_rpg_new = "0"; -$Data::DamageFlash427694980_AlphaSector = "0"; -$Data::DamageFlash427694980_Earth = "0"; -$Data::Deaths = 10262; -$Data::Deaths0 = 0; -$Data::Deaths1682851961 = 4; -$Data::Deaths1836101295 = 16; -$Data::Deaths2003098 = 276; -$Data::Deaths2139104 = 1; -$Data::Deaths2450675 = 3; -$Data::Deaths2485526 = 4; -$Data::Deaths2544511 = 1; -$Data::Deaths3119044 = 5; -$Data::Deaths3392146 = 38; -$Data::Deaths3637691 = 4; -$Data::Deaths3738647 = 11; -$Data::Deaths3819266 = 9; -$Data::Deaths427694980 = 12; -$Data::Deaths960691562 = 1; -$Data::EMail::Contents0_1 = "Welcome to T2Bol, try not to die."; -$Data::EMail::Contents2003098_1 = "Welcome to T2Bol, try not to die."; -$Data::EMail::Contents2485526_1 = "Welcome to T2Bol, try not to die."; -$Data::Email::Contents427694980_ = "Hey.. does it work?"; -$Data::Email::Contents427694980_1 = "blah"; -$Data::EMail::Contents427694980_10 = "blah"; -$Data::EMail::Contents427694980_11 = "blah"; -$Data::EMail::Contents427694980_12 = "blah"; -$Data::EMail::Contents427694980_13 = "Noticed this is working.. holy shit. Test Test Test Test Test Test Test Test Test"; -$Data::EMail::Contents427694980_14 = "ddddddddddddddddddddddddddddddddddddddddd"; -$Data::EMail::Contents427694980_15 = "ddddddddddddddddddddddddddddddddddddddddd"; -$Data::EMail::Contents427694980_16 = "ddddddddddddddddddddddddddddddddddddddd\tdddddd"; -$Data::EMail::Contents427694980_17 = "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq\tqt"; -$Data::EMail::Contents427694980_18 = "LOLOLOLOLODFUYSFDSFSDFSDFSDFSDFFFDLOLS"; -$Data::Email::Contents427694980_2 = "blah"; -$Data::Email::Contents427694980_3 = "blah"; -$Data::Email::Contents427694980_4 = "blah"; -$Data::Email::Contents427694980_5 = "blah"; -$Data::Email::Contents427694980_6 = "blah"; -$Data::Email::Contents427694980_7 = "blah"; -$Data::Email::Contents427694980_8 = "blah"; -$Data::Email::Contents427694980_9 = "blah"; -$Data::EMail::Contents_ = "Hey, this is awesome, right?"; -$Data::EMail::Contents_1 = "Wootage Test. Fantastic email system ya\t got here."; -$Data::EMail::Contents_2 = "Works?"; -$Data::EMail::Contents_3 = "Free stuff! o-o"; -$Data::EMail::Count = 4; -$Data::EMail::Count0 = 1; -$Data::EMail::Count2003098 = 1; -$Data::EMail::Count2485526 = 1; -$Data::Email::Count427694980 = 19; -$Data::EMail::Date0_1 = "Saturday, July 28, 2012 @ 08:32 PM"; -$Data::EMail::Date2003098_1 = "Monday, March 29, 2010 @ 03:42 PM"; -$Data::EMail::Date2485526_1 = "Tuesday, October 26, 2010 @ 03:25 AM"; -$Data::Email::Date427694980_ = "Wednesday, March 24, 2010 amt 12:43 AM"; -$Data::Email::Date427694980_1 = "Wednesday, March 24, 2010 pmt 10:33 PM"; -$Data::EMail::Date427694980_10 = "Wednesday, March 24, 2010 @ 10:50 PM"; -$Data::EMail::Date427694980_11 = "Wednesday, March 24, 2010 @ 10:55 PM"; -$Data::EMail::Date427694980_12 = "Wednesday, March 24, 2010 @ 10:55 PM"; -$Data::EMail::Date427694980_13 = "Wednesday, March 24, 2010 @ 10:56 PM"; -$Data::EMail::Date427694980_14 = "Wednesday, March 24, 2010 @ 11:03 PM"; -$Data::EMail::Date427694980_15 = "Wednesday, March 24, 2010 @ 11:04 PM"; -$Data::EMail::Date427694980_16 = "Wednesday, March 24, 2010 @ 11:10 PM"; -$Data::EMail::Date427694980_17 = "Wednesday, March 24, 2010 @ 11:13 PM"; -$Data::EMail::Date427694980_18 = "Wednesday, March 24, 2010 @ 11:14 PM"; -$Data::Email::Date427694980_2 = "Wednesday, March 24, 2010 pmt 10:33 PM"; -$Data::Email::Date427694980_3 = "Wednesday, March 24, 2010 @ 10:46 PM"; -$Data::Email::Date427694980_4 = "Wednesday, March 24, 2010 @ 10:46 PM"; -$Data::Email::Date427694980_5 = "Wednesday, March 24, 2010 @ 10:47 PM"; -$Data::Email::Date427694980_6 = "Wednesday, March 24, 2010 @ 10:47 PM"; -$Data::Email::Date427694980_7 = "Wednesday, March 24, 2010 @ 10:47 PM"; -$Data::Email::Date427694980_8 = "Wednesday, March 24, 2010 @ 10:47 PM"; -$Data::Email::Date427694980_9 = "Wednesday, March 24, 2010 @ 10:50 PM"; -$Data::EMail::Date_ = "Tuesday, October 26, 2010 @ 03:30 AM"; -$Data::EMail::Date_1 = "Tuesday, October 26, 2010 @ 03:33 AM"; -$Data::EMail::Date_2 = "Tuesday, October 26, 2010 @ 04:01 AM"; -$Data::EMail::Date_3 = "Thursday, August 02, 2012 @ 10:08 PM"; -$Data::EMail::Sender0_1 = "The Comittee"; -$Data::EMail::Sender2003098_1 = "The Comittee"; -$Data::EMail::Sender2485526_1 = "The Comittee"; -$Data::Email::Sender427694980_ = "\x10\c7DRK\c6Dark Dragon DX\x11"; -$Data::Email::Sender427694980_1 = "\x10\c7|-{DRK}-|\c6Dark Dragon DX\x11"; -$Data::EMail::Sender427694980_10 = "\x10\c7|-{DRK}-|\c6Dark Dragon DX\x11"; -$Data::EMail::Sender427694980_11 = "\x10\c7|-{DRK}-|\c6Dark Dragon DX\x11"; -$Data::EMail::Sender427694980_12 = "\x10\c7|-{DRK}-|\c6Dark Dragon DX\x11"; -$Data::EMail::Sender427694980_13 = "\x10\c7|-{DRK}-|\c6Dark Dragon DX\x11"; -$Data::EMail::Sender427694980_14 = "\x10\c7|-{DRK}-|\c6Dark Dragon DX\x11"; -$Data::EMail::Sender427694980_15 = "\x10\c7|-{DRK}-|\c6Dark Dragon DX\x11"; -$Data::EMail::Sender427694980_16 = "\x10\c7|-{DRK}-|\c6Dark Dragon DX\x11"; -$Data::EMail::Sender427694980_17 = "\x10\c7|-{DRK}-|\c6Dark Dragon DX\x11"; -$Data::EMail::Sender427694980_18 = "\x10\c7|-{DRK}-|\c6Dark Dragon DX\x11"; -$Data::Email::Sender427694980_2 = "\x10\c7|-{DRK}-|\c6Dark Dragon DX\x11"; -$Data::Email::Sender427694980_3 = "\x10\c7|-{DRK}-|\c6Dark Dragon DX\x11"; -$Data::Email::Sender427694980_4 = "\x10\c7|-{DRK}-|\c6Dark Dragon DX\x11"; -$Data::Email::Sender427694980_5 = "\x10\c7|-{DRK}-|\c6Dark Dragon DX\x11"; -$Data::Email::Sender427694980_6 = "\x10\c7|-{DRK}-|\c6Dark Dragon DX\x11"; -$Data::Email::Sender427694980_7 = "\x10\c7|-{DRK}-|\c6Dark Dragon DX\x11"; -$Data::Email::Sender427694980_8 = "\x10\c7|-{DRK}-|\c6Dark Dragon DX\x11"; -$Data::Email::Sender427694980_9 = "\x10\c7|-{DRK}-|\c6Dark Dragon DX\x11"; -$Data::EMail::Sender_ = "DarkDragonDX"; -$Data::EMail::Sender_1 = "Dayuppy"; -$Data::EMail::Sender_2 = "\x10\c7-|{VPR}|-\c6DarkDragonDX\x11"; -$Data::EMail::Sender_3 = "\x10\c7-|{VPR}|-\c6DarkDragonDX\x11"; -$Data::EMail::Title0_1 = "Welcome"; -$Data::EMail::Title2003098_1 = "Welcome"; -$Data::EMail::Title2485526_1 = "Welcome"; -$Data::Email::Title427694980_ = "Test"; -$Data::EMail::Title_ = "Hey"; -$Data::EMail::Title_1 = "Woot"; -$Data::EMail::Title_2 = "Test"; -$Data::EMail::Title_3 = "Paws"; -$Data::EMailCount427694980 = 10; -$Data::Energy1836101295_AlphaSector = "34.2759"; -$Data::Energy1836101295_Earth = "60"; -$Data::Energy2003098_Earth = "60"; -$Data::Energy2003098_rpg_new = "46.552"; -$Data::Energy427694980_AlphaSector = "60"; -$Data::Energy427694980_Earth = "60"; -$Data::FlagReturns = 42; -$Data::FlagReturns0 = 0; -$Data::FlagReturns1682851961 = 0; -$Data::FlagReturns1836101295 = 0; -$Data::FlagReturns2003098 = 5; -$Data::FlagReturns2485526 = 0; -$Data::FlagReturns3738647 = 0; -$Data::FlagReturns427694980 = 0; -$Data::FlagReturns960691562 = 0; -$Data::Headshots = 0; -$Data::Headshots0 = 0; -$Data::Headshots1682851961 = 0; -$Data::Headshots1836101295 = 0; -$Data::Headshots2003098 = 0; -$Data::Headshots2485526 = 0; -$Data::Headshots3738647 = 0; -$Data::Headshots427694980 = 0; -$Data::Headshots960691562 = 0; -$Data::Health1836101295_AlphaSector = "0"; -$Data::Health1836101295_Earth = "0.0139489"; -$Data::Health2003098_Earth = "0.499071"; -$Data::Health2003098_rpg_new = "0.617923"; -$Data::Health427694980_AlphaSector = "0"; -$Data::Health427694980_Earth = "0.645"; -$Data::Hits = 133656; -$Data::Hits0 = 0; -$Data::Hits1682851961 = 1122; -$Data::Hits1836101295 = 652; -$Data::Hits2003098 = 4572; -$Data::Hits2139104 = 23; -$Data::Hits2450675 = 30; -$Data::Hits2485526 = 327; -$Data::Hits2544511 = 227; -$Data::Hits2886178 = 13; -$Data::Hits3119044 = 271; -$Data::Hits3392146 = 395; -$Data::Hits3637691 = 112; -$Data::Hits3738647 = 75; -$Data::Hits3819266 = 63; -$Data::Hits427694980 = 867; -$Data::Hits960691562 = 33; -$Data::IsInClan1836101295 = 1; -$Data::IsInClan2003098 = 1; -$Data::IsInClan427694980 = 1; -$Data::IsRegistered = 1; -$Data::IsRegistered0 = 1; -$Data::IsRegistered1682851961 = 1; -$Data::IsRegistered1836101295 = 1; -$Data::IsRegistered2003098 = 1; -$Data::IsRegistered2485526 = 1; -$Data::IsRegistered3738647 = 1; -$Data::IsRegistered427694980 = 1; -$Data::IsRegistered960691562 = 1; -$Data::IsRPGReady0 = 1; -$Data::IsRPGReady1836101295 = 1; -$Data::IsRPGReady2003098 = 1; -$Data::IsRPGReady2485526 = 1; -$Data::IsRPGReady427694980 = 1; -$Data::Kills = 9706; -$Data::Kills0 = 0; -$Data::Kills1682851961 = 30; -$Data::Kills1836101295 = 54; -$Data::Kills2003098 = 636; -$Data::Kills2139104 = 1; -$Data::Kills2450675 = 1; -$Data::Kills2485526 = 18; -$Data::Kills2544511 = 13; -$Data::Kills3119044 = 84; -$Data::Kills3392146 = 32; -$Data::Kills3637691 = 12; -$Data::Kills3738647 = 5; -$Data::Kills3819266 = 5; -$Data::Kills427694980 = 76; -$Data::Kills960691562 = 13; -$Data::Lost = 0; -$Data::Lost0 = 0; -$Data::Lost1682851961 = 0; -$Data::Lost1836101295 = 1; -$Data::Lost2003098 = 0; -$Data::Lost2485526 = 0; -$Data::Lost3738647 = 0; -$Data::Lost427694980 = 0; -$Data::Lost960691562 = 0; -$Data::Misses = 0; -$Data::Misses0 = 0; -$Data::Misses1682851961 = 0; -$Data::Misses1836101295 = 0; -$Data::Misses2003098 = 0; -$Data::Misses2485526 = 0; -$Data::Misses3738647 = 0; -$Data::Misses427694980 = 0; -$Data::Misses960691562 = 0; -$Data::Money0_Earth = 0; -$Data::Money1836101295_AlphaSector = "800"; -$Data::Money2003098_Earth = "0"; -$Data::Money2485526_Earth = 0; -$Data::Money427694980_Earth = "0"; -$Data::Pack1836101295_AlphaSector = "EnergyPack"; -$Data::Pack1836101295_Earth = "MiningTool"; -$Data::Pack2003098_Earth = "MiningTool"; -$Data::Pack427694980_Earth = "MiningTool"; -$Data::Race0 = "Draakan"; -$Data::Race1836101295 = "Draakan"; -$Data::Race2003098 = "Draakan"; -$Data::Race2485526 = "Draakan"; -$Data::Race427694980 = "Draakan"; -$Data::RepairKits1836101295_AlphaSector = "1"; -$Data::RepairKits1836101295_Earth = "1"; -$Data::RepairKits2003098_Earth = "0"; -$Data::RepairKits2003098_rpg_new = "0"; -$Data::RepairKits427694980_AlphaSector = "1"; -$Data::RepairKits427694980_Earth = "0"; -$Data::Rounds1682851961_SlapDashSV = 3; -$Data::Rounds1836101295_SlapDashSV = 1; -$Data::Rounds2003098_KatabaticSV = 6; -$Data::Rounds2003098_SlapDashSV = 6; -$Data::Rounds2485526_SlapDashSV = 3; -$Data::Rounds2544511_SlapDashSV = 3; -$Data::Rounds3119044_SlapDashSV = 3; -$Data::Rounds3392146_SlapDashSV = 1; -$Data::Rounds3637691_SlapDashSV = 4; -$Data::Rounds427694980_KatabaticSV = 1; -$Data::Rounds427694980_SlapdashSV = 2; -$Data::Rounds960691562_KatabaticSV = 1; -$Data::Rounds960691562_SlapDashSV = 2; -$Data::Rounds_KatabaticSV = 5; -$Data::Rounds_SlapDashSV = 1; -$Data::Sex0 = "A"; -$Data::Sex1836101295 = "A"; -$Data::Sex2003098 = "A"; -$Data::Sex2485526 = "A"; -$Data::Sex427694980 = "A"; -$Data::Shots = 167489; -$Data::Shots0 = 0; -$Data::Shots1682851961 = 1744; -$Data::Shots1836101295 = 780; -$Data::Shots2003098 = 5964; -$Data::Shots2139104 = 24; -$Data::Shots2450675 = 36; -$Data::Shots2485526 = 450; -$Data::Shots2544511 = 293; -$Data::Shots2886178 = 15; -$Data::Shots3119044 = 471; -$Data::Shots3392146 = 476; -$Data::Shots3637691 = 161; -$Data::Shots3738647 = 99; -$Data::Shots3819266 = 63; -$Data::Shots427694980 = 1258; -$Data::Shots960691562 = 37; -$Data::ShouldApply = 0; -$Data::ShouldApply1836101295 = 0; -$Data::ShouldApply1836101295_AlphaSector = 1; -$Data::ShouldApply1836101295_Earth = 1; -$Data::ShouldApply2003098 = 0; -$Data::ShouldApply2003098_Earth = 1; -$Data::ShouldApply2003098_rpg_new = 1; -$Data::ShouldApply2485526 = 0; -$Data::ShouldApply2886178 = 0; -$Data::ShouldApply3119044 = 0; -$Data::ShouldApply3392146 = 0; -$Data::ShouldApply3434461 = 0; -$Data::ShouldApply427694980 = 0; -$Data::ShouldApply427694980_AlphaSector = 1; -$Data::ShouldApply427694980_Earth = 1; -$Data::Steel0_Earth = 0; -$Data::Steel1836101295_AlphaSector = "0.182"; -$Data::Steel1836101295_Earth = "0.044"; -$Data::Steel2485526_Earth = 0; -$Data::Suicides = 1205; -$Data::Suicides0 = 0; -$Data::Suicides1682851961 = 0; -$Data::Suicides1836101295 = 1; -$Data::Suicides2003098 = 27; -$Data::Suicides2450675 = 2; -$Data::Suicides2485526 = 1; -$Data::Suicides3119044 = 3; -$Data::Suicides3392146 = 9; -$Data::Suicides3738647 = 1; -$Data::Suicides427694980 = 8; -$Data::Suicides960691562 = 0; -$Data::Transform1836101295_AlphaSector = "-309.232 334.187 309.913 0 0 1 0.667341"; -$Data::Transform1836101295_Earth = "-370.341 851.922 68.7601 0 0 1 1.14368"; -$Data::Transform2003098_Earth = "-1060.18 469.128 92.4371 0 0 -0.99993 0.0256617"; -$Data::Transform2003098_rpg_new = "-32.9661 334.381 93.2455 0 0 1 3.65726"; -$Data::Transform427694980_AlphaSector = "82.863 -653.983 186.762 0 0 -1 0.916839"; -$Data::Transform427694980_Earth = "-1023.9 512.742 92.3865 0 0 1 2.39569"; -$Data::Velocity1836101295_AlphaSector = "15.4637 13.9548 3.02164"; -$Data::Velocity1836101295_Earth = "0 0 0"; -$Data::Velocity2003098_Earth = "0 0 0"; -$Data::Velocity2003098_rpg_new = "12.4202 -23.2183 1.94154"; -$Data::Velocity427694980_AlphaSector = "0.82034 0.175601 -33.5394"; -$Data::Velocity427694980_Earth = "0 0 0"; -$Data::WasInVehicle1836101295_AlphaSector = 0; -$Data::WasInVehicle1836101295_Earth = 0; -$Data::WasInVehicle2003098_Earth = 0; -$Data::WasInVehicle2003098_rpg_new = 0; -$Data::WasInVehicle427694980_AlphaSector = 0; -$Data::WasInVehicle427694980_Earth = 0; -$Data::Weapon1836101295_0_AlphaSector = "Chaingun"; -$Data::Weapon1836101295_0_Earth = "Chaingun"; -$Data::Weapon1836101295_1_AlphaSector = "Disc"; -$Data::Weapon1836101295_1_Earth = "Disc"; -$Data::Weapon1836101295_2_AlphaSector = "ShockLance"; -$Data::Weapon1836101295_2_Earth = "ShockLance"; -$Data::Weapon1836101295_3_AlphaSector = "TargetingLaser"; -$Data::Weapon1836101295_3_Earth = "TargetingLaser"; -$Data::Weapon1836101295_4_AlphaSector = "TargetingLaser"; -$Data::Weapon2003098_0_Earth = "Blaster"; -$Data::Weapon2003098_0_rpg_new = "Blaster"; -$Data::Weapon2003098_1_Earth = "Disc"; -$Data::Weapon2003098_1_rpg_new = "Disc"; -$Data::Weapon2003098_2_Earth = "Chaingun"; -$Data::Weapon2003098_2_rpg_new = "Chaingun"; -$Data::Weapon2003098_3_Earth = "TargetingLaser"; -$Data::Weapon2003098_4_Earth = "TargetingLaser"; -$Data::Weapon2003098_4_rpg_new = "TargetingLaser"; -$Data::Weapon427694980_0_AlphaSector = "Blaster"; -$Data::Weapon427694980_0_Earth = "Blaster"; -$Data::Weapon427694980_1_AlphaSector = "Disc"; -$Data::Weapon427694980_1_Earth = "Disc"; -$Data::Weapon427694980_2_AlphaSector = "Chaingun"; -$Data::Weapon427694980_2_Earth = "Chaingun"; -$Data::Weapon427694980_4_AlphaSector = "TargetingLaser"; -$Data::Weapon427694980_4_Earth = "TargetingLaser"; -$Data::Whiteout1836101295_AlphaSector = "0"; -$Data::Whiteout1836101295_Earth = "0"; -$Data::Whiteout2003098_Earth = "0"; -$Data::Whiteout2003098_rpg_new = "0"; -$Data::Whiteout427694980_AlphaSector = "0"; -$Data::Whiteout427694980_Earth = "0"; -$Data::Won = 0; -$Data::Won0 = 0; -$Data::Won1682851961 = 0; -$Data::Won1836101295 = 0; -$Data::Won2003098 = 0; -$Data::Won2485526 = 0; -$Data::Won3738647 = 0; -$Data::Won427694980 = 0; -$Data::Won960691562 = 0; diff --git a/data/bolContent/pdaApplications/Clan Management.cs b/data/bolContent/pdaApplications/Clan Management.cs index a3daebe..0966a0e 100644 --- a/data/bolContent/pdaApplications/Clan Management.cs +++ b/data/bolContent/pdaApplications/Clan Management.cs @@ -1,15 +1,15 @@ -//------------------------------------------------------------------------------ -// Clan Management.cs -// The clan management system for BoL RPg Mod. -// Copyright (c) 2012 The DarkDragonDX -//============================================================================== - -// Entry Point (called when the client first clicks it) -function EMailClient::main(%this, %client) -{ -} - -// action function, it's called when the client navigates. -function EMailClient::action(%this, %client, %page) -{ +//------------------------------------------------------------------------------ +// Clan Management.cs +// The clan management system for BoL RPg Mod. +// Copyright (c) 2012 Robert MacGregor +//============================================================================== + +// Entry Point (called when the client first clicks it) +function EMailClient::main(%this, %client) +{ +} + +// action function, it's called when the client navigates. +function EMailClient::action(%this, %client, %page) +{ } \ No newline at end of file diff --git a/data/bolContent/pdaApplications/EMail.cs b/data/bolContent/pdaApplications/EMail.cs index 6c811d5..f40e0ff 100644 --- a/data/bolContent/pdaApplications/EMail.cs +++ b/data/bolContent/pdaApplications/EMail.cs @@ -1,15 +1,15 @@ -//------------------------------------------------------------------------------ -// EMail.cs -// An E-Mail client for the Birth of Legend RPG Mod. -// Copyright (c) 2012 The DarkDragonDX -//============================================================================== - -// Entry Point (called when the client first clicks it) -function EMailClient::main(%this, %client) -{ -} - -// action function, it's called when the client navigates. -function EMailClient::action(%this, %client, %page) -{ +//------------------------------------------------------------------------------ +// EMail.cs +// An E-Mail client for the Birth of Legend RPG Mod. +// Copyright (c) 2012 Robert MacGregor +//============================================================================== + +// Entry Point (called when the client first clicks it) +function EMailClient::main(%this, %client) +{ +} + +// action function, it's called when the client navigates. +function EMailClient::action(%this, %client, %page) +{ } \ No newline at end of file diff --git a/data/bolContent/pdaApplications/Save.cs b/data/bolContent/pdaApplications/Save.cs index faba7c2..22c7f79 100644 --- a/data/bolContent/pdaApplications/Save.cs +++ b/data/bolContent/pdaApplications/Save.cs @@ -1,20 +1,20 @@ -//------------------------------------------------------------------------------ -// Save.cs -// The PDA Save function for BoL RPG mod. -// Copyright (c) 2012 The DarkDragonDX -//============================================================================== - -// Entry Point (called when the client first clicks it) -function EMailClient::main(%this, %client) -{ -} - -// action function, it's called when the client navigates. -function EMailClient::action(%this, %client, %page) -{ -} - -// exit function, it's called when the client exits (returns to PDAMain) -function EMailClient::exit(%this, %client, %page) -{ +//------------------------------------------------------------------------------ +// Save.cs +// The PDA Save function for BoL RPG mod. +// Copyright (c) 2012 Robert MacGregor +//============================================================================== + +// Entry Point (called when the client first clicks it) +function EMailClient::main(%this, %client) +{ +} + +// action function, it's called when the client navigates. +function EMailClient::action(%this, %client, %page) +{ +} + +// exit function, it's called when the client exits (returns to PDAMain) +function EMailClient::exit(%this, %client, %page) +{ } \ No newline at end of file diff --git a/data/campaigns/Tribes 2.dat b/data/campaigns/Tribes 2.dat index 9700808..52a902f 100644 --- a/data/campaigns/Tribes 2.dat +++ b/data/campaigns/Tribes 2.dat @@ -1,33 +1,33 @@ -Tribes 2.dat -Tribes 2 Campaign Configuration -Copyright (c) 2012 The DarkDragonDX - -[Campaign] -Training = Training; -Mission1 = Training1; -MissionText1 = Charybdis; -Mission2 = Training2; -MissionText2 = Sehrganda Prime; -Mission3 = Training3; -MissionText3 = Ymir; -Mission4 = Training4; -MissionText4 = Bloodjewel; -Mission5 = Training5; -MissionText5 = Shi-Draconis Alpha; -MissionCount = 5; -Name = Tribes 2; - -[Settings] -Name = Lone Wolf; -TeamName = Star Wolf; -Race = Human; -Sex = Male; -Voice = Male1; -VoicePitch = 1; -Skin = SWolf; -EnemySkin = Horde; -EnemyName = Horde; -PlayerTeam = 1; -EnemyTeam = 2; -StartLives = 3; +Tribes 2.dat +Tribes 2 Campaign Configuration +Copyright (c) 2012 The DarkDragonDX + +[Campaign] +Training = Training; +Mission1 = Training1; +MissionText1 = Charybdis; +Mission2 = Training2; +MissionText2 = Sehrganda Prime; +Mission3 = Training3; +MissionText3 = Ymir; +Mission4 = Training4; +MissionText4 = Bloodjewel; +Mission5 = Training5; +MissionText5 = Shi-Draconis Alpha; +MissionCount = 5; +Name = Tribes 2; + +[Settings] +Name = Lone Wolf; +TeamName = Star Wolf; +Race = Human; +Sex = Male; +Voice = Male1; +VoicePitch = 1; +Skin = SWolf; +EnemySkin = Horde; +EnemyName = Horde; +PlayerTeam = 1; +EnemyTeam = 2; +StartLives = 3; EnemyRace = BioDerm; \ No newline at end of file diff --git a/data/creditsText.txt b/data/creditsText.txt index 0423f2f..f0f08a9 100644 --- a/data/creditsText.txt +++ b/data/creditsText.txt @@ -1,62 +1,62 @@ - - - - -Tribes2\x99 is a registered trademark of Sierra Games and the original development team of Tribes2\x99 - Dynamix. - -Scripters -Dark Dragon DX (Vector) - Lead Developer -EmperorsChamp - His RPG Script helped insired this mod -UberGuy - Borrowed DSO Script - - -Modelers -Netmanx - Attempted to model Draakans -UrbanAssault - Borrowed some interiors -IronSphere - Borrowed shapes & interiors -Low Poly Cooperative - Borrowed Camera & Pipe Model - - -Audio Mixers -Blnukem - Lead Music Mixer -Josef Jahn - Borrowed TribesHymn (I plan on changing the song unless I can get a hold of this guy) - - -Artists -"Velo" - Provided Draakan concept sketch - - -Meta Testers -Castiger (Lyra) -DeathBorn (Tigr0nix) -Numbuh 178 (Tyler 178) -Alviss (EmperorsChamp) -Phantom139 (ShadowForce) - - -Original Roleplayers -evilhodag - Tribes 2 -StingWraith - Tribes 2 -HelterSkelter - Tribes 2 -S-Guy - Tribes 2 -Numbuh 178 (Tyler 178) - GMOD -DS=DragonStalker (Wraithz0r) - GMOD - - -General Support -Naosyth - Special Thanks for helping me get started on Torque scripting -Zaxxman -Mentulmhat -DS=DragonStalker (Wraithz0r) -DeadSoldier -NiniN -The-Construct.net - Community helped decide upon a name - - - -Sierra On-Line, Inc. owns the copyright to Tribes2. Dark Dragon DX (Vector), DEV Team, and any associates claim the copyright to this Modification (the \"mod\"), and any derivative works of this mod. By using this mod you must agree with the end user license agreement (\"EULA.txt\"). - -The events, persons, and entities contained in this mod and it's game are purely fictional. Any similarities to any real events, persons, and entities are purely coinidental. - - + + + + +Tribes2\x99 is a registered trademark of Sierra Games and the original development team of Tribes2\x99 - Dynamix. + +Scripters +Dark Dragon DX (Vector) - Lead Developer +EmperorsChamp - His RPG Script helped insired this mod +UberGuy - Borrowed DSO Script + + +Modelers +Netmanx - Attempted to model Draakans +UrbanAssault - Borrowed some interiors +IronSphere - Borrowed shapes & interiors +Low Poly Cooperative - Borrowed Camera & Pipe Model + + +Audio Mixers +Blnukem - Lead Music Mixer +Josef Jahn - Borrowed TribesHymn (I plan on changing the song unless I can get a hold of this guy) + + +Artists +"Velo" - Provided Draakan concept sketch + + +Meta Testers +Castiger (Lyra) +DeathBorn (Tigr0nix) +Numbuh 178 (Tyler 178) +Alviss (EmperorsChamp) +Phantom139 (ShadowForce) + + +Original Roleplayers +evilhodag - Tribes 2 +StingWraith - Tribes 2 +HelterSkelter - Tribes 2 +S-Guy - Tribes 2 +Numbuh 178 (Tyler 178) - GMOD +DS=DragonStalker (Wraithz0r) - GMOD + + +General Support +Naosyth - Special Thanks for helping me get started on Torque scripting +Zaxxman +Mentulmhat +DS=DragonStalker (Wraithz0r) +DeadSoldier +NiniN +The-Construct.net - Community helped decide upon a name + + + +Sierra On-Line, Inc. owns the copyright to Tribes2. Dark Dragon DX (Vector), DEV Team, and any associates claim the copyright to this Modification (the \"mod\"), and any derivative works of this mod. By using this mod you must agree with the end user license agreement (\"EULA.txt\"). + +The events, persons, and entities contained in this mod and it's game are purely fictional. Any similarities to any real events, persons, and entities are purely coinidental. + + \ No newline at end of file diff --git a/data/encyclopedia/Encyclopedia.conf b/data/encyclopedia/Encyclopedia.conf index 290fbfa..8d73efd 100644 --- a/data/encyclopedia/Encyclopedia.conf +++ b/data/encyclopedia/Encyclopedia.conf @@ -1,11 +1,11 @@ -Encyclopedia.conf -Configurations for the Encyclopedia -Copyright (c) 2012 The DarkDragonDX - -[Config] -Entry0 = "Races"; -Entry1 = "Vehicles"; -Entry2 = "Packs"; -Entry3 = "Factions"; -Entry4 = "Weapons"; +Encyclopedia.conf +Configurations for the Encyclopedia +Copyright (c) 2012 The DarkDragonDX + +[Config] +Entry0 = "Races"; +Entry1 = "Vehicles"; +Entry2 = "Packs"; +Entry3 = "Factions"; +Entry4 = "Weapons"; EncryCount = 5; \ No newline at end of file diff --git a/data/encyclopedia/characters/Beast.txt b/data/encyclopedia/characters/Beast.txt index 4603943..bd707aa 100644 --- a/data/encyclopedia/characters/Beast.txt +++ b/data/encyclopedia/characters/Beast.txt @@ -1,5 +1,5 @@ -Character: Beast -Race: BioDerm - -Beast supervises the BioDerm genetics engineering process. +Character: Beast +Race: BioDerm + +Beast supervises the BioDerm genetics engineering process. \ No newline at end of file diff --git a/data/encyclopedia/characters/Cobra.txt b/data/encyclopedia/characters/Cobra.txt index 06ae8b8..e3f7a49 100644 --- a/data/encyclopedia/characters/Cobra.txt +++ b/data/encyclopedia/characters/Cobra.txt @@ -1,5 +1,5 @@ -Character: Cobra -Race: Draakan - -Alchaldes is considered the smartest being alive. +Character: Cobra +Race: Draakan + +Alchaldes is considered the smartest being alive. \ No newline at end of file diff --git a/data/encyclopedia/characters/Commander Jackson.txt b/data/encyclopedia/characters/Commander Jackson.txt index 06ae8b8..e3f7a49 100644 --- a/data/encyclopedia/characters/Commander Jackson.txt +++ b/data/encyclopedia/characters/Commander Jackson.txt @@ -1,5 +1,5 @@ -Character: Cobra -Race: Draakan - -Alchaldes is considered the smartest being alive. +Character: Cobra +Race: Draakan + +Alchaldes is considered the smartest being alive. \ No newline at end of file diff --git a/data/encyclopedia/characters/Corperal Jones.txt b/data/encyclopedia/characters/Corperal Jones.txt index 06ae8b8..e3f7a49 100644 --- a/data/encyclopedia/characters/Corperal Jones.txt +++ b/data/encyclopedia/characters/Corperal Jones.txt @@ -1,5 +1,5 @@ -Character: Cobra -Race: Draakan - -Alchaldes is considered the smartest being alive. +Character: Cobra +Race: Draakan + +Alchaldes is considered the smartest being alive. \ No newline at end of file diff --git a/data/encyclopedia/characters/Cynthia Fisher.txt b/data/encyclopedia/characters/Cynthia Fisher.txt index 06ae8b8..e3f7a49 100644 --- a/data/encyclopedia/characters/Cynthia Fisher.txt +++ b/data/encyclopedia/characters/Cynthia Fisher.txt @@ -1,5 +1,5 @@ -Character: Cobra -Race: Draakan - -Alchaldes is considered the smartest being alive. +Character: Cobra +Race: Draakan + +Alchaldes is considered the smartest being alive. \ No newline at end of file diff --git a/data/encyclopedia/characters/Dalaila Hayes.txt b/data/encyclopedia/characters/Dalaila Hayes.txt index 06ae8b8..e3f7a49 100644 --- a/data/encyclopedia/characters/Dalaila Hayes.txt +++ b/data/encyclopedia/characters/Dalaila Hayes.txt @@ -1,5 +1,5 @@ -Character: Cobra -Race: Draakan - -Alchaldes is considered the smartest being alive. +Character: Cobra +Race: Draakan + +Alchaldes is considered the smartest being alive. \ No newline at end of file diff --git a/data/encyclopedia/characters/Diamond Back.txt b/data/encyclopedia/characters/Diamond Back.txt index 06ae8b8..e3f7a49 100644 --- a/data/encyclopedia/characters/Diamond Back.txt +++ b/data/encyclopedia/characters/Diamond Back.txt @@ -1,5 +1,5 @@ -Character: Cobra -Race: Draakan - -Alchaldes is considered the smartest being alive. +Character: Cobra +Race: Draakan + +Alchaldes is considered the smartest being alive. \ No newline at end of file diff --git a/data/encyclopedia/characters/Dolosus.txt b/data/encyclopedia/characters/Dolosus.txt index 06ae8b8..e3f7a49 100644 --- a/data/encyclopedia/characters/Dolosus.txt +++ b/data/encyclopedia/characters/Dolosus.txt @@ -1,5 +1,5 @@ -Character: Cobra -Race: Draakan - -Alchaldes is considered the smartest being alive. +Character: Cobra +Race: Draakan + +Alchaldes is considered the smartest being alive. \ No newline at end of file diff --git a/data/encyclopedia/characters/Eva.txt b/data/encyclopedia/characters/Eva.txt index 06ae8b8..e3f7a49 100644 --- a/data/encyclopedia/characters/Eva.txt +++ b/data/encyclopedia/characters/Eva.txt @@ -1,5 +1,5 @@ -Character: Cobra -Race: Draakan - -Alchaldes is considered the smartest being alive. +Character: Cobra +Race: Draakan + +Alchaldes is considered the smartest being alive. \ No newline at end of file diff --git a/data/encyclopedia/characters/Gecko.txt b/data/encyclopedia/characters/Gecko.txt index 06ae8b8..e3f7a49 100644 --- a/data/encyclopedia/characters/Gecko.txt +++ b/data/encyclopedia/characters/Gecko.txt @@ -1,5 +1,5 @@ -Character: Cobra -Race: Draakan - -Alchaldes is considered the smartest being alive. +Character: Cobra +Race: Draakan + +Alchaldes is considered the smartest being alive. \ No newline at end of file diff --git a/data/encyclopedia/characters/Gerex Chol.txt b/data/encyclopedia/characters/Gerex Chol.txt index 06ae8b8..e3f7a49 100644 --- a/data/encyclopedia/characters/Gerex Chol.txt +++ b/data/encyclopedia/characters/Gerex Chol.txt @@ -1,5 +1,5 @@ -Character: Cobra -Race: Draakan - -Alchaldes is considered the smartest being alive. +Character: Cobra +Race: Draakan + +Alchaldes is considered the smartest being alive. \ No newline at end of file diff --git a/data/encyclopedia/characters/Gila.txt b/data/encyclopedia/characters/Gila.txt index 06ae8b8..e3f7a49 100644 --- a/data/encyclopedia/characters/Gila.txt +++ b/data/encyclopedia/characters/Gila.txt @@ -1,5 +1,5 @@ -Character: Cobra -Race: Draakan - -Alchaldes is considered the smartest being alive. +Character: Cobra +Race: Draakan + +Alchaldes is considered the smartest being alive. \ No newline at end of file diff --git a/data/encyclopedia/characters/Iguana.txt b/data/encyclopedia/characters/Iguana.txt index 06ae8b8..e3f7a49 100644 --- a/data/encyclopedia/characters/Iguana.txt +++ b/data/encyclopedia/characters/Iguana.txt @@ -1,5 +1,5 @@ -Character: Cobra -Race: Draakan - -Alchaldes is considered the smartest being alive. +Character: Cobra +Race: Draakan + +Alchaldes is considered the smartest being alive. \ No newline at end of file diff --git a/data/encyclopedia/characters/Lore.txt b/data/encyclopedia/characters/Lore.txt index 06ae8b8..e3f7a49 100644 --- a/data/encyclopedia/characters/Lore.txt +++ b/data/encyclopedia/characters/Lore.txt @@ -1,5 +1,5 @@ -Character: Cobra -Race: Draakan - -Alchaldes is considered the smartest being alive. +Character: Cobra +Race: Draakan + +Alchaldes is considered the smartest being alive. \ No newline at end of file diff --git a/data/encyclopedia/characters/Raptor.txt b/data/encyclopedia/characters/Raptor.txt index 06ae8b8..e3f7a49 100644 --- a/data/encyclopedia/characters/Raptor.txt +++ b/data/encyclopedia/characters/Raptor.txt @@ -1,5 +1,5 @@ -Character: Cobra -Race: Draakan - -Alchaldes is considered the smartest being alive. +Character: Cobra +Race: Draakan + +Alchaldes is considered the smartest being alive. \ No newline at end of file diff --git a/data/encyclopedia/characters/Rex.txt b/data/encyclopedia/characters/Rex.txt index 06ae8b8..e3f7a49 100644 --- a/data/encyclopedia/characters/Rex.txt +++ b/data/encyclopedia/characters/Rex.txt @@ -1,5 +1,5 @@ -Character: Cobra -Race: Draakan - -Alchaldes is considered the smartest being alive. +Character: Cobra +Race: Draakan + +Alchaldes is considered the smartest being alive. \ No newline at end of file diff --git a/data/encyclopedia/characters/Rragh Zhek.txt b/data/encyclopedia/characters/Rragh Zhek.txt index 06ae8b8..e3f7a49 100644 --- a/data/encyclopedia/characters/Rragh Zhek.txt +++ b/data/encyclopedia/characters/Rragh Zhek.txt @@ -1,5 +1,5 @@ -Character: Cobra -Race: Draakan - -Alchaldes is considered the smartest being alive. +Character: Cobra +Race: Draakan + +Alchaldes is considered the smartest being alive. \ No newline at end of file diff --git a/data/encyclopedia/characters/Sharp Tooth.txt b/data/encyclopedia/characters/Sharp Tooth.txt index 06ae8b8..e3f7a49 100644 --- a/data/encyclopedia/characters/Sharp Tooth.txt +++ b/data/encyclopedia/characters/Sharp Tooth.txt @@ -1,5 +1,5 @@ -Character: Cobra -Race: Draakan - -Alchaldes is considered the smartest being alive. +Character: Cobra +Race: Draakan + +Alchaldes is considered the smartest being alive. \ No newline at end of file diff --git a/data/encyclopedia/characters/Snake.txt b/data/encyclopedia/characters/Snake.txt index 06ae8b8..e3f7a49 100644 --- a/data/encyclopedia/characters/Snake.txt +++ b/data/encyclopedia/characters/Snake.txt @@ -1,5 +1,5 @@ -Character: Cobra -Race: Draakan - -Alchaldes is considered the smartest being alive. +Character: Cobra +Race: Draakan + +Alchaldes is considered the smartest being alive. \ No newline at end of file diff --git a/data/encyclopedia/characters/Viper.txt b/data/encyclopedia/characters/Viper.txt index 06ae8b8..e3f7a49 100644 --- a/data/encyclopedia/characters/Viper.txt +++ b/data/encyclopedia/characters/Viper.txt @@ -1,5 +1,5 @@ -Character: Cobra -Race: Draakan - -Alchaldes is considered the smartest being alive. +Character: Cobra +Race: Draakan + +Alchaldes is considered the smartest being alive. \ No newline at end of file diff --git a/data/encyclopedia/factions/Alpha Viper.txt b/data/encyclopedia/factions/Alpha Viper.txt index f85084c..8ff1293 100644 --- a/data/encyclopedia/factions/Alpha Viper.txt +++ b/data/encyclopedia/factions/Alpha Viper.txt @@ -1,9 +1,9 @@ -Faction: Alpha Viper -Specialty: Accuracy -Race: Draakan - -In the event of a close encounter: cook em'. - -- Alpha Viper saying - - +Faction: Alpha Viper +Specialty: Accuracy +Race: Draakan + +In the event of a close encounter: cook em'. + -- Alpha Viper saying + + \ No newline at end of file diff --git a/data/encyclopedia/factions/Blood Eagle.txt b/data/encyclopedia/factions/Blood Eagle.txt index e0913dd..0049bee 100644 --- a/data/encyclopedia/factions/Blood Eagle.txt +++ b/data/encyclopedia/factions/Blood Eagle.txt @@ -1,9 +1,9 @@ -Faction: Blood Eagle -Specialty: Accuracy -Race: Human - -I got a plascannon that says no one's immortal. - -- Blood Eagle saying - - +Faction: Blood Eagle +Specialty: Accuracy +Race: Human + +I got a plascannon that says no one's immortal. + -- Blood Eagle saying + + \ No newline at end of file diff --git a/data/encyclopedia/factions/Diamond Sword.txt b/data/encyclopedia/factions/Diamond Sword.txt index 7ac30a4..7d5dbf7 100644 --- a/data/encyclopedia/factions/Diamond Sword.txt +++ b/data/encyclopedia/factions/Diamond Sword.txt @@ -1,9 +1,9 @@ -Faction: Diamond Sword -Specialty: Accuracy -Race: Human - -Be patient and the enemy shall consume himself. - -- Diamond Sword saying - - +Faction: Diamond Sword +Specialty: Accuracy +Race: Human + +Be patient and the enemy shall consume himself. + -- Diamond Sword saying + + \ No newline at end of file diff --git a/data/encyclopedia/factions/Horde.txt b/data/encyclopedia/factions/Horde.txt index ad452ba..cada1b9 100644 --- a/data/encyclopedia/factions/Horde.txt +++ b/data/encyclopedia/factions/Horde.txt @@ -1,9 +1,9 @@ -Faction: Horde -Specialty: Accuracy -Race: Bioderm - -I am of the Chainless. I am Strong. I show no mercy. ---BioDerm battle chant - - +Faction: Horde +Specialty: Accuracy +Race: Bioderm + +I am of the Chainless. I am Strong. I show no mercy. +--BioDerm battle chant + + \ No newline at end of file diff --git a/data/encyclopedia/factions/Phoenix.txt b/data/encyclopedia/factions/Phoenix.txt index a62cfa9..8ae739c 100644 --- a/data/encyclopedia/factions/Phoenix.txt +++ b/data/encyclopedia/factions/Phoenix.txt @@ -1,9 +1,9 @@ -Faction: Phoenix -Specialty: Accuracy -Race: Human - -Fire only burns the faithless. - -- Harbingers of Phoenix saying - - +Faction: Phoenix +Specialty: Accuracy +Race: Human + +Fire only burns the faithless. + -- Harbingers of Phoenix saying + + \ No newline at end of file diff --git a/data/encyclopedia/factions/Star Wolf.txt b/data/encyclopedia/factions/Star Wolf.txt index 3f8cef3..035f550 100644 --- a/data/encyclopedia/factions/Star Wolf.txt +++ b/data/encyclopedia/factions/Star Wolf.txt @@ -1,11 +1,11 @@ -Faction: Star Wolf -Specialty: Accuracy -Race: Human - -Silent as the mouths of the dead. - -- Starwolf saying - - - - +Faction: Star Wolf +Specialty: Accuracy +Race: Human + +Silent as the mouths of the dead. + -- Starwolf saying + + + + In 3941 CE, the BioDerm Hordes crushed the Starwolf tribe at the star system of Ymir. Many Starwolf merceneries now serve in the armies of other tribes. \ No newline at end of file diff --git a/data/encyclopedia/factions/Storm.txt b/data/encyclopedia/factions/Storm.txt index c2a3961..41de62c 100644 --- a/data/encyclopedia/factions/Storm.txt +++ b/data/encyclopedia/factions/Storm.txt @@ -1,9 +1,9 @@ -Faction: Storm -Specialty: Accuracy -Race: Human - -In the eye of your enemy, you look like an easy kill. Prove them wrong. - - - +Faction: Storm +Specialty: Accuracy +Race: Human + +In the eye of your enemy, you look like an easy kill. Prove them wrong. + + + \ No newline at end of file diff --git a/data/encyclopedia/packs/Dampening Field.txt b/data/encyclopedia/packs/Dampening Field.txt index ebc40d1..e76fd38 100644 --- a/data/encyclopedia/packs/Dampening Field.txt +++ b/data/encyclopedia/packs/Dampening Field.txt @@ -1,8 +1,8 @@ -Pack: Dampening Field - -Blind them. - - - - +Pack: Dampening Field + +Blind them. + + + + The dampening field comes as a base asset and a pack. When activated, the dampening field produces an electromagnetic field that prevents unauthorized signals from entering or exiting. Basically, it disables all sensor and radio activity. A special armor addon is required to detect dampening fields. \ No newline at end of file diff --git a/data/encyclopedia/packs/Mining Tool.txt b/data/encyclopedia/packs/Mining Tool.txt index 4bb66a8..0ae8807 100644 --- a/data/encyclopedia/packs/Mining Tool.txt +++ b/data/encyclopedia/packs/Mining Tool.txt @@ -1,8 +1,8 @@ -Pack: Mining Tool - -Warning: Aim away from face. - - - - +Pack: Mining Tool + +Warning: Aim away from face. + + + + Neutrons are fired at the rock to break it apart molecule by molecule, then a tractor beam brings the segments in. \ No newline at end of file diff --git a/data/encyclopedia/planets/Earth.txt b/data/encyclopedia/planets/Earth.txt index dd2bc01..6b9a0a7 100644 --- a/data/encyclopedia/planets/Earth.txt +++ b/data/encyclopedia/planets/Earth.txt @@ -1,6 +1,6 @@ -Planet: Earth - -Considered the 'celestial' planet, Earth is great place for vacations. - - +Planet: Earth + +Considered the 'celestial' planet, Earth is great place for vacations. + + \ No newline at end of file diff --git a/data/encyclopedia/planets/Xeron.txt b/data/encyclopedia/planets/Xeron.txt index 8f4c74e..e326acd 100644 --- a/data/encyclopedia/planets/Xeron.txt +++ b/data/encyclopedia/planets/Xeron.txt @@ -1,6 +1,6 @@ -Planet: Xeron - -Xeron looks a lot hotter than it actually is from space. - - +Planet: Xeron + +Xeron looks a lot hotter than it actually is from space. + + \ No newline at end of file diff --git a/data/encyclopedia/races/BioDerm.txt b/data/encyclopedia/races/BioDerm.txt index 18b567e..a297246 100644 --- a/data/encyclopedia/races/BioDerm.txt +++ b/data/encyclopedia/races/BioDerm.txt @@ -1,10 +1,10 @@ -Race: BioDerm - -These humans are hard to catch off-guard. Rrrh, so be it! We’ll crush them the old-fashioned way -- brute force! - -- from a Horde Maul tactical briefing - - - - -The Bioderms are an artificially created workrace. Sometimes used in combat, a great number of Derms rebelled against the Human race. +Race: BioDerm + +These humans are hard to catch off-guard. Rrrh, so be it! We’ll crush them the old-fashioned way -- brute force! + -- from a Horde Maul tactical briefing + + + + +The Bioderms are an artificially created workrace. Sometimes used in combat, a great number of Derms rebelled against the Human race. But in 3956 CE, six years after the turning point of the war, the BioDerms were given the right to be considered their own race. \ No newline at end of file diff --git a/data/encyclopedia/races/Criollos.txt b/data/encyclopedia/races/Criollos.txt index e5208ad..4a2e70d 100644 --- a/data/encyclopedia/races/Criollos.txt +++ b/data/encyclopedia/races/Criollos.txt @@ -1,9 +1,9 @@ -Race: Criollos - -Could we really rip a hole in the universe? - -- Hammurabi - - - - +Race: Criollos + +Could we really rip a hole in the universe? + -- Hammurabi + + + + The Criollos are smart bastards, their leader Alchaldes beat the best Super Computer at Chess. \ No newline at end of file diff --git a/data/encyclopedia/races/Draakan.txt b/data/encyclopedia/races/Draakan.txt index 24d6010..536865e 100644 --- a/data/encyclopedia/races/Draakan.txt +++ b/data/encyclopedia/races/Draakan.txt @@ -1,24 +1,24 @@ -Race: Draakan - -What is the point of our existance? - -- Dolosus, after finding the truth - - - - -The Draakans have the same origin as the Bioderms: Once a genetic experiment, early Draakans escaped from their testing facilities on Xeron. They were originially very basic lifeforms, but after many years of evolving and evading the Criollos, the Draakans became the sophisticated creatures they are today. The Criollos eventually left the Draakans alone after their most recent evolution; happy with how advanced their creations have become. Today, the Criollos are mindful to not let the Draakans know they created them. - -The Draakans (or for short, "Drakes") are considered to be direct descendants of velociraptors. They resemble raptors in almost every way possible, except eye color. Most Draakans have yellow eyes that are described as "bright as the sun". However, in rare cases, a Draakan may be born with red eyes. - -Draakans have an extraordinary ability to spew & resist fire. Said fire is produced in 'sacs' just below the lungs. The fire produced was meant to be an emergency backup for body heat. However, a simple surgery allows this fire to be diverted to the mouth, ready to be expelled at will. - -There is a largely spread rumor that the Drakaans are of Creole creation. Once a genetic experiment, early Draakans escaped from their testing facility on Xeron and then on evolved into the sophisticated creatures that they are now. - -Pros: - *Faster running speed - *Flame breath ability - *Advanced understanding of robotic technology (faster leveling on robotics) - *Fire & lava resistance - -Cons: - *Takes less damage before death +Race: Draakan + +What is the point of our existance? + -- Dolosus, after finding the truth + + + + +The Draakans have the same origin as the Bioderms: Once a genetic experiment, early Draakans escaped from their testing facilities on Xeron. They were originially very basic lifeforms, but after many years of evolving and evading the Criollos, the Draakans became the sophisticated creatures they are today. The Criollos eventually left the Draakans alone after their most recent evolution; happy with how advanced their creations have become. Today, the Criollos are mindful to not let the Draakans know they created them. + +The Draakans (or for short, "Drakes") are considered to be direct descendants of velociraptors. They resemble raptors in almost every way possible, except eye color. Most Draakans have yellow eyes that are described as "bright as the sun". However, in rare cases, a Draakan may be born with red eyes. + +Draakans have an extraordinary ability to spew & resist fire. Said fire is produced in 'sacs' just below the lungs. The fire produced was meant to be an emergency backup for body heat. However, a simple surgery allows this fire to be diverted to the mouth, ready to be expelled at will. + +There is a largely spread rumor that the Drakaans are of Creole creation. Once a genetic experiment, early Draakans escaped from their testing facility on Xeron and then on evolved into the sophisticated creatures that they are now. + +Pros: + *Faster running speed + *Flame breath ability + *Advanced understanding of robotic technology (faster leveling on robotics) + *Fire & lava resistance + +Cons: + *Takes less damage before death diff --git a/data/encyclopedia/races/Human.txt b/data/encyclopedia/races/Human.txt index 75ae736..a09e23d 100644 --- a/data/encyclopedia/races/Human.txt +++ b/data/encyclopedia/races/Human.txt @@ -1,9 +1,9 @@ -Race: Human - -One small step for man. One giant leap for mankind. - -- Louis Armstrong, the Moon Landing - - - - +Race: Human + +One small step for man. One giant leap for mankind. + -- Louis Armstrong, the Moon Landing + + + + The Humans have tried to find extraterrestial life since their Modern ages, but with no luck. However in 2578 CE, the song "Accross the Universe" that is broadcasted as far into space as possible by NASA was heard and interpreted as an SOS signal. A large battleShip then landed on Earth, carrying a large amount of Draakan footsoldiers. The misunderstanding was then worked out. Before the Draakans left, they helped the Humans upgrade their technology. \ No newline at end of file diff --git a/data/encyclopedia/vehicles/Shrike.txt b/data/encyclopedia/vehicles/Shrike.txt index d53539d..b7b69d3 100644 --- a/data/encyclopedia/vehicles/Shrike.txt +++ b/data/encyclopedia/vehicles/Shrike.txt @@ -1,8 +1,8 @@ -Vehicle: Shrike - -The Shrike is your basic turbograb fighter. - - - - +Vehicle: Shrike + +The Shrike is your basic turbograb fighter. + + + + With dual mounted blasters & 2000 CC engine, the Shrike is best for light air support & escort. A 280W shield protects the shrike from most damage, and recharages at 0.8W a second. \ No newline at end of file diff --git a/data/encyclopedia/weapons/ELF Projector.txt b/data/encyclopedia/weapons/ELF Projector.txt index e81dbbb..3cd4c10 100644 --- a/data/encyclopedia/weapons/ELF Projector.txt +++ b/data/encyclopedia/weapons/ELF Projector.txt @@ -1,8 +1,8 @@ -Weapon: ELF Projector - -Shoot em' down. - - - - +Weapon: ELF Projector + +Shoot em' down. + + + + A heat seeking missile is fired from this launcher which can track both vehicles and infantry. \ No newline at end of file diff --git a/data/encyclopedia/weapons/Grenade Launcher.txt b/data/encyclopedia/weapons/Grenade Launcher.txt index 828f906..1652b5b 100644 --- a/data/encyclopedia/weapons/Grenade Launcher.txt +++ b/data/encyclopedia/weapons/Grenade Launcher.txt @@ -1,8 +1,8 @@ -Weapon: Grenade Launcher - -Shoot em' down. - - - - +Weapon: Grenade Launcher + +Shoot em' down. + + + + Fires small explosive grenades. \ No newline at end of file diff --git a/data/encyclopedia/weapons/Laser Rifle.txt b/data/encyclopedia/weapons/Laser Rifle.txt index d5b463a..de7c4b6 100644 --- a/data/encyclopedia/weapons/Laser Rifle.txt +++ b/data/encyclopedia/weapons/Laser Rifle.txt @@ -1,8 +1,8 @@ -Weapon: Mortar - -Pop your enemys' head. - - - - +Weapon: Mortar + +Pop your enemys' head. + + + + The Laser Rifle fires concentrated laser beams that reach it's target at lightspeed. \ No newline at end of file diff --git a/data/encyclopedia/weapons/Missile Launcher.txt b/data/encyclopedia/weapons/Missile Launcher.txt index 4c5c5f9..e202087 100644 --- a/data/encyclopedia/weapons/Missile Launcher.txt +++ b/data/encyclopedia/weapons/Missile Launcher.txt @@ -1,8 +1,8 @@ -Weapon: Mortar - -Shoot em' down. - - - - +Weapon: Mortar + +Shoot em' down. + + + + A heat seeking missile is fired from this launcher which can track both vehicles and infantry. \ No newline at end of file diff --git a/data/encyclopedia/weapons/Mortar.txt b/data/encyclopedia/weapons/Mortar.txt index 6351640..f9004aa 100644 --- a/data/encyclopedia/weapons/Mortar.txt +++ b/data/encyclopedia/weapons/Mortar.txt @@ -1,8 +1,8 @@ -Weapon: Mortar - -The mortar has been built to destroy. - - - - +Weapon: Mortar + +The mortar has been built to destroy. + + + + The fusion mortar fires small uranium rounds, creating a powerful explosion. \ No newline at end of file diff --git a/data/encyclopedia/weapons/Plasma Rifle.txt b/data/encyclopedia/weapons/Plasma Rifle.txt index ae73771..75d1f3a 100644 --- a/data/encyclopedia/weapons/Plasma Rifle.txt +++ b/data/encyclopedia/weapons/Plasma Rifle.txt @@ -1,8 +1,8 @@ -Weapon: Mortar - -Aim away from face. - - - - +Weapon: Mortar + +Aim away from face. + + + + Capable of melting flesh, the Plasmarifle fires balls of plasma. \ No newline at end of file diff --git a/data/encyclopedia/weapons/Shock Lance.txt b/data/encyclopedia/weapons/Shock Lance.txt index db77970..0f996ce 100644 --- a/data/encyclopedia/weapons/Shock Lance.txt +++ b/data/encyclopedia/weapons/Shock Lance.txt @@ -1,8 +1,8 @@ -Weapon: Mortar - -Go shove 10,000 volts of electricity up your enemys' ass! - - - - +Weapon: Mortar + +Go shove 10,000 volts of electricity up your enemys' ass! + + + + The shocklance fires beams of concentrated electricity at close range. \ No newline at end of file diff --git a/data/encyclopedia/weapons/Spinfusor.txt b/data/encyclopedia/weapons/Spinfusor.txt index af6592d..56ba8c7 100644 --- a/data/encyclopedia/weapons/Spinfusor.txt +++ b/data/encyclopedia/weapons/Spinfusor.txt @@ -1,9 +1,9 @@ -Weapon: Mortar - -The Spinfusor is your bread and butter weapon. - -- Lieutenant Kenzie - - - - +Weapon: Mortar + +The Spinfusor is your bread and butter weapon. + -- Lieutenant Kenzie + + + + The Spinfusor fires small explosive discs. \ No newline at end of file diff --git a/data/game/Encyclopedia_Intro.des b/data/game/Encyclopedia_Intro.des index 2873835..bb67762 100644 --- a/data/game/Encyclopedia_Intro.des +++ b/data/game/Encyclopedia_Intro.des @@ -1,5 +1,5 @@ -Select a category from the dropdown menu on my left. -Then select an article you wish to read about. - -Underlined text such as this are references. -These references, if clicked on will send you to the subject it is talking about. +Select a category from the dropdown menu on my left. +Then select an article you wish to read about. + +Underlined text such as this are references. +These references, if clicked on will send you to the subject it is talking about. diff --git a/data/game/ammunition.txt b/data/game/ammunition.txt index 4f2eb61..c751133 100644 --- a/data/game/ammunition.txt +++ b/data/game/ammunition.txt @@ -1,45 +1,45 @@ -;Prices will work in any monitary value; they'll just show with the US Dollar symbol ($) -;This is just for store intergration -;Anything without 'display' set will show as the db name in browser - -[Ammo] -DataBlock = ChaingunAmmo; -Price = 50; -SellPrice = 30; -Count = 30; -Display = "Chaingun Bullets"; - -[Ammo] -DataBlock = DiscAmmo; -Price = 50; -SellPrice = 30; -Count = 30; -Display = "Explosive Discs"; - -[Ammo] -DataBlock = GrenadeLauncherAmmo; -Price = 50; -SellPrice = 30; -Count = 30; -Display = "Grenades"; - -[Ammo] -DataBlock = MissileLauncherAmmo; -Price = 50; -SellPrice = 30; -Count = 30; -Display = "Missile Pods"; - -[Ammo] -DataBlock = MortarAmmo; -Price = 50; -SellPrice = 30; -Count = 30; -Display = "Mortar Shells"; - -[Ammo] -DataBlock = PlasmaAmmo; -Price = 50; -SellPrice = 30; -Count = 30; +;Prices will work in any monitary value; they'll just show with the US Dollar symbol ($) +;This is just for store intergration +;Anything without 'display' set will show as the db name in browser + +[Ammo] +DataBlock = ChaingunAmmo; +Price = 50; +SellPrice = 30; +Count = 30; +Display = "Chaingun Bullets"; + +[Ammo] +DataBlock = DiscAmmo; +Price = 50; +SellPrice = 30; +Count = 30; +Display = "Explosive Discs"; + +[Ammo] +DataBlock = GrenadeLauncherAmmo; +Price = 50; +SellPrice = 30; +Count = 30; +Display = "Grenades"; + +[Ammo] +DataBlock = MissileLauncherAmmo; +Price = 50; +SellPrice = 30; +Count = 30; +Display = "Missile Pods"; + +[Ammo] +DataBlock = MortarAmmo; +Price = 50; +SellPrice = 30; +Count = 30; +Display = "Mortar Shells"; + +[Ammo] +DataBlock = PlasmaAmmo; +Price = 50; +SellPrice = 30; +Count = 30; Display = "Plasmatoids"; \ No newline at end of file diff --git a/data/game/encyclopediaData.txt b/data/game/encyclopediaData.txt index 46a4453..f1fdf54 100644 --- a/data/game/encyclopediaData.txt +++ b/data/game/encyclopediaData.txt @@ -1,10 +1,10 @@ -;Encyclopedia Settings - -[Encyclopedia] -categoryCount = 6; -category0 = "Characters"; -category1 = "Factions"; -category2 = "Races"; -category3 = "Vehicles"; -category4 = "Weapons"; -category5 = "Packs"; +;Encyclopedia Settings + +[Encyclopedia] +categoryCount = 6; +category0 = "Characters"; +category1 = "Factions"; +category2 = "Races"; +category3 = "Vehicles"; +category4 = "Weapons"; +category5 = "Packs"; diff --git a/data/game/gems.txt b/data/game/gems.txt index aca281e..f3df6f6 100644 --- a/data/game/gems.txt +++ b/data/game/gems.txt @@ -1,31 +1,31 @@ -;Gem Listing - -[Gem] -Name = "Sapphire"; -Price = 5000; -SellPrice = 10000; - -[Gem] -Name = "Diamond"; -Price = 5000; -SellPrice = 10000; - -[Gem] -Name = "Ruby"; -Price = 5000; -SellPrice = 10000; - -[Gem] -Name = "Opal"; -Price = 5000; -SellPrice = 10000; - -[Gem] -Name = "Jade"; -Price = 5000; -SellPrice = 10000; - -[Gem] -Name = "Turquoise"; -Price = 5000; +;Gem Listing + +[Gem] +Name = "Sapphire"; +Price = 5000; +SellPrice = 10000; + +[Gem] +Name = "Diamond"; +Price = 5000; +SellPrice = 10000; + +[Gem] +Name = "Ruby"; +Price = 5000; +SellPrice = 10000; + +[Gem] +Name = "Opal"; +Price = 5000; +SellPrice = 10000; + +[Gem] +Name = "Jade"; +Price = 5000; +SellPrice = 10000; + +[Gem] +Name = "Turquoise"; +Price = 5000; SellPrice = 10000; \ No newline at end of file diff --git a/data/game/items.txt b/data/game/items.txt index eab1bd9..149b874 100644 --- a/data/game/items.txt +++ b/data/game/items.txt @@ -1,4 +1,4 @@ -;Prices work in whole US dollars -;This is just for store intergration -;Anything without 'display' set will show as the db name in browser - +;Prices work in whole US dollars +;This is just for store intergration +;Anything without 'display' set will show as the db name in browser + diff --git a/data/game/ores.txt b/data/game/ores.txt index 3639b79..f636098 100644 --- a/data/game/ores.txt +++ b/data/game/ores.txt @@ -1,16 +1,16 @@ -;Ore Listing - -[Ore] -Name = "Steel"; -Price = 5000; -SellPrice = 10000; - -[Ore] -Name = "Silver"; -Price = 5000; -SellPrice = 10000; - -[Ore] -Name = "Gold"; -Price = 5000; +;Ore Listing + +[Ore] +Name = "Steel"; +Price = 5000; +SellPrice = 10000; + +[Ore] +Name = "Silver"; +Price = 5000; +SellPrice = 10000; + +[Ore] +Name = "Gold"; +Price = 5000; SellPrice = 10000; \ No newline at end of file diff --git a/data/game/saves/IceRidge_nef/427694980.txt b/data/game/saves/IceRidge_nef/427694980.txt index c8ccbb4..87bf648 100644 --- a/data/game/saves/IceRidge_nef/427694980.txt +++ b/data/game/saves/IceRidge_nef/427694980.txt @@ -1,31 +1,31 @@ -;Saved by DarkDragonDX on 08/18/2010 at 10:59 PM - -[Character] -transform = "-11.015 -737.939 93.042 0 0 -1 0.875028"; -velocity = "0 0 0"; -damage = "0"; -race = "Draakan"; -armor = "LIGHT"; -energy = "60"; -whiteOut = "0"; -damageFlash = "0"; -cash = ""; -hasRadio = ""; -underStandsHuman = ""; -underStandsBioderm = ""; -underStandsDraakan = ""; -underStandsCriollos = ""; - -[Inventory] -slotCount = "5"; -slot0 = "Blaster"; -slot0Ammo = ""; -slot1 = "Disc"; -slot1Ammo = "15"; -slot2 = "Chaingun"; -slot2Ammo = "100"; -slot3 = "Flamer"; -slot3Ammo = ""; -slot4 = "TargetingLaser"; -slot4Ammo = ""; -healthKits = "1"; +;Saved by DarkDragonDX on 08/18/2010 at 10:59 PM + +[Character] +transform = "-11.015 -737.939 93.042 0 0 -1 0.875028"; +velocity = "0 0 0"; +damage = "0"; +race = "Draakan"; +armor = "LIGHT"; +energy = "60"; +whiteOut = "0"; +damageFlash = "0"; +cash = ""; +hasRadio = ""; +underStandsHuman = ""; +underStandsBioderm = ""; +underStandsDraakan = ""; +underStandsCriollos = ""; + +[Inventory] +slotCount = "5"; +slot0 = "Blaster"; +slot0Ammo = ""; +slot1 = "Disc"; +slot1Ammo = "15"; +slot2 = "Chaingun"; +slot2Ammo = "100"; +slot3 = "Flamer"; +slot3Ammo = ""; +slot4 = "TargetingLaser"; +slot4Ammo = ""; +healthKits = "1"; diff --git a/data/game/saves/earth/427694980.txt b/data/game/saves/earth/427694980.txt index 8ca19e9..409924d 100644 --- a/data/game/saves/earth/427694980.txt +++ b/data/game/saves/earth/427694980.txt @@ -1,31 +1,31 @@ -;Saved by  |-{DRK}-|DarkDragonDX on 08/18/2010 at 11:01 PM - -[Character] -transform = "-1054.25 510.256 92.3871 0 0 -1 1.38941"; -velocity = "0 0 0"; -damage = "0.645"; -race = "Draakan"; -armor = "LIGHT"; -energy = "60"; -whiteOut = "0"; -damageFlash = "0"; -cash = ""; -hasRadio = ""; -underStandsHuman = ""; -underStandsBioderm = ""; -underStandsDraakan = ""; -underStandsCriollos = ""; - -[Inventory] -slotCount = "5"; -slot0 = "Blaster"; -slot0Ammo = ""; -slot1 = "Disc"; -slot1Ammo = "12"; -slot2 = "Chaingun"; -slot2Ammo = "0"; -slot3 = "Flamer"; -slot3Ammo = ""; -slot4 = "TargetingLaser"; -slot4Ammo = ""; -healthKits = "0"; +;Saved by  |-{DRK}-|DarkDragonDX on 08/18/2010 at 11:01 PM + +[Character] +transform = "-1054.25 510.256 92.3871 0 0 -1 1.38941"; +velocity = "0 0 0"; +damage = "0.645"; +race = "Draakan"; +armor = "LIGHT"; +energy = "60"; +whiteOut = "0"; +damageFlash = "0"; +cash = ""; +hasRadio = ""; +underStandsHuman = ""; +underStandsBioderm = ""; +underStandsDraakan = ""; +underStandsCriollos = ""; + +[Inventory] +slotCount = "5"; +slot0 = "Blaster"; +slot0Ammo = ""; +slot1 = "Disc"; +slot1Ammo = "12"; +slot2 = "Chaingun"; +slot2Ammo = "0"; +slot3 = "Flamer"; +slot3Ammo = ""; +slot4 = "TargetingLaser"; +slot4Ammo = ""; +healthKits = "0"; diff --git a/data/game/structures/BBunk.txt b/data/game/structures/BBunk.txt index 7f1028b..22128a1 100644 --- a/data/game/structures/BBunk.txt +++ b/data/game/structures/BBunk.txt @@ -1,9 +1,9 @@ -;Prices work in whole US dollars - -[Structure] -Name = "Small Cabin"; -Price = 5000; -SellPrice = 10000; -MaterialList = "Wood 10 Stone 10"; -File = "SMLCabin.cs"; - +;Prices work in whole US dollars + +[Structure] +Name = "Small Cabin"; +Price = 5000; +SellPrice = 10000; +MaterialList = "Wood 10 Stone 10"; +File = "SMLCabin.cs"; + diff --git a/data/game/structures/SMLCabin.cs b/data/game/structures/SMLCabin.cs index bd22771..b0419d2 100644 --- a/data/game/structures/SMLCabin.cs +++ b/data/game/structures/SMLCabin.cs @@ -1,92 +1,92 @@ -//------------------------------------------------------------------------------ -// Saved By DarkDragonDX - -function Build_SMLCabin(%client, %center, %team) -{ - if (%team $= "") - %team = 1; -%offset = VectorSub(GetWords(%center, 0, 1) SPC GetWord(%center, 2), "51.6009 63.784 0"); - -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("58.9785 62.1428 4.314", %offset);Scale = "1.12496 0.166666 16";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("0.338275 0.782451 0.522819 3.58617"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("48.8582 60.862 4.064", %offset);Scale = "0.125 0.166666 8.128";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("-0.36845 0.929648 1.17841e-06 3.14159"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("57.426 63.4285 4.064", %offset);Scale = "0.125 0.166666 8.128";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("0.396826 0.917894 1.16351e-06 3.14159"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("60.1665 60.5145 4.064", %offset);Scale = "0.125 0.166666 8.128";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("0.917893 -0.396827 -5.03014e-07 3.14159"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("51.6009 63.784 4.314", %offset);Scale = "0.125 2.83332 24.9998";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("-0.368847 -0.853174 0.368845 1.72893"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("57.079 52.12 4.064", %offset);Scale = "0.125 0.166666 8.128";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("-0.36845 0.929648 1.17841e-06 3.14159"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("62.907 57.6005 4.064", %offset);Scale = "0.125 0.166666 8.128";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("0.917893 -0.396827 -5.03014e-07 3.14159"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("54.686 66.3425 4.064", %offset);Scale = "0.125 0.166666 8.128";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("0.917893 -0.396827 -5.03014e-07 3.14159"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("54.6861 66.3421 4.564", %offset);Scale = "0.125 0.166666 8";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("0 0 1 0.816115"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("48.8582 60.8617 4.564", %offset);Scale = "0.125 0.166666 8";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("0 0 1 0.816115"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("57.0788 52.1199 4.564", %offset);Scale = "0.125 0.166666 8";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("0 0 1 0.816115"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("62.9065 57.6005 8.564", %offset);Scale = "0.125 0.166666 8";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("0.917893 -0.396827 -5.03014e-07 3.14159"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("49.0402 61.0331 6.564", %offset);Scale = "1 0.166666 14.9999";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("0.680876 0.269853 0.680873 2.61444"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("51.9435 63.4198 8.314", %offset);Scale = "0.125 2.8333 22.9998";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("0.676216 -0.292345 0.676214 3.71043"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("50.5057 56.9202 4.623", %offset);Scale = "0.125 0.166666 9.246";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("-0.36845 0.929648 1.17841e-06 3.14159"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("62.7248 57.429 6.564", %offset);Scale = "1 0.166666 14.9999";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("-0.345729 0.872321 -0.345728 1.70698"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("57.38 63.4774 4.564", %offset);Scale = "0.125 0.166666 7";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("0 0 1 0.816115"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("60.1619 60.5191 4.564", %offset);Scale = "0.125 0.166666 7";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("0 0 1 0.816115"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("57.2087 63.6593 7.564", %offset);Scale = "0.25 0.166666 6.8647";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("-0.676214 0.292342 0.676218 3.71043"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("57.2087 63.6593 5.064", %offset);Scale = "0.25 0.166666 6.8647";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("0.368848 0.853172 0.368847 1.72893"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("62.7351 57.7822 7.564", %offset);Scale = "0.25 0.166666 7.01328";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("-0.676214 0.292342 0.676218 3.71043"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("62.735 57.7823 5.064", %offset);Scale = "0.25 0.166666 7.0127";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("0.368848 0.853172 0.368847 1.72893"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("51.4163 57.7765 4.873", %offset);Scale = "0.125 0.166666 3";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("-0.853172 0.368847 0.368848 1.72893"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("54.1564 54.8626 4.814", %offset);Scale = "0.125 0.166666 3";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("0.292345 0.676216 -0.676215 2.57276"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("53.2458 54.0063 4.564", %offset);Scale = "0.125 0.166666 9.128";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("-0.36845 0.929648 1.17841e-06 3.14159"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("50.3995 59.2225 8.064", %offset);Scale = "0.999965 0.166666 7";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("0.917891 -0.396833 -5.03022e-07 3.14159"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("51.7697 57.7658 7.235", %offset);Scale = "0.414252 0.166666 6.9997";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("0.676217 -0.292344 0.676214 3.71043"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("55.5375 53.759 4.564", %offset);Scale = "1.00004 0.166666 7";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("0 0 1 3.95771"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("53.2458 54.0063 5.064", %offset);Scale = "0.125 0.166666 16.1189";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("0 0 1 2.38691"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("50.5057 56.9202 5.123", %offset);Scale = "0.125 0.166666 16";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("0 0 1 2.38691"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("50.677 56.7381 12.873", %offset);Scale = "0.125 0.166666 6.9997";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("0.676217 -0.292344 0.676214 3.71043"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("53.4279 54.1776 12.873", %offset);Scale = "0.125 0.166666 3";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("0.680875 0.269854 0.680873 2.61444"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("50.6878 57.0915 12.873", %offset);Scale = "0.125 0.166666 3";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("0.680875 0.269854 0.680873 2.61444"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("54.1672 55.216 12.873", %offset);Scale = "0.125 0.166666 6.9997";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("0.872319 0.345729 -0.345733 1.70697"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("52.9685 56.491 12.623", %offset);Scale = "0.125 1.49999 8.118";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("0.929647 0.368452 4.67046e-07 3.14159"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("53.7922 54.5202 5.064", %offset);Scale = "0.125 0.333393 15.1179";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("2.94032e-07 3.06284e-06 1 3.95771"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("51.0521 57.4341 5.123", %offset);Scale = "0.125 0.33337 15";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("2.94032e-07 3.06284e-06 1 3.95771"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("53.0743 54.1882 8.593", %offset);Scale = "0.125 2.68633 6.9997";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("-0.269854 0.680875 0.680873 2.61444"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("53.4279 54.1776 4.314", %offset);Scale = "0.125 0.166666 2.00008";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("0.345728 -0.872321 -0.345728 1.70698"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("53.4371 54.5293 4.314", %offset);Scale = "0.125 0.501492 6.9997";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("-0.676214 0.292343 0.676218 3.71043"); -%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("50.6878 57.0915 4.373", %offset);Scale = "0.125 0.166666 1.99979";Type = "Cabin";team = %team;};addToDeployGroup(%obj); -%building.setRotation("0.345728 -0.872321 -0.345728 1.70698"); -} +//------------------------------------------------------------------------------ +// Saved By DarkDragonDX + +function Build_SMLCabin(%client, %center, %team) +{ + if (%team $= "") + %team = 1; +%offset = VectorSub(GetWords(%center, 0, 1) SPC GetWord(%center, 2), "51.6009 63.784 0"); + +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("58.9785 62.1428 4.314", %offset);Scale = "1.12496 0.166666 16";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("0.338275 0.782451 0.522819 3.58617"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("48.8582 60.862 4.064", %offset);Scale = "0.125 0.166666 8.128";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("-0.36845 0.929648 1.17841e-06 3.14159"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("57.426 63.4285 4.064", %offset);Scale = "0.125 0.166666 8.128";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("0.396826 0.917894 1.16351e-06 3.14159"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("60.1665 60.5145 4.064", %offset);Scale = "0.125 0.166666 8.128";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("0.917893 -0.396827 -5.03014e-07 3.14159"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("51.6009 63.784 4.314", %offset);Scale = "0.125 2.83332 24.9998";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("-0.368847 -0.853174 0.368845 1.72893"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("57.079 52.12 4.064", %offset);Scale = "0.125 0.166666 8.128";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("-0.36845 0.929648 1.17841e-06 3.14159"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("62.907 57.6005 4.064", %offset);Scale = "0.125 0.166666 8.128";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("0.917893 -0.396827 -5.03014e-07 3.14159"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("54.686 66.3425 4.064", %offset);Scale = "0.125 0.166666 8.128";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("0.917893 -0.396827 -5.03014e-07 3.14159"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("54.6861 66.3421 4.564", %offset);Scale = "0.125 0.166666 8";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("0 0 1 0.816115"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("48.8582 60.8617 4.564", %offset);Scale = "0.125 0.166666 8";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("0 0 1 0.816115"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("57.0788 52.1199 4.564", %offset);Scale = "0.125 0.166666 8";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("0 0 1 0.816115"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("62.9065 57.6005 8.564", %offset);Scale = "0.125 0.166666 8";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("0.917893 -0.396827 -5.03014e-07 3.14159"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("49.0402 61.0331 6.564", %offset);Scale = "1 0.166666 14.9999";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("0.680876 0.269853 0.680873 2.61444"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("51.9435 63.4198 8.314", %offset);Scale = "0.125 2.8333 22.9998";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("0.676216 -0.292345 0.676214 3.71043"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("50.5057 56.9202 4.623", %offset);Scale = "0.125 0.166666 9.246";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("-0.36845 0.929648 1.17841e-06 3.14159"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("62.7248 57.429 6.564", %offset);Scale = "1 0.166666 14.9999";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("-0.345729 0.872321 -0.345728 1.70698"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("57.38 63.4774 4.564", %offset);Scale = "0.125 0.166666 7";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("0 0 1 0.816115"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("60.1619 60.5191 4.564", %offset);Scale = "0.125 0.166666 7";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("0 0 1 0.816115"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("57.2087 63.6593 7.564", %offset);Scale = "0.25 0.166666 6.8647";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("-0.676214 0.292342 0.676218 3.71043"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("57.2087 63.6593 5.064", %offset);Scale = "0.25 0.166666 6.8647";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("0.368848 0.853172 0.368847 1.72893"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("62.7351 57.7822 7.564", %offset);Scale = "0.25 0.166666 7.01328";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("-0.676214 0.292342 0.676218 3.71043"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("62.735 57.7823 5.064", %offset);Scale = "0.25 0.166666 7.0127";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("0.368848 0.853172 0.368847 1.72893"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("51.4163 57.7765 4.873", %offset);Scale = "0.125 0.166666 3";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("-0.853172 0.368847 0.368848 1.72893"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("54.1564 54.8626 4.814", %offset);Scale = "0.125 0.166666 3";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("0.292345 0.676216 -0.676215 2.57276"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("53.2458 54.0063 4.564", %offset);Scale = "0.125 0.166666 9.128";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("-0.36845 0.929648 1.17841e-06 3.14159"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("50.3995 59.2225 8.064", %offset);Scale = "0.999965 0.166666 7";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("0.917891 -0.396833 -5.03022e-07 3.14159"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("51.7697 57.7658 7.235", %offset);Scale = "0.414252 0.166666 6.9997";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("0.676217 -0.292344 0.676214 3.71043"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("55.5375 53.759 4.564", %offset);Scale = "1.00004 0.166666 7";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("0 0 1 3.95771"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("53.2458 54.0063 5.064", %offset);Scale = "0.125 0.166666 16.1189";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("0 0 1 2.38691"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("50.5057 56.9202 5.123", %offset);Scale = "0.125 0.166666 16";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("0 0 1 2.38691"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("50.677 56.7381 12.873", %offset);Scale = "0.125 0.166666 6.9997";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("0.676217 -0.292344 0.676214 3.71043"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("53.4279 54.1776 12.873", %offset);Scale = "0.125 0.166666 3";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("0.680875 0.269854 0.680873 2.61444"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("50.6878 57.0915 12.873", %offset);Scale = "0.125 0.166666 3";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("0.680875 0.269854 0.680873 2.61444"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("54.1672 55.216 12.873", %offset);Scale = "0.125 0.166666 6.9997";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("0.872319 0.345729 -0.345733 1.70697"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("52.9685 56.491 12.623", %offset);Scale = "0.125 1.49999 8.118";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("0.929647 0.368452 4.67046e-07 3.14159"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("53.7922 54.5202 5.064", %offset);Scale = "0.125 0.333393 15.1179";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("2.94032e-07 3.06284e-06 1 3.95771"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("51.0521 57.4341 5.123", %offset);Scale = "0.125 0.33337 15";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("2.94032e-07 3.06284e-06 1 3.95771"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("53.0743 54.1882 8.593", %offset);Scale = "0.125 2.68633 6.9997";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("-0.269854 0.680875 0.680873 2.61444"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("53.4279 54.1776 4.314", %offset);Scale = "0.125 0.166666 2.00008";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("0.345728 -0.872321 -0.345728 1.70698"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("53.4371 54.5293 4.314", %offset);Scale = "0.125 0.501492 6.9997";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("-0.676214 0.292343 0.676218 3.71043"); +%building = new (StaticShape) () {datablock = DeployedSpine;Position = VectorAdd("50.6878 57.0915 4.373", %offset);Scale = "0.125 0.166666 1.99979";Type = "Cabin";team = %team;};addToDeployGroup(%obj); +%building.setRotation("0.345728 -0.872321 -0.345728 1.70698"); +} diff --git a/data/game/structures/SMLCabin.txt b/data/game/structures/SMLCabin.txt index 7f1028b..22128a1 100644 --- a/data/game/structures/SMLCabin.txt +++ b/data/game/structures/SMLCabin.txt @@ -1,9 +1,9 @@ -;Prices work in whole US dollars - -[Structure] -Name = "Small Cabin"; -Price = 5000; -SellPrice = 10000; -MaterialList = "Wood 10 Stone 10"; -File = "SMLCabin.cs"; - +;Prices work in whole US dollars + +[Structure] +Name = "Small Cabin"; +Price = 5000; +SellPrice = 10000; +MaterialList = "Wood 10 Stone 10"; +File = "SMLCabin.cs"; + diff --git a/data/game/vehicles.txt b/data/game/vehicles.txt index cbc7244..3ebb0cd 100644 --- a/data/game/vehicles.txt +++ b/data/game/vehicles.txt @@ -1,37 +1,37 @@ -;This does not add vehicles to the list -;This only stores prices by Db name - -[Price] -Datablock = "BomberFlyer"; -SellPrice = 2000; -Price = 5000; - - -[Price] -Datablock = "HAPCFlyer"; -SellPrice = 2000; -Price = 5000; - - -[Price] -Datablock = "MobileBaseVehicle"; -SellPrice = 2000; -Price = 5000; - - -[Price] -Datablock = "ScoutFlyer"; -SellPrice = 2000; -Price = 5000; - - -[Price] -Datablock = "AssaultVehicle"; -SellPrice = 2000; -Price = 5000; - - -[Price] -Datablock = "ScoutVehicle"; -SellPrice = 2000; -Price = 5000; +;This does not add vehicles to the list +;This only stores prices by Db name + +[Price] +Datablock = "BomberFlyer"; +SellPrice = 2000; +Price = 5000; + + +[Price] +Datablock = "HAPCFlyer"; +SellPrice = 2000; +Price = 5000; + + +[Price] +Datablock = "MobileBaseVehicle"; +SellPrice = 2000; +Price = 5000; + + +[Price] +Datablock = "ScoutFlyer"; +SellPrice = 2000; +Price = 5000; + + +[Price] +Datablock = "AssaultVehicle"; +SellPrice = 2000; +Price = 5000; + + +[Price] +Datablock = "ScoutVehicle"; +SellPrice = 2000; +Price = 5000; diff --git a/data/game/weapons.txt b/data/game/weapons.txt index 5bde91f..9733594 100644 --- a/data/game/weapons.txt +++ b/data/game/weapons.txt @@ -1,62 +1,62 @@ -;Prices work in whole US dollars -;This is just for store intergration -;Anything without 'display' set will show as the db name in browser - -[Weapon] -DataBlock = Blaster; -Price = 50; -SellPrice = 30; - -[Weapon] -DataBlock = Chaingun; -Price = 50; -SellPrice = 30; - -[Weapon] -DataBlock = Disc; -Price = 50; -SellPrice = 30; -Display = "SpinFusor"; - -[Weapon] -DataBlock = ELFGun; -Price = 50; -SellPrice = 30; -Display = "ELF Gun"; - -[Weapon] -DataBlock = GrenadeLauncher; -Price = 50; -SellPrice = 30; -Display = "Grenade Launcher"; - -[Weapon] -DataBlock = MissileLauncher; -Price = 50; -SellPrice = 30; -Display = "Missile Launcher"; - -[Weapon] -DataBlock = Mortar; -Price = 50; -SellPrice = 30; -Display = "Fusion Mortar"; - -[Weapon] -DataBlock = Plasma; -Price = 50; -SellPrice = 30; -Display = "Plasma Rifle"; - -[Weapon] -DataBlock = Shocklance; -Price = 50; -SellPrice = 30; - -[Weapon] -DataBlock = SniperRifle; -Price = 50; -SellPrice = 30; -Display = "Laser Rifle"; - - +;Prices work in whole US dollars +;This is just for store intergration +;Anything without 'display' set will show as the db name in browser + +[Weapon] +DataBlock = Blaster; +Price = 50; +SellPrice = 30; + +[Weapon] +DataBlock = Chaingun; +Price = 50; +SellPrice = 30; + +[Weapon] +DataBlock = Disc; +Price = 50; +SellPrice = 30; +Display = "SpinFusor"; + +[Weapon] +DataBlock = ELFGun; +Price = 50; +SellPrice = 30; +Display = "ELF Gun"; + +[Weapon] +DataBlock = GrenadeLauncher; +Price = 50; +SellPrice = 30; +Display = "Grenade Launcher"; + +[Weapon] +DataBlock = MissileLauncher; +Price = 50; +SellPrice = 30; +Display = "Missile Launcher"; + +[Weapon] +DataBlock = Mortar; +Price = 50; +SellPrice = 30; +Display = "Fusion Mortar"; + +[Weapon] +DataBlock = Plasma; +Price = 50; +SellPrice = 30; +Display = "Plasma Rifle"; + +[Weapon] +DataBlock = Shocklance; +Price = 50; +SellPrice = 30; + +[Weapon] +DataBlock = SniperRifle; +Price = 50; +SellPrice = 30; +Display = "Laser Rifle"; + + diff --git a/data/http/templates/403.html b/data/http/templates/403.html index 6fb6508..b95b1b6 100644 --- a/data/http/templates/403.html +++ b/data/http/templates/403.html @@ -1,9 +1,9 @@ - -
- 403 - Forbidden -
- -

403 - Forbidden

- VGS! You're not allowed here. - - + +
+ 403 - Forbidden +
+ +

403 - Forbidden

+ VGS! You're not allowed here. + + diff --git a/data/http/templates/404.html b/data/http/templates/404.html index 922337b..f98ea83 100644 --- a/data/http/templates/404.html +++ b/data/http/templates/404.html @@ -1,9 +1,9 @@ - -
- 404 - Not Found -
- -

404 - Not Found

- VGS! The requested document "#DOC#" was not found. - - + +
+ 404 - Not Found +
+ +

404 - Not Found

+ VGS! The requested document "#DOC#" was not found. + + diff --git a/data/http/templates/Copy of 404.html b/data/http/templates/Copy of 404.html index 9c9ea2a..62164aa 100644 --- a/data/http/templates/Copy of 404.html +++ b/data/http/templates/Copy of 404.html @@ -1,9 +1,9 @@ - -
- 405 - Not Allowed -
- -

405 - Not Allowed

- The method #METHOD# is not allowed for this document. - - + +
+ 405 - Not Allowed +
+ +

405 - Not Allowed

+ The method #METHOD# is not allowed for this document. + + diff --git a/data/http/templates/Directory.html b/data/http/templates/Directory.html index 6908096..c575766 100644 --- a/data/http/templates/Directory.html +++ b/data/http/templates/Directory.html @@ -1,10 +1,10 @@ - -
- Index of #DIR# -
- -

Index of #DIR#

- #CONTENT# -
#APPLICATION# #OS# Server at #HOSTNAME# Port #PORT#
- - + +
+ Index of #DIR# +
+ +

Index of #DIR#

+ #CONTENT# +
#APPLICATION# #OS# Server at #HOSTNAME# Port #PORT#
+ + diff --git a/data/http/test.cs b/data/http/test.cs index 377837c..5212012 100644 --- a/data/http/test.cs +++ b/data/http/test.cs @@ -1,8 +1,8 @@ - - -function ServerApp::execute(%this,%data) -{ - %data = strReplace(%data,"#TIME#",formatTimeString("hh:nn:ss A")); - %data = strReplace(%data,"#DATE#",formatTimeString("mm/dd/yy")); - return %data; + + +function ServerApp::execute(%this,%data) +{ + %data = strReplace(%data,"#TIME#",formatTimeString("hh:nn:ss A")); + %data = strReplace(%data,"#DATE#",formatTimeString("mm/dd/yy")); + return %data; } \ No newline at end of file diff --git a/data/http/test.html b/data/http/test.html index 34f5638..6fd4fb4 100644 --- a/data/http/test.html +++ b/data/http/test.html @@ -1,10 +1,10 @@ - -
- Time -
- - Time: #TIME#
- Date: #DATE#
- This is a test. - - + +
+ Time +
+ + Time: #TIME#
+ Date: #DATE#
+ This is a test. + + diff --git a/data/survivalPreferences.txt b/data/survivalPreferences.txt index c3d5120..32cf759 100644 --- a/data/survivalPreferences.txt +++ b/data/survivalPreferences.txt @@ -1,11 +1,11 @@ -[Survival] -maxBots = 16; -difficultyIncrement = 0.008; -fastDifficultyIncrement = 0.09; -startDifficulty = 0.004; -enableGodbot = true; -godBotFrequency = 5; -hintsEnabled = true; -hintTimeMS = 120000; -allowSetup = true; -setupTimeMS = 60000; +[Survival] +maxBots = 16; +difficultyIncrement = 0.008; +fastDifficultyIncrement = 0.09; +startDifficulty = 0.004; +enableGodbot = true; +godBotFrequency = 5; +hintsEnabled = true; +hintTimeMS = 120000; +allowSetup = true; +setupTimeMS = 60000; diff --git a/doc/races.txt b/doc/races.txt new file mode 100644 index 0000000..dcdd1c3 --- /dev/null +++ b/doc/races.txt @@ -0,0 +1,46 @@ +Intelligence - Determines how well you operate with sophisicated entities such as computer systems + +Strength - Determines how much you may attempt to carry on you in any given moment. + +Dexterity - Determines how well you can work with your hands. Affects the quality of produces items +and how long it may take to produce said items. Could possibly work in conjunction with intelligence +(perhaps for forming sophisicated items -- computer parts used in bots?) + +Robot (not playable)--- + - Least starting intelligence + + + Friendly with all; dependent upon owner + +Draakan---- + + Increased Manueverability + + Flame Breath + + Able to regen health from raw flesh + - Notably less HP overall + + + Pounce/Maul ability (not in BoL) + - Least technologically advanced + - Generally Considered beasts + - Least starting intelligence (just above robots) + + * Friendly with Humans, BioDerms -- enemies are Criollos + +Human---- + - Very low in Numbers (well, spread out) + + Very well advanced in technology + + Decent starting intelligence + + Decent starting strength + + * Friendly with Draakans -- enemies are BioDerms and Criollos + +BioDerm---- + + Numbers (can clone) + + Decently technologically advanced (scavenged from Humans) + + Most starting strength-- results in a notable health increase? + - Mostly artificially supported; predigested food and such. + - Lack of vehicles supplied by the race (they rely on foot assaults) + + * Friendly with Draakans and Criollos -- enemies are Humans +Criollos---- + + Most advanced in technology + + Most starting intelligence + * Friendly with BioDerms -- enemies are Draakans and Humans diff --git a/doc/versions.txt b/doc/versions.txt new file mode 100644 index 0000000..9e8b0ea --- /dev/null +++ b/doc/versions.txt @@ -0,0 +1,14 @@ +Versioning scheme goes as such: + +Major.Minor.Revision +Changes in the major portion means that any client/servers that do not have matching major versions +will immediately be determined as incompatible and will be asked to upgrade (or downgrade in some events) + +Changes in minor are generally feature implementations that do not affect overall compatability between newer +and older versions of the modification. + +Changes in revision indicate quick bugfixes that are released as small patches for the modification rather +than an entirely new download. + +1.0: + \ No newline at end of file diff --git a/gui/DebriefGui.gui b/gui/DebriefGui.gui index e80b888..3c53421 100644 --- a/gui/DebriefGui.gui +++ b/gui/DebriefGui.gui @@ -1,252 +1,252 @@ -//--- OBJECT WRITE BEGIN --- -new GuiChunkedBitmapCtrl(DebriefGui) { - profile = "GuiContentProfile"; - horizSizing = "width"; - vertSizing = "height"; - position = "0 0"; - extent = "640 480"; - minExtent = "8 8"; - visible = "1"; - variable = "$ShellBackground"; - helpTag = "0"; - useVariable = "1"; - - new ShellPaneCtrl(DB_Pane) { - profile = "ShellPaneProfile"; - horizSizing = "width"; - vertSizing = "height"; - position = "28 13"; - extent = "584 459"; - minExtent = "48 92"; - visible = "1"; - helpTag = "0"; - noTitleBar = "1"; - }; - new GuiProgressCtrl(DB_LoadingProgress) { - profile = "ShellProgressBarProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "67 423"; - extent = "300 25"; - minExtent = "8 8"; - visible = "1"; - helpTag = "0"; - - new GuiTextCtrl(DB_LoadingProgressTxt) { - profile = "ShellProgressBarTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "0 3"; - extent = "300 19"; - minExtent = "8 8"; - visible = "1"; - helpTag = "0"; - text = "LOADING MISSION..."; - }; - }; - new GuiControl() { - profile = "GuiDefaultProfile"; - horizSizing = "relative"; - vertSizing = "relative"; - position = "0 0"; - extent = "300 236"; - minExtent = "8 8"; - visible = "1"; - helpTag = "0"; - - new ShellScrollCtrl(DB_ChatScroll) { - profile = "NewScrollCtrlProfile"; - horizSizing = "width"; - vertSizing = "height"; - position = "50 18"; - extent = "251 184"; - minExtent = "24 24"; - visible = "1"; - helpTag = "0"; - willFirstRespond = "1"; - hScrollBar = "alwaysOff"; - vScrollBar = "alwaysOn"; - constantThumbHeight = "0"; - defaultLineHeight = "15"; - childMargin = "3 3"; - fieldBase = "gui/shll_field"; - - new GuiScrollContentCtrl() { - profile = "GuiDefaultProfile"; - horizSizing = "width"; - vertSizing = "height"; - position = "7 7"; - extent = "221 170"; - minExtent = "8 8"; - visible = "1"; - helpTag = "0"; - - new GuiMessageVectorCtrl(DB_ChatVector) { - profile = "GuiChatHudProfile"; - horizSizing = "width"; - vertSizing = "height"; - position = "0 0"; - extent = "221 170"; - minExtent = "8 8"; - visible = "1"; - helpTag = "0"; - lineSpacing = "0"; - lineContinuedIndex = "10"; - allowedMatches[0] = "http"; - allowedMatches[1] = "t2server"; - matchColor = "0 0 255 255"; - maxColorIndex = "5"; - matchColors1 = "255 0 0 255"; - matchColors0 = "0 0 255 255"; - }; - }; - }; - }; - new GuiControl() { - profile = "GuiDefaultProfile"; - horizSizing = "relative"; - vertSizing = "height"; - position = "300 15"; - extent = "340 405"; - minExtent = "8 8"; - visible = "1"; - helpTag = "0"; - - new ShellFieldCtrl(DB_ResultPane) { - profile = "ShellFieldProfile"; - horizSizing = "width"; - vertSizing = "height"; - position = "5 7"; - extent = "280 392"; - minExtent = "16 18"; - visible = "1"; - helpTag = "0"; - - new GuiMLTextCtrl(DebriefResultText) { - profile = "DebriefHeadlineTextProfile"; - horizSizing = "width"; - vertSizing = "bottom"; - position = "4 3"; - extent = "272 28"; - minExtent = "8 8"; - visible = "1"; - helpTag = "0"; - lineSpacing = "2"; - allowColorChars = "0"; - }; - new ShellScrollCtrl(DB_ResultScroll) { - profile = "NewScrollCtrlProfile"; - horizSizing = "width"; - vertSizing = "height"; - position = "2 58"; - extent = "276 332"; - minExtent = "24 24"; - visible = "1"; - helpTag = "0"; - willFirstRespond = "1"; - hScrollBar = "alwaysOff"; - vScrollBar = "dynamic"; - constantThumbHeight = "0"; - defaultLineHeight = "15"; - childMargin = "3 3"; - fieldBase = "gui/shll_field"; - - new GuiScrollContentCtrl() { - profile = "GuiDefaultProfile"; - horizSizing = "width"; - vertSizing = "height"; - position = "7 7"; - extent = "262 318"; - minExtent = "8 8"; - visible = "1"; - helpTag = "0"; - - new GuiMLTextCtrl(DebriefText) { - profile = "DebriefTextProfile"; - horizSizing = "width"; - vertSizing = "height"; - position = "0 0"; - extent = "262 18"; - minExtent = "8 8"; - visible = "1"; - helpTag = "0"; - lineSpacing = "2"; - allowColorChars = "1"; - }; - }; - }; - }; - }; - new ShellBitmapButton() { - profile = "ShellButtonNoTabProfile"; - horizSizing = "left"; - vertSizing = "top"; - position = "372 417"; - extent = "115 38"; - minExtent = "32 38"; - visible = "1"; - setFirstResponder = "0"; - command = "debriefDisconnect();"; - helpTag = "0"; - text = "DISCONNECT"; - simpleStyle = "0"; - }; - new ShellBitmapButton(DB_ContinueBTN) { - profile = "ShellButtonNoTabProfile"; - horizSizing = "left"; - vertSizing = "top"; - position = "478 417"; - extent = "115 38"; - minExtent = "32 38"; - visible = "1"; - setFirstResponder = "0"; - command = "debriefContinue();"; - accelerator = "escape"; - helpTag = "0"; - text = "CONTINUE"; - simpleStyle = "0"; - }; -}; -//--- OBJECT WRITE END --- - -//--- OBJECT WRITE BEGIN --- -new GuiControl(DB_ChatDlg) { - profile = "GuiModelessDialogProfile"; - horizSizing = "width"; - vertSizing = "height"; - position = "0 0"; - extent = "640 480"; - minExtent = "8 8"; - visible = "1"; - helpTag = "0"; - - new GuiControl() { - profile = "GuiDefaultProfile"; - horizSizing = "relative"; - vertSizing = "relative"; - position = "0 0"; - extent = "300 236"; - minExtent = "8 8"; - visible = "1"; - helpTag = "0"; - - new ShellTextEditCtrl(DB_ChatEntry) { - profile = "NewTextEditProfile"; - horizSizing = "width"; - vertSizing = "top"; - position = "45 197"; - extent = "261 38"; - minExtent = "32 38"; - visible = "1"; - setFirstResponder = "0"; - altCommand = "DB_ChatEntry.sendChat();"; - escapeCommand = "DB_ChatEntry.onEscape();"; - helpTag = "0"; - historySize = "0"; - maxLength = "120"; - password = "0"; - glowOffset = "9 9"; - }; - }; -}; -//--- OBJECT WRITE END --- +//--- OBJECT WRITE BEGIN --- +new GuiChunkedBitmapCtrl(DebriefGui) { + profile = "GuiContentProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "1"; + variable = "$ShellBackground"; + helpTag = "0"; + useVariable = "1"; + + new ShellPaneCtrl(DB_Pane) { + profile = "ShellPaneProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "28 13"; + extent = "584 459"; + minExtent = "48 92"; + visible = "1"; + helpTag = "0"; + noTitleBar = "1"; + }; + new GuiProgressCtrl(DB_LoadingProgress) { + profile = "ShellProgressBarProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "67 423"; + extent = "300 25"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + + new GuiTextCtrl(DB_LoadingProgressTxt) { + profile = "ShellProgressBarTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 3"; + extent = "300 19"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + text = "LOADING MISSION..."; + }; + }; + new GuiControl() { + profile = "GuiDefaultProfile"; + horizSizing = "relative"; + vertSizing = "relative"; + position = "0 0"; + extent = "300 236"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + + new ShellScrollCtrl(DB_ChatScroll) { + profile = "NewScrollCtrlProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "50 18"; + extent = "251 184"; + minExtent = "24 24"; + visible = "1"; + helpTag = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "alwaysOn"; + constantThumbHeight = "0"; + defaultLineHeight = "15"; + childMargin = "3 3"; + fieldBase = "gui/shll_field"; + + new GuiScrollContentCtrl() { + profile = "GuiDefaultProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "7 7"; + extent = "221 170"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + + new GuiMessageVectorCtrl(DB_ChatVector) { + profile = "GuiChatHudProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "221 170"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + lineSpacing = "0"; + lineContinuedIndex = "10"; + allowedMatches[0] = "http"; + allowedMatches[1] = "t2server"; + matchColor = "0 0 255 255"; + maxColorIndex = "5"; + matchColors1 = "255 0 0 255"; + matchColors0 = "0 0 255 255"; + }; + }; + }; + }; + new GuiControl() { + profile = "GuiDefaultProfile"; + horizSizing = "relative"; + vertSizing = "height"; + position = "300 15"; + extent = "340 405"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + + new ShellFieldCtrl(DB_ResultPane) { + profile = "ShellFieldProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "5 7"; + extent = "280 392"; + minExtent = "16 18"; + visible = "1"; + helpTag = "0"; + + new GuiMLTextCtrl(DebriefResultText) { + profile = "DebriefHeadlineTextProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "4 3"; + extent = "272 28"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + lineSpacing = "2"; + allowColorChars = "0"; + }; + new ShellScrollCtrl(DB_ResultScroll) { + profile = "NewScrollCtrlProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "2 58"; + extent = "276 332"; + minExtent = "24 24"; + visible = "1"; + helpTag = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + constantThumbHeight = "0"; + defaultLineHeight = "15"; + childMargin = "3 3"; + fieldBase = "gui/shll_field"; + + new GuiScrollContentCtrl() { + profile = "GuiDefaultProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "7 7"; + extent = "262 318"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + + new GuiMLTextCtrl(DebriefText) { + profile = "DebriefTextProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "262 18"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + lineSpacing = "2"; + allowColorChars = "1"; + }; + }; + }; + }; + }; + new ShellBitmapButton() { + profile = "ShellButtonNoTabProfile"; + horizSizing = "left"; + vertSizing = "top"; + position = "372 417"; + extent = "115 38"; + minExtent = "32 38"; + visible = "1"; + setFirstResponder = "0"; + command = "debriefDisconnect();"; + helpTag = "0"; + text = "DISCONNECT"; + simpleStyle = "0"; + }; + new ShellBitmapButton(DB_ContinueBTN) { + profile = "ShellButtonNoTabProfile"; + horizSizing = "left"; + vertSizing = "top"; + position = "478 417"; + extent = "115 38"; + minExtent = "32 38"; + visible = "1"; + setFirstResponder = "0"; + command = "debriefContinue();"; + accelerator = "escape"; + helpTag = "0"; + text = "CONTINUE"; + simpleStyle = "0"; + }; +}; +//--- OBJECT WRITE END --- + +//--- OBJECT WRITE BEGIN --- +new GuiControl(DB_ChatDlg) { + profile = "GuiModelessDialogProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + + new GuiControl() { + profile = "GuiDefaultProfile"; + horizSizing = "relative"; + vertSizing = "relative"; + position = "0 0"; + extent = "300 236"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + + new ShellTextEditCtrl(DB_ChatEntry) { + profile = "NewTextEditProfile"; + horizSizing = "width"; + vertSizing = "top"; + position = "45 197"; + extent = "261 38"; + minExtent = "32 38"; + visible = "1"; + setFirstResponder = "0"; + altCommand = "DB_ChatEntry.sendChat();"; + escapeCommand = "DB_ChatEntry.onEscape();"; + helpTag = "0"; + historySize = "0"; + maxLength = "120"; + password = "0"; + glowOffset = "9 9"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/gui/InputDLG.gui b/gui/InputDLG.gui index fe396cb..aacfd51 100644 --- a/gui/InputDLG.gui +++ b/gui/InputDLG.gui @@ -1,91 +1,91 @@ -//--- OBJECT WRITE BEGIN --- -new GuiControl(InputDLG) { - profile = "DlgBackProfile"; - horizSizing = "width"; - vertSizing = "height"; - position = "0 0"; - extent = "640 480"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - - new ShellPaneCtrl(InputTransFrame) { - profile = "ShellDlgPaneProfile"; - horizSizing = "center"; - vertSizing = "center"; - position = "120 157"; - extent = "400 118"; - minExtent = "48 92"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Input"; - longTextBuffer = "0"; - maxLength = "255"; - noTitleBar = "0"; - - new ShellBitmapButton(InputDone) { - profile = "ShellButtonProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "120 70"; - extent = "140 38"; - minExtent = "32 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = ""; - helpTag = "0"; - text = "DONE"; - command = "InputOnDone();"; - simpleStyle = "0"; - }; - new GuiTextCtrl(InputText) { - profile = "SiegeHalftimeClockProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "22 27"; - extent = "76 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Text"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellTextEditCtrl(Input) { - profile = "NewTextEditProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "12 42"; - extent = "362 38"; - minExtent = "32 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = ""; - command = ""; - helpTag = "0"; - longTextBuffer = "0"; - maxLength = "255"; - historySize = "0"; - password = "0"; - IRCName = "0"; - tabComplete = "0"; - deniedSound = "InputDeniedSound"; - glowOffset = "9 9"; - }; - }; -}; -//--- OBJECT WRITE END --- - -function InputOnDone() -{ -canvas.popDialog(InputDLG); -commandToServer('InputDone',$InputType,Input.getValue()); -} +//--- OBJECT WRITE BEGIN --- +new GuiControl(InputDLG) { + profile = "DlgBackProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + + new ShellPaneCtrl(InputTransFrame) { + profile = "ShellDlgPaneProfile"; + horizSizing = "center"; + vertSizing = "center"; + position = "120 157"; + extent = "400 118"; + minExtent = "48 92"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Input"; + longTextBuffer = "0"; + maxLength = "255"; + noTitleBar = "0"; + + new ShellBitmapButton(InputDone) { + profile = "ShellButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "120 70"; + extent = "140 38"; + minExtent = "32 38"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + command = ""; + helpTag = "0"; + text = "DONE"; + command = "InputOnDone();"; + simpleStyle = "0"; + }; + new GuiTextCtrl(InputText) { + profile = "SiegeHalftimeClockProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "22 27"; + extent = "76 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Text"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellTextEditCtrl(Input) { + profile = "NewTextEditProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "12 42"; + extent = "362 38"; + minExtent = "32 38"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = ""; + command = ""; + helpTag = "0"; + longTextBuffer = "0"; + maxLength = "255"; + historySize = "0"; + password = "0"; + IRCName = "0"; + tabComplete = "0"; + deniedSound = "InputDeniedSound"; + glowOffset = "9 9"; + }; + }; +}; +//--- OBJECT WRITE END --- + +function InputOnDone() +{ +canvas.popDialog(InputDLG); +commandToServer('InputDone',$InputType,Input.getValue()); +} diff --git a/gui/LANAccountCreationDLG.gui b/gui/LANAccountCreationDLG.gui index ad99405..c72ff2c 100644 --- a/gui/LANAccountCreationDLG.gui +++ b/gui/LANAccountCreationDLG.gui @@ -1,122 +1,122 @@ -//--- OBJECT WRITE BEGIN --- -new GuiControl(LANAccountCreationDLG) { - profile = "DlgBackProfile"; - horizSizing = "width"; - vertSizing = "height"; - position = "0 0"; - extent = "640 480"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - - new ShellPaneCtrl(LANTransFrame) { - profile = "ShellDlgPaneProfile"; - horizSizing = "center"; - vertSizing = "center"; - position = "140 170"; - extent = "400 165"; - minExtent = "48 92"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "LAN Account"; - longTextBuffer = "0"; - maxLength = "255"; - noTitleBar = "0"; - - new ShellBitmapButton(LANAccountDone) { - profile = "ShellButtonProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "127 118"; - extent = "140 38"; - minExtent = "32 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "DONE"; - command = "LANAccountDone();"; - simpleStyle = "0"; - }; - new ShellTextEditCtrl(AccountPassword) { - profile = "NewTextEditProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "11 89"; - extent = "362 38"; - minExtent = "32 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "$Pref::LANAccount::Password"; - command = "OnLANPasswordInput();"; - helpTag = "0"; - longTextBuffer = "0"; - maxLength = "255"; - historySize = "0"; - password = "1"; - IRCName = "0"; - tabComplete = "0"; - deniedSound = "InputDeniedSound"; - glowOffset = "9 9"; - }; - new ShellTextEditCtrl(AccountName) { - profile = "NewTextEditProfile"; - horizSizing = "right"; - variable = "$Pref::LANAccount::Name"; - command = "OnLANNameInput();"; - vertSizing = "bottom"; - position = "12 42"; - extent = "362 38"; - minExtent = "32 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - longTextBuffer = "0"; - maxLength = "255"; - historySize = "0"; - password = "0"; - IRCName = "0"; - tabComplete = "0"; - deniedSound = "InputDeniedSound"; - glowOffset = "9 9"; - }; - new GuiTextCtrl() { - profile = "SiegeHalftimeClockProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "22 27"; - extent = "76 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Account Name"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new GuiTextCtrl() { - profile = "SiegeHalftimeClockProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "22 74"; - extent = "61 15"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Password"; - longTextBuffer = "0"; - maxLength = "255"; - }; - }; -}; -//--- OBJECT WRITE END --- - +//--- OBJECT WRITE BEGIN --- +new GuiControl(LANAccountCreationDLG) { + profile = "DlgBackProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + + new ShellPaneCtrl(LANTransFrame) { + profile = "ShellDlgPaneProfile"; + horizSizing = "center"; + vertSizing = "center"; + position = "140 170"; + extent = "400 165"; + minExtent = "48 92"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "LAN Account"; + longTextBuffer = "0"; + maxLength = "255"; + noTitleBar = "0"; + + new ShellBitmapButton(LANAccountDone) { + profile = "ShellButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "127 118"; + extent = "140 38"; + minExtent = "32 38"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "DONE"; + command = "LANAccountDone();"; + simpleStyle = "0"; + }; + new ShellTextEditCtrl(AccountPassword) { + profile = "NewTextEditProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "11 89"; + extent = "362 38"; + minExtent = "32 38"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "$Pref::LANAccount::Password"; + command = "OnLANPasswordInput();"; + helpTag = "0"; + longTextBuffer = "0"; + maxLength = "255"; + historySize = "0"; + password = "1"; + IRCName = "0"; + tabComplete = "0"; + deniedSound = "InputDeniedSound"; + glowOffset = "9 9"; + }; + new ShellTextEditCtrl(AccountName) { + profile = "NewTextEditProfile"; + horizSizing = "right"; + variable = "$Pref::LANAccount::Name"; + command = "OnLANNameInput();"; + vertSizing = "bottom"; + position = "12 42"; + extent = "362 38"; + minExtent = "32 38"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + longTextBuffer = "0"; + maxLength = "255"; + historySize = "0"; + password = "0"; + IRCName = "0"; + tabComplete = "0"; + deniedSound = "InputDeniedSound"; + glowOffset = "9 9"; + }; + new GuiTextCtrl() { + profile = "SiegeHalftimeClockProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "22 27"; + extent = "76 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Account Name"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new GuiTextCtrl() { + profile = "SiegeHalftimeClockProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "22 74"; + extent = "61 15"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Password"; + longTextBuffer = "0"; + maxLength = "255"; + }; + }; +}; +//--- OBJECT WRITE END --- + diff --git a/gui/LaunchToolbarDlg.gui b/gui/LaunchToolbarDlg.gui index 2105908..5f77cd2 100644 --- a/gui/LaunchToolbarDlg.gui +++ b/gui/LaunchToolbarDlg.gui @@ -1,76 +1,76 @@ -//--- OBJECT WRITE BEGIN --- -new GuiControl(LaunchToolbarDlg) { - profile = "GuiModelessDialogProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "0 0"; - extent = "640 480"; - minExtent = "8 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "0"; - helpTag = "0"; - ctrlCount = "0"; - - new GuiControl(LaunchToolbarPane) { - profile = "GuiDefaultProfile"; - horizSizing = "width"; - vertSizing = "top"; - position = "-2 436"; - extent = "644 44"; - minExtent = "8 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - helpTag = "0"; - - new ShellLaunchMenu(LaunchToolbarMenu) { - profile = "LaunchMenuProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "3 0"; - extent = "115 56"; - minExtent = "8 8"; - visible = "1"; - setFirstResponder = "1"; - modal = "1"; - helpTag = "0"; - text = "LAUNCH"; - maxPopupHeight = "200"; - buttonFontType = "Sui Generis"; - buttonFontSize = "14"; - }; - - new ShellTabGroupCtrl(LaunchTabView) { - profile = "LaunchTabProfile"; - horizSizing = "width"; - vertSizing = "bottom"; - position = "120 11"; - extent = "520 29"; - minExtent = "38 29"; - visible = "1"; - helpTag = "0"; - glowOffset = "0"; - tabSpacing = "1"; - maxTabWidth = "160"; - stretchToFit = "0"; - }; - }; - new ShellBitmapButton(LaunchToolbarCloseButton) { - profile = "CloseButtonProfile"; - horizSizing = "left"; - vertSizing = "bottom"; - position = "583 13"; - extent = "33 26"; - minExtent = "8 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - helpTag = "0"; - command = "LaunchTabView.closeCurrentTab();"; - text = ""; - simpleStyle = "1"; - }; -}; -//--- OBJECT WRITE END --- - +//--- OBJECT WRITE BEGIN --- +new GuiControl(LaunchToolbarDlg) { + profile = "GuiModelessDialogProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "0"; + helpTag = "0"; + ctrlCount = "0"; + + new GuiControl(LaunchToolbarPane) { + profile = "GuiDefaultProfile"; + horizSizing = "width"; + vertSizing = "top"; + position = "-2 436"; + extent = "644 44"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + helpTag = "0"; + + new ShellLaunchMenu(LaunchToolbarMenu) { + profile = "LaunchMenuProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "3 0"; + extent = "115 56"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "1"; + modal = "1"; + helpTag = "0"; + text = "LAUNCH"; + maxPopupHeight = "200"; + buttonFontType = "Sui Generis"; + buttonFontSize = "14"; + }; + + new ShellTabGroupCtrl(LaunchTabView) { + profile = "LaunchTabProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "120 11"; + extent = "520 29"; + minExtent = "38 29"; + visible = "1"; + helpTag = "0"; + glowOffset = "0"; + tabSpacing = "1"; + maxTabWidth = "160"; + stretchToFit = "0"; + }; + }; + new ShellBitmapButton(LaunchToolbarCloseButton) { + profile = "CloseButtonProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "583 13"; + extent = "33 26"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + helpTag = "0"; + command = "LaunchTabView.closeCurrentTab();"; + text = ""; + simpleStyle = "1"; + }; +}; +//--- OBJECT WRITE END --- + diff --git a/gui/MP3PlayerDLG.gui b/gui/MP3PlayerDLG.gui index fb4dfb9..8d153a6 100644 --- a/gui/MP3PlayerDLG.gui +++ b/gui/MP3PlayerDLG.gui @@ -1,125 +1,125 @@ -//--- OBJECT WRITE BEGIN --- -new GuiControl(MP3PlayerDLG) { - profile = "GuiDefaultProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "0 0"; - extent = "640 480"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - - new ShellPaneCtrl(MP3_Pane) { - profile = "ShellPaneProfile"; - horizSizing = "center"; - vertSizing = "center"; - position = "112 106"; - extent = "416 267"; - minExtent = "48 92"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "MP3 Player"; - longTextBuffer = "0"; - maxLength = "255"; - noTitleBar = "0"; - - new ShellScrollCtrl() { - profile = "NewScrollCtrlProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "13 22"; - extent = "200 234"; - minExtent = "24 24"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - willFirstRespond = "1"; - hScrollBar = "alwaysOn"; - vScrollBar = "alwaysOn"; - constantThumbHeight = "0"; - defaultLineHeight = "15"; - childMargin = "0 0"; - fieldBase = "gui/shll_field"; - - new GuiScrollContentCtrl() { - profile = "GuiDefaultProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 4"; - extent = "176 210"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - - new ShellTextList(MP3_List) { - profile = "GuiDefaultProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "0 0"; - extent = "176 8"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - enumerate = "0"; - resizeCell = "1"; - columns = "0"; - fitParentWidth = "1"; - clipColumnText = "0"; - }; - }; - }; - new GuiTextCtrl(MP3_Text) { - profile = "CommanderButtonProfile"; - horizSizing = "relative"; - vertSizing = "relative"; - position = "211 30"; - extent = "190 198"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Try using some other MP3 player."; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellBitmapButton(MP3_Play) { - profile = "ShellButtonProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "200 221"; - extent = "77 38"; - minExtent = "32 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "PLAY"; - simpleStyle = "0"; - }; - new ShellBitmapButton(MP3_Close) { - profile = "ShellButtonProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "270 221"; - extent = "140 38"; - minExtent = "32 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "CLOSE"; - simpleStyle = "0"; - }; - }; -}; -//--- OBJECT WRITE END --- +//--- OBJECT WRITE BEGIN --- +new GuiControl(MP3PlayerDLG) { + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + + new ShellPaneCtrl(MP3_Pane) { + profile = "ShellPaneProfile"; + horizSizing = "center"; + vertSizing = "center"; + position = "112 106"; + extent = "416 267"; + minExtent = "48 92"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "MP3 Player"; + longTextBuffer = "0"; + maxLength = "255"; + noTitleBar = "0"; + + new ShellScrollCtrl() { + profile = "NewScrollCtrlProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "13 22"; + extent = "200 234"; + minExtent = "24 24"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOn"; + vScrollBar = "alwaysOn"; + constantThumbHeight = "0"; + defaultLineHeight = "15"; + childMargin = "0 0"; + fieldBase = "gui/shll_field"; + + new GuiScrollContentCtrl() { + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "4 4"; + extent = "176 210"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + + new ShellTextList(MP3_List) { + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "176 8"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + enumerate = "0"; + resizeCell = "1"; + columns = "0"; + fitParentWidth = "1"; + clipColumnText = "0"; + }; + }; + }; + new GuiTextCtrl(MP3_Text) { + profile = "CommanderButtonProfile"; + horizSizing = "relative"; + vertSizing = "relative"; + position = "211 30"; + extent = "190 198"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Try using some other MP3 player."; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellBitmapButton(MP3_Play) { + profile = "ShellButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "200 221"; + extent = "77 38"; + minExtent = "32 38"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "PLAY"; + simpleStyle = "0"; + }; + new ShellBitmapButton(MP3_Close) { + profile = "ShellButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "270 221"; + extent = "140 38"; + minExtent = "32 38"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "CLOSE"; + simpleStyle = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/gui/MessageBoxFileTransfer.gui b/gui/MessageBoxFileTransfer.gui index cb54e4a..a02131e 100644 --- a/gui/MessageBoxFileTransfer.gui +++ b/gui/MessageBoxFileTransfer.gui @@ -1,75 +1,75 @@ -//--- OBJECT WRITE BEGIN --- -new GuiControl(MessageBoxTransfer) { - profile = "DlgBackProfile"; - horizSizing = "width"; - vertSizing = "height"; - position = "0 0"; - extent = "640 480"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - - new ShellPaneCtrl(MBTransFrame) { - profile = "ShellDlgPaneProfile"; - horizSizing = "center"; - vertSizing = "center"; - position = "170 184"; - extent = "300 111"; - minExtent = "48 92"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Updating"; - longTextBuffer = "0"; - maxLength = "255"; - noTitleBar = "0"; - - new GuiProgressCtrl() { - profile = "ShellProgressBarProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "19 28"; - extent = "262 24"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - - new GuiTextCtrl(UpdateProgress) { - profile = "ShellProgressBarTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "0 3"; - extent = "262 19"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Updating file"; - longTextBuffer = "0"; - maxLength = "255"; - }; - }; - new GuiTextCtrl() { - profile = "NewTextEditProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "114 65"; - extent = "254 64"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Please wait..."; - longTextBuffer = "0"; - maxLength = "255"; - }; - }; -}; -//--- OBJECT WRITE END --- +//--- OBJECT WRITE BEGIN --- +new GuiControl(MessageBoxTransfer) { + profile = "DlgBackProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + + new ShellPaneCtrl(MBTransFrame) { + profile = "ShellDlgPaneProfile"; + horizSizing = "center"; + vertSizing = "center"; + position = "170 184"; + extent = "300 111"; + minExtent = "48 92"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Updating"; + longTextBuffer = "0"; + maxLength = "255"; + noTitleBar = "0"; + + new GuiProgressCtrl() { + profile = "ShellProgressBarProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "19 28"; + extent = "262 24"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + + new GuiTextCtrl(UpdateProgress) { + profile = "ShellProgressBarTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 3"; + extent = "262 19"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Updating file"; + longTextBuffer = "0"; + maxLength = "255"; + }; + }; + new GuiTextCtrl() { + profile = "NewTextEditProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "114 65"; + extent = "254 64"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Please wait..."; + longTextBuffer = "0"; + maxLength = "255"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/gui/OptionsDlg.gui b/gui/OptionsDlg.gui index 362a0ba..1528567 100644 --- a/gui/OptionsDlg.gui +++ b/gui/OptionsDlg.gui @@ -1,2715 +1,2715 @@ -//--- OBJECT WRITE BEGIN --- -new GuiControl(OptionsDlg) { - profile = "DlgBackProfile"; - horizSizing = "width"; - vertSizing = "height"; - position = "0 0"; - extent = "640 480"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - pane = "VIDEO"; - - new ShellPaneCtrl() { - profile = "ShellDlgPaneProfile"; - horizSizing = "center"; - vertSizing = "center"; - position = "20 30"; - extent = "600 420"; - minExtent = "48 92"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "SETTINGS"; - longTextBuffer = "0"; - maxLength = "255"; - noTitleBar = "0"; - - new ShellBitmapButton() { - profile = "ShellButtonProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "34 362"; - extent = "82 38"; - minExtent = "32 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "Canvas.popDialog(OptionsDlg);"; - helpTag = "0"; - text = "DONE"; - simpleStyle = "0"; - }; - new ShellTabButton(OP_VideoTab) { - profile = "ShellTabProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "19 46"; - extent = "108 38"; - minExtent = "48 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "OptionsDlg.setPane(Video);"; - helpTag = "0"; - text = "VIDEO"; - longTextBuffer = "0"; - maxLength = "255"; - simpleStyle = "0"; - }; - new ShellTabButton(OP_GraphicsTab) { - profile = "ShellTabProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "19 76"; - extent = "108 38"; - minExtent = "48 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "OptionsDlg.setPane(Graphics);"; - helpTag = "0"; - text = "GRAPHICS"; - longTextBuffer = "0"; - maxLength = "255"; - simpleStyle = "0"; - }; - new ShellTabButton(OP_TexturesTab) { - profile = "ShellTabProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "19 106"; - extent = "108 38"; - minExtent = "48 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "OptionsDlg.setPane(Textures);"; - helpTag = "0"; - text = "TEXTURES"; - longTextBuffer = "0"; - maxLength = "255"; - simpleStyle = "0"; - }; - new ShellTabButton(OP_SoundTab) { - profile = "ShellTabProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "19 136"; - extent = "108 38"; - minExtent = "48 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "OptionsDlg.setPane(Sound);"; - helpTag = "0"; - text = "SOUND"; - longTextBuffer = "0"; - maxLength = "255"; - simpleStyle = "0"; - }; - new ShellTabButton(OP_VoiceTab) { - profile = "ShellTabProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "19 166"; - extent = "108 38"; - minExtent = "48 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "OptionsDlg.setPane(Voice);"; - helpTag = "0"; - text = "VOICE"; - longTextBuffer = "0"; - maxLength = "255"; - simpleStyle = "0"; - }; - new ShellTabButton(OP_ControlsTab) { - profile = "ShellTabProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "19 196"; - extent = "108 38"; - minExtent = "48 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "OptionsDlg.setPane(Controls);"; - helpTag = "0"; - text = "CONTROLS"; - longTextBuffer = "0"; - maxLength = "255"; - simpleStyle = "0"; - }; - new ShellTabButton(OP_NetworkTab) { - profile = "ShellTabProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "19 226"; - extent = "108 38"; - minExtent = "48 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "OptionsDlg.setPane(Network);"; - helpTag = "0"; - text = "NETWORK"; - longTextBuffer = "0"; - maxLength = "255"; - simpleStyle = "0"; - }; - new ShellTabButton(OP_GameTab) { - profile = "ShellTabProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "19 256"; - extent = "108 38"; - minExtent = "48 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "OptionsDlg.setPane(Game);"; - helpTag = "0"; - text = "GAME"; - longTextBuffer = "0"; - maxLength = "255"; - simpleStyle = "0"; - }; - new ShellTabButton(OP_RPGTab) { - profile = "ShellTabProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "19 286"; - extent = "108 38"; - minExtent = "48 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "OptionsDlg.setPane(RPG);"; - helpTag = "0"; - text = "RPG"; - longTextBuffer = "0"; - maxLength = "255"; - simpleStyle = "0"; - }; - new ShellTabFrame() { - profile = "ShellTabFrameProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "127 31"; - extent = "254 368"; - minExtent = "254 26"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - isVertical = "1"; - useCloseButton = "0"; - edgeInset = "0"; - }; - new ShellFieldCtrl(OP_RPGPane) { - profile = "ShellFieldProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "138 42"; - extent = "437 346"; - minExtent = "16 18"; - visible = "0"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - - new ShellBitmapButton() { - profile = "ShellButtonProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "151 3"; - extent = "131 38"; - minExtent = "32 38"; - visible = "1"; - command = "canvas.popDialog(OptionsDLG); canvas.pushDialog(LANAccountCreationDLG); $ChangeSettings = true;"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "LAN ACCOUNT"; - simpleStyle = "0"; - }; - }; - - new ShellFieldCtrl(OP_VideoPane) { - profile = "ShellFieldProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "138 42"; - extent = "437 346"; - minExtent = "16 18"; - visible = "0"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - - new GuiTextCtrl() { - profile = "ShellTextRightProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "2 16"; - extent = "100 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Video Driver:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellPopupMenu(OP_VideoDriverMenu) { - profile = "ShellPopupProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "99 7"; - extent = "140 36"; - minExtent = "49 36"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Select Driver"; - longTextBuffer = "0"; - maxLength = "255"; - maxPopupHeight = "200"; - buttonBitmap = "gui/shll_pulldown"; - rolloverBarBitmap = "gui/shll_pulldownbar_rol"; - selectedBarBitmap = "gui/shll_pulldownbar_act"; - noButtonStyle = "0"; - }; - new GuiTextCtrl() { - profile = "ShellTextRightProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "2 54"; - extent = "100 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Resolution:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellPopupMenu(OP_ResMenu) { - profile = "ShellPopupProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "99 45"; - extent = "140 36"; - minExtent = "49 36"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Select Resolution"; - longTextBuffer = "0"; - maxLength = "255"; - maxPopupHeight = "200"; - buttonBitmap = "gui/shll_pulldown"; - rolloverBarBitmap = "gui/shll_pulldownbar_rol"; - selectedBarBitmap = "gui/shll_pulldownbar_act"; - noButtonStyle = "0"; - }; - new GuiTextCtrl() { - profile = "ShellTextRightProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "2 92"; - extent = "100 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Bit Depth:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellPopupMenu(OP_BPPMenu) { - profile = "ShellPopupProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "99 83"; - extent = "140 36"; - minExtent = "49 36"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Default"; - longTextBuffer = "0"; - maxLength = "255"; - maxPopupHeight = "200"; - buttonBitmap = "gui/shll_pulldown"; - rolloverBarBitmap = "gui/shll_pulldownbar_rol"; - selectedBarBitmap = "gui/shll_pulldownbar_act"; - noButtonStyle = "0"; - }; - new ShellToggleButton(OP_FullScreenTgl) { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "102 125"; - extent = "127 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "FULL SCREEN"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellBitmapButton(OP_ApplyBtn) { - profile = "ShellButtonProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "275 176"; - extent = "128 38"; - minExtent = "32 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "OptionsDlg.applyGraphicChanges();"; - helpTag = "0"; - text = "APPLY CHANGES"; - simpleStyle = "0"; - }; - new ShellBitmapButton() { - profile = "ShellButtonProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "275 8"; - extent = "128 38"; - minExtent = "32 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "Canvas.pushDialog(DriverInfoDlg);"; - helpTag = "0"; - text = "DRIVER INFO"; - simpleStyle = "0"; - }; - new ShellToggleButton(OP_VSyncTgl) { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "133 243"; - extent = "170 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "DISABLE VERTICAL SYNC"; - longTextBuffer = "0"; - maxLength = "255"; - }; - }; - new ShellFieldCtrl(OP_GraphicsPane) { - profile = "ShellFieldProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "138 42"; - extent = "437 346"; - minExtent = "16 18"; - visible = "0"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - - new GuiTextCtrl() { - profile = "ShellTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "231 6"; - extent = "97 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Gamma Correction:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellSliderCtrl(OP_GammaSlider) { - profile = "ShellSliderProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "241 21"; - extent = "170 24"; - minExtent = "12 24"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "value"; - altCommand = "updateGammaCorrection();"; - helpTag = "0"; - range = "0.000000 1.000000"; - ticks = "1000"; - value = "0.385965"; - usePlusMinus = "1"; - }; - new GuiTextCtrl() { - profile = "ShellTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "26 6"; - extent = "72 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Terrain Detail:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellSliderCtrl(OP_TerrainSlider) { - profile = "ShellSliderProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "36 21"; - extent = "170 24"; - minExtent = "12 24"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "value"; - command = "updateTerrainDetail();"; - helpTag = "0"; - range = "0.000000 25.000000"; - ticks = "26"; - value = "23"; - usePlusMinus = "1"; - }; - new GuiTextCtrl() { - profile = "ShellTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "231 44"; - extent = "67 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Shape Detail:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellSliderCtrl(OP_ShapeSlider) { - profile = "ShellSliderProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "241 59"; - extent = "170 24"; - minExtent = "12 24"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "value"; - helpTag = "0"; - range = "0.000000 1.000000"; - ticks = "19"; - value = "1"; - usePlusMinus = "1"; - }; - new GuiTextCtrl() { - profile = "ShellTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "27 44"; - extent = "77 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Shadow Detail:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellSliderCtrl(OP_ShadowSlider) { - profile = "ShellSliderProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "37 59"; - extent = "170 24"; - minExtent = "12 24"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "value"; - helpTag = "0"; - range = "0.000000 1.000000"; - ticks = "1000"; - value = "0.596491"; - usePlusMinus = "1"; - }; - new GuiTextCtrl() { - profile = "ShellTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "27 82"; - extent = "72 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Interior Detail:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellSliderCtrl(OP_InteriorDetailSlider) { - profile = "ShellSliderProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "37 97"; - extent = "170 24"; - minExtent = "12 24"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "value"; - helpTag = "0"; - range = "0.300000 1.000000"; - ticks = "1000"; - value = "0.950877"; - usePlusMinus = "1"; - }; - new GuiTextCtrl() { - profile = "ShellTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "231 82"; - extent = "85 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Visible Distance:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellSliderCtrl(OP_VisibleDistanceSlider) { - profile = "ShellSliderProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "241 97"; - extent = "170 24"; - minExtent = "12 24"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "value"; - helpTag = "0"; - range = "0.600000 1.000000"; - ticks = "400"; - value = "1"; - usePlusMinus = "1"; - }; - new GuiTextCtrl() { - profile = "ShellTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "27 120"; - extent = "84 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Particle Density:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellSliderCtrl(OP_ParticleDensitySlider) { - profile = "ShellSliderProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "37 135"; - extent = "170 24"; - minExtent = "12 24"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "value"; - helpTag = "0"; - range = "0.000000 3.000000"; - ticks = "1000"; - value = "3"; - usePlusMinus = "1"; - }; - new GuiTextCtrl(OP_DynamicLightText) { - profile = "ShellTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "231 120"; - extent = "160 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Dynamic Light Visible Distance:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new GuiTextCtrl(OP_DynamicLightText_Disabled) { - profile = "DisabledTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "231 120"; - extent = "160 22"; - minExtent = "8 8"; - visible = "0"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Dynamic Light Visible Distance:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellSliderCtrl(OP_DynamicLightSlider) { - profile = "ShellSliderProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "241 135"; - extent = "170 24"; - minExtent = "12 24"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "value"; - helpTag = "0"; - range = "0.000000 100.000000"; - ticks = "100"; - value = "92.1053"; - usePlusMinus = "1"; - }; - new GuiTextCtrl() { - profile = "ShellTextRightProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "79 168"; - extent = "70 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Sky Detail:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellPopupMenu(OP_SkyDetailMenu) { - profile = "ShellPopupProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "146 159"; - extent = "200 36"; - minExtent = "49 36"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Default"; - longTextBuffer = "0"; - maxLength = "255"; - maxPopupHeight = "200"; - buttonBitmap = "gui/shll_pulldown"; - rolloverBarBitmap = "gui/shll_pulldownbar_rol"; - selectedBarBitmap = "gui/shll_pulldownbar_act"; - noButtonStyle = "0"; - }; - new GuiTextCtrl() { - profile = "ShellTextRightProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "35 198"; - extent = "114 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "First Person Draw:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellPopupMenu(OP_PlayerRenderMenu) { - profile = "ShellPopupProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "146 189"; - extent = "200 36"; - minExtent = "49 36"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Default"; - longTextBuffer = "0"; - maxLength = "255"; - maxPopupHeight = "200"; - buttonBitmap = "gui/shll_pulldown"; - rolloverBarBitmap = "gui/shll_pulldownbar_rol"; - selectedBarBitmap = "gui/shll_pulldownbar_act"; - noButtonStyle = "0"; - }; - new ShellToggleButton() { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "31 226"; - extent = "170 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "$pref::precipitationOn"; - helpTag = "0"; - text = "PRECIPITATION"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellToggleButton() { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "236 226"; - extent = "170 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "$pref::Interior::DynamicLights"; - command = "updateDynamicLightSliderState();"; - helpTag = "0"; - text = "DYNAMIC INTERIOR LIGHTS"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellToggleButton() { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "31 256"; - extent = "170 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "$pref::decalsOn"; - helpTag = "0"; - text = "DECALS"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellToggleButton() { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "236 256"; - extent = "170 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "$pref::Terrain::dynamicLights"; - command = "updateDynamicLightSliderState();"; - helpTag = "0"; - text = "DYNAMIC TERRAIN LIGHTS"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellToggleButton() { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "31 286"; - extent = "170 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "$pref::Terrain::enableDetails"; - helpTag = "0"; - text = "TERRAIN DETAILS"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellToggleButton(OP_IntTexturedFogTgl) { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "236 286"; - extent = "170 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "INTERIOR TEXTURED FOG"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellToggleButton() { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "31 316"; - extent = "170 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "$pref::useOldShieldEffect"; - helpTag = "0"; - text = "HI-RES SHIELD EFFECTS"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellToggleButton(OP_VertexLightTgl) { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "236 316"; - extent = "170 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "VERTEX LIGHTING"; - longTextBuffer = "0"; - maxLength = "255"; - }; - }; - new ShellFieldCtrl(OP_TexturesPane) { - profile = "ShellFieldProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "138 42"; - extent = "437 346"; - minExtent = "16 18"; - visible = "0"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - - new GuiTextCtrl() { - profile = "ShellTextRightProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "37 16"; - extent = "100 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Texture Quality:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellPopupMenu(OP_TexQualityMenu) { - profile = "ShellPopupProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "134 7"; - extent = "140 36"; - minExtent = "49 36"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Default"; - longTextBuffer = "0"; - maxLength = "255"; - maxPopupHeight = "200"; - buttonBitmap = "gui/shll_pulldown"; - rolloverBarBitmap = "gui/shll_pulldownbar_rol"; - selectedBarBitmap = "gui/shll_pulldownbar_act"; - noButtonStyle = "0"; - }; - new GuiTextCtrl() { - profile = "ShellTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "26 85"; - extent = "114 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Terrain Texture Detail:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellSliderCtrl(OP_TerrainTexSlider) { - profile = "ShellSliderProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "36 100"; - extent = "170 24"; - minExtent = "12 24"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "value"; - helpTag = "0"; - range = "0.000000 6.000000"; - ticks = "7"; - value = "5"; - usePlusMinus = "1"; - }; - new GuiTextCtrl() { - profile = "ShellTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "231 85"; - extent = "109 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Shape Texture Detail:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellSliderCtrl(OP_ShapeTexSlider) { - profile = "ShellSliderProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "241 100"; - extent = "170 24"; - minExtent = "12 24"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "value"; - helpTag = "0"; - range = "0.000000 1.000000"; - ticks = "6"; - value = "1"; - usePlusMinus = "1"; - }; - new GuiTextCtrl() { - profile = "ShellTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "26 123"; - extent = "119 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Building Texture Detail:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellSliderCtrl(OP_BuildingTexSlider) { - profile = "ShellSliderProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "36 138"; - extent = "170 24"; - minExtent = "12 24"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "value"; - helpTag = "0"; - range = "0.000000 1.000000"; - ticks = "6"; - value = "0.8"; - usePlusMinus = "1"; - }; - new GuiTextCtrl() { - profile = "ShellTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "231 123"; - extent = "97 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Sky Texture Detail:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellSliderCtrl(OP_SkyTexSlider) { - profile = "ShellSliderProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "241 138"; - extent = "170 24"; - minExtent = "12 24"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "value"; - helpTag = "0"; - range = "0.000000 1.000000"; - ticks = "6"; - value = "0.8"; - usePlusMinus = "1"; - }; - new GuiTextCtrl(OP_CompressLabel) { - profile = "ShellTextRightProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "17 46"; - extent = "120 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Texture Compression:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new GuiTextCtrl(OP_CompressLabel_Disabled) { - profile = "DisabledTextRightProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "6 46"; - extent = "135 22"; - minExtent = "8 8"; - visible = "0"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Texture Compression:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellPopupMenu(OP_CompressMenu) { - profile = "ShellPopupProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "134 37"; - extent = "140 36"; - minExtent = "49 36"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "None"; - longTextBuffer = "0"; - maxLength = "255"; - maxPopupHeight = "200"; - buttonBitmap = "gui/shll_pulldown"; - rolloverBarBitmap = "gui/shll_pulldownbar_rol"; - selectedBarBitmap = "gui/shll_pulldownbar_act"; - noButtonStyle = "0"; - }; - new GuiTextCtrl(OP_AnisotropyLabel) { - profile = "ShellTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "26 179"; - extent = "58 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Anisotropy:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new GuiTextCtrl(OP_AnisotropyLabel_Disabled) { - profile = "DisabledTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "26 179"; - extent = "58 22"; - minExtent = "8 8"; - visible = "0"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Anisotropy:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellSliderCtrl(OP_AnisotropySlider) { - profile = "ShellSliderProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "37 194"; - extent = "170 24"; - minExtent = "12 24"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "value"; - helpTag = "0"; - range = "0.000000 1.000000"; - ticks = "1000"; - value = "0"; - usePlusMinus = "1"; - }; - new ShellToggleButton(OP_EnvMapTgl) { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "236 180"; - extent = "170 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "$pref::environmentMaps"; - helpTag = "0"; - text = "ENVIRONMENT MAPS"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellToggleButton(OP_IntEnvMapTgl) { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "236 210"; - extent = "170 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "$pref::Interior::ShowEnvironmentMaps"; - helpTag = "0"; - text = "INTERIOR ENV. MAPS"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellToggleButton(OP_HiResSkinTgl) { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "236 250"; - extent = "170 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "HI-RES PLAYER SKINS"; - longTextBuffer = "0"; - maxLength = "255"; - }; - }; - new ShellFieldCtrl(OP_SoundPane) { - profile = "ShellFieldProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "138 42"; - extent = "437 346"; - minExtent = "16 18"; - visible = "0"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - - new GuiTextCtrl() { - profile = "ShellTextRightProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "10 16"; - extent = "72 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "3D Provider:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellPopupMenu(OP_AudioProviderMenu) { - profile = "ShellPopupProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "79 7"; - extent = "268 36"; - minExtent = "49 36"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Select Provider"; - longTextBuffer = "0"; - maxLength = "255"; - maxPopupHeight = "200"; - buttonBitmap = "gui/shll_pulldown"; - rolloverBarBitmap = "gui/shll_pulldownbar_rol"; - selectedBarBitmap = "gui/shll_pulldownbar_act"; - noButtonStyle = "0"; - }; - new ShellBitmapButton(OP_AudioResetProvider) { - profile = "ShellButtonProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "339 7"; - extent = "79 38"; - minExtent = "32 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "RESET"; - simpleStyle = "0"; - }; - new ShellToggleButton(OP_AudioEnvironmentTgl) { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "249 42"; - extent = "160 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "$pref::Audio::environmentEnabled"; - helpTag = "0"; - text = "ENVIRONMENT ENABLED"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new GuiTextCtrl() { - profile = "ShellTextRightProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "10 46"; - extent = "72 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Speakers:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellPopupMenu(OP_AudioSpeakerMenu) { - profile = "ShellPopupProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "79 37"; - extent = "169 36"; - minExtent = "49 36"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Select Speaker"; - longTextBuffer = "0"; - maxLength = "255"; - maxPopupHeight = "200"; - buttonBitmap = "gui/shll_pulldown"; - rolloverBarBitmap = "gui/shll_pulldownbar_rol"; - selectedBarBitmap = "gui/shll_pulldownbar_act"; - noButtonStyle = "0"; - }; - new GuiTextCtrl() { - profile = "ShellTextRightProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "11 97"; - extent = "72 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Frequency:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellPopupMenu(OP_AudioFrequencyMenu) { - profile = "ShellPopupProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "80 88"; - extent = "169 36"; - minExtent = "49 36"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Select Frequency"; - longTextBuffer = "0"; - maxLength = "255"; - maxPopupHeight = "200"; - buttonBitmap = "gui/shll_pulldown"; - rolloverBarBitmap = "gui/shll_pulldownbar_rol"; - selectedBarBitmap = "gui/shll_pulldownbar_act"; - noButtonStyle = "0"; - }; - new GuiTextCtrl() { - profile = "ShellTextRightProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "11 127"; - extent = "72 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Bit Rate:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellPopupMenu(OP_AudioBitRateMenu) { - profile = "ShellPopupProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "80 118"; - extent = "100 36"; - minExtent = "49 36"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Select Bit Rate"; - longTextBuffer = "0"; - maxLength = "255"; - maxPopupHeight = "200"; - buttonBitmap = "gui/shll_pulldown"; - rolloverBarBitmap = "gui/shll_pulldownbar_rol"; - selectedBarBitmap = "gui/shll_pulldownbar_act"; - noButtonStyle = "0"; - }; - new GuiTextCtrl() { - profile = "ShellTextRightProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "221 127"; - extent = "60 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Channels:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellPopupMenu(OP_AudioChannelsMenu) { - profile = "ShellPopupProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "278 118"; - extent = "100 36"; - minExtent = "49 36"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Select # Channels"; - longTextBuffer = "0"; - maxLength = "255"; - maxPopupHeight = "200"; - buttonBitmap = "gui/shll_pulldown"; - rolloverBarBitmap = "gui/shll_pulldownbar_rol"; - selectedBarBitmap = "gui/shll_pulldownbar_act"; - noButtonStyle = "0"; - }; - new GuiTextCtrl() { - profile = "ShellTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "26 177"; - extent = "79 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Master Volume:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellSliderCtrl(OP_MasterVolumeSlider) { - profile = "ShellSliderProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "36 192"; - extent = "170 24"; - minExtent = "12 24"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "value"; - altCommand = "updateMasterVolume();"; - helpTag = "0"; - range = "0.000000 1.000000"; - ticks = "1000"; - value = "0.894737"; - usePlusMinus = "1"; - }; - new GuiTextCtrl() { - profile = "ShellTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "231 177"; - extent = "79 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Effects Volume:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellSliderCtrl(OP_EffectsVolumeSlider) { - profile = "ShellSliderProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "241 192"; - extent = "170 24"; - minExtent = "12 24"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "value"; - helpTag = "0"; - range = "0.000000 1.000000"; - ticks = "1000"; - value = "0.938596"; - usePlusMinus = "1"; - }; - new GuiTextCtrl() { - profile = "ShellTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "26 215"; - extent = "60 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Gui Volume:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellSliderCtrl(OP_GuiVolumeSlider) { - profile = "ShellSliderProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "36 230"; - extent = "170 24"; - minExtent = "12 24"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "value"; - altCommand = "updateGuiVolume();"; - helpTag = "0"; - range = "0.000000 1.000000"; - ticks = "1000"; - value = "0.692982"; - usePlusMinus = "1"; - }; - new GuiTextCtrl() { - profile = "ShellTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "231 215"; - extent = "97 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Voice Bind Volume:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellSliderCtrl(OP_VoiceBindVolumeSlider) { - profile = "ShellSliderProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "241 230"; - extent = "170 24"; - minExtent = "12 24"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "value"; - helpTag = "0"; - range = "0.000000 1.000000"; - ticks = "1000"; - value = "0.824561"; - usePlusMinus = "1"; - }; - new ShellToggleButton(OP_MusicTgl) { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "31 266"; - extent = "170 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "$pref::Audio::musicEnabled"; - helpTag = "0"; - text = "MP3 MUSIC"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new GuiTextCtrl(OP_MusicVolumeLabel) { - profile = "ShellTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "231 257"; - extent = "74 22"; - minExtent = "8 8"; - visible = "0"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Music Volume:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new GuiTextCtrl(OP_MusicVolumeLabel_Disabled) { - profile = "DisabledTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "231 253"; - extent = "74 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Music Volume:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellSliderCtrl(OP_MusicVolumeSlider) { - profile = "ShellSliderProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "241 268"; - extent = "170 24"; - minExtent = "12 24"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "value"; - altCommand = "updateMusicVolume();"; - helpTag = "0"; - range = "0.000000 1.000000"; - ticks = "1000"; - value = "0.859649"; - usePlusMinus = "1"; - }; - }; - new ShellFieldCtrl(OP_VoicePane) { - profile = "ShellFieldProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "138 42"; - extent = "437 346"; - minExtent = "16 18"; - visible = "0"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - - new ShellToggleButton(OP_MicrophoneEnabledTgl) { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "31 13"; - extent = "170 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "$pref::Audio::enableVoiceCapture"; - helpTag = "0"; - text = "MICROPHONE ENABLED"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellBitmapButton(OP_RecordTestBtn) { - profile = "ShellButtonProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "232 8"; - extent = "173 38"; - minExtent = "32 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "alxCaptureStart(true);"; - helpTag = "0"; - text = "TEST RECORD"; - simpleStyle = "0"; - }; - new GuiTextCtrl(OP_MicVolumeLabel) { - profile = "ShellTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "28 43"; - extent = "102 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Microphone Volume:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new GuiTextCtrl(OP_MicVolumeLabel_Disabled) { - profile = "DisabledTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "28 43"; - extent = "102 22"; - minExtent = "8 8"; - visible = "0"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Microphone Volume:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellSliderCtrl(OP_MicrophoneVolumeSlider) { - profile = "ShellSliderProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "38 58"; - extent = "170 24"; - minExtent = "12 24"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "value"; - helpTag = "0"; - range = "0.000000 1.000000"; - ticks = "1000"; - value = "1"; - usePlusMinus = "1"; - }; - new GuiTextCtrl(OP_InputBoostLabel) { - profile = "ShellTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "231 43"; - extent = "123 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Microphone Input Boost:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new GuiTextCtrl(OP_InputBoostLabel_Disabled) { - profile = "DisabledTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "231 43"; - extent = "123 22"; - minExtent = "8 8"; - visible = "0"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Microphone Input Boost:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new GuiTextCtrl(OP_InputBoostPercentTxt) { - profile = "ShellTextCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "271 61"; - extent = "110 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "100%"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellSliderCtrl(OP_InputBoostSlider) { - profile = "ShellSliderProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "241 58"; - extent = "170 24"; - minExtent = "12 24"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "value"; - altCommand = "updateInputBoost();"; - helpTag = "0"; - range = "1.000000 5.000000"; - ticks = "5000"; - value = "3.70175"; - usePlusMinus = "1"; - }; - new GuiTextCtrl(OP_VoiceListenLabel) { - profile = "ShellTextRightProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "46 96"; - extent = "140 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Voice Listen Codec(s):"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellPopupMenu(OP_VoiceListenMenu) { - profile = "ShellPopupProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "183 87"; - extent = "129 36"; - minExtent = "49 36"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Select Quality"; - longTextBuffer = "0"; - maxLength = "255"; - maxPopupHeight = "200"; - buttonBitmap = "gui/shll_pulldown"; - rolloverBarBitmap = "gui/shll_pulldownbar_rol"; - selectedBarBitmap = "gui/shll_pulldownbar_act"; - noButtonStyle = "0"; - }; - new GuiTextCtrl(OP_VoiceSendLabel) { - profile = "ShellTextRightProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "46 126"; - extent = "140 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Voice Send Codec:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellPopupMenu(OP_VoiceSendMenu) { - profile = "ShellPopupProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "183 117"; - extent = "129 36"; - minExtent = "49 36"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Select Quality"; - longTextBuffer = "0"; - maxLength = "255"; - maxPopupHeight = "200"; - buttonBitmap = "gui/shll_pulldown"; - rolloverBarBitmap = "gui/shll_pulldownbar_rol"; - selectedBarBitmap = "gui/shll_pulldownbar_act"; - noButtonStyle = "0"; - }; - new GuiTextCtrl(OP_VoiceListenLabel_Disabled) { - profile = "DisabledTextRightProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "46 96"; - extent = "140 22"; - minExtent = "8 8"; - visible = "0"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Voice Listen Quality:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new GuiTextCtrl(OP_VoiceSendLabel_Disabled) { - profile = "DisabledTextRightProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "46 126"; - extent = "140 22"; - minExtent = "8 8"; - visible = "0"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Voice Send Quality:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new GuiMLTextCtrl(OP_VoiceCodecInfo) { - profile = "GuiDefaultProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "25 159"; - extent = "395 140"; - minExtent = "8 140"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - lineSpacing = "2"; - allowColorChars = "0"; - maxChars = "-1"; - deniedSound = "InputDeniedSound"; - }; - }; - new ShellFieldCtrl(OP_ControlsPane) { - profile = "ShellFieldProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "138 42"; - extent = "437 346"; - minExtent = "16 18"; - visible = "0"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - group = "Main"; - - new ShellScrollCtrl() { - profile = "NewScrollCtrlProfile"; - horizSizing = "right"; - vertSizing = "height"; - position = "2 31"; - extent = "290 283"; - minExtent = "24 52"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - willFirstRespond = "1"; - hScrollBar = "alwaysOff"; - vScrollBar = "alwaysOn"; - constantThumbHeight = "0"; - defaultLineHeight = "15"; - childMargin = "0 2"; - fieldBase = "gui/shll_field"; - - new GuiScrollContentCtrl() { - profile = "GuiDefaultProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 6"; - extent = "266 271"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - - new ShellTextList(OP_RemapList) { - profile = "ShellTextArrayProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "0 0"; - extent = "266 8"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - altCommand = "OP_RemapList.doRemap();"; - helpTag = "0"; - enumerate = "0"; - resizeCell = "1"; - columns = "2 150"; - fitParentWidth = "1"; - clipColumnText = "0"; - }; - }; - }; - new ShellBitmapButton() { - profile = "ShellButtonProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "292 8"; - extent = "140 38"; - minExtent = "32 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "restoreDefaultMappings();"; - helpTag = "0"; - text = "RESTORE DEFAULTS"; - simpleStyle = "0"; - }; - new ShellBitmapButton() { - profile = "ShellButtonProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "292 38"; - extent = "140 38"; - minExtent = "32 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "ShellGetLoadFilename( \"LOAD CONTROL CONFIG\", \"prefs/*.cs\", \"isMapFile\", \"loadMapFile\" );"; - helpTag = "0"; - text = "LOAD"; - simpleStyle = "0"; - }; - new ShellBitmapButton() { - profile = "ShellButtonProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "292 68"; - extent = "140 38"; - minExtent = "32 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "ShellGetSaveFilename( \"SAVE CONTROL CONFIG\", \"prefs/*.cs\", \"isMapFile\", \"saveMapFile\", $pref::Input::ActiveConfig );"; - helpTag = "0"; - text = "SAVE AS"; - simpleStyle = "0"; - }; - new ShellToggleButton(OP_MouseTgl) { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "296 116"; - extent = "126 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "$pref::Input::MouseEnabled"; - helpTag = "0"; - text = "DINPUT MOUSE"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellBitmapButton(OP_ConfigureMouseBtn) { - profile = "ShellButtonProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "292 146"; - extent = "140 38"; - minExtent = "32 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "Canvas.pushDialog(MouseConfigDlg);"; - helpTag = "0"; - text = "CONFIGURE MOUSE"; - simpleStyle = "0"; - }; - new ShellToggleButton(OP_JoystickTgl) { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "296 194"; - extent = "126 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "ENABLE JOYSTICK"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellBitmapButton(OP_ConfigureJoystickBtn) { - profile = "ShellButtonProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "292 224"; - extent = "140 38"; - minExtent = "32 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "Canvas.pushDialog(JoystickConfigDlg);"; - helpTag = "0"; - text = "CONFIGURE JOYSTICK"; - simpleStyle = "0"; - }; - new GuiTextCtrl() { - profile = "ShellTextRightProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "32 317"; - extent = "124 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Toggle Console Key:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellFieldCtrl() { - profile = "ShellFieldProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "161 316"; - extent = "128 23"; - minExtent = "16 18"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - - new GuiButtonCtrl(OP_ConsoleKeyBtn) { - profile = "ShellActiveTextProfile"; - horizSizing = "width"; - vertSizing = "height"; - position = "3 3"; - extent = "122 17"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "OP_ConsoleKeyBtn.doRemap();"; - helpTag = "0"; - text = "grave"; - }; - }; - new GuiTextCtrl() { - profile = "ShellTextRightProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "22 9"; - extent = "100 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Control Group:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellPopupMenu(OP_ControlGroupMenu) { - profile = "ShellPopupProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "118 0"; - extent = "180 36"; - minExtent = "49 36"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Select Control Group"; - longTextBuffer = "0"; - maxLength = "255"; - maxPopupHeight = "200"; - buttonBitmap = "gui/shll_pulldown"; - rolloverBarBitmap = "gui/shll_pulldownbar_rol"; - selectedBarBitmap = "gui/shll_pulldownbar_act"; - noButtonStyle = "0"; - }; - }; - new ShellFieldCtrl(OP_NetworkPane) { - profile = "ShellFieldProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "138 42"; - extent = "437 346"; - minExtent = "16 18"; - visible = "0"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - - new GuiTextCtrl() { - profile = "ShellTextRightProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "9 16"; - extent = "60 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Presets:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellPopupMenu(OP_NetworkPresetsMenu) { - profile = "ShellPopupProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "73 8"; - extent = "151 36"; - minExtent = "49 36"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Select Preset"; - longTextBuffer = "0"; - maxLength = "255"; - maxPopupHeight = "200"; - buttonBitmap = "gui/shll_pulldown"; - rolloverBarBitmap = "gui/shll_pulldownbar_rol"; - selectedBarBitmap = "gui/shll_pulldownbar_act"; - noButtonStyle = "0"; - updateSettings = "1"; - }; - new GuiTextCtrl() { - profile = "ShellTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "26 52"; - extent = "65 22"; - minExtent = "8 8"; - visible = "0"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Packet Rate:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellSliderCtrl(OP_PacketRateSlider) { - profile = "ShellSliderProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "36 67"; - extent = "170 24"; - minExtent = "12 24"; - visible = "0"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "value"; - helpTag = "0"; - range = "2.000000 32.000000"; - ticks = "31"; - value = "32"; - usePlusMinus = "1"; - }; - new GuiTextCtrl() { - profile = "ShellTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "231 52"; - extent = "62 22"; - minExtent = "8 8"; - visible = "0"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Packet Size:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellSliderCtrl(OP_PacketSizeSlider) { - profile = "ShellSliderProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "241 67"; - extent = "170 24"; - minExtent = "12 24"; - visible = "0"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "value"; - helpTag = "0"; - range = "100.000000 450.000000"; - ticks = "36"; - value = "450"; - usePlusMinus = "1"; - }; - new GuiTextCtrl() { - profile = "ShellTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "26 47"; - extent = "99 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Client Update Rate:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellSliderCtrl(OP_UpdateRateSlider) { - profile = "ShellSliderProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "36 62"; - extent = "170 24"; - minExtent = "12 24"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "value"; - command = "updateNetworkSettings();"; - helpTag = "0"; - range = "8.000000 32.000000"; - ticks = "25"; - value = "32"; - usePlusMinus = "1"; - }; - new GuiTextCtrl(OP_MasterServerTxt) { - profile = "ShellTextRightProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "11 222"; - extent = "200 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Display on Master Server:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellPopupMenu(OP_MasterServerMenu) { - profile = "ShellPopupProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "208 214"; - extent = "180 36"; - minExtent = "49 36"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Select Display Option"; - longTextBuffer = "0"; - maxLength = "255"; - maxPopupHeight = "200"; - buttonBitmap = "gui/shll_pulldown"; - rolloverBarBitmap = "gui/shll_pulldownbar_rol"; - selectedBarBitmap = "gui/shll_pulldownbar_act"; - noButtonStyle = "0"; - }; - new GuiTextCtrl() { - profile = "ShellTextRightProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "67 253"; - extent = "144 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Server Location:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellPopupMenu(OP_RegionMenu) { - profile = "ShellPopupProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "208 244"; - extent = "180 36"; - minExtent = "49 36"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Select Region"; - longTextBuffer = "0"; - maxLength = "255"; - maxPopupHeight = "200"; - buttonBitmap = "gui/shll_pulldown"; - rolloverBarBitmap = "gui/shll_pulldownbar_rol"; - selectedBarBitmap = "gui/shll_pulldownbar_act"; - noButtonStyle = "0"; - }; - new ShellToggleButton(OP_CheckEmailTgl) { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "123 283"; - extent = "190 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "$pref::Net::CheckEmail"; - helpTag = "0"; - text = "CHECK EMAIL WHILE PLAYING"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellToggleButton(OP_ChatDisconnectTgl) { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "123 311"; - extent = "190 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "$pref::Net::DisconnectChat"; - helpTag = "0"; - text = "DISCONNECT FROM CHAT"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellFieldCtrl() { - profile = "ShellFieldProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "183 100"; - extent = "227 103"; - minExtent = "16 18"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - - new HudNetDisplay(OP_NetworkDisplayHud) { - profile = "GuiDefaultProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "2 1"; - extent = "223 101"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - fillColor = "0.250000 0.250000 0.250000 0.250000"; - frameColor = "0.000000 1.000000 0.000000 1.000000"; - opacity = "1"; - historySize = "100"; - updatePeriod = "50"; - renderField[0] = "1"; - renderField[1] = "1"; - renderField[2] = "0"; - renderField[3] = "1"; - renderField[4] = "0"; - renderField[5] = "1"; - fieldColors[0] = "0 220 0 255"; - fieldColors[1] = "220 0 0 255"; - fieldColors[2] = "220 220 220 255"; - fieldColors[3] = "120 120 120 255"; - fieldColors[4] = "0 190 240 255"; - fieldColors[5] = "0 120 170 255"; - lowerBound[0] = "0"; - lowerBound[1] = "0"; - lowerBound[2] = "0"; - lowerBound[3] = "0"; - lowerBound[4] = "0"; - lowerBound[5] = "0"; - upperBound[0] = "500"; - upperBound[1] = "100"; - upperBound[2] = "32"; - upperBound[3] = "4096"; - upperBound[4] = "32"; - upperBound[5] = "4096"; - infoCallback = "1"; - renderGraph = "1"; - }; - }; - new ShellFieldCtrl(OP_NetworkDisplayTextFrame) { - profile = "ShellFieldProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "25 100"; - extent = "149 103"; - minExtent = "16 18"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - }; - }; - new ShellFieldCtrl(OP_GamePane) { - profile = "ShellFieldProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "138 42"; - extent = "437 346"; - minExtent = "16 18"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - - new GuiTextCtrl() { - profile = "ShellTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "26 8"; - extent = "65 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Zoom Speed:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellSliderCtrl(OP_ZoomSpeedSlider) { - profile = "ShellSliderProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "36 23"; - extent = "170 24"; - minExtent = "12 24"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "value"; - helpTag = "0"; - range = "0.000000 500.000000"; - ticks = "501"; - value = "500"; - usePlusMinus = "1"; - }; - new ShellBitmapButton(OP_EditChatMenuBtn) { - profile = "ShellButtonProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "237 11"; - extent = "173 38"; - minExtent = "32 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "Canvas.popDialog( OptionsDlg ); Canvas.pushDialog(EditChatMenuGui);"; - helpTag = "0"; - text = "EDIT CHAT MENU"; - simpleStyle = "0"; - }; - new ShellToggleButton() { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "31 64"; - extent = "170 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "$pref::toggleVehicleView"; - helpTag = "0"; - text = "3RD PERSON VEHICLE"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellToggleButton() { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "236 64"; - extent = "170 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "$pref::SkipIntro"; - helpTag = "0"; - text = "SKIP INTRO"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellToggleButton() { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "31 94"; - extent = "170 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "$pref::Vehicle::InvertYAxis"; - command = "toggleInvertYAxis();"; - helpTag = "0"; - text = "INVERT VEHICLE Y-AXIS"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellToggleButton(OP_ForceFeedbackTgl) { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "236 94"; - extent = "170 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "$Pref::useImmersion"; - command = "toggleImmersion();"; - helpTag = "0"; - text = "ENABLE FORCE FEEDBACK"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellToggleButton() { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "31 124"; - extent = "170 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "$pref::Vehicle::pilotTeleport"; - command = "toggleVehicleTeleportPref();"; - helpTag = "0"; - text = "TELEPORT TO VEHICLES"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellToggleButton() { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "236 124"; - extent = "170 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "$pref::usePrefSkins"; - helpTag = "0"; - text = "SHOW PERSONAL SKINS"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellToggleButton() { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "31 154"; - extent = "170 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "$pref::enableBadWordFilter"; - helpTag = "0"; - text = "ENABLE BAD WORD FILTER"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellToggleButton() { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "236 154"; - extent = "170 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "$pref::RenderOOBGrid"; - helpTag = "0"; - text = "SHOW OUT OF BOUNDS GRID"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new GuiTextCtrl(OP_LaunchScreenTxt) { - profile = "ShellTextRightProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "79 233"; - extent = "100 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Launch Screen:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellPopupMenu(OP_LaunchScreenMenu) { - profile = "ShellPopupProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "176 224"; - extent = "180 36"; - minExtent = "49 36"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Select Screen"; - longTextBuffer = "0"; - maxLength = "255"; - maxPopupHeight = "200"; - buttonBitmap = "gui/shll_pulldown"; - rolloverBarBitmap = "gui/shll_pulldownbar_rol"; - selectedBarBitmap = "gui/shll_pulldownbar_act"; - noButtonStyle = "0"; - }; - new ShellToggleButton() { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "31 185"; - extent = "170 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "$pref::ignoreTeamRepairMessages"; - helpTag = "0"; - text = "IGNORE REPAIR MESSAGES"; - longTextBuffer = "0"; - maxLength = "255"; - }; - }; - }; -}; -//--- OBJECT WRITE END --- +//--- OBJECT WRITE BEGIN --- +new GuiControl(OptionsDlg) { + profile = "DlgBackProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + pane = "VIDEO"; + + new ShellPaneCtrl() { + profile = "ShellDlgPaneProfile"; + horizSizing = "center"; + vertSizing = "center"; + position = "20 30"; + extent = "600 420"; + minExtent = "48 92"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "SETTINGS"; + longTextBuffer = "0"; + maxLength = "255"; + noTitleBar = "0"; + + new ShellBitmapButton() { + profile = "ShellButtonProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "34 362"; + extent = "82 38"; + minExtent = "32 38"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + command = "Canvas.popDialog(OptionsDlg);"; + helpTag = "0"; + text = "DONE"; + simpleStyle = "0"; + }; + new ShellTabButton(OP_VideoTab) { + profile = "ShellTabProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "19 46"; + extent = "108 38"; + minExtent = "48 38"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + command = "OptionsDlg.setPane(Video);"; + helpTag = "0"; + text = "VIDEO"; + longTextBuffer = "0"; + maxLength = "255"; + simpleStyle = "0"; + }; + new ShellTabButton(OP_GraphicsTab) { + profile = "ShellTabProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "19 76"; + extent = "108 38"; + minExtent = "48 38"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + command = "OptionsDlg.setPane(Graphics);"; + helpTag = "0"; + text = "GRAPHICS"; + longTextBuffer = "0"; + maxLength = "255"; + simpleStyle = "0"; + }; + new ShellTabButton(OP_TexturesTab) { + profile = "ShellTabProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "19 106"; + extent = "108 38"; + minExtent = "48 38"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + command = "OptionsDlg.setPane(Textures);"; + helpTag = "0"; + text = "TEXTURES"; + longTextBuffer = "0"; + maxLength = "255"; + simpleStyle = "0"; + }; + new ShellTabButton(OP_SoundTab) { + profile = "ShellTabProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "19 136"; + extent = "108 38"; + minExtent = "48 38"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + command = "OptionsDlg.setPane(Sound);"; + helpTag = "0"; + text = "SOUND"; + longTextBuffer = "0"; + maxLength = "255"; + simpleStyle = "0"; + }; + new ShellTabButton(OP_VoiceTab) { + profile = "ShellTabProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "19 166"; + extent = "108 38"; + minExtent = "48 38"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + command = "OptionsDlg.setPane(Voice);"; + helpTag = "0"; + text = "VOICE"; + longTextBuffer = "0"; + maxLength = "255"; + simpleStyle = "0"; + }; + new ShellTabButton(OP_ControlsTab) { + profile = "ShellTabProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "19 196"; + extent = "108 38"; + minExtent = "48 38"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + command = "OptionsDlg.setPane(Controls);"; + helpTag = "0"; + text = "CONTROLS"; + longTextBuffer = "0"; + maxLength = "255"; + simpleStyle = "0"; + }; + new ShellTabButton(OP_NetworkTab) { + profile = "ShellTabProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "19 226"; + extent = "108 38"; + minExtent = "48 38"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + command = "OptionsDlg.setPane(Network);"; + helpTag = "0"; + text = "NETWORK"; + longTextBuffer = "0"; + maxLength = "255"; + simpleStyle = "0"; + }; + new ShellTabButton(OP_GameTab) { + profile = "ShellTabProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "19 256"; + extent = "108 38"; + minExtent = "48 38"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + command = "OptionsDlg.setPane(Game);"; + helpTag = "0"; + text = "GAME"; + longTextBuffer = "0"; + maxLength = "255"; + simpleStyle = "0"; + }; + new ShellTabButton(OP_RPGTab) { + profile = "ShellTabProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "19 286"; + extent = "108 38"; + minExtent = "48 38"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + command = "OptionsDlg.setPane(RPG);"; + helpTag = "0"; + text = "RPG"; + longTextBuffer = "0"; + maxLength = "255"; + simpleStyle = "0"; + }; + new ShellTabFrame() { + profile = "ShellTabFrameProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "127 31"; + extent = "254 368"; + minExtent = "254 26"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + isVertical = "1"; + useCloseButton = "0"; + edgeInset = "0"; + }; + new ShellFieldCtrl(OP_RPGPane) { + profile = "ShellFieldProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "138 42"; + extent = "437 346"; + minExtent = "16 18"; + visible = "0"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + + new ShellBitmapButton() { + profile = "ShellButtonProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "151 3"; + extent = "131 38"; + minExtent = "32 38"; + visible = "1"; + command = "canvas.popDialog(OptionsDLG); canvas.pushDialog(LANAccountCreationDLG); $ChangeSettings = true;"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "LAN ACCOUNT"; + simpleStyle = "0"; + }; + }; + + new ShellFieldCtrl(OP_VideoPane) { + profile = "ShellFieldProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "138 42"; + extent = "437 346"; + minExtent = "16 18"; + visible = "0"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + + new GuiTextCtrl() { + profile = "ShellTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "2 16"; + extent = "100 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Video Driver:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellPopupMenu(OP_VideoDriverMenu) { + profile = "ShellPopupProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "99 7"; + extent = "140 36"; + minExtent = "49 36"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Select Driver"; + longTextBuffer = "0"; + maxLength = "255"; + maxPopupHeight = "200"; + buttonBitmap = "gui/shll_pulldown"; + rolloverBarBitmap = "gui/shll_pulldownbar_rol"; + selectedBarBitmap = "gui/shll_pulldownbar_act"; + noButtonStyle = "0"; + }; + new GuiTextCtrl() { + profile = "ShellTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "2 54"; + extent = "100 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Resolution:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellPopupMenu(OP_ResMenu) { + profile = "ShellPopupProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "99 45"; + extent = "140 36"; + minExtent = "49 36"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Select Resolution"; + longTextBuffer = "0"; + maxLength = "255"; + maxPopupHeight = "200"; + buttonBitmap = "gui/shll_pulldown"; + rolloverBarBitmap = "gui/shll_pulldownbar_rol"; + selectedBarBitmap = "gui/shll_pulldownbar_act"; + noButtonStyle = "0"; + }; + new GuiTextCtrl() { + profile = "ShellTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "2 92"; + extent = "100 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Bit Depth:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellPopupMenu(OP_BPPMenu) { + profile = "ShellPopupProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "99 83"; + extent = "140 36"; + minExtent = "49 36"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Default"; + longTextBuffer = "0"; + maxLength = "255"; + maxPopupHeight = "200"; + buttonBitmap = "gui/shll_pulldown"; + rolloverBarBitmap = "gui/shll_pulldownbar_rol"; + selectedBarBitmap = "gui/shll_pulldownbar_act"; + noButtonStyle = "0"; + }; + new ShellToggleButton(OP_FullScreenTgl) { + profile = "ShellRadioProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "102 125"; + extent = "127 30"; + minExtent = "26 27"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "FULL SCREEN"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellBitmapButton(OP_ApplyBtn) { + profile = "ShellButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "275 176"; + extent = "128 38"; + minExtent = "32 38"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + command = "OptionsDlg.applyGraphicChanges();"; + helpTag = "0"; + text = "APPLY CHANGES"; + simpleStyle = "0"; + }; + new ShellBitmapButton() { + profile = "ShellButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "275 8"; + extent = "128 38"; + minExtent = "32 38"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + command = "Canvas.pushDialog(DriverInfoDlg);"; + helpTag = "0"; + text = "DRIVER INFO"; + simpleStyle = "0"; + }; + new ShellToggleButton(OP_VSyncTgl) { + profile = "ShellRadioProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "133 243"; + extent = "170 30"; + minExtent = "26 27"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "DISABLE VERTICAL SYNC"; + longTextBuffer = "0"; + maxLength = "255"; + }; + }; + new ShellFieldCtrl(OP_GraphicsPane) { + profile = "ShellFieldProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "138 42"; + extent = "437 346"; + minExtent = "16 18"; + visible = "0"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + + new GuiTextCtrl() { + profile = "ShellTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "231 6"; + extent = "97 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Gamma Correction:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellSliderCtrl(OP_GammaSlider) { + profile = "ShellSliderProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "241 21"; + extent = "170 24"; + minExtent = "12 24"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "value"; + altCommand = "updateGammaCorrection();"; + helpTag = "0"; + range = "0.000000 1.000000"; + ticks = "1000"; + value = "0.385965"; + usePlusMinus = "1"; + }; + new GuiTextCtrl() { + profile = "ShellTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "26 6"; + extent = "72 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Terrain Detail:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellSliderCtrl(OP_TerrainSlider) { + profile = "ShellSliderProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "36 21"; + extent = "170 24"; + minExtent = "12 24"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "value"; + command = "updateTerrainDetail();"; + helpTag = "0"; + range = "0.000000 25.000000"; + ticks = "26"; + value = "23"; + usePlusMinus = "1"; + }; + new GuiTextCtrl() { + profile = "ShellTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "231 44"; + extent = "67 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Shape Detail:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellSliderCtrl(OP_ShapeSlider) { + profile = "ShellSliderProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "241 59"; + extent = "170 24"; + minExtent = "12 24"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "value"; + helpTag = "0"; + range = "0.000000 1.000000"; + ticks = "19"; + value = "1"; + usePlusMinus = "1"; + }; + new GuiTextCtrl() { + profile = "ShellTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "27 44"; + extent = "77 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Shadow Detail:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellSliderCtrl(OP_ShadowSlider) { + profile = "ShellSliderProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "37 59"; + extent = "170 24"; + minExtent = "12 24"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "value"; + helpTag = "0"; + range = "0.000000 1.000000"; + ticks = "1000"; + value = "0.596491"; + usePlusMinus = "1"; + }; + new GuiTextCtrl() { + profile = "ShellTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "27 82"; + extent = "72 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Interior Detail:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellSliderCtrl(OP_InteriorDetailSlider) { + profile = "ShellSliderProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "37 97"; + extent = "170 24"; + minExtent = "12 24"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "value"; + helpTag = "0"; + range = "0.300000 1.000000"; + ticks = "1000"; + value = "0.950877"; + usePlusMinus = "1"; + }; + new GuiTextCtrl() { + profile = "ShellTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "231 82"; + extent = "85 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Visible Distance:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellSliderCtrl(OP_VisibleDistanceSlider) { + profile = "ShellSliderProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "241 97"; + extent = "170 24"; + minExtent = "12 24"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "value"; + helpTag = "0"; + range = "0.600000 1.000000"; + ticks = "400"; + value = "1"; + usePlusMinus = "1"; + }; + new GuiTextCtrl() { + profile = "ShellTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "27 120"; + extent = "84 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Particle Density:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellSliderCtrl(OP_ParticleDensitySlider) { + profile = "ShellSliderProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "37 135"; + extent = "170 24"; + minExtent = "12 24"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "value"; + helpTag = "0"; + range = "0.000000 3.000000"; + ticks = "1000"; + value = "3"; + usePlusMinus = "1"; + }; + new GuiTextCtrl(OP_DynamicLightText) { + profile = "ShellTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "231 120"; + extent = "160 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Dynamic Light Visible Distance:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new GuiTextCtrl(OP_DynamicLightText_Disabled) { + profile = "DisabledTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "231 120"; + extent = "160 22"; + minExtent = "8 8"; + visible = "0"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Dynamic Light Visible Distance:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellSliderCtrl(OP_DynamicLightSlider) { + profile = "ShellSliderProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "241 135"; + extent = "170 24"; + minExtent = "12 24"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "value"; + helpTag = "0"; + range = "0.000000 100.000000"; + ticks = "100"; + value = "92.1053"; + usePlusMinus = "1"; + }; + new GuiTextCtrl() { + profile = "ShellTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "79 168"; + extent = "70 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Sky Detail:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellPopupMenu(OP_SkyDetailMenu) { + profile = "ShellPopupProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "146 159"; + extent = "200 36"; + minExtent = "49 36"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Default"; + longTextBuffer = "0"; + maxLength = "255"; + maxPopupHeight = "200"; + buttonBitmap = "gui/shll_pulldown"; + rolloverBarBitmap = "gui/shll_pulldownbar_rol"; + selectedBarBitmap = "gui/shll_pulldownbar_act"; + noButtonStyle = "0"; + }; + new GuiTextCtrl() { + profile = "ShellTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "35 198"; + extent = "114 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "First Person Draw:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellPopupMenu(OP_PlayerRenderMenu) { + profile = "ShellPopupProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "146 189"; + extent = "200 36"; + minExtent = "49 36"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Default"; + longTextBuffer = "0"; + maxLength = "255"; + maxPopupHeight = "200"; + buttonBitmap = "gui/shll_pulldown"; + rolloverBarBitmap = "gui/shll_pulldownbar_rol"; + selectedBarBitmap = "gui/shll_pulldownbar_act"; + noButtonStyle = "0"; + }; + new ShellToggleButton() { + profile = "ShellRadioProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "31 226"; + extent = "170 30"; + minExtent = "26 27"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "$pref::precipitationOn"; + helpTag = "0"; + text = "PRECIPITATION"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellToggleButton() { + profile = "ShellRadioProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "236 226"; + extent = "170 30"; + minExtent = "26 27"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "$pref::Interior::DynamicLights"; + command = "updateDynamicLightSliderState();"; + helpTag = "0"; + text = "DYNAMIC INTERIOR LIGHTS"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellToggleButton() { + profile = "ShellRadioProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "31 256"; + extent = "170 30"; + minExtent = "26 27"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "$pref::decalsOn"; + helpTag = "0"; + text = "DECALS"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellToggleButton() { + profile = "ShellRadioProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "236 256"; + extent = "170 30"; + minExtent = "26 27"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "$pref::Terrain::dynamicLights"; + command = "updateDynamicLightSliderState();"; + helpTag = "0"; + text = "DYNAMIC TERRAIN LIGHTS"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellToggleButton() { + profile = "ShellRadioProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "31 286"; + extent = "170 30"; + minExtent = "26 27"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "$pref::Terrain::enableDetails"; + helpTag = "0"; + text = "TERRAIN DETAILS"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellToggleButton(OP_IntTexturedFogTgl) { + profile = "ShellRadioProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "236 286"; + extent = "170 30"; + minExtent = "26 27"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "INTERIOR TEXTURED FOG"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellToggleButton() { + profile = "ShellRadioProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "31 316"; + extent = "170 30"; + minExtent = "26 27"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "$pref::useOldShieldEffect"; + helpTag = "0"; + text = "HI-RES SHIELD EFFECTS"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellToggleButton(OP_VertexLightTgl) { + profile = "ShellRadioProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "236 316"; + extent = "170 30"; + minExtent = "26 27"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "VERTEX LIGHTING"; + longTextBuffer = "0"; + maxLength = "255"; + }; + }; + new ShellFieldCtrl(OP_TexturesPane) { + profile = "ShellFieldProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "138 42"; + extent = "437 346"; + minExtent = "16 18"; + visible = "0"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + + new GuiTextCtrl() { + profile = "ShellTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "37 16"; + extent = "100 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Texture Quality:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellPopupMenu(OP_TexQualityMenu) { + profile = "ShellPopupProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "134 7"; + extent = "140 36"; + minExtent = "49 36"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Default"; + longTextBuffer = "0"; + maxLength = "255"; + maxPopupHeight = "200"; + buttonBitmap = "gui/shll_pulldown"; + rolloverBarBitmap = "gui/shll_pulldownbar_rol"; + selectedBarBitmap = "gui/shll_pulldownbar_act"; + noButtonStyle = "0"; + }; + new GuiTextCtrl() { + profile = "ShellTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "26 85"; + extent = "114 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Terrain Texture Detail:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellSliderCtrl(OP_TerrainTexSlider) { + profile = "ShellSliderProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "36 100"; + extent = "170 24"; + minExtent = "12 24"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "value"; + helpTag = "0"; + range = "0.000000 6.000000"; + ticks = "7"; + value = "5"; + usePlusMinus = "1"; + }; + new GuiTextCtrl() { + profile = "ShellTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "231 85"; + extent = "109 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Shape Texture Detail:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellSliderCtrl(OP_ShapeTexSlider) { + profile = "ShellSliderProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "241 100"; + extent = "170 24"; + minExtent = "12 24"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "value"; + helpTag = "0"; + range = "0.000000 1.000000"; + ticks = "6"; + value = "1"; + usePlusMinus = "1"; + }; + new GuiTextCtrl() { + profile = "ShellTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "26 123"; + extent = "119 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Building Texture Detail:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellSliderCtrl(OP_BuildingTexSlider) { + profile = "ShellSliderProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "36 138"; + extent = "170 24"; + minExtent = "12 24"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "value"; + helpTag = "0"; + range = "0.000000 1.000000"; + ticks = "6"; + value = "0.8"; + usePlusMinus = "1"; + }; + new GuiTextCtrl() { + profile = "ShellTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "231 123"; + extent = "97 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Sky Texture Detail:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellSliderCtrl(OP_SkyTexSlider) { + profile = "ShellSliderProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "241 138"; + extent = "170 24"; + minExtent = "12 24"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "value"; + helpTag = "0"; + range = "0.000000 1.000000"; + ticks = "6"; + value = "0.8"; + usePlusMinus = "1"; + }; + new GuiTextCtrl(OP_CompressLabel) { + profile = "ShellTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "17 46"; + extent = "120 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Texture Compression:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new GuiTextCtrl(OP_CompressLabel_Disabled) { + profile = "DisabledTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "6 46"; + extent = "135 22"; + minExtent = "8 8"; + visible = "0"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Texture Compression:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellPopupMenu(OP_CompressMenu) { + profile = "ShellPopupProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "134 37"; + extent = "140 36"; + minExtent = "49 36"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "None"; + longTextBuffer = "0"; + maxLength = "255"; + maxPopupHeight = "200"; + buttonBitmap = "gui/shll_pulldown"; + rolloverBarBitmap = "gui/shll_pulldownbar_rol"; + selectedBarBitmap = "gui/shll_pulldownbar_act"; + noButtonStyle = "0"; + }; + new GuiTextCtrl(OP_AnisotropyLabel) { + profile = "ShellTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "26 179"; + extent = "58 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Anisotropy:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new GuiTextCtrl(OP_AnisotropyLabel_Disabled) { + profile = "DisabledTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "26 179"; + extent = "58 22"; + minExtent = "8 8"; + visible = "0"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Anisotropy:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellSliderCtrl(OP_AnisotropySlider) { + profile = "ShellSliderProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "37 194"; + extent = "170 24"; + minExtent = "12 24"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "value"; + helpTag = "0"; + range = "0.000000 1.000000"; + ticks = "1000"; + value = "0"; + usePlusMinus = "1"; + }; + new ShellToggleButton(OP_EnvMapTgl) { + profile = "ShellRadioProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "236 180"; + extent = "170 30"; + minExtent = "26 27"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "$pref::environmentMaps"; + helpTag = "0"; + text = "ENVIRONMENT MAPS"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellToggleButton(OP_IntEnvMapTgl) { + profile = "ShellRadioProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "236 210"; + extent = "170 30"; + minExtent = "26 27"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "$pref::Interior::ShowEnvironmentMaps"; + helpTag = "0"; + text = "INTERIOR ENV. MAPS"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellToggleButton(OP_HiResSkinTgl) { + profile = "ShellRadioProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "236 250"; + extent = "170 30"; + minExtent = "26 27"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "HI-RES PLAYER SKINS"; + longTextBuffer = "0"; + maxLength = "255"; + }; + }; + new ShellFieldCtrl(OP_SoundPane) { + profile = "ShellFieldProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "138 42"; + extent = "437 346"; + minExtent = "16 18"; + visible = "0"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + + new GuiTextCtrl() { + profile = "ShellTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "10 16"; + extent = "72 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "3D Provider:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellPopupMenu(OP_AudioProviderMenu) { + profile = "ShellPopupProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "79 7"; + extent = "268 36"; + minExtent = "49 36"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Select Provider"; + longTextBuffer = "0"; + maxLength = "255"; + maxPopupHeight = "200"; + buttonBitmap = "gui/shll_pulldown"; + rolloverBarBitmap = "gui/shll_pulldownbar_rol"; + selectedBarBitmap = "gui/shll_pulldownbar_act"; + noButtonStyle = "0"; + }; + new ShellBitmapButton(OP_AudioResetProvider) { + profile = "ShellButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "339 7"; + extent = "79 38"; + minExtent = "32 38"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "RESET"; + simpleStyle = "0"; + }; + new ShellToggleButton(OP_AudioEnvironmentTgl) { + profile = "ShellRadioProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "249 42"; + extent = "160 30"; + minExtent = "26 27"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "$pref::Audio::environmentEnabled"; + helpTag = "0"; + text = "ENVIRONMENT ENABLED"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new GuiTextCtrl() { + profile = "ShellTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "10 46"; + extent = "72 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Speakers:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellPopupMenu(OP_AudioSpeakerMenu) { + profile = "ShellPopupProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "79 37"; + extent = "169 36"; + minExtent = "49 36"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Select Speaker"; + longTextBuffer = "0"; + maxLength = "255"; + maxPopupHeight = "200"; + buttonBitmap = "gui/shll_pulldown"; + rolloverBarBitmap = "gui/shll_pulldownbar_rol"; + selectedBarBitmap = "gui/shll_pulldownbar_act"; + noButtonStyle = "0"; + }; + new GuiTextCtrl() { + profile = "ShellTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "11 97"; + extent = "72 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Frequency:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellPopupMenu(OP_AudioFrequencyMenu) { + profile = "ShellPopupProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "80 88"; + extent = "169 36"; + minExtent = "49 36"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Select Frequency"; + longTextBuffer = "0"; + maxLength = "255"; + maxPopupHeight = "200"; + buttonBitmap = "gui/shll_pulldown"; + rolloverBarBitmap = "gui/shll_pulldownbar_rol"; + selectedBarBitmap = "gui/shll_pulldownbar_act"; + noButtonStyle = "0"; + }; + new GuiTextCtrl() { + profile = "ShellTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "11 127"; + extent = "72 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Bit Rate:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellPopupMenu(OP_AudioBitRateMenu) { + profile = "ShellPopupProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "80 118"; + extent = "100 36"; + minExtent = "49 36"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Select Bit Rate"; + longTextBuffer = "0"; + maxLength = "255"; + maxPopupHeight = "200"; + buttonBitmap = "gui/shll_pulldown"; + rolloverBarBitmap = "gui/shll_pulldownbar_rol"; + selectedBarBitmap = "gui/shll_pulldownbar_act"; + noButtonStyle = "0"; + }; + new GuiTextCtrl() { + profile = "ShellTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "221 127"; + extent = "60 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Channels:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellPopupMenu(OP_AudioChannelsMenu) { + profile = "ShellPopupProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "278 118"; + extent = "100 36"; + minExtent = "49 36"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Select # Channels"; + longTextBuffer = "0"; + maxLength = "255"; + maxPopupHeight = "200"; + buttonBitmap = "gui/shll_pulldown"; + rolloverBarBitmap = "gui/shll_pulldownbar_rol"; + selectedBarBitmap = "gui/shll_pulldownbar_act"; + noButtonStyle = "0"; + }; + new GuiTextCtrl() { + profile = "ShellTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "26 177"; + extent = "79 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Master Volume:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellSliderCtrl(OP_MasterVolumeSlider) { + profile = "ShellSliderProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "36 192"; + extent = "170 24"; + minExtent = "12 24"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "value"; + altCommand = "updateMasterVolume();"; + helpTag = "0"; + range = "0.000000 1.000000"; + ticks = "1000"; + value = "0.894737"; + usePlusMinus = "1"; + }; + new GuiTextCtrl() { + profile = "ShellTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "231 177"; + extent = "79 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Effects Volume:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellSliderCtrl(OP_EffectsVolumeSlider) { + profile = "ShellSliderProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "241 192"; + extent = "170 24"; + minExtent = "12 24"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "value"; + helpTag = "0"; + range = "0.000000 1.000000"; + ticks = "1000"; + value = "0.938596"; + usePlusMinus = "1"; + }; + new GuiTextCtrl() { + profile = "ShellTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "26 215"; + extent = "60 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Gui Volume:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellSliderCtrl(OP_GuiVolumeSlider) { + profile = "ShellSliderProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "36 230"; + extent = "170 24"; + minExtent = "12 24"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "value"; + altCommand = "updateGuiVolume();"; + helpTag = "0"; + range = "0.000000 1.000000"; + ticks = "1000"; + value = "0.692982"; + usePlusMinus = "1"; + }; + new GuiTextCtrl() { + profile = "ShellTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "231 215"; + extent = "97 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Voice Bind Volume:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellSliderCtrl(OP_VoiceBindVolumeSlider) { + profile = "ShellSliderProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "241 230"; + extent = "170 24"; + minExtent = "12 24"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "value"; + helpTag = "0"; + range = "0.000000 1.000000"; + ticks = "1000"; + value = "0.824561"; + usePlusMinus = "1"; + }; + new ShellToggleButton(OP_MusicTgl) { + profile = "ShellRadioProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "31 266"; + extent = "170 30"; + minExtent = "26 27"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "$pref::Audio::musicEnabled"; + helpTag = "0"; + text = "MP3 MUSIC"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new GuiTextCtrl(OP_MusicVolumeLabel) { + profile = "ShellTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "231 257"; + extent = "74 22"; + minExtent = "8 8"; + visible = "0"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Music Volume:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new GuiTextCtrl(OP_MusicVolumeLabel_Disabled) { + profile = "DisabledTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "231 253"; + extent = "74 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Music Volume:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellSliderCtrl(OP_MusicVolumeSlider) { + profile = "ShellSliderProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "241 268"; + extent = "170 24"; + minExtent = "12 24"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "value"; + altCommand = "updateMusicVolume();"; + helpTag = "0"; + range = "0.000000 1.000000"; + ticks = "1000"; + value = "0.859649"; + usePlusMinus = "1"; + }; + }; + new ShellFieldCtrl(OP_VoicePane) { + profile = "ShellFieldProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "138 42"; + extent = "437 346"; + minExtent = "16 18"; + visible = "0"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + + new ShellToggleButton(OP_MicrophoneEnabledTgl) { + profile = "ShellRadioProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "31 13"; + extent = "170 30"; + minExtent = "26 27"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "$pref::Audio::enableVoiceCapture"; + helpTag = "0"; + text = "MICROPHONE ENABLED"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellBitmapButton(OP_RecordTestBtn) { + profile = "ShellButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "232 8"; + extent = "173 38"; + minExtent = "32 38"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + command = "alxCaptureStart(true);"; + helpTag = "0"; + text = "TEST RECORD"; + simpleStyle = "0"; + }; + new GuiTextCtrl(OP_MicVolumeLabel) { + profile = "ShellTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "28 43"; + extent = "102 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Microphone Volume:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new GuiTextCtrl(OP_MicVolumeLabel_Disabled) { + profile = "DisabledTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "28 43"; + extent = "102 22"; + minExtent = "8 8"; + visible = "0"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Microphone Volume:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellSliderCtrl(OP_MicrophoneVolumeSlider) { + profile = "ShellSliderProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "38 58"; + extent = "170 24"; + minExtent = "12 24"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "value"; + helpTag = "0"; + range = "0.000000 1.000000"; + ticks = "1000"; + value = "1"; + usePlusMinus = "1"; + }; + new GuiTextCtrl(OP_InputBoostLabel) { + profile = "ShellTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "231 43"; + extent = "123 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Microphone Input Boost:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new GuiTextCtrl(OP_InputBoostLabel_Disabled) { + profile = "DisabledTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "231 43"; + extent = "123 22"; + minExtent = "8 8"; + visible = "0"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Microphone Input Boost:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new GuiTextCtrl(OP_InputBoostPercentTxt) { + profile = "ShellTextCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "271 61"; + extent = "110 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "100%"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellSliderCtrl(OP_InputBoostSlider) { + profile = "ShellSliderProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "241 58"; + extent = "170 24"; + minExtent = "12 24"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "value"; + altCommand = "updateInputBoost();"; + helpTag = "0"; + range = "1.000000 5.000000"; + ticks = "5000"; + value = "3.70175"; + usePlusMinus = "1"; + }; + new GuiTextCtrl(OP_VoiceListenLabel) { + profile = "ShellTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "46 96"; + extent = "140 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Voice Listen Codec(s):"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellPopupMenu(OP_VoiceListenMenu) { + profile = "ShellPopupProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "183 87"; + extent = "129 36"; + minExtent = "49 36"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Select Quality"; + longTextBuffer = "0"; + maxLength = "255"; + maxPopupHeight = "200"; + buttonBitmap = "gui/shll_pulldown"; + rolloverBarBitmap = "gui/shll_pulldownbar_rol"; + selectedBarBitmap = "gui/shll_pulldownbar_act"; + noButtonStyle = "0"; + }; + new GuiTextCtrl(OP_VoiceSendLabel) { + profile = "ShellTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "46 126"; + extent = "140 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Voice Send Codec:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellPopupMenu(OP_VoiceSendMenu) { + profile = "ShellPopupProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "183 117"; + extent = "129 36"; + minExtent = "49 36"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Select Quality"; + longTextBuffer = "0"; + maxLength = "255"; + maxPopupHeight = "200"; + buttonBitmap = "gui/shll_pulldown"; + rolloverBarBitmap = "gui/shll_pulldownbar_rol"; + selectedBarBitmap = "gui/shll_pulldownbar_act"; + noButtonStyle = "0"; + }; + new GuiTextCtrl(OP_VoiceListenLabel_Disabled) { + profile = "DisabledTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "46 96"; + extent = "140 22"; + minExtent = "8 8"; + visible = "0"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Voice Listen Quality:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new GuiTextCtrl(OP_VoiceSendLabel_Disabled) { + profile = "DisabledTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "46 126"; + extent = "140 22"; + minExtent = "8 8"; + visible = "0"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Voice Send Quality:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new GuiMLTextCtrl(OP_VoiceCodecInfo) { + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "25 159"; + extent = "395 140"; + minExtent = "8 140"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + deniedSound = "InputDeniedSound"; + }; + }; + new ShellFieldCtrl(OP_ControlsPane) { + profile = "ShellFieldProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "138 42"; + extent = "437 346"; + minExtent = "16 18"; + visible = "0"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + group = "Main"; + + new ShellScrollCtrl() { + profile = "NewScrollCtrlProfile"; + horizSizing = "right"; + vertSizing = "height"; + position = "2 31"; + extent = "290 283"; + minExtent = "24 52"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "alwaysOn"; + constantThumbHeight = "0"; + defaultLineHeight = "15"; + childMargin = "0 2"; + fieldBase = "gui/shll_field"; + + new GuiScrollContentCtrl() { + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "4 6"; + extent = "266 271"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + + new ShellTextList(OP_RemapList) { + profile = "ShellTextArrayProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "266 8"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + altCommand = "OP_RemapList.doRemap();"; + helpTag = "0"; + enumerate = "0"; + resizeCell = "1"; + columns = "2 150"; + fitParentWidth = "1"; + clipColumnText = "0"; + }; + }; + }; + new ShellBitmapButton() { + profile = "ShellButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "292 8"; + extent = "140 38"; + minExtent = "32 38"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + command = "restoreDefaultMappings();"; + helpTag = "0"; + text = "RESTORE DEFAULTS"; + simpleStyle = "0"; + }; + new ShellBitmapButton() { + profile = "ShellButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "292 38"; + extent = "140 38"; + minExtent = "32 38"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + command = "ShellGetLoadFilename( \"LOAD CONTROL CONFIG\", \"prefs/*.cs\", \"isMapFile\", \"loadMapFile\" );"; + helpTag = "0"; + text = "LOAD"; + simpleStyle = "0"; + }; + new ShellBitmapButton() { + profile = "ShellButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "292 68"; + extent = "140 38"; + minExtent = "32 38"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + command = "ShellGetSaveFilename( \"SAVE CONTROL CONFIG\", \"prefs/*.cs\", \"isMapFile\", \"saveMapFile\", $pref::Input::ActiveConfig );"; + helpTag = "0"; + text = "SAVE AS"; + simpleStyle = "0"; + }; + new ShellToggleButton(OP_MouseTgl) { + profile = "ShellRadioProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "296 116"; + extent = "126 30"; + minExtent = "26 27"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "$pref::Input::MouseEnabled"; + helpTag = "0"; + text = "DINPUT MOUSE"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellBitmapButton(OP_ConfigureMouseBtn) { + profile = "ShellButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "292 146"; + extent = "140 38"; + minExtent = "32 38"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + command = "Canvas.pushDialog(MouseConfigDlg);"; + helpTag = "0"; + text = "CONFIGURE MOUSE"; + simpleStyle = "0"; + }; + new ShellToggleButton(OP_JoystickTgl) { + profile = "ShellRadioProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "296 194"; + extent = "126 30"; + minExtent = "26 27"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "ENABLE JOYSTICK"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellBitmapButton(OP_ConfigureJoystickBtn) { + profile = "ShellButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "292 224"; + extent = "140 38"; + minExtent = "32 38"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + command = "Canvas.pushDialog(JoystickConfigDlg);"; + helpTag = "0"; + text = "CONFIGURE JOYSTICK"; + simpleStyle = "0"; + }; + new GuiTextCtrl() { + profile = "ShellTextRightProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "32 317"; + extent = "124 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Toggle Console Key:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellFieldCtrl() { + profile = "ShellFieldProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "161 316"; + extent = "128 23"; + minExtent = "16 18"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + + new GuiButtonCtrl(OP_ConsoleKeyBtn) { + profile = "ShellActiveTextProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "3 3"; + extent = "122 17"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + command = "OP_ConsoleKeyBtn.doRemap();"; + helpTag = "0"; + text = "grave"; + }; + }; + new GuiTextCtrl() { + profile = "ShellTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "22 9"; + extent = "100 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Control Group:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellPopupMenu(OP_ControlGroupMenu) { + profile = "ShellPopupProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "118 0"; + extent = "180 36"; + minExtent = "49 36"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Select Control Group"; + longTextBuffer = "0"; + maxLength = "255"; + maxPopupHeight = "200"; + buttonBitmap = "gui/shll_pulldown"; + rolloverBarBitmap = "gui/shll_pulldownbar_rol"; + selectedBarBitmap = "gui/shll_pulldownbar_act"; + noButtonStyle = "0"; + }; + }; + new ShellFieldCtrl(OP_NetworkPane) { + profile = "ShellFieldProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "138 42"; + extent = "437 346"; + minExtent = "16 18"; + visible = "0"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + + new GuiTextCtrl() { + profile = "ShellTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "9 16"; + extent = "60 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Presets:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellPopupMenu(OP_NetworkPresetsMenu) { + profile = "ShellPopupProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "73 8"; + extent = "151 36"; + minExtent = "49 36"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Select Preset"; + longTextBuffer = "0"; + maxLength = "255"; + maxPopupHeight = "200"; + buttonBitmap = "gui/shll_pulldown"; + rolloverBarBitmap = "gui/shll_pulldownbar_rol"; + selectedBarBitmap = "gui/shll_pulldownbar_act"; + noButtonStyle = "0"; + updateSettings = "1"; + }; + new GuiTextCtrl() { + profile = "ShellTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "26 52"; + extent = "65 22"; + minExtent = "8 8"; + visible = "0"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Packet Rate:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellSliderCtrl(OP_PacketRateSlider) { + profile = "ShellSliderProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "36 67"; + extent = "170 24"; + minExtent = "12 24"; + visible = "0"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "value"; + helpTag = "0"; + range = "2.000000 32.000000"; + ticks = "31"; + value = "32"; + usePlusMinus = "1"; + }; + new GuiTextCtrl() { + profile = "ShellTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "231 52"; + extent = "62 22"; + minExtent = "8 8"; + visible = "0"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Packet Size:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellSliderCtrl(OP_PacketSizeSlider) { + profile = "ShellSliderProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "241 67"; + extent = "170 24"; + minExtent = "12 24"; + visible = "0"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "value"; + helpTag = "0"; + range = "100.000000 450.000000"; + ticks = "36"; + value = "450"; + usePlusMinus = "1"; + }; + new GuiTextCtrl() { + profile = "ShellTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "26 47"; + extent = "99 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Client Update Rate:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellSliderCtrl(OP_UpdateRateSlider) { + profile = "ShellSliderProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "36 62"; + extent = "170 24"; + minExtent = "12 24"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "value"; + command = "updateNetworkSettings();"; + helpTag = "0"; + range = "8.000000 32.000000"; + ticks = "25"; + value = "32"; + usePlusMinus = "1"; + }; + new GuiTextCtrl(OP_MasterServerTxt) { + profile = "ShellTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "11 222"; + extent = "200 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Display on Master Server:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellPopupMenu(OP_MasterServerMenu) { + profile = "ShellPopupProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "208 214"; + extent = "180 36"; + minExtent = "49 36"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Select Display Option"; + longTextBuffer = "0"; + maxLength = "255"; + maxPopupHeight = "200"; + buttonBitmap = "gui/shll_pulldown"; + rolloverBarBitmap = "gui/shll_pulldownbar_rol"; + selectedBarBitmap = "gui/shll_pulldownbar_act"; + noButtonStyle = "0"; + }; + new GuiTextCtrl() { + profile = "ShellTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "67 253"; + extent = "144 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Server Location:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellPopupMenu(OP_RegionMenu) { + profile = "ShellPopupProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "208 244"; + extent = "180 36"; + minExtent = "49 36"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Select Region"; + longTextBuffer = "0"; + maxLength = "255"; + maxPopupHeight = "200"; + buttonBitmap = "gui/shll_pulldown"; + rolloverBarBitmap = "gui/shll_pulldownbar_rol"; + selectedBarBitmap = "gui/shll_pulldownbar_act"; + noButtonStyle = "0"; + }; + new ShellToggleButton(OP_CheckEmailTgl) { + profile = "ShellRadioProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "123 283"; + extent = "190 30"; + minExtent = "26 27"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "$pref::Net::CheckEmail"; + helpTag = "0"; + text = "CHECK EMAIL WHILE PLAYING"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellToggleButton(OP_ChatDisconnectTgl) { + profile = "ShellRadioProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "123 311"; + extent = "190 30"; + minExtent = "26 27"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "$pref::Net::DisconnectChat"; + helpTag = "0"; + text = "DISCONNECT FROM CHAT"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellFieldCtrl() { + profile = "ShellFieldProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "183 100"; + extent = "227 103"; + minExtent = "16 18"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + + new HudNetDisplay(OP_NetworkDisplayHud) { + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "2 1"; + extent = "223 101"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + fillColor = "0.250000 0.250000 0.250000 0.250000"; + frameColor = "0.000000 1.000000 0.000000 1.000000"; + opacity = "1"; + historySize = "100"; + updatePeriod = "50"; + renderField[0] = "1"; + renderField[1] = "1"; + renderField[2] = "0"; + renderField[3] = "1"; + renderField[4] = "0"; + renderField[5] = "1"; + fieldColors[0] = "0 220 0 255"; + fieldColors[1] = "220 0 0 255"; + fieldColors[2] = "220 220 220 255"; + fieldColors[3] = "120 120 120 255"; + fieldColors[4] = "0 190 240 255"; + fieldColors[5] = "0 120 170 255"; + lowerBound[0] = "0"; + lowerBound[1] = "0"; + lowerBound[2] = "0"; + lowerBound[3] = "0"; + lowerBound[4] = "0"; + lowerBound[5] = "0"; + upperBound[0] = "500"; + upperBound[1] = "100"; + upperBound[2] = "32"; + upperBound[3] = "4096"; + upperBound[4] = "32"; + upperBound[5] = "4096"; + infoCallback = "1"; + renderGraph = "1"; + }; + }; + new ShellFieldCtrl(OP_NetworkDisplayTextFrame) { + profile = "ShellFieldProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "25 100"; + extent = "149 103"; + minExtent = "16 18"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + }; + }; + new ShellFieldCtrl(OP_GamePane) { + profile = "ShellFieldProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "138 42"; + extent = "437 346"; + minExtent = "16 18"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + + new GuiTextCtrl() { + profile = "ShellTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "26 8"; + extent = "65 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Zoom Speed:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellSliderCtrl(OP_ZoomSpeedSlider) { + profile = "ShellSliderProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "36 23"; + extent = "170 24"; + minExtent = "12 24"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "value"; + helpTag = "0"; + range = "0.000000 500.000000"; + ticks = "501"; + value = "500"; + usePlusMinus = "1"; + }; + new ShellBitmapButton(OP_EditChatMenuBtn) { + profile = "ShellButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "237 11"; + extent = "173 38"; + minExtent = "32 38"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + command = "Canvas.popDialog( OptionsDlg ); Canvas.pushDialog(EditChatMenuGui);"; + helpTag = "0"; + text = "EDIT CHAT MENU"; + simpleStyle = "0"; + }; + new ShellToggleButton() { + profile = "ShellRadioProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "31 64"; + extent = "170 30"; + minExtent = "26 27"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "$pref::toggleVehicleView"; + helpTag = "0"; + text = "3RD PERSON VEHICLE"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellToggleButton() { + profile = "ShellRadioProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "236 64"; + extent = "170 30"; + minExtent = "26 27"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "$pref::SkipIntro"; + helpTag = "0"; + text = "SKIP INTRO"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellToggleButton() { + profile = "ShellRadioProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "31 94"; + extent = "170 30"; + minExtent = "26 27"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "$pref::Vehicle::InvertYAxis"; + command = "toggleInvertYAxis();"; + helpTag = "0"; + text = "INVERT VEHICLE Y-AXIS"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellToggleButton(OP_ForceFeedbackTgl) { + profile = "ShellRadioProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "236 94"; + extent = "170 30"; + minExtent = "26 27"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "$Pref::useImmersion"; + command = "toggleImmersion();"; + helpTag = "0"; + text = "ENABLE FORCE FEEDBACK"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellToggleButton() { + profile = "ShellRadioProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "31 124"; + extent = "170 30"; + minExtent = "26 27"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "$pref::Vehicle::pilotTeleport"; + command = "toggleVehicleTeleportPref();"; + helpTag = "0"; + text = "TELEPORT TO VEHICLES"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellToggleButton() { + profile = "ShellRadioProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "236 124"; + extent = "170 30"; + minExtent = "26 27"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "$pref::usePrefSkins"; + helpTag = "0"; + text = "SHOW PERSONAL SKINS"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellToggleButton() { + profile = "ShellRadioProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "31 154"; + extent = "170 30"; + minExtent = "26 27"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "$pref::enableBadWordFilter"; + helpTag = "0"; + text = "ENABLE BAD WORD FILTER"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellToggleButton() { + profile = "ShellRadioProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "236 154"; + extent = "170 30"; + minExtent = "26 27"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "$pref::RenderOOBGrid"; + helpTag = "0"; + text = "SHOW OUT OF BOUNDS GRID"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new GuiTextCtrl(OP_LaunchScreenTxt) { + profile = "ShellTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "79 233"; + extent = "100 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Launch Screen:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellPopupMenu(OP_LaunchScreenMenu) { + profile = "ShellPopupProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "176 224"; + extent = "180 36"; + minExtent = "49 36"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Select Screen"; + longTextBuffer = "0"; + maxLength = "255"; + maxPopupHeight = "200"; + buttonBitmap = "gui/shll_pulldown"; + rolloverBarBitmap = "gui/shll_pulldownbar_rol"; + selectedBarBitmap = "gui/shll_pulldownbar_act"; + noButtonStyle = "0"; + }; + new ShellToggleButton() { + profile = "ShellRadioProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "31 185"; + extent = "170 30"; + minExtent = "26 27"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "$pref::ignoreTeamRepairMessages"; + helpTag = "0"; + text = "IGNORE REPAIR MESSAGES"; + longTextBuffer = "0"; + maxLength = "255"; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/gui/RPGBrowserGui.gui b/gui/RPGBrowserGui.gui index 36e4c85..9ac98bb 100644 --- a/gui/RPGBrowserGui.gui +++ b/gui/RPGBrowserGui.gui @@ -1,343 +1,343 @@ -//--- OBJECT WRITE BEGIN --- -new GuiChunkedBitmapCtrl(RPGBrowserGui) { - profile = "GuiContentProfile"; - horizSizing = "width"; - vertSizing = "height"; - position = "0 0"; - extent = "640 480"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "$ShellBackground"; - helpTag = "0"; - useVariable = "1"; - - pane = "News"; - - new ShellPaneCtrl(RPG_Frame) { - profile = "ShellPaneProfile"; - horizSizing = "width"; - vertSizing = "height"; - position = "12 13"; - extent = "620 423"; - minExtent = "48 92"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "MOD BROWSER"; - longTextBuffer = "0"; - maxLength = "255"; - noTitleBar = "0"; - - new ShellTabFrame(RPG_TabFrame) { - profile = "ShellHorzTabFrameProfile"; - horizSizing = "width"; - vertSizing = "bottom"; - position = "22 54"; - extent = "576 254"; - minExtent = "26 254"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - isVertical = "0"; - useCloseButton = "0"; - edgeInset = "0"; - }; - new GuiTextCtrl(RPG_VersionText) { - profile = "VersionTextProfile"; - horizSizing = "left"; - vertSizing = "bottom"; - position = "396 4"; - extent = "160 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Version "; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellTabGroupCtrl(RPG_TabView) { - profile = "TabGroupProfile"; - horizSizing = "width"; - vertSizing = "bottom"; - position = "30 25"; - extent = "560 29"; - minExtent = "38 29"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - glowOffset = "7"; - tabSpacing = "2"; - maxTabWidth = "150"; - stretchToFit = "0"; - }; - }; - new GuiControl(RPG_NewsPane) { - profile = "GuiDefaultProfile"; - horizSizing = "width"; - vertSizing = "height"; - position = "31 62"; - extent = "558 345"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - - new GuiControl() { - profile = "GuiDefaultProfile"; - horizSizing = "center"; - vertSizing = "center"; - position = "0 16"; - extent = "558 312"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - - new GuiTextCtrl(Enc_ErrorText) { - profile = "BrowserFilterLabelProfile"; - horizSizing = "center"; - vertSizing = "center"; - position = "114 143"; - extent = "330 26"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "The news tab is not functional in this version of T2Bol."; - longTextBuffer = "0"; - maxLength = "255"; - }; - }; - new ShellBitmapButton() { - profile = "ShellButtonProfile"; - horizSizing = "center"; - vertSizing = "bottom"; - position = "250 221"; - extent = "140 38"; - minExtent = "32 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "launchCredits(1);"; - helpTag = "0"; - text = "SHOW MOD CREDITS"; - simpleStyle = "0"; - }; - }; - new GuiControl(RPG_BrowserPane) { - profile = "GuiDefaultProfile"; - horizSizing = "width"; - vertSizing = "height"; - position = "31 70"; - extent = "900 900"; - minExtent = "8 8"; - visible = "0"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - - new ShellPopupMenu(RPG_Category) { - profile = "ShellPopupProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "8 4"; - extent = "180 36"; - minExtent = "49 36"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Select Category"; - longTextBuffer = "0"; - maxLength = "255"; - maxPopupHeight = "200"; - buttonBitmap = "gui/shll_pulldown"; - rolloverBarBitmap = "gui/shll_pulldownbar_rol"; - selectedBarBitmap = "gui/shll_pulldownbar_act"; - noButtonStyle = "0"; - - count = "5"; - }; - new ShellScrollCtrl(RPG_Scroll) { - profile = "NewScrollCtrlProfile"; - horizSizing = "right"; - vertSizing = "height"; - position = "10 30"; - extent = "175 298"; - minExtent = "24 52"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - willFirstRespond = "1"; - hScrollBar = "alwaysOff"; - vScrollBar = "dynamic"; - constantThumbHeight = "0"; - defaultLineHeight = "15"; - childMargin = "0 3"; - fieldBase = "gui/shll_field"; - - new GuiScrollContentCtrl() { - profile = "GuiDefaultProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 7"; - extent = "167 284"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - - new ShellTextList(RPG_ItemList) { - profile = "ShellTextArrayProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "0 0"; - extent = "167 8"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - enumerate = "0"; - resizeCell = "1"; - columns = "0"; - fitParentWidth = "1"; - clipColumnText = "0"; - }; - }; - }; - new GuiControl(RPG_Info) { - profile = "GuiDefaultProfile"; - horizSizing = "width"; - vertSizing = "height"; - position = "180 5"; - extent = "750 339"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - - new ShellScrollCtrl() { - profile = "NewScrollCtrlProfile"; - horizSizing = "width"; - vertSizing = "height"; - position = "0 6"; - extent = "393 338"; - minExtent = "24 24"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - willFirstRespond = "1"; - hScrollBar = "alwaysOff"; - vScrollBar = "dynamic"; - constantThumbHeight = "0"; - defaultLineHeight = "15"; - childMargin = "0 3"; - fieldBase = "gui/shll_field"; - - new GuiScrollContentCtrl() { - profile = "GuiDefaultProfile"; - horizSizing = "width"; - vertSizing = "bottom"; - position = "4 7"; - extent = "385 324"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - - new GuiMLTextCtrl(RPG_Text) { - profile = "ShellAltTextProfile"; - horizSizing = "width"; - vertSizing = "bottom"; - position = "0 0"; - extent = "370 112"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - lineSpacing = "2"; - allowColorChars = "1"; - maxChars = "-1"; - deniedSound = "InputDeniedSound"; - }; - }; - }; - }; - new ShellBitmapButton(RPG_DownloadButton) { - profile = "ShellButtonProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "5 605"; - extent = "183 50"; - minExtent = "32 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "BrowserDoSave();"; - helpTag = "0"; - text = "SAVE CONTENTS"; - simpleStyle = "0"; - - isActive = "0"; - }; - }; - new GuiControl(RPG_DownloadsPane) { - profile = "GuiDefaultProfile"; - horizSizing = "width"; - vertSizing = "height"; - position = "31 62"; - extent = "558 345"; - minExtent = "8 8"; - visible = "0"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - - new GuiControl() { - profile = "GuiDefaultProfile"; - horizSizing = "center"; - vertSizing = "center"; - position = "0 16"; - extent = "558 312"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - - new GuiTextCtrl() { - profile = "ShellTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "34 13"; - extent = "74 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "DOWNLOADS:"; - longTextBuffer = "0"; - maxLength = "255"; - }; - }; - }; -}; +//--- OBJECT WRITE BEGIN --- +new GuiChunkedBitmapCtrl(RPGBrowserGui) { + profile = "GuiContentProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "$ShellBackground"; + helpTag = "0"; + useVariable = "1"; + + pane = "News"; + + new ShellPaneCtrl(RPG_Frame) { + profile = "ShellPaneProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "12 13"; + extent = "620 423"; + minExtent = "48 92"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "MOD BROWSER"; + longTextBuffer = "0"; + maxLength = "255"; + noTitleBar = "0"; + + new ShellTabFrame(RPG_TabFrame) { + profile = "ShellHorzTabFrameProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "22 54"; + extent = "576 254"; + minExtent = "26 254"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + isVertical = "0"; + useCloseButton = "0"; + edgeInset = "0"; + }; + new GuiTextCtrl(RPG_VersionText) { + profile = "VersionTextProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "396 4"; + extent = "160 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Version "; + longTextBuffer = "0"; + maxLength = "255"; + }; + new ShellTabGroupCtrl(RPG_TabView) { + profile = "TabGroupProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "30 25"; + extent = "560 29"; + minExtent = "38 29"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + glowOffset = "7"; + tabSpacing = "2"; + maxTabWidth = "150"; + stretchToFit = "0"; + }; + }; + new GuiControl(RPG_NewsPane) { + profile = "GuiDefaultProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "31 62"; + extent = "558 345"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + + new GuiControl() { + profile = "GuiDefaultProfile"; + horizSizing = "center"; + vertSizing = "center"; + position = "0 16"; + extent = "558 312"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + + new GuiTextCtrl(Enc_ErrorText) { + profile = "BrowserFilterLabelProfile"; + horizSizing = "center"; + vertSizing = "center"; + position = "114 143"; + extent = "330 26"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "The news tab is not functional in this version of T2Bol."; + longTextBuffer = "0"; + maxLength = "255"; + }; + }; + new ShellBitmapButton() { + profile = "ShellButtonProfile"; + horizSizing = "center"; + vertSizing = "bottom"; + position = "250 221"; + extent = "140 38"; + minExtent = "32 38"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + command = "launchCredits(1);"; + helpTag = "0"; + text = "SHOW MOD CREDITS"; + simpleStyle = "0"; + }; + }; + new GuiControl(RPG_BrowserPane) { + profile = "GuiDefaultProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "31 70"; + extent = "900 900"; + minExtent = "8 8"; + visible = "0"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + + new ShellPopupMenu(RPG_Category) { + profile = "ShellPopupProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "8 4"; + extent = "180 36"; + minExtent = "49 36"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Select Category"; + longTextBuffer = "0"; + maxLength = "255"; + maxPopupHeight = "200"; + buttonBitmap = "gui/shll_pulldown"; + rolloverBarBitmap = "gui/shll_pulldownbar_rol"; + selectedBarBitmap = "gui/shll_pulldownbar_act"; + noButtonStyle = "0"; + + count = "5"; + }; + new ShellScrollCtrl(RPG_Scroll) { + profile = "NewScrollCtrlProfile"; + horizSizing = "right"; + vertSizing = "height"; + position = "10 30"; + extent = "175 298"; + minExtent = "24 52"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + constantThumbHeight = "0"; + defaultLineHeight = "15"; + childMargin = "0 3"; + fieldBase = "gui/shll_field"; + + new GuiScrollContentCtrl() { + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "4 7"; + extent = "167 284"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + + new ShellTextList(RPG_ItemList) { + profile = "ShellTextArrayProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "167 8"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + enumerate = "0"; + resizeCell = "1"; + columns = "0"; + fitParentWidth = "1"; + clipColumnText = "0"; + }; + }; + }; + new GuiControl(RPG_Info) { + profile = "GuiDefaultProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "180 5"; + extent = "750 339"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + + new ShellScrollCtrl() { + profile = "NewScrollCtrlProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 6"; + extent = "393 338"; + minExtent = "24 24"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + constantThumbHeight = "0"; + defaultLineHeight = "15"; + childMargin = "0 3"; + fieldBase = "gui/shll_field"; + + new GuiScrollContentCtrl() { + profile = "GuiDefaultProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "4 7"; + extent = "385 324"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + + new GuiMLTextCtrl(RPG_Text) { + profile = "ShellAltTextProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "0 0"; + extent = "370 112"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + lineSpacing = "2"; + allowColorChars = "1"; + maxChars = "-1"; + deniedSound = "InputDeniedSound"; + }; + }; + }; + }; + new ShellBitmapButton(RPG_DownloadButton) { + profile = "ShellButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 605"; + extent = "183 50"; + minExtent = "32 38"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + command = "BrowserDoSave();"; + helpTag = "0"; + text = "SAVE CONTENTS"; + simpleStyle = "0"; + + isActive = "0"; + }; + }; + new GuiControl(RPG_DownloadsPane) { + profile = "GuiDefaultProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "31 62"; + extent = "558 345"; + minExtent = "8 8"; + visible = "0"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + + new GuiControl() { + profile = "GuiDefaultProfile"; + horizSizing = "center"; + vertSizing = "center"; + position = "0 16"; + extent = "558 312"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + + new GuiTextCtrl() { + profile = "ShellTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "34 13"; + extent = "74 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "DOWNLOADS:"; + longTextBuffer = "0"; + maxLength = "255"; + }; + }; + }; +}; //--- OBJECT WRITE END --- \ No newline at end of file diff --git a/gui/TrainingGui.gui b/gui/TrainingGui.gui index 4302ac5..b5cff77 100644 --- a/gui/TrainingGui.gui +++ b/gui/TrainingGui.gui @@ -1,294 +1,294 @@ -//--- OBJECT WRITE BEGIN --- -new GuiChunkedBitmapCtrl(TrainingGui) { - profile = "GuiContentProfile"; - horizSizing = "width"; - vertSizing = "height"; - position = "0 0"; - extent = "640 480"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "$ShellBackground"; - helpTag = "0"; - useVariable = "1"; - - new ShellPaneCtrl() { - profile = "ShellPaneProfile"; - horizSizing = "width"; - vertSizing = "height"; - position = "12 13"; - extent = "620 423"; - minExtent = "48 92"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "CAMPAIGN"; - maxLength = "255"; - noTitleBar = "0"; - - new ShellFieldCtrl(TrainingPicFrame) { - profile = "ShellFieldProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "30 186"; - extent = "175 175"; - minExtent = "16 18"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - - new GuiBitmapCtrl(TrainingPic) { - profile = "GuiDefaultProfile"; - horizSizing = "width"; - vertSizing = "height"; - position = "2 3"; - extent = "169 169"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - wrap = "0"; - }; - }; - new ShellPopupMenu(TrainingSelectMenu) { - profile = "ShellPopupProfile"; - horizSizing = "left"; - vertSizing = "top"; - position = "100 368"; - extent = "165 36"; - minExtent = "49 36"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - maxLength = "255"; - maxPopupHeight = "200"; - buttonBitmap = "gui/shll_pulldown"; - rolloverBarBitmap = "gui/shll_pulldownbar_rol"; - selectedBarBitmap = "gui/shll_pulldownbar_act"; - noButtonStyle = "0"; - }; - new GuiTextCtrl() { - profile = "ShellTextRightProfile"; - horizSizing = "left"; - vertSizing = "top"; - position = "29 377"; - extent = "74 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Campaign:"; - maxLength = "255"; - }; - new GuiTextCtrl() { - profile = "ShellTextRightProfile"; - horizSizing = "left"; - vertSizing = "top"; - position = "236 377"; - extent = "74 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Difficulty:"; - maxLength = "255"; - }; - new ShellPopupMenu(TrainingDifficultyMenu) { - profile = "ShellPopupProfile"; - horizSizing = "left"; - vertSizing = "top"; - position = "307 368"; - extent = "137 36"; - minExtent = "49 36"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - maxLength = "255"; - maxPopupHeight = "200"; - buttonBitmap = "gui/shll_pulldown"; - rolloverBarBitmap = "gui/shll_pulldownbar_rol"; - selectedBarBitmap = "gui/shll_pulldownbar_act"; - noButtonStyle = "0"; - }; - new ShellScrollCtrl() { - profile = "NewScrollCtrlProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "26 31"; - extent = "183 146"; - minExtent = "24 52"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - willFirstRespond = "1"; - hScrollBar = "alwaysOff"; - vScrollBar = "dynamic"; - constantThumbHeight = "0"; - defaultLineHeight = "15"; - childMargin = "3 3"; - fieldBase = "gui/shll_field"; - - new GuiScrollContentCtrl() { - profile = "GuiDefaultProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "7 7"; - extent = "169 132"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - - new ShellTextList(TrainingMissionList) { - profile = "ShellTextArrayProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "0 0"; - extent = "169 8"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - enumerate = "1"; - resizeCell = "1"; - columns = "0 200"; - fitParentWidth = "1"; - clipColumnText = "0"; - }; - }; - }; - new ShellToggleButton(TrainingPlayTgl) { - profile = "ShellRadioProfile"; - horizSizing = "left"; - vertSizing = "bottom"; - position = "448 27"; - extent = "140 30"; - minExtent = "26 27"; - visible = "0"; - hideCursor = "0"; - bypassHideCursor = "0"; - variable = "$pref::TrainingPlayBriefing"; - helpTag = "0"; - text = "Play Briefing"; - maxLength = "255"; - }; - new GuiTextCtrl() { - profile = "ShellTextRightProfile"; - horizSizing = "left"; - vertSizing = "bottom"; - position = "444 31"; - extent = "122 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Play Briefing:"; - maxLength = "255"; - }; - new ShellBitmapButton(TrainingPlayBtn) { - profile = "SoundTestButtonProfile"; - horizSizing = "left"; - vertSizing = "bottom"; - position = "568 28"; - extent = "24 24"; - minExtent = "24 24"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "TrainingGui.toggleBriefing();"; - helpTag = "0"; - simpleStyle = "1"; - }; - new GuiTextCtrl() { - profile = "ShellTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "219 31"; - extent = "99 22"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "MISSION BRIEFING"; - maxLength = "255"; - }; - new ShellScrollCtrl(TrainingBriefingScroll) { - profile = "NewScrollCtrlProfile"; - horizSizing = "width"; - vertSizing = "height"; - position = "214 50"; - extent = "378 318"; - minExtent = "24 52"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - willFirstRespond = "1"; - hScrollBar = "alwaysOff"; - vScrollBar = "alwaysOn"; - constantThumbHeight = "0"; - defaultLineHeight = "15"; - childMargin = "3 3"; - fieldBase = "gui/shll_field"; - - new GuiScrollContentCtrl() { - profile = "GuiDefaultProfile"; - horizSizing = "width"; - vertSizing = "bottom"; - position = "7 7"; - extent = "348 304"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - - new GuiMLTextCtrl(TrainingBriefingText) { - profile = "ShellLoadTextProfile"; - horizSizing = "width"; - vertSizing = "bottom"; - position = "0 0"; - extent = "348 18"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - lineSpacing = "2"; - allowColorChars = "0"; - maxChars = "-1"; - deniedSound = "InputDeniedSound"; - }; - }; - }; - new ShellBitmapButton() { - profile = "ShellButtonProfile"; - horizSizing = "left"; - vertSizing = "top"; - position = "469 368"; - extent = "128 38"; - minExtent = "32 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "TrainingGui.startTraining();"; - helpTag = "0"; - text = "START"; - simpleStyle = "0"; - }; - }; -}; -//--- OBJECT WRITE END --- +//--- OBJECT WRITE BEGIN --- +new GuiChunkedBitmapCtrl(TrainingGui) { + profile = "GuiContentProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "$ShellBackground"; + helpTag = "0"; + useVariable = "1"; + + new ShellPaneCtrl() { + profile = "ShellPaneProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "12 13"; + extent = "620 423"; + minExtent = "48 92"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "CAMPAIGN"; + maxLength = "255"; + noTitleBar = "0"; + + new ShellFieldCtrl(TrainingPicFrame) { + profile = "ShellFieldProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "30 186"; + extent = "175 175"; + minExtent = "16 18"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + + new GuiBitmapCtrl(TrainingPic) { + profile = "GuiDefaultProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "2 3"; + extent = "169 169"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + wrap = "0"; + }; + }; + new ShellPopupMenu(TrainingSelectMenu) { + profile = "ShellPopupProfile"; + horizSizing = "left"; + vertSizing = "top"; + position = "100 368"; + extent = "165 36"; + minExtent = "49 36"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + maxLength = "255"; + maxPopupHeight = "200"; + buttonBitmap = "gui/shll_pulldown"; + rolloverBarBitmap = "gui/shll_pulldownbar_rol"; + selectedBarBitmap = "gui/shll_pulldownbar_act"; + noButtonStyle = "0"; + }; + new GuiTextCtrl() { + profile = "ShellTextRightProfile"; + horizSizing = "left"; + vertSizing = "top"; + position = "29 377"; + extent = "74 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Campaign:"; + maxLength = "255"; + }; + new GuiTextCtrl() { + profile = "ShellTextRightProfile"; + horizSizing = "left"; + vertSizing = "top"; + position = "236 377"; + extent = "74 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Difficulty:"; + maxLength = "255"; + }; + new ShellPopupMenu(TrainingDifficultyMenu) { + profile = "ShellPopupProfile"; + horizSizing = "left"; + vertSizing = "top"; + position = "307 368"; + extent = "137 36"; + minExtent = "49 36"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + maxLength = "255"; + maxPopupHeight = "200"; + buttonBitmap = "gui/shll_pulldown"; + rolloverBarBitmap = "gui/shll_pulldownbar_rol"; + selectedBarBitmap = "gui/shll_pulldownbar_act"; + noButtonStyle = "0"; + }; + new ShellScrollCtrl() { + profile = "NewScrollCtrlProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "26 31"; + extent = "183 146"; + minExtent = "24 52"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + constantThumbHeight = "0"; + defaultLineHeight = "15"; + childMargin = "3 3"; + fieldBase = "gui/shll_field"; + + new GuiScrollContentCtrl() { + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "7 7"; + extent = "169 132"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + + new ShellTextList(TrainingMissionList) { + profile = "ShellTextArrayProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "169 8"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + enumerate = "1"; + resizeCell = "1"; + columns = "0 200"; + fitParentWidth = "1"; + clipColumnText = "0"; + }; + }; + }; + new ShellToggleButton(TrainingPlayTgl) { + profile = "ShellRadioProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "448 27"; + extent = "140 30"; + minExtent = "26 27"; + visible = "0"; + hideCursor = "0"; + bypassHideCursor = "0"; + variable = "$pref::TrainingPlayBriefing"; + helpTag = "0"; + text = "Play Briefing"; + maxLength = "255"; + }; + new GuiTextCtrl() { + profile = "ShellTextRightProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "444 31"; + extent = "122 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "Play Briefing:"; + maxLength = "255"; + }; + new ShellBitmapButton(TrainingPlayBtn) { + profile = "SoundTestButtonProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "568 28"; + extent = "24 24"; + minExtent = "24 24"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + command = "TrainingGui.toggleBriefing();"; + helpTag = "0"; + simpleStyle = "1"; + }; + new GuiTextCtrl() { + profile = "ShellTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "219 31"; + extent = "99 22"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + text = "MISSION BRIEFING"; + maxLength = "255"; + }; + new ShellScrollCtrl(TrainingBriefingScroll) { + profile = "NewScrollCtrlProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "214 50"; + extent = "378 318"; + minExtent = "24 52"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "alwaysOn"; + constantThumbHeight = "0"; + defaultLineHeight = "15"; + childMargin = "3 3"; + fieldBase = "gui/shll_field"; + + new GuiScrollContentCtrl() { + profile = "GuiDefaultProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "7 7"; + extent = "348 304"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + + new GuiMLTextCtrl(TrainingBriefingText) { + profile = "ShellLoadTextProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "0 0"; + extent = "348 18"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + deniedSound = "InputDeniedSound"; + }; + }; + }; + new ShellBitmapButton() { + profile = "ShellButtonProfile"; + horizSizing = "left"; + vertSizing = "top"; + position = "469 368"; + extent = "128 38"; + minExtent = "32 38"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + command = "TrainingGui.startTraining();"; + helpTag = "0"; + text = "START"; + simpleStyle = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/gui/guiProfiles.cs b/gui/guiProfiles.cs index 0862de1..0722d7f 100644 --- a/gui/guiProfiles.cs +++ b/gui/guiProfiles.cs @@ -1,1656 +1,1656 @@ - -//-------------------------------------------------------------------------- -//-------------------------------------- Cursors -// -new GuiCursor(DefaultCursor) -{ - hotSpot = "1 1"; - bitmapName = "gui/CUR_3darrow"; -}; - -new GuiCursor(ArrowNoCursor) -{ - hotSpot = "1 1"; - bitmapName = "gui/CUR_3darrowno"; -}; - -new GuiCursor(ArrowWaitCursor) -{ - hotSpot = "1 1"; - bitmapName = "gui/CUR_3darrowwait"; -}; - -new GuiCursor(ArrowHelpCursor) -{ - hotSpot = "1 1"; - bitmapName = "gui/CUR_3darrowhelp"; -}; - -new GuiCursor(MoveCursor) -{ - hotSpot = "11 11"; - bitmapName = "gui/CUR_3dmove"; -}; - -new GuiCursor(UpDownCursor) -{ - hotSpot = "5 10"; - bitmapName = "gui/CUR_3dupdown"; -}; - -new GuiCursor(LeftRightCursor) -{ - hotSpot = "9 5"; - bitmapName = "gui/CUR_3dleftright"; -}; - -new GuiCursor(DiagRightCursor) -{ - hotSpot = "8 8"; - bitmapName = "gui/CUR_3ddiagright"; -}; - -new GuiCursor(DiagLeftCursor) -{ - hotSpot = "8 8"; - bitmapName = "gui/CUR_3ddiagleft"; -}; - -new GuiCursor(RotateCursor) -{ - hotSpot = "11 14"; - bitmapName = "gui/CUR_rotate"; -}; - -new GuiCursor(ResizeDownCursor) -{ - hotSpot = "4 8"; - bitmapName = "gui/CUR_3dresizeright"; -}; - -new GuiCursor(GrabCursor) -{ - hotSpot = "9 13"; - bitmapName = "gui/CUR_Grab"; -}; - -//-------------------------------------------------------------------------- -//-------------------------------------- Profiles -// -new GuiControlProfile("GuiDialogProfile"); - -new GuiControlProfile("GuiModelessDialogProfile") -{ - modal = false; -}; - -new GuiControlProfile ("GuiContentProfile") -{ - opaque = true; - fillColor = "255 255 255"; -}; - -new GuiControlProfile ("clockProfile") -{ - fontType = "Univers Condensed"; - fontSize = 12; - fontColor = "255 255 255"; -}; - -new GuiControlProfile ("SiegeHalftimeClockProfile") -{ - fontType = "Univers Condensed"; - fontSize = 18; - fontColor = "255 255 255"; -}; - -new GuiControlProfile ("GuiContentProfileNoClear") -{ - opaque = false; - fillColor = "255 255 255"; -}; - -//-------------------------------------------------------------------------- -// Base font definitions: -//-------------------------------------------------------------------------- -$ShellFont = "Univers"; -$ShellFontSize = 16; -$ShellMediumFontSize = 18; -$ShellHeaderFont = "Sui Generis"; -$ShellHeaderFontSize = 22; -$ShellButtonFont = "Univers Condensed"; -$ShellButtonFontSize = 16; -$ShellLabelFont = "Univers Condensed"; -$ShellLabelFontSize = 18; -$ShellBoldFont = "Univers Bold"; - -$ShellColorBright = "173 255 250"; -$ShellColorDark = "130 190 185"; -$ShellColorVeryDark = "0 117 133"; - -// Color coding system for Player names in the game: -$PlayerNameColor = "200 200 200"; -$TribeTagColor = "220 220 20"; -$SmurfNameColor = "150 150 250"; -$BotNameColor = "60 220 150"; - -//-------------------------------------------------------------------------- -// Beginning of the "New Shell" section: -new GuiControlProfile ("ShellButtonProfile") -{ - fontType = $ShellButtonFont; - fontSize = $ShellButtonFontSize; - fontColor = "8 19 6"; - fontColorHL = "25 68 56"; - fontColorNA = "5 5 5"; - fontColorSEL = "25 68 56"; - fixedExtent = true; - justify = "center"; - bitmap = "gui/shll_button"; - textOffset = "0 10"; - soundButtonDown = sButtonDown; - soundButtonOver = sButtonOver; - tab = true; - canKeyFocus = true; -}; - -new GuiControlProfile ("ShellButtonNoTabProfile") -{ - fontType = $ShellButtonFont; - fontSize = $ShellButtonFontSize; - fontColor = "8 19 6"; - fontColorHL = "25 68 56"; - fontColorNA = "5 5 5"; - fontColorSEL = "25 68 56"; - fixedExtent = true; - justify = "center"; - bitmap = "gui/shll_button"; - textOffset = "0 10"; - soundButtonDown = sButtonDown; - soundButtonOver = sButtonOver; - tab = false; - canKeyFocus = true; -}; - -new GuiControlProfile ("ShellRadioProfile") -{ - fontType = $ShellButtonFont; - fontSize = $ShellButtonFontSize; - fontColor = "8 19 6"; - fontColorHL = "25 68 56"; - fontColorNA = "5 5 5"; - fixedExtent = true; - justify = "center"; - bitmap = "gui/shll_radio"; - soundButtonDown = sButtonDown; - soundButtonOver = sButtonOver; - tab = true; - canKeyFocus = true; -}; - -new GuiControlProfile ("ShellTabProfile") -{ - fontType = $ShellButtonFont; - fontSize = $ShellButtonFontSize; - fontColor = "8 19 6"; - fontColorHL = "25 68 56"; - fontColorNA = "5 5 5"; - fontColorSEL = "8 19 6"; - fixedExtent = true; - justify = "center"; - bitmap = "gui/shll_tabbutton"; - soundButtonDown = sButtonDown; - soundButtonOver = sButtonOver; - tab = true; - canKeyFocus = true; -}; - -new GuiControlProfile ("TabGroupProfile") -{ - fontType = $ShellButtonFont; - fontSize = $ShellButtonFontSize; - fontColor = "8 19 6"; - fontColorHL = "25 68 56"; - fontColorNA = "5 5 5"; - fontColorSEL = "8 19 6"; - fixedExtent = true; - bitmapBase = "gui/shll_horztabbutton"; - justify = "center"; - textOffset = "8 0"; - soundButtonDown = sButtonDown; - soundButtonOver = sButtonOver; - tab = true; - canKeyFocus = true; -}; - -new GuiControlProfile ("LaunchTabProfile") -{ - fontType = $ShellButtonFont; - fontSize = $ShellButtonFontSize; - fontColor = "60 140 140"; - fontColorHL = "6 245 215"; - fontColorNA = "64 64 64"; - fontColorSEL = "6 245 215"; - fixedExtent = true; - bitmapBase = "gui/lnch_tab"; - justify = "center"; - textOffset = "8 0"; - soundButtonDown = sButtonDown; - soundButtonOver = sButtonOver; - tab = true; - canKeyFocus = true; -}; - -new GuiControlProfile ("ShellTabFrameProfile") -{ - bitmapBase = "gui/shll_tabframe"; -}; - -new GuiControlProfile ("ShellHorzTabFrameProfile") -{ - bitmapBase = "gui/shll_horztabframe"; -}; - -new GuiControlProfile ("ShellPopupProfile") -{ - fontType = $ShellFont; - fontSize = $ShellFontSize; - fontColor = "8 19 6"; - fontColorHL = "25 68 56"; - fontColorNA = "5 5 5"; - fontColorSEL = "8 19 6"; - fixedExtent = true; - justify = "center"; - soundButtonDown = sButtonDown; - soundButtonOver = sButtonOver; - bitmapBase = "gui/shll_scroll"; - tab = true; - canKeyFocus = true; -}; - -new GuiControlProfile ("NewTextEditProfile") -{ - fillColorHL = $ShellColorDark; - fontType = $ShellFont; - fontSize = $ShellFontSize; - fontColor = "60 140 140"; - fontColorHL = "25 68 56"; - fontColorNA = "128 128 128"; - cursorColor = $ShellColorBright; - bitmap = "gui/shll_entryfield"; - textOffset = "14 0"; - autoSizeWidth = false; - autoSizeHeight = false; - tab = true; - canKeyFocus = true; -}; - -new GuiControlProfile ("NewTextEditNumericProfile") -{ - fillColorHL = $ShellColorDark; - fontType = $ShellFont; - fontSize = $ShellFontSize; - fontColor = "60 140 140"; - fontColorHL = "25 68 56"; - fontColorNA = "128 128 128"; - cursorColor = $ShellColorBright; - bitmap = "gui/shll_entryfield"; - justify = "center"; - textOffset = "14 0"; - autoSizeWidth = false; - autoSizeHeight = false; - numbersOnly = true; - tab = true; - canKeyFocus = true; -}; - -new GuiControlProfile ("NewTextEditCenterProfile") -{ - fillColorHL = $ShellColorDark; - fontType = $ShellFont; - fontSize = $ShellFontSize; - fontColor = "60 140 140"; - fontColorHL = "25 68 56"; - fontColorNA = "128 128 128"; - cursorColor = $ShellColorBright; - bitmap = "gui/shll_entryfield"; - justify = "center"; - autoSizeWidth = false; - autoSizeHeight = false; - tab = true; - canKeyFocus = true; -}; - -new GuiControlProfile ("NewScrollCtrlProfile") -{ - bitmapBase = "gui/shll_scroll"; - soundButtonDown = sButtonDown; - soundButtonOver = sButtonOver; -}; - -new GuiControlProfile ("ShellFieldProfile") -{ - bitmapBase = "gui/shll_field"; -}; - -new GuiControlProfile ("ShellSliderProfile") -{ - fontType = $ShellLabelFont; - fontSize = $ShellFontSize; - fontColor = "60 180 180"; - fontColorNA = "128 128 128"; - bitmapBase = "gui/shll_scroll"; - canKeyFocus = true; - soundButtonOver = sButtonOver; -}; - -new GuiControlProfile ("ShellTextArrayProfile") -{ - fontType = $ShellFont; - fontSize = $ShellFontSize; - fontColor = "60 180 180"; - fontColorHL = "6 245 215"; - fontColorNA = "108 108 108"; - fontColorSEL = "25 68 56"; - bitmapBase = "gui/shll_bar"; - tab = true; - canKeyFocus = true; -}; - -new GuiControlProfile ("ShellActiveTextProfile") -{ - fontType = $ShellFont; - fontSize = $ShellFontSize; - fontColor = "60 180 180"; - fontColorHL = "6 245 215"; - fontColorNA = "128 128 128"; - fontColorSEL = "25 68 56"; - justify = "center"; -}; - -new GuiControlProfile ("ShellPaneProfile") -{ - fontType = $ShellHeaderFont; - fontSize = $ShellHeaderFontSize; - fontColor = "5 5 5"; - autoSizeWidth = false; - autoSizeHeight = false; - bitmapBase = "gui/shll"; -}; - -new GuiControlProfile ("ShellDlgPaneProfile") -{ - fontType = $ShellHeaderFont; - fontSize = $ShellHeaderFontSize; - fontColor = "5 5 5"; - autoSizeWidth = false; - autoSizeHeight = false; - bitmapBase = "gui/dlg"; -}; - -new GuiControlProfile ("ShellWindowProfile") -{ - borderColor = "3 124 134"; - fontType = $ShellHeaderFont; - fontSize = $ShellHeaderFontSize; - fontColor = "5 5 5"; - autoSizeWidth = false; - autoSizeHeight = false; - bitmapBase = "gui/dlg"; - soundButtonDown = sButtonDown; - soundButtonOver = sButtonOver; -}; - -new GuiControlProfile ("ShellDlgProfile") -{ - fontType = $ShellHeaderFont; - fontSize = $ShellHeaderFontSize; - fontColor = "5 5 5"; - bitmap = "gui/dlg_box"; - autoSizeWidth = false; - autoSizeHeight = false; -}; - -new GuiControlProfile ("BrowserH1Profile") -{ - fontType = "Univers Condensed Bold"; - fontSize = 28; - fontColor = "40 247 113"; // green - autoSizeWidth = false; - autoSizeHeight = true; - bitmapBase = "gui/shll"; -}; - -new GuiControlProfile ("CloseButtonProfile") -{ - bitmap = "gui/shll_menuclose"; - soundButtonDown = sButtonDown; - soundButtonOver = sButtonOver; - tab = true; - canKeyFocus = true; -}; - -new GuiControlProfile ("SoundTestButtonProfile") -{ - bitmap = "gui/shll_soundbutton"; - soundButtonOver = sButtonOver; - tab = true; - canKeyFocus = true; -}; - -new GuiControlProfile ("LaunchMenuProfile") -{ - fontType = $ShellFont; - fontSize = $ShellFontSize; - fontColor = "6 245 215"; - fontColorHL = "74 251 228"; - fontColorSEL = "4 41 45"; - borderColor = "84 121 125 200"; - fixedExtent = true; - justify = "center"; - bitmapBase = "gui/launch_btn"; - textOffset = "0 19"; - soundButtonDown = sLaunchMenuOpen; - soundButtonOver = sLaunchMenuOver; - tab = true; - canKeyFocus = true; -}; - -new GuiControlProfile ("LaunchBtnTopProfile") -{ - fixedExtent = true; - bitmapBase = "gui/launchtop_btn"; -}; - -new GuiControlProfile ("ShellServerBrowserProfile") -{ - fontType = $ShellFont; - fontSize = $ShellFontSize; - fontColor = "60 180 180"; - fontColorHL = "6 245 215"; - fontColorNA = "128 128 128"; - fontColorSEL = "25 68 56"; - fontColors[4] = "20 167 93"; // Mod base color - fontColors[5] = "40 217 113"; // Mod rollover color - fontColors[6] = "5 60 30"; // Mod selected color - fontColors[7] = "108 108 108"; // Differing build base color - fontColors[8] = "168 168 168"; // Differing build rollover color - fontColors[9] = "58 58 58"; // Differing build selected color - bitmapBase = "gui/shll_scroll"; - soundButtonDown = sButtonDown; - soundButtonOver = sButtonOver; - tab = true; - canKeyFocus = true; -}; - -new GuiControlProfile ("ShellBrowserListProfile") -{ - fontType = $ShellFont; - fontSize = 12; - fontColor = "20 220 20"; - fontColorHL = "60 250 60"; - fontColorNA = "128 128 128"; - fontColorSEL = "0 60 0"; - soundButtonDown = sButtonDown; - soundButtonOver = sButtonOver; - tab = true; - canKeyFocus = true; -}; - -new GuiControlProfile ("LobbyPlayerListProfile") -{ - fontType = $ShellFont; - fontSize = $ShellFontSize; - fontColor = "60 180 180"; - fontColorHL = "6 245 215"; - fontColorNA = "128 128 128"; - fontColorSEL = "25 68 56"; - fontColors[6] = $PlayerNameColor; - fontColors[7] = $TribeTagColor; - fontColors[8] = $SmurfNameColor; - fontColors[9] = $BotNameColor; - bitmapBase = "gui/shll_scroll"; - soundButtonDown = sButtonDown; - soundButtonOver = sButtonOver; - tab = true; - canKeyFocus = true; -}; - -new GuiControlProfile ("ShellBrowserTitleProfile") -{ - fontType = "Sui Generis"; - fontSize = 32; - fontColor = "173 255 250"; - autoSizeWidth = true; - autoSizeHeight = true; - tab = false; - canKeyFocus = false; -}; -//-------------------------------------------------------------------------- -// End of "New Shell" section. - -new GuiControlProfile ("ShellHoloButtonProfile") -{ - opaque = true; - fillColor = $ShellColorVeryDark; - fillColorNA = "128 128 128"; - border = true; - borderColor = $ShellColorBright; - borderColorHL = "127 127 127"; - borderColorNA = "192 192 192"; - fontType = "Univers"; - fontSize = 14; - fontColor = $ShellColorBright; - fontColorHL = $ShellColorDark; - fontColorNA = "192 192 192"; - fixedExtent = true; - justify = "center"; - soundButtonDown = sButtonDown; - soundButtonOver = sButtonOver; - tab = true; - canKeyFocus = true; -}; - -new GuiControlProfile ("GameHoloButtonProfile") -{ - opaque = true; - fillColor = "0 64 0 80"; - border = true; - borderColor = "0 255 0"; - borderColorHL = "127 127 127"; - fontType = "Univers"; - fontSize = 14; - fontColor = "0 255 0"; - fontColorHL = "0 128 0"; - fixedExtent = true; - justify = "center"; - soundButtonDown = sButtonDown; - soundButtonOver = sButtonOver; - tab = true; -}; - -new GuiControlProfile ("ShellHoloBox") -{ - opaque = true; - fillColor = "72 72 72 128"; - border = true; - borderColor = $ShellColorBright; -}; - -new GuiControlProfile ("TaskHudBox") -{ - opaque = true; - fillColor = "72 72 72 128"; - border = true; - borderColor = "30 59 56 80"; -}; - -new GuiControlProfile ("ShellOpaqueBox") -{ - opaque = true; - fillColor = $ShellColorVeryDark; - border = true; - borderColor = $ShellColorBright; -}; - -new GuiControlProfile ("ShellScrollCtrlProfile") -{ - border = true; - borderColor = $ShellColorBright; - bitmap = "gui/shellScroll"; -}; - -new GuiControlProfile ("ShellTextProfile") -{ - fontType = $ShellLabelFont; - fontSize = $ShellLabelFontSize; - fontColor = "66 229 244"; - autoSizeWidth = true; - autoSizeHeight = true; -}; - -new GuiControlProfile ("ShellTextRightProfile") -{ - fontType = $ShellLabelFont; - fontSize = $ShellLabelFontSize; - fontColor = "66 229 244"; - justify = "right"; - autoSizeWidth = false; - autoSizeHeight = true; -}; - -new GuiControlProfile ("ShellTextCenterProfile") -{ - fontType = $ShellLabelFont; - fontSize = $ShellLabelFontSize; - fontColor = "66 229 244"; - justify = "center"; - autoSizeWidth = false; - autoSizeHeight = true; -}; - -new GuiControlProfile ("DisabledTextProfile") -{ - fontType = $ShellLabelFont; - fontSize = $ShellLabelFontSize; - fontColor = "128 128 128"; - autoSizeWidth = true; - autoSizeHeight = true; -}; - -new GuiControlProfile ("DisabledTextRightProfile") -{ - fontType = $ShellLabelFont; - fontSize = $ShellLabelFontSize; - fontColor = "128 128 128"; - justify = "right"; - autoSizeWidth = false; - autoSizeHeight = true; -}; - -new GuiControlProfile ("ShellAltTextProfile") -{ - fontType = $ShellFont; - fontSize = $ShellFontSize; - fontColor = "66 219 234"; - autoSizeWidth = true; - autoSizeHeight = true; -}; - -new GuiControlProfile ("ShellAltTextRightProfile") -{ - fontType = $ShellFont; - fontSize = $ShellFontSize; - fontColor = "66 219 234"; - justify = "right"; - autoSizeWidth = false; - autoSizeHeight = true; -}; - -new GuiControlProfile ("ShellAltTextCenterProfile") -{ - fontType = $ShellFont; - fontSize = $ShellFontSize; - fontColor = "66 219 234"; - justify = "center"; - autoSizeWidth = false; - autoSizeHeight = true; -}; - -new GuiControlProfile ("ShellStaticTextProfile") -{ - fontType = $ShellFont; - fontSize = $ShellFontSize; - fontColor = "66 219 234"; - autoSizeWidth = false; - autoSizeHeight = true; -}; - -new GuiControlProfile ("VersionTextProfile") -{ - fontType = "Univers Bold"; - fontSize = $ShellMediumFontSize; - fontColor = "0 0 0"; - justify = "right"; - autoSizeWidth = false; - autoSizeHeight = true; -}; - -new GuiControlProfile ("CenterPrintTextProfile") -{ - fontType = $ShellFont; - fontSize = $ShellMediumFontSize; - fontColor = $ShellColorBright; - autoSizeWidth = false; - autoSizeHeight = true; -}; - - -new GuiControlProfile ("ShellEditMOTDTextProfile") -{ - fontType = $ShellFont; - fontSize = $ShellFontSize; - fontColor = "66 219 234"; - fontColorHL = "25 68 56"; - fillColorHL = "50 233 206"; - cursorColor = "200 240 240"; - autoSizeWidth = false; - autoSizeHeight = false; - tab = true; - canKeyFocus = true; -}; - -new GuiControlProfile ("ShellTopicTextProfile") -{ - fontType = $ShellFont; - fontSize = $ShellMediumFontSize; - fontColor = "100 200 200"; - autoSizeWidth = false; - autoSizeHeight = true; -}; - -new GuiControlProfile ("BrowserFilterLabelProfile") -{ - fontType = $ShellLabelFont; - fontSize = 22; - fontColor = "0 220 0"; - justify = "left"; - autoSizeWidth = true; - autoSizeHeight = true; -}; - -new GuiControlProfile ("BrowserFilterTextProfile") -{ - fontType = $ShellLabelFont; - fontSize = 22; - fontColor = "66 219 234"; - justify = "left"; - autoSizeWidth = true; - autoSizeHeight = true; -}; - -new GuiControlProfile ("BrowserStatusTextProfile") -{ - fontType = $ShellLabelFont; - fontSize = 22; - fontColor = "66 219 234"; - justify = "right"; - autoSizeWidth = false; - autoSizeHeight = true; -}; - -new GuiControlProfile ("BrowserProgressProfile") -{ - opaque = false; - fillColor = "79 253 181 180"; - border = true; - borderColor = "3 124 134"; -}; - -new GuiControlProfile ("InfoWindowProfile") -{ - fontType = $ShellFont; - fontSize = $ShellFontSize; - fontColor = "66 219 234"; - fontColors[6] = $PlayerNameColor; - fontColors[7] = $TribeTagColor; - fontColors[8] = $SmurfNameColor; - fontColors[9] = $BotNameColor; - autoSizeWidth = true; - autoSizeHeight = true; -}; - -new GuiControlProfile ("ShellMessageTextProfile") -{ - fontType = $ShellFont; - fontSize = $ShellMediumFontSize; - fontColor = "66 219 234"; - fontColorHL = "25 68 56"; - fillColorHL = "50 233 206"; - cursorColor = "200 240 240"; - autoSizeWidth = false; - autoSizeHeight = false; - tab = true; - canKeyFocus = true; -}; - -new GuiControlProfile ("ShellLoadTextProfile") -{ - fontType = $ShellFont; - fontSize = $ShellMediumFontSize; - fontColor = "66 219 234"; - autoSizeWidth = true; - autoSizeHeight = true; -}; - -new GuiControlProfile ("ShellLargeLabelProfile" ) -{ - fontType = $ShellLabelFont; - fontSize = 22; - fontColor = "60 180 180"; - autoSizeWidth = false; - autoSizeHeight = true; -}; - -new GuiControlProfile ("ShellMediumTextProfile") -{ - fontType = $ShellFont; - fontSize = $ShellMediumFontSize; - fontColor = $ShellColorBright; - autoSizeWidth = true; - autoSizeHeight = true; -}; - -new GuiControlProfile ("ShellMediumTextCenterProfile") -{ - fontType = $ShellFont; - fontSize = $ShellMediumFontSize; - fontColor = $ShellColorBright; - autoSizeWidth = false; - autoSizeHeight = true; - justify = "center"; -}; - -new GuiControlProfile ("DebriefHeadlineTextProfile") -{ - fontType = $ShellLabelFont; - fontSize = 28; - fontColor = $ShellColorBright; - autoSizeWidth = false; - autoSizeHeight = true; - tab = false; - canKeyFocus = false; -}; - -new GuiControlProfile ("DebriefTextProfile") -{ - fontType = $ShellFont; - fontSize = $ShellMediumFontSize; - fontColor = "60 180 180"; - fontColors[6] = $PlayerNameColor; - fontColors[7] = $TribeTagColor; - fontColors[8] = $SmurfNameColor; - fontColors[9] = $BotNameColor; - autoSizeWidth = false; - autoSizeHeight = false; - tab = false; - canKeyFocus = false; -}; - -new GuiControlProfile ("ScoreHeaderTextProfile") -{ - fontType = $ShellLabelFont; - fontSize = 28; - fontColor = "0 255 255"; - autoSizeWidth = false; - autoSizeHeight = true; - tab = false; - canKeyFocus = false; -}; - -new GuiControlProfile ("ScoreSubheaderTextProfile") -{ - fontType = $ShellLabelFont; - fontSize = 22; - fontColor = "0 255 255"; - autoSizeWidth = false; - autoSizeHeight = true; - tab = false; - canKeyFocus = false; -}; - -new GuiControlProfile ("ScoreTextProfile") -{ - fontType = $ShellFont; - fontSize = $ShellMediumFontSize; - fontColor = "0 220 220"; - autoSizeWidth = false; - autoSizeHeight = false; - tab = false; - canKeyFocus = false; -}; - -new GuiControlProfile ("ShellTreeViewProfile") -{ - fontType = $ShellFont; - fontSize = $ShellFontSize; - fontColor = "6 245 215"; - fontColorHL = "6 245 215"; - fontColorSEL = "25 68 56"; - bitmapBase = "gui/shll_bar"; - tab = true; - canKeyFocus = true; -}; - -new GuiControlProfile ("ShellBigTextProfile") -{ - fontType = $ShellHeaderFont; - fontSize = $ShellHeaderFontSize; - fontColor = $ShellColorBright; - autoSizeWidth = true; - autoSizeHeight = true; -}; - -new GuiControlProfile ("HudScoreListProfile") -{ - fontType = $ShellFont; - fontSize = $ShellMediumFontSize; - fontColor = "60 180 180"; -}; - -new GuiControlProfile ("GuiHelpBoxProfile") -{ - border = false; - //borderColor = "3 144 156"; - opaque = true; - fillColor = "3 144 156 86"; -}; - -new GuiControlProfile ("GuiHelpTextProfile") -{ - fontType = $ShellFont; - fontSize = $ShellFontSize; - fontColor = "169 215 250"; - autoSizeWidth = false; - autoSizeHeight = false; - justify = "left"; -}; - -new GuiControlProfile ("GuiHelpHeaderProfile") -{ - fontType = $ShellLabelFont; - fontSize = $ShellLabelFontSize; - fontColor = "169 215 250"; - autoSizeWidth = true; - autoSizeHeight = true; - justify = "left"; -}; - -new GuiControlProfile ("GuiVoiceRedProfile") -{ - fontType = $ShellFont; - fontSize = $ShellFontSize; - fontColor = "180 0 0"; - justify = "left"; -}; - -new GuiControlProfile ("GuiVoiceGreenProfile") -{ - fontType = $ShellFont; - fontSize = $ShellFontSize; - fontColor = "0 180 0"; - justify = "left"; -}; - -new GuiControlProfile( "GuiDeathMsgHudProfile" ) -{ - opaque = false; - border = false; - //borderColor = "255 255 0 128"; -}; - -new GuiControlProfile ("GuiTextProfile") -{ - fontType = "Univers"; - fontSize = 16; - fontColor = "0 0 0"; - autoSizeWidth = true; - autoSizeHeight = true; -}; - -new GuiControlProfile ("GuiCenterTextProfile") -{ - fontType = "Univers"; - fontSize = 16; - fontColor = "0 0 0"; - fixedExtent = true; - justify = "center"; -}; - -new GuiControlProfile ("GuiBigTextProfile") -{ - fontType = "Times"; - fontSize = 36; - fontColor = "0 0 0"; - autoSizeWidth = true; - autoSizeHeight = true; -}; - -new GuiControlProfile ("GuiBigTextProfileWhite") -{ - fontType = "Times"; - fontSize = 24; - - fontColor = " 0 0 0"; - fillColor = "255 255 255"; - - fontColorHL = "255 255 255"; - fillColorHL = "0 0 0"; - - autoSizeWidth = true; - autoSizeHeight = true; - - opaque = true; -}; - -new GuiControlProfile("GuiBorderProfile") -{ - border = "true"; - borderColor = "40 205 170"; - opaque = true; - fillColor = "0 64 100 80"; -}; - -new GuiControlProfile("ZoomHudProfile") -{ - border = "true"; - borderColor = "40 205 170"; - opaque = false; - fillColor = "0 64 100 80"; -}; - -new GuiControlProfile("GuiDashBoxProfile") -{ - border = "false"; - opaque = false; -}; - -new GuiControlProfile("GuiDashTextProfile") -{ - fontType = "Univers Condensed"; - fontSize = 16; - fontColor = "154 208 253"; - justify = "center"; -}; - -new GuiControlProfile ("GuiTextBGLeftProfile") -{ - fontType = "Univers Condensed"; - fontSize = 20; - fontColor = "70 235 200"; - justify = "center"; -}; - -new GuiControlProfile ("GuiTextBGCenterProfile") -{ - fontType = "Univers"; - fontSize = 16; - fontColor = "70 235 200"; - justify = "center"; -}; - -new GuiControlProfile ("GuiTextBGRightProfile") -{ - fontType = "Univers"; - fontSize = 16; - fontColor = "70 235 200"; - justify = "right"; -}; - -new GuiControlProfile ("GuiTextBGWhiteRightProfile") -{ - fontType = "Univers Condensed"; - fontSize = 16; - fontColor = "90 255 220"; - justify = "right"; -}; - -new GuiControlProfile ("GuiHelpLineProfile") -{ - borderColor = "231 101 26"; - bitmap = "gui/hud_dot"; -}; - -new GuiControlProfile ("GuiTextObjHudCenterProfile") -{ - fontType = "Univers Condensed"; - fontSize = 16; - fontColor = "169 215 250"; - fontColors[6] = $PlayerNameColor; - fontColors[7] = $TribeTagColor; - fontColors[8] = $SmurfNameColor; - fontColors[9] = $BotNameColor; - justify = "center"; -}; - -new GuiControlProfile ("GuiTextObjHudLeftProfile") -{ - fontType = "Univers Condensed"; - fontSize = 16; - fontColor = "169 215 250"; - fontColors[6] = $PlayerNameColor; - fontColors[7] = $TribeTagColor; - fontColors[8] = $SmurfNameColor; - fontColors[9] = $BotNameColor; - justify = "left"; -}; - -new GuiControlProfile ("GuiTextObjGreenLeftProfile") -{ - fontType = "Univers Condensed"; - fontSize = 16; - fontColor = "23 236 67"; - fontColors[6] = $PlayerNameColor; - fontColors[7] = $TribeTagColor; - fontColors[8] = $SmurfNameColor; - fontColors[9] = $BotNameColor; - justify = "left"; -}; - -new GuiControlProfile ("GuiTextObjGreenCenterProfile") -{ - fontType = "Univers Condensed"; - fontSize = 16; - fontColor = "23 236 67"; - fontColors[6] = $PlayerNameColor; - fontColors[7] = $TribeTagColor; - fontColors[8] = $SmurfNameColor; - fontColors[9] = $BotNameColor; - justify = "center"; -}; - -new GuiControlProfile ("DeathMsgTextProfile") -{ - fontType = "Univers"; - fontSize = 14; - fontColor = "40 247 113"; // green - justify = "left"; -}; - -new GuiControlProfile("DebuggerWindowProfile") { - border = "true"; - borderColor = "255 255 255"; - opaque = "true"; - fillColor = "0 0 0"; -}; - -new GuiControlProfile ("GuiTextEditProfile") -{ - opaque = true; - fillColor = "255 255 255"; - fillColorHL = "128 128 128"; - border = true; - borderColor = "0 0 0"; - fontType = "Lucida Console"; - fontSize = 12; - fontColor = "0 0 0"; - fontColorHL = "255 255 255"; - fontColorNA = "128 128 128"; - textOffset = "0 2"; - autoSizeWidth = false; - autoSizeHeight = true; - tab = true; - canKeyFocus = true; -}; - -new GuiControlProfile ("GuiInspectorTextEditProfile") -{ - opaque = true; - fillColor = "255 255 255"; - fillColorHL = "128 128 128"; - border = true; - borderColor = "0 0 0"; - fontType = "Univers"; - fontSize = 16; - fontColor = "0 0 0"; - fontColorHL = "255 255 255"; - autoSizeWidth = false; - autoSizeHeight = true; - tab = false; - canKeyFocus = true; -}; - -new GuiControlProfile ("GuiMessageEditHudProfile") -{ - fontType = "verdana"; - fontSize = 14; - fontColor = "255 255 0"; - cursorColor = "255 205 0"; - autoSizeWidth = false; - autoSizeHeight = true; - tab = false; - canKeyFocus = true; -}; - -new GuiControlProfile ("GuiMessageEditHudTextProfile") -{ - fontType = "verdana"; - fontSize = 14; - fontColor = "255 255 255"; - autoSizeWidth = true; - autoSizeHeight = true; - tab = false; -}; - -new GuiControlProfile("GuiAmmoHudProfile") -{ - fontType = "Univers Condensed"; - fontSize = 16; - fontColor = "169 215 250"; - autoSizeWidth = false; - autoSizeHeight = true; -}; - -new GuiControlProfile("GuiPackTextProfile") -{ - fontType = "Univers"; - fontSize = 12; - fontColor = "169 215 250"; - justify = "center"; - autoSizeWidth = false; - autoSizeHeight = true; -}; - -new GuiControlProfile("GuiTempSpeedProfile") -{ - fontType = "Univers Condensed"; - fontSize = 16; - fontColor = "240 0 240"; - autoSizeWidth = false; - autoSizeHeight = true; -}; - -new GuiControlProfile("GuiRecordingHudProfile") -{ - fontType = "Univers Condensed"; - fontSize = 16; - fontColor = "255 0 0"; - justify = "center"; - autoSizeWidth = false; - autoSizeHeight = true; -}; - -new GuiControlProfile ("GuiChatBackProfile") -{ - bitmapbase = "gui/hud_new_window"; -}; - -new GuiControlProfile ("HudScoreProfile") -{ - bitmap = "gui/hud_new_scorewindow"; - borderColor = "30 59 56"; -}; - -new GuiControlProfile ("HudHelpTagProfile") -{ - borderColor = "231 101 26"; - bitmap = "gui/hud_dot"; -}; - -new GuiControlProfile ("HudVoteBackProfile") -{ - bitmapBase = "gui/hud_new_window_B"; -}; - -new GuiControlProfile ("GuiVMenuProfile") -{ - bitmapBase = "gui/hud_new_window"; - fontType = $ShellFont; - fontSize = $ShellMediumFontSize; -}; - -new GuiControlProfile ("GuiChatHudProfile") -{ - fontType = $ShellFont; - fontSize = $ShellFontSize; - 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; -}; - -new GuiControlProfile ("GuiHudNavProfile") -{ -// fontType = "Univers Condensed"; -// fontSize = 16; -// fontColor = "255 255 255"; -// autoSizeWidth = false; -// autoSizeHeight = true; - fontColors[6] = $PlayerNameColor; - fontColors[7] = $TribeTagColor; - fontColors[8] = $SmurfNameColor; - fontColors[9] = $BotNameColor; -}; - -new GuiControlProfile ( "GuiHudVoiceMenuProfile" ) -{ - fontType = $ShellFont; - fontSize = $ShellFontSize; - fontColor = "70 235 200"; - justify = "left"; - autoSizeWidth = false; - autoSizeHeight = true; -}; - -new GuiControlProfile ( "GuiHudVoiceCommandProfile" ) -{ - fontType = $ShellFont; - fontSize = $ShellFontSize; - fontColor = "40 205 210"; - justify = "left"; - autoSizeWidth = false; - autoSizeHeight = true; -}; - - -new GuiControlProfile ("GuiCommandMsgHudProfile") -{ - fontType = "Univers Condensed"; - fontSize = 16; - fontColor = "253 221 0"; - autoSizeWidth = false; - autoSizeHeight = true; - tab = false; -}; - -new GuiControlProfile ("GuiButtonProfile") -{ - opaque = true; - fillColor = "232 232 232"; - border = true; - borderColor = "0 0 0"; - borderColorHL = "127 127 127"; - fontType = "Univers Condensed"; - fontSize = 16; - fontColor = "0 0 0"; - fontColorHL = "32 100 100"; - fixedExtent = true; - justify = "center"; - soundButtonDown = sButtonDown; - soundButtonOver = sButtonOver; - canKeyFocus = false; -}; - -new GuiControlProfile ("GuiHudCounterProfile") -{ - opaque = true; - fillColor = "232 232 232"; - border = false; - borderColor = "0 0 0"; - borderColorHL = "127 127 127"; - fontType = $ShellFont; - fontSize = 12; - fontColor = "0 0 0"; - fontColorHL = "32 100 100"; - fixedExtent = true; - justify = "center"; -}; - -new GuiControlProfile ("GuiRadioProfile") -{ - opaque = false; - fillColor = "232 232 232"; - border = false; - borderColor = "0 0 0"; - fontType = "Univers"; - fontSize = 14; - fontColor = "0 0 0"; - fontColorHL = "32 100 100"; - fixedExtent = true; - justify = "center"; -}; - -new GuiControlProfile ("GuiCheckBoxProfile") -{ - opaque = false; - fillColor = "232 232 232"; - border = false; - borderColor = "0 0 0"; - fontType = "Univers"; - fontSize = 14; - fontColor = "0 0 0"; - fontColorHL = "32 100 100"; - fixedExtent = true; - justify = "center"; -}; - -new GuiControlProfile ("GuiPopUpMenuProfile") -{ - opaque = true; - fillColor = "232 232 232"; - border = true; - borderColor = "0 0 0"; - fontType = "Univers"; - fontSize = 14; - fontColor = "0 0 0"; - fontColorHL = "32 100 100"; - fontColorSEL = "32 100 100"; - fixedExtent = true; - justify = "center"; -}; - -new GuiControlProfile ("GuiWindowProfile") -{ - opaque = true; - fillColor = "200 200 200"; - fillColorHL = "64 150 150"; - fillColorNA = "150 150 150"; - fontType = "Univers"; - fontSize = 16; - fontColor = "0 0 0"; - fontColorHL = "0 0 0"; - text = "GuiWindowCtrl test"; - bitmap = "gui/darkWindow"; -}; - -new GuiControlProfile ("GuiScrollCtrlProfile") -{ - border = true; - borderColor = "0 0 0"; - bitmap = "gui/darkScroll"; -}; - -new GuiControlProfile ("GuiScrollContentProfile") -{ - opaque = false; - autoSizeWidth = true; - autoSizeHeight = true; - border = false; - -}; - -new GuiControlProfile ("GuiTreeViewProfile") -{ - fontType = "Lucida Console"; - fontSize = 12; - fontColor = "0 0 0"; - fontColorHL = "255 255 255"; - bitmap = "gui/treeView"; -}; - -new GuiControlProfile ("GuiTextArrayProfile") -{ - fontType = "Univers"; - fontSize = 16; - fontColor = "0 0 0"; - fontColorHL = "32 100 100"; - fillColorHL = "200 200 200"; -}; - -new GuiControlProfile ("GuiConsoleProfile") -{ - fontType = "Lucida Console"; - fontSize = 12; - fontColor = "0 0 0"; - fontColorHL = "130 130 130"; - fontColorNA = "255 0 0"; - fontColors[6] = "50 50 50"; - fontColors[7] = "50 50 0"; - fontColors[8] = "0 0 50"; - fontColors[9] = "0 50 0"; -}; - -new GuiControlProfile ("GuiConsoleTextProfile") -{ - fontType = "Lucida Console"; - fontSize = 12; - fontColor = "0 0 0"; - autoSizeWidth = false; - autoSizeHeight = true; -}; - -new GuiControlProfile("GuiMediumBoldTextProfile") -{ - fontType = "Univers Condensed"; - fontSize = 16; - fontColor = "0 0 0"; - autoSizeWidth = true; - autoSizeHeight = true; -}; - -new GuiControlProfile("EditTSControlProfile") -{ - fontType = "Univers"; - fontSize = 16; - fontColor = "200 200 200"; - autoSizeWidth = true; - autoSizeHeight = true; - fillColor = "255 255 0"; - opaque = "true"; -}; - -new GuiControlProfile("EditorContentProfile") -{ - fontType = "Univers"; - fontSize = 16; - fontColor = "200 200 200"; - autoSizeWidth = true; - autoSizeHeight = true; - fillColor = "220 220 220"; - opaque = "true"; - border = true; - borderColor = "180 180 180"; -}; - -new GuiControlProfile ("ShellProgressBarProfile") -{ - opaque = false; - fillColor = "44 152 162 100"; - border = true; - borderColor = "78 88 120"; -}; - -new GuiControlProfile ("ShellProgressBarTextProfile") -{ - fontType = $ShellLabelFont; - fontSize = $ShellLabelFontSize; - fontColor = "169 215 250"; - justify = "center"; -}; - -new GuiControlProfile ("ShellLoadFrameProfile" ) -{ - border = true; - borderColor = "78 88 120"; -}; - -new GuiControlProfile ("ShellSubHeaderProfile" ) -{ - fontType = "Univers Condensed Bold"; - fontSize = 28; - fontColor = "66 219 234"; - justify = "left"; - autoSizeWidth = true; - autoSizeHeight = true; -}; - -new GuiControlProfile( "DlgBackProfile" ) -{ - opaque = true; - fillColor = "0 0 0 160"; -}; - -new GuiControlProfile( "MotdCProfile" ) -{ - justify = "center"; - opaque = true; - autoSizeWidth = true; - fillColor = "0 0 0 160"; - fontType = "Univers Condensed"; - fontSize = 14; - fontColor = "000 219 234"; -}; - -new GuiControlProfile( "GuiInputCtrlProfile" ) -{ - tab = true; - canKeyFocus = true; -}; - -new GuiControlProfile( "TesterProfile" ) -{ - border = true; - borderColor = "255 255 0"; -}; - -new GuiControlProfile ("TaskHudProfile") -{ - fontType = $ShellFont; - fontSize = $ShellFontSize; - fontColor = "66 229 244"; - autoSizeWidth = true; - autoSizeHeight = true; - fontColors[1] = "0 200 0 200"; - fontColors[2] = "200 0 0 200"; - fontColors[3] = "0 0 200 200"; - fontColors[6] = $PlayerNameColor; - fontColors[7] = $TribeTagColor; - fontColors[8] = $SmurfNameColor; - fontColors[9] = $BotNameColor; -}; - -new GuiControlProfile ("TaskHudTextProfile") -{ - fontType = $ShellLabelFont; - fontSize = $ShellFontSize; - fontColor = "66 229 244"; - autoSizeWidth = true; - autoSizeHeight = true; -}; - -new GuiControlProfile ("ShellChatMemberListProfile") -{ - fontType = $ShellFont; - fontSize = $ShellFontSize; - fontColor = "60 180 180"; - fontColorHL = "6 245 215"; - fontColorNA = "128 128 128"; - fontColorSEL = "25 68 56"; - fontColors[4] = "255 255 255"; // nick font color - fontColors[5] = "200 255 255"; // nick highlighted color - fontColors[6] = "0 0 0"; // nick selected color - fontColors[7] = "255 255 0"; // tribe font color - fontColors[8] = "200 255 0"; // tribe highlighted color - fontColors[9] = "0 0 255"; // tribe selected color - bitmapBase = "gui/shll_bar"; - tab = true; - canKeyFocus = true; -}; - -new GuiControlProfile ("GuiChannelVectorProfile") -{ - fontType = $ShellFont; - fontSize = $ShellFontSize; - fontColor = "249 250 194"; // default font color - fontColors[1] = "255 255 255"; // nick font color - fontColors[2] = "255 255 0"; // tribe font color - fontColors[3] = "0 200 0"; // server font color - fontColors[4] = "4 235 105"; // client join/drop, tournament mode - fontColors[5] = "219 200 128"; // gameplay, admin/voting, pack/deployable - fontColors[6] = "77 253 95"; // team chat, spam protection message, client tasks - fontColors[7] = "40 231 240"; // global chat - fontColors[8] = "200 200 50 200"; // used in single player game - fontColors[9] = "66 219 234"; - autoSizeWidth = false; - autoSizeHeight = true; -}; - -new GuiControlProfile ("GuiTempHeatProfile") -{ - fontType = $ShellButtonFont; - fontSize = $ShellFontSize; - fontColor = "230 40 230"; - justify = "center"; -}; - -new GuiControlProfile ("GuiBubblePopupProfile") -{ - border = false; - opaque = true; - fillColor = "3 144 156 200"; -}; - -new GuiControlProfile ("GuiBubbleTextProfile") -{ - fontType = $ShellFont; - fontSize = $ShellMediumFontSize; - fontColor = "100 200 200"; - autoSizeWidth = false; - autoSizeHeight = true; -}; - + +//-------------------------------------------------------------------------- +//-------------------------------------- Cursors +// +new GuiCursor(DefaultCursor) +{ + hotSpot = "1 1"; + bitmapName = "gui/CUR_3darrow"; +}; + +new GuiCursor(ArrowNoCursor) +{ + hotSpot = "1 1"; + bitmapName = "gui/CUR_3darrowno"; +}; + +new GuiCursor(ArrowWaitCursor) +{ + hotSpot = "1 1"; + bitmapName = "gui/CUR_3darrowwait"; +}; + +new GuiCursor(ArrowHelpCursor) +{ + hotSpot = "1 1"; + bitmapName = "gui/CUR_3darrowhelp"; +}; + +new GuiCursor(MoveCursor) +{ + hotSpot = "11 11"; + bitmapName = "gui/CUR_3dmove"; +}; + +new GuiCursor(UpDownCursor) +{ + hotSpot = "5 10"; + bitmapName = "gui/CUR_3dupdown"; +}; + +new GuiCursor(LeftRightCursor) +{ + hotSpot = "9 5"; + bitmapName = "gui/CUR_3dleftright"; +}; + +new GuiCursor(DiagRightCursor) +{ + hotSpot = "8 8"; + bitmapName = "gui/CUR_3ddiagright"; +}; + +new GuiCursor(DiagLeftCursor) +{ + hotSpot = "8 8"; + bitmapName = "gui/CUR_3ddiagleft"; +}; + +new GuiCursor(RotateCursor) +{ + hotSpot = "11 14"; + bitmapName = "gui/CUR_rotate"; +}; + +new GuiCursor(ResizeDownCursor) +{ + hotSpot = "4 8"; + bitmapName = "gui/CUR_3dresizeright"; +}; + +new GuiCursor(GrabCursor) +{ + hotSpot = "9 13"; + bitmapName = "gui/CUR_Grab"; +}; + +//-------------------------------------------------------------------------- +//-------------------------------------- Profiles +// +new GuiControlProfile("GuiDialogProfile"); + +new GuiControlProfile("GuiModelessDialogProfile") +{ + modal = false; +}; + +new GuiControlProfile ("GuiContentProfile") +{ + opaque = true; + fillColor = "255 255 255"; +}; + +new GuiControlProfile ("clockProfile") +{ + fontType = "Univers Condensed"; + fontSize = 12; + fontColor = "255 255 255"; +}; + +new GuiControlProfile ("SiegeHalftimeClockProfile") +{ + fontType = "Univers Condensed"; + fontSize = 18; + fontColor = "255 255 255"; +}; + +new GuiControlProfile ("GuiContentProfileNoClear") +{ + opaque = false; + fillColor = "255 255 255"; +}; + +//-------------------------------------------------------------------------- +// Base font definitions: +//-------------------------------------------------------------------------- +$ShellFont = "Univers"; +$ShellFontSize = 16; +$ShellMediumFontSize = 18; +$ShellHeaderFont = "Sui Generis"; +$ShellHeaderFontSize = 22; +$ShellButtonFont = "Univers Condensed"; +$ShellButtonFontSize = 16; +$ShellLabelFont = "Univers Condensed"; +$ShellLabelFontSize = 18; +$ShellBoldFont = "Univers Bold"; + +$ShellColorBright = "173 255 250"; +$ShellColorDark = "130 190 185"; +$ShellColorVeryDark = "0 117 133"; + +// Color coding system for Player names in the game: +$PlayerNameColor = "200 200 200"; +$TribeTagColor = "220 220 20"; +$SmurfNameColor = "150 150 250"; +$BotNameColor = "60 220 150"; + +//-------------------------------------------------------------------------- +// Beginning of the "New Shell" section: +new GuiControlProfile ("ShellButtonProfile") +{ + fontType = $ShellButtonFont; + fontSize = $ShellButtonFontSize; + fontColor = "8 19 6"; + fontColorHL = "25 68 56"; + fontColorNA = "5 5 5"; + fontColorSEL = "25 68 56"; + fixedExtent = true; + justify = "center"; + bitmap = "gui/shll_button"; + textOffset = "0 10"; + soundButtonDown = sButtonDown; + soundButtonOver = sButtonOver; + tab = true; + canKeyFocus = true; +}; + +new GuiControlProfile ("ShellButtonNoTabProfile") +{ + fontType = $ShellButtonFont; + fontSize = $ShellButtonFontSize; + fontColor = "8 19 6"; + fontColorHL = "25 68 56"; + fontColorNA = "5 5 5"; + fontColorSEL = "25 68 56"; + fixedExtent = true; + justify = "center"; + bitmap = "gui/shll_button"; + textOffset = "0 10"; + soundButtonDown = sButtonDown; + soundButtonOver = sButtonOver; + tab = false; + canKeyFocus = true; +}; + +new GuiControlProfile ("ShellRadioProfile") +{ + fontType = $ShellButtonFont; + fontSize = $ShellButtonFontSize; + fontColor = "8 19 6"; + fontColorHL = "25 68 56"; + fontColorNA = "5 5 5"; + fixedExtent = true; + justify = "center"; + bitmap = "gui/shll_radio"; + soundButtonDown = sButtonDown; + soundButtonOver = sButtonOver; + tab = true; + canKeyFocus = true; +}; + +new GuiControlProfile ("ShellTabProfile") +{ + fontType = $ShellButtonFont; + fontSize = $ShellButtonFontSize; + fontColor = "8 19 6"; + fontColorHL = "25 68 56"; + fontColorNA = "5 5 5"; + fontColorSEL = "8 19 6"; + fixedExtent = true; + justify = "center"; + bitmap = "gui/shll_tabbutton"; + soundButtonDown = sButtonDown; + soundButtonOver = sButtonOver; + tab = true; + canKeyFocus = true; +}; + +new GuiControlProfile ("TabGroupProfile") +{ + fontType = $ShellButtonFont; + fontSize = $ShellButtonFontSize; + fontColor = "8 19 6"; + fontColorHL = "25 68 56"; + fontColorNA = "5 5 5"; + fontColorSEL = "8 19 6"; + fixedExtent = true; + bitmapBase = "gui/shll_horztabbutton"; + justify = "center"; + textOffset = "8 0"; + soundButtonDown = sButtonDown; + soundButtonOver = sButtonOver; + tab = true; + canKeyFocus = true; +}; + +new GuiControlProfile ("LaunchTabProfile") +{ + fontType = $ShellButtonFont; + fontSize = $ShellButtonFontSize; + fontColor = "60 140 140"; + fontColorHL = "6 245 215"; + fontColorNA = "64 64 64"; + fontColorSEL = "6 245 215"; + fixedExtent = true; + bitmapBase = "gui/lnch_tab"; + justify = "center"; + textOffset = "8 0"; + soundButtonDown = sButtonDown; + soundButtonOver = sButtonOver; + tab = true; + canKeyFocus = true; +}; + +new GuiControlProfile ("ShellTabFrameProfile") +{ + bitmapBase = "gui/shll_tabframe"; +}; + +new GuiControlProfile ("ShellHorzTabFrameProfile") +{ + bitmapBase = "gui/shll_horztabframe"; +}; + +new GuiControlProfile ("ShellPopupProfile") +{ + fontType = $ShellFont; + fontSize = $ShellFontSize; + fontColor = "8 19 6"; + fontColorHL = "25 68 56"; + fontColorNA = "5 5 5"; + fontColorSEL = "8 19 6"; + fixedExtent = true; + justify = "center"; + soundButtonDown = sButtonDown; + soundButtonOver = sButtonOver; + bitmapBase = "gui/shll_scroll"; + tab = true; + canKeyFocus = true; +}; + +new GuiControlProfile ("NewTextEditProfile") +{ + fillColorHL = $ShellColorDark; + fontType = $ShellFont; + fontSize = $ShellFontSize; + fontColor = "60 140 140"; + fontColorHL = "25 68 56"; + fontColorNA = "128 128 128"; + cursorColor = $ShellColorBright; + bitmap = "gui/shll_entryfield"; + textOffset = "14 0"; + autoSizeWidth = false; + autoSizeHeight = false; + tab = true; + canKeyFocus = true; +}; + +new GuiControlProfile ("NewTextEditNumericProfile") +{ + fillColorHL = $ShellColorDark; + fontType = $ShellFont; + fontSize = $ShellFontSize; + fontColor = "60 140 140"; + fontColorHL = "25 68 56"; + fontColorNA = "128 128 128"; + cursorColor = $ShellColorBright; + bitmap = "gui/shll_entryfield"; + justify = "center"; + textOffset = "14 0"; + autoSizeWidth = false; + autoSizeHeight = false; + numbersOnly = true; + tab = true; + canKeyFocus = true; +}; + +new GuiControlProfile ("NewTextEditCenterProfile") +{ + fillColorHL = $ShellColorDark; + fontType = $ShellFont; + fontSize = $ShellFontSize; + fontColor = "60 140 140"; + fontColorHL = "25 68 56"; + fontColorNA = "128 128 128"; + cursorColor = $ShellColorBright; + bitmap = "gui/shll_entryfield"; + justify = "center"; + autoSizeWidth = false; + autoSizeHeight = false; + tab = true; + canKeyFocus = true; +}; + +new GuiControlProfile ("NewScrollCtrlProfile") +{ + bitmapBase = "gui/shll_scroll"; + soundButtonDown = sButtonDown; + soundButtonOver = sButtonOver; +}; + +new GuiControlProfile ("ShellFieldProfile") +{ + bitmapBase = "gui/shll_field"; +}; + +new GuiControlProfile ("ShellSliderProfile") +{ + fontType = $ShellLabelFont; + fontSize = $ShellFontSize; + fontColor = "60 180 180"; + fontColorNA = "128 128 128"; + bitmapBase = "gui/shll_scroll"; + canKeyFocus = true; + soundButtonOver = sButtonOver; +}; + +new GuiControlProfile ("ShellTextArrayProfile") +{ + fontType = $ShellFont; + fontSize = $ShellFontSize; + fontColor = "60 180 180"; + fontColorHL = "6 245 215"; + fontColorNA = "108 108 108"; + fontColorSEL = "25 68 56"; + bitmapBase = "gui/shll_bar"; + tab = true; + canKeyFocus = true; +}; + +new GuiControlProfile ("ShellActiveTextProfile") +{ + fontType = $ShellFont; + fontSize = $ShellFontSize; + fontColor = "60 180 180"; + fontColorHL = "6 245 215"; + fontColorNA = "128 128 128"; + fontColorSEL = "25 68 56"; + justify = "center"; +}; + +new GuiControlProfile ("ShellPaneProfile") +{ + fontType = $ShellHeaderFont; + fontSize = $ShellHeaderFontSize; + fontColor = "5 5 5"; + autoSizeWidth = false; + autoSizeHeight = false; + bitmapBase = "gui/shll"; +}; + +new GuiControlProfile ("ShellDlgPaneProfile") +{ + fontType = $ShellHeaderFont; + fontSize = $ShellHeaderFontSize; + fontColor = "5 5 5"; + autoSizeWidth = false; + autoSizeHeight = false; + bitmapBase = "gui/dlg"; +}; + +new GuiControlProfile ("ShellWindowProfile") +{ + borderColor = "3 124 134"; + fontType = $ShellHeaderFont; + fontSize = $ShellHeaderFontSize; + fontColor = "5 5 5"; + autoSizeWidth = false; + autoSizeHeight = false; + bitmapBase = "gui/dlg"; + soundButtonDown = sButtonDown; + soundButtonOver = sButtonOver; +}; + +new GuiControlProfile ("ShellDlgProfile") +{ + fontType = $ShellHeaderFont; + fontSize = $ShellHeaderFontSize; + fontColor = "5 5 5"; + bitmap = "gui/dlg_box"; + autoSizeWidth = false; + autoSizeHeight = false; +}; + +new GuiControlProfile ("BrowserH1Profile") +{ + fontType = "Univers Condensed Bold"; + fontSize = 28; + fontColor = "40 247 113"; // green + autoSizeWidth = false; + autoSizeHeight = true; + bitmapBase = "gui/shll"; +}; + +new GuiControlProfile ("CloseButtonProfile") +{ + bitmap = "gui/shll_menuclose"; + soundButtonDown = sButtonDown; + soundButtonOver = sButtonOver; + tab = true; + canKeyFocus = true; +}; + +new GuiControlProfile ("SoundTestButtonProfile") +{ + bitmap = "gui/shll_soundbutton"; + soundButtonOver = sButtonOver; + tab = true; + canKeyFocus = true; +}; + +new GuiControlProfile ("LaunchMenuProfile") +{ + fontType = $ShellFont; + fontSize = $ShellFontSize; + fontColor = "6 245 215"; + fontColorHL = "74 251 228"; + fontColorSEL = "4 41 45"; + borderColor = "84 121 125 200"; + fixedExtent = true; + justify = "center"; + bitmapBase = "gui/launch_btn"; + textOffset = "0 19"; + soundButtonDown = sLaunchMenuOpen; + soundButtonOver = sLaunchMenuOver; + tab = true; + canKeyFocus = true; +}; + +new GuiControlProfile ("LaunchBtnTopProfile") +{ + fixedExtent = true; + bitmapBase = "gui/launchtop_btn"; +}; + +new GuiControlProfile ("ShellServerBrowserProfile") +{ + fontType = $ShellFont; + fontSize = $ShellFontSize; + fontColor = "60 180 180"; + fontColorHL = "6 245 215"; + fontColorNA = "128 128 128"; + fontColorSEL = "25 68 56"; + fontColors[4] = "20 167 93"; // Mod base color + fontColors[5] = "40 217 113"; // Mod rollover color + fontColors[6] = "5 60 30"; // Mod selected color + fontColors[7] = "108 108 108"; // Differing build base color + fontColors[8] = "168 168 168"; // Differing build rollover color + fontColors[9] = "58 58 58"; // Differing build selected color + bitmapBase = "gui/shll_scroll"; + soundButtonDown = sButtonDown; + soundButtonOver = sButtonOver; + tab = true; + canKeyFocus = true; +}; + +new GuiControlProfile ("ShellBrowserListProfile") +{ + fontType = $ShellFont; + fontSize = 12; + fontColor = "20 220 20"; + fontColorHL = "60 250 60"; + fontColorNA = "128 128 128"; + fontColorSEL = "0 60 0"; + soundButtonDown = sButtonDown; + soundButtonOver = sButtonOver; + tab = true; + canKeyFocus = true; +}; + +new GuiControlProfile ("LobbyPlayerListProfile") +{ + fontType = $ShellFont; + fontSize = $ShellFontSize; + fontColor = "60 180 180"; + fontColorHL = "6 245 215"; + fontColorNA = "128 128 128"; + fontColorSEL = "25 68 56"; + fontColors[6] = $PlayerNameColor; + fontColors[7] = $TribeTagColor; + fontColors[8] = $SmurfNameColor; + fontColors[9] = $BotNameColor; + bitmapBase = "gui/shll_scroll"; + soundButtonDown = sButtonDown; + soundButtonOver = sButtonOver; + tab = true; + canKeyFocus = true; +}; + +new GuiControlProfile ("ShellBrowserTitleProfile") +{ + fontType = "Sui Generis"; + fontSize = 32; + fontColor = "173 255 250"; + autoSizeWidth = true; + autoSizeHeight = true; + tab = false; + canKeyFocus = false; +}; +//-------------------------------------------------------------------------- +// End of "New Shell" section. + +new GuiControlProfile ("ShellHoloButtonProfile") +{ + opaque = true; + fillColor = $ShellColorVeryDark; + fillColorNA = "128 128 128"; + border = true; + borderColor = $ShellColorBright; + borderColorHL = "127 127 127"; + borderColorNA = "192 192 192"; + fontType = "Univers"; + fontSize = 14; + fontColor = $ShellColorBright; + fontColorHL = $ShellColorDark; + fontColorNA = "192 192 192"; + fixedExtent = true; + justify = "center"; + soundButtonDown = sButtonDown; + soundButtonOver = sButtonOver; + tab = true; + canKeyFocus = true; +}; + +new GuiControlProfile ("GameHoloButtonProfile") +{ + opaque = true; + fillColor = "0 64 0 80"; + border = true; + borderColor = "0 255 0"; + borderColorHL = "127 127 127"; + fontType = "Univers"; + fontSize = 14; + fontColor = "0 255 0"; + fontColorHL = "0 128 0"; + fixedExtent = true; + justify = "center"; + soundButtonDown = sButtonDown; + soundButtonOver = sButtonOver; + tab = true; +}; + +new GuiControlProfile ("ShellHoloBox") +{ + opaque = true; + fillColor = "72 72 72 128"; + border = true; + borderColor = $ShellColorBright; +}; + +new GuiControlProfile ("TaskHudBox") +{ + opaque = true; + fillColor = "72 72 72 128"; + border = true; + borderColor = "30 59 56 80"; +}; + +new GuiControlProfile ("ShellOpaqueBox") +{ + opaque = true; + fillColor = $ShellColorVeryDark; + border = true; + borderColor = $ShellColorBright; +}; + +new GuiControlProfile ("ShellScrollCtrlProfile") +{ + border = true; + borderColor = $ShellColorBright; + bitmap = "gui/shellScroll"; +}; + +new GuiControlProfile ("ShellTextProfile") +{ + fontType = $ShellLabelFont; + fontSize = $ShellLabelFontSize; + fontColor = "66 229 244"; + autoSizeWidth = true; + autoSizeHeight = true; +}; + +new GuiControlProfile ("ShellTextRightProfile") +{ + fontType = $ShellLabelFont; + fontSize = $ShellLabelFontSize; + fontColor = "66 229 244"; + justify = "right"; + autoSizeWidth = false; + autoSizeHeight = true; +}; + +new GuiControlProfile ("ShellTextCenterProfile") +{ + fontType = $ShellLabelFont; + fontSize = $ShellLabelFontSize; + fontColor = "66 229 244"; + justify = "center"; + autoSizeWidth = false; + autoSizeHeight = true; +}; + +new GuiControlProfile ("DisabledTextProfile") +{ + fontType = $ShellLabelFont; + fontSize = $ShellLabelFontSize; + fontColor = "128 128 128"; + autoSizeWidth = true; + autoSizeHeight = true; +}; + +new GuiControlProfile ("DisabledTextRightProfile") +{ + fontType = $ShellLabelFont; + fontSize = $ShellLabelFontSize; + fontColor = "128 128 128"; + justify = "right"; + autoSizeWidth = false; + autoSizeHeight = true; +}; + +new GuiControlProfile ("ShellAltTextProfile") +{ + fontType = $ShellFont; + fontSize = $ShellFontSize; + fontColor = "66 219 234"; + autoSizeWidth = true; + autoSizeHeight = true; +}; + +new GuiControlProfile ("ShellAltTextRightProfile") +{ + fontType = $ShellFont; + fontSize = $ShellFontSize; + fontColor = "66 219 234"; + justify = "right"; + autoSizeWidth = false; + autoSizeHeight = true; +}; + +new GuiControlProfile ("ShellAltTextCenterProfile") +{ + fontType = $ShellFont; + fontSize = $ShellFontSize; + fontColor = "66 219 234"; + justify = "center"; + autoSizeWidth = false; + autoSizeHeight = true; +}; + +new GuiControlProfile ("ShellStaticTextProfile") +{ + fontType = $ShellFont; + fontSize = $ShellFontSize; + fontColor = "66 219 234"; + autoSizeWidth = false; + autoSizeHeight = true; +}; + +new GuiControlProfile ("VersionTextProfile") +{ + fontType = "Univers Bold"; + fontSize = $ShellMediumFontSize; + fontColor = "0 0 0"; + justify = "right"; + autoSizeWidth = false; + autoSizeHeight = true; +}; + +new GuiControlProfile ("CenterPrintTextProfile") +{ + fontType = $ShellFont; + fontSize = $ShellMediumFontSize; + fontColor = $ShellColorBright; + autoSizeWidth = false; + autoSizeHeight = true; +}; + + +new GuiControlProfile ("ShellEditMOTDTextProfile") +{ + fontType = $ShellFont; + fontSize = $ShellFontSize; + fontColor = "66 219 234"; + fontColorHL = "25 68 56"; + fillColorHL = "50 233 206"; + cursorColor = "200 240 240"; + autoSizeWidth = false; + autoSizeHeight = false; + tab = true; + canKeyFocus = true; +}; + +new GuiControlProfile ("ShellTopicTextProfile") +{ + fontType = $ShellFont; + fontSize = $ShellMediumFontSize; + fontColor = "100 200 200"; + autoSizeWidth = false; + autoSizeHeight = true; +}; + +new GuiControlProfile ("BrowserFilterLabelProfile") +{ + fontType = $ShellLabelFont; + fontSize = 22; + fontColor = "0 220 0"; + justify = "left"; + autoSizeWidth = true; + autoSizeHeight = true; +}; + +new GuiControlProfile ("BrowserFilterTextProfile") +{ + fontType = $ShellLabelFont; + fontSize = 22; + fontColor = "66 219 234"; + justify = "left"; + autoSizeWidth = true; + autoSizeHeight = true; +}; + +new GuiControlProfile ("BrowserStatusTextProfile") +{ + fontType = $ShellLabelFont; + fontSize = 22; + fontColor = "66 219 234"; + justify = "right"; + autoSizeWidth = false; + autoSizeHeight = true; +}; + +new GuiControlProfile ("BrowserProgressProfile") +{ + opaque = false; + fillColor = "79 253 181 180"; + border = true; + borderColor = "3 124 134"; +}; + +new GuiControlProfile ("InfoWindowProfile") +{ + fontType = $ShellFont; + fontSize = $ShellFontSize; + fontColor = "66 219 234"; + fontColors[6] = $PlayerNameColor; + fontColors[7] = $TribeTagColor; + fontColors[8] = $SmurfNameColor; + fontColors[9] = $BotNameColor; + autoSizeWidth = true; + autoSizeHeight = true; +}; + +new GuiControlProfile ("ShellMessageTextProfile") +{ + fontType = $ShellFont; + fontSize = $ShellMediumFontSize; + fontColor = "66 219 234"; + fontColorHL = "25 68 56"; + fillColorHL = "50 233 206"; + cursorColor = "200 240 240"; + autoSizeWidth = false; + autoSizeHeight = false; + tab = true; + canKeyFocus = true; +}; + +new GuiControlProfile ("ShellLoadTextProfile") +{ + fontType = $ShellFont; + fontSize = $ShellMediumFontSize; + fontColor = "66 219 234"; + autoSizeWidth = true; + autoSizeHeight = true; +}; + +new GuiControlProfile ("ShellLargeLabelProfile" ) +{ + fontType = $ShellLabelFont; + fontSize = 22; + fontColor = "60 180 180"; + autoSizeWidth = false; + autoSizeHeight = true; +}; + +new GuiControlProfile ("ShellMediumTextProfile") +{ + fontType = $ShellFont; + fontSize = $ShellMediumFontSize; + fontColor = $ShellColorBright; + autoSizeWidth = true; + autoSizeHeight = true; +}; + +new GuiControlProfile ("ShellMediumTextCenterProfile") +{ + fontType = $ShellFont; + fontSize = $ShellMediumFontSize; + fontColor = $ShellColorBright; + autoSizeWidth = false; + autoSizeHeight = true; + justify = "center"; +}; + +new GuiControlProfile ("DebriefHeadlineTextProfile") +{ + fontType = $ShellLabelFont; + fontSize = 28; + fontColor = $ShellColorBright; + autoSizeWidth = false; + autoSizeHeight = true; + tab = false; + canKeyFocus = false; +}; + +new GuiControlProfile ("DebriefTextProfile") +{ + fontType = $ShellFont; + fontSize = $ShellMediumFontSize; + fontColor = "60 180 180"; + fontColors[6] = $PlayerNameColor; + fontColors[7] = $TribeTagColor; + fontColors[8] = $SmurfNameColor; + fontColors[9] = $BotNameColor; + autoSizeWidth = false; + autoSizeHeight = false; + tab = false; + canKeyFocus = false; +}; + +new GuiControlProfile ("ScoreHeaderTextProfile") +{ + fontType = $ShellLabelFont; + fontSize = 28; + fontColor = "0 255 255"; + autoSizeWidth = false; + autoSizeHeight = true; + tab = false; + canKeyFocus = false; +}; + +new GuiControlProfile ("ScoreSubheaderTextProfile") +{ + fontType = $ShellLabelFont; + fontSize = 22; + fontColor = "0 255 255"; + autoSizeWidth = false; + autoSizeHeight = true; + tab = false; + canKeyFocus = false; +}; + +new GuiControlProfile ("ScoreTextProfile") +{ + fontType = $ShellFont; + fontSize = $ShellMediumFontSize; + fontColor = "0 220 220"; + autoSizeWidth = false; + autoSizeHeight = false; + tab = false; + canKeyFocus = false; +}; + +new GuiControlProfile ("ShellTreeViewProfile") +{ + fontType = $ShellFont; + fontSize = $ShellFontSize; + fontColor = "6 245 215"; + fontColorHL = "6 245 215"; + fontColorSEL = "25 68 56"; + bitmapBase = "gui/shll_bar"; + tab = true; + canKeyFocus = true; +}; + +new GuiControlProfile ("ShellBigTextProfile") +{ + fontType = $ShellHeaderFont; + fontSize = $ShellHeaderFontSize; + fontColor = $ShellColorBright; + autoSizeWidth = true; + autoSizeHeight = true; +}; + +new GuiControlProfile ("HudScoreListProfile") +{ + fontType = $ShellFont; + fontSize = $ShellMediumFontSize; + fontColor = "60 180 180"; +}; + +new GuiControlProfile ("GuiHelpBoxProfile") +{ + border = false; + //borderColor = "3 144 156"; + opaque = true; + fillColor = "3 144 156 86"; +}; + +new GuiControlProfile ("GuiHelpTextProfile") +{ + fontType = $ShellFont; + fontSize = $ShellFontSize; + fontColor = "169 215 250"; + autoSizeWidth = false; + autoSizeHeight = false; + justify = "left"; +}; + +new GuiControlProfile ("GuiHelpHeaderProfile") +{ + fontType = $ShellLabelFont; + fontSize = $ShellLabelFontSize; + fontColor = "169 215 250"; + autoSizeWidth = true; + autoSizeHeight = true; + justify = "left"; +}; + +new GuiControlProfile ("GuiVoiceRedProfile") +{ + fontType = $ShellFont; + fontSize = $ShellFontSize; + fontColor = "180 0 0"; + justify = "left"; +}; + +new GuiControlProfile ("GuiVoiceGreenProfile") +{ + fontType = $ShellFont; + fontSize = $ShellFontSize; + fontColor = "0 180 0"; + justify = "left"; +}; + +new GuiControlProfile( "GuiDeathMsgHudProfile" ) +{ + opaque = false; + border = false; + //borderColor = "255 255 0 128"; +}; + +new GuiControlProfile ("GuiTextProfile") +{ + fontType = "Univers"; + fontSize = 16; + fontColor = "0 0 0"; + autoSizeWidth = true; + autoSizeHeight = true; +}; + +new GuiControlProfile ("GuiCenterTextProfile") +{ + fontType = "Univers"; + fontSize = 16; + fontColor = "0 0 0"; + fixedExtent = true; + justify = "center"; +}; + +new GuiControlProfile ("GuiBigTextProfile") +{ + fontType = "Times"; + fontSize = 36; + fontColor = "0 0 0"; + autoSizeWidth = true; + autoSizeHeight = true; +}; + +new GuiControlProfile ("GuiBigTextProfileWhite") +{ + fontType = "Times"; + fontSize = 24; + + fontColor = " 0 0 0"; + fillColor = "255 255 255"; + + fontColorHL = "255 255 255"; + fillColorHL = "0 0 0"; + + autoSizeWidth = true; + autoSizeHeight = true; + + opaque = true; +}; + +new GuiControlProfile("GuiBorderProfile") +{ + border = "true"; + borderColor = "40 205 170"; + opaque = true; + fillColor = "0 64 100 80"; +}; + +new GuiControlProfile("ZoomHudProfile") +{ + border = "true"; + borderColor = "40 205 170"; + opaque = false; + fillColor = "0 64 100 80"; +}; + +new GuiControlProfile("GuiDashBoxProfile") +{ + border = "false"; + opaque = false; +}; + +new GuiControlProfile("GuiDashTextProfile") +{ + fontType = "Univers Condensed"; + fontSize = 16; + fontColor = "154 208 253"; + justify = "center"; +}; + +new GuiControlProfile ("GuiTextBGLeftProfile") +{ + fontType = "Univers Condensed"; + fontSize = 20; + fontColor = "70 235 200"; + justify = "center"; +}; + +new GuiControlProfile ("GuiTextBGCenterProfile") +{ + fontType = "Univers"; + fontSize = 16; + fontColor = "70 235 200"; + justify = "center"; +}; + +new GuiControlProfile ("GuiTextBGRightProfile") +{ + fontType = "Univers"; + fontSize = 16; + fontColor = "70 235 200"; + justify = "right"; +}; + +new GuiControlProfile ("GuiTextBGWhiteRightProfile") +{ + fontType = "Univers Condensed"; + fontSize = 16; + fontColor = "90 255 220"; + justify = "right"; +}; + +new GuiControlProfile ("GuiHelpLineProfile") +{ + borderColor = "231 101 26"; + bitmap = "gui/hud_dot"; +}; + +new GuiControlProfile ("GuiTextObjHudCenterProfile") +{ + fontType = "Univers Condensed"; + fontSize = 16; + fontColor = "169 215 250"; + fontColors[6] = $PlayerNameColor; + fontColors[7] = $TribeTagColor; + fontColors[8] = $SmurfNameColor; + fontColors[9] = $BotNameColor; + justify = "center"; +}; + +new GuiControlProfile ("GuiTextObjHudLeftProfile") +{ + fontType = "Univers Condensed"; + fontSize = 16; + fontColor = "169 215 250"; + fontColors[6] = $PlayerNameColor; + fontColors[7] = $TribeTagColor; + fontColors[8] = $SmurfNameColor; + fontColors[9] = $BotNameColor; + justify = "left"; +}; + +new GuiControlProfile ("GuiTextObjGreenLeftProfile") +{ + fontType = "Univers Condensed"; + fontSize = 16; + fontColor = "23 236 67"; + fontColors[6] = $PlayerNameColor; + fontColors[7] = $TribeTagColor; + fontColors[8] = $SmurfNameColor; + fontColors[9] = $BotNameColor; + justify = "left"; +}; + +new GuiControlProfile ("GuiTextObjGreenCenterProfile") +{ + fontType = "Univers Condensed"; + fontSize = 16; + fontColor = "23 236 67"; + fontColors[6] = $PlayerNameColor; + fontColors[7] = $TribeTagColor; + fontColors[8] = $SmurfNameColor; + fontColors[9] = $BotNameColor; + justify = "center"; +}; + +new GuiControlProfile ("DeathMsgTextProfile") +{ + fontType = "Univers"; + fontSize = 14; + fontColor = "40 247 113"; // green + justify = "left"; +}; + +new GuiControlProfile("DebuggerWindowProfile") { + border = "true"; + borderColor = "255 255 255"; + opaque = "true"; + fillColor = "0 0 0"; +}; + +new GuiControlProfile ("GuiTextEditProfile") +{ + opaque = true; + fillColor = "255 255 255"; + fillColorHL = "128 128 128"; + border = true; + borderColor = "0 0 0"; + fontType = "Lucida Console"; + fontSize = 12; + fontColor = "0 0 0"; + fontColorHL = "255 255 255"; + fontColorNA = "128 128 128"; + textOffset = "0 2"; + autoSizeWidth = false; + autoSizeHeight = true; + tab = true; + canKeyFocus = true; +}; + +new GuiControlProfile ("GuiInspectorTextEditProfile") +{ + opaque = true; + fillColor = "255 255 255"; + fillColorHL = "128 128 128"; + border = true; + borderColor = "0 0 0"; + fontType = "Univers"; + fontSize = 16; + fontColor = "0 0 0"; + fontColorHL = "255 255 255"; + autoSizeWidth = false; + autoSizeHeight = true; + tab = false; + canKeyFocus = true; +}; + +new GuiControlProfile ("GuiMessageEditHudProfile") +{ + fontType = "verdana"; + fontSize = 14; + fontColor = "255 255 0"; + cursorColor = "255 205 0"; + autoSizeWidth = false; + autoSizeHeight = true; + tab = false; + canKeyFocus = true; +}; + +new GuiControlProfile ("GuiMessageEditHudTextProfile") +{ + fontType = "verdana"; + fontSize = 14; + fontColor = "255 255 255"; + autoSizeWidth = true; + autoSizeHeight = true; + tab = false; +}; + +new GuiControlProfile("GuiAmmoHudProfile") +{ + fontType = "Univers Condensed"; + fontSize = 16; + fontColor = "169 215 250"; + autoSizeWidth = false; + autoSizeHeight = true; +}; + +new GuiControlProfile("GuiPackTextProfile") +{ + fontType = "Univers"; + fontSize = 12; + fontColor = "169 215 250"; + justify = "center"; + autoSizeWidth = false; + autoSizeHeight = true; +}; + +new GuiControlProfile("GuiTempSpeedProfile") +{ + fontType = "Univers Condensed"; + fontSize = 16; + fontColor = "240 0 240"; + autoSizeWidth = false; + autoSizeHeight = true; +}; + +new GuiControlProfile("GuiRecordingHudProfile") +{ + fontType = "Univers Condensed"; + fontSize = 16; + fontColor = "255 0 0"; + justify = "center"; + autoSizeWidth = false; + autoSizeHeight = true; +}; + +new GuiControlProfile ("GuiChatBackProfile") +{ + bitmapbase = "gui/hud_new_window"; +}; + +new GuiControlProfile ("HudScoreProfile") +{ + bitmap = "gui/hud_new_scorewindow"; + borderColor = "30 59 56"; +}; + +new GuiControlProfile ("HudHelpTagProfile") +{ + borderColor = "231 101 26"; + bitmap = "gui/hud_dot"; +}; + +new GuiControlProfile ("HudVoteBackProfile") +{ + bitmapBase = "gui/hud_new_window_B"; +}; + +new GuiControlProfile ("GuiVMenuProfile") +{ + bitmapBase = "gui/hud_new_window"; + fontType = $ShellFont; + fontSize = $ShellMediumFontSize; +}; + +new GuiControlProfile ("GuiChatHudProfile") +{ + fontType = $ShellFont; + fontSize = $ShellFontSize; + 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; +}; + +new GuiControlProfile ("GuiHudNavProfile") +{ +// fontType = "Univers Condensed"; +// fontSize = 16; +// fontColor = "255 255 255"; +// autoSizeWidth = false; +// autoSizeHeight = true; + fontColors[6] = $PlayerNameColor; + fontColors[7] = $TribeTagColor; + fontColors[8] = $SmurfNameColor; + fontColors[9] = $BotNameColor; +}; + +new GuiControlProfile ( "GuiHudVoiceMenuProfile" ) +{ + fontType = $ShellFont; + fontSize = $ShellFontSize; + fontColor = "70 235 200"; + justify = "left"; + autoSizeWidth = false; + autoSizeHeight = true; +}; + +new GuiControlProfile ( "GuiHudVoiceCommandProfile" ) +{ + fontType = $ShellFont; + fontSize = $ShellFontSize; + fontColor = "40 205 210"; + justify = "left"; + autoSizeWidth = false; + autoSizeHeight = true; +}; + + +new GuiControlProfile ("GuiCommandMsgHudProfile") +{ + fontType = "Univers Condensed"; + fontSize = 16; + fontColor = "253 221 0"; + autoSizeWidth = false; + autoSizeHeight = true; + tab = false; +}; + +new GuiControlProfile ("GuiButtonProfile") +{ + opaque = true; + fillColor = "232 232 232"; + border = true; + borderColor = "0 0 0"; + borderColorHL = "127 127 127"; + fontType = "Univers Condensed"; + fontSize = 16; + fontColor = "0 0 0"; + fontColorHL = "32 100 100"; + fixedExtent = true; + justify = "center"; + soundButtonDown = sButtonDown; + soundButtonOver = sButtonOver; + canKeyFocus = false; +}; + +new GuiControlProfile ("GuiHudCounterProfile") +{ + opaque = true; + fillColor = "232 232 232"; + border = false; + borderColor = "0 0 0"; + borderColorHL = "127 127 127"; + fontType = $ShellFont; + fontSize = 12; + fontColor = "0 0 0"; + fontColorHL = "32 100 100"; + fixedExtent = true; + justify = "center"; +}; + +new GuiControlProfile ("GuiRadioProfile") +{ + opaque = false; + fillColor = "232 232 232"; + border = false; + borderColor = "0 0 0"; + fontType = "Univers"; + fontSize = 14; + fontColor = "0 0 0"; + fontColorHL = "32 100 100"; + fixedExtent = true; + justify = "center"; +}; + +new GuiControlProfile ("GuiCheckBoxProfile") +{ + opaque = false; + fillColor = "232 232 232"; + border = false; + borderColor = "0 0 0"; + fontType = "Univers"; + fontSize = 14; + fontColor = "0 0 0"; + fontColorHL = "32 100 100"; + fixedExtent = true; + justify = "center"; +}; + +new GuiControlProfile ("GuiPopUpMenuProfile") +{ + opaque = true; + fillColor = "232 232 232"; + border = true; + borderColor = "0 0 0"; + fontType = "Univers"; + fontSize = 14; + fontColor = "0 0 0"; + fontColorHL = "32 100 100"; + fontColorSEL = "32 100 100"; + fixedExtent = true; + justify = "center"; +}; + +new GuiControlProfile ("GuiWindowProfile") +{ + opaque = true; + fillColor = "200 200 200"; + fillColorHL = "64 150 150"; + fillColorNA = "150 150 150"; + fontType = "Univers"; + fontSize = 16; + fontColor = "0 0 0"; + fontColorHL = "0 0 0"; + text = "GuiWindowCtrl test"; + bitmap = "gui/darkWindow"; +}; + +new GuiControlProfile ("GuiScrollCtrlProfile") +{ + border = true; + borderColor = "0 0 0"; + bitmap = "gui/darkScroll"; +}; + +new GuiControlProfile ("GuiScrollContentProfile") +{ + opaque = false; + autoSizeWidth = true; + autoSizeHeight = true; + border = false; + +}; + +new GuiControlProfile ("GuiTreeViewProfile") +{ + fontType = "Lucida Console"; + fontSize = 12; + fontColor = "0 0 0"; + fontColorHL = "255 255 255"; + bitmap = "gui/treeView"; +}; + +new GuiControlProfile ("GuiTextArrayProfile") +{ + fontType = "Univers"; + fontSize = 16; + fontColor = "0 0 0"; + fontColorHL = "32 100 100"; + fillColorHL = "200 200 200"; +}; + +new GuiControlProfile ("GuiConsoleProfile") +{ + fontType = "Lucida Console"; + fontSize = 12; + fontColor = "0 0 0"; + fontColorHL = "130 130 130"; + fontColorNA = "255 0 0"; + fontColors[6] = "50 50 50"; + fontColors[7] = "50 50 0"; + fontColors[8] = "0 0 50"; + fontColors[9] = "0 50 0"; +}; + +new GuiControlProfile ("GuiConsoleTextProfile") +{ + fontType = "Lucida Console"; + fontSize = 12; + fontColor = "0 0 0"; + autoSizeWidth = false; + autoSizeHeight = true; +}; + +new GuiControlProfile("GuiMediumBoldTextProfile") +{ + fontType = "Univers Condensed"; + fontSize = 16; + fontColor = "0 0 0"; + autoSizeWidth = true; + autoSizeHeight = true; +}; + +new GuiControlProfile("EditTSControlProfile") +{ + fontType = "Univers"; + fontSize = 16; + fontColor = "200 200 200"; + autoSizeWidth = true; + autoSizeHeight = true; + fillColor = "255 255 0"; + opaque = "true"; +}; + +new GuiControlProfile("EditorContentProfile") +{ + fontType = "Univers"; + fontSize = 16; + fontColor = "200 200 200"; + autoSizeWidth = true; + autoSizeHeight = true; + fillColor = "220 220 220"; + opaque = "true"; + border = true; + borderColor = "180 180 180"; +}; + +new GuiControlProfile ("ShellProgressBarProfile") +{ + opaque = false; + fillColor = "44 152 162 100"; + border = true; + borderColor = "78 88 120"; +}; + +new GuiControlProfile ("ShellProgressBarTextProfile") +{ + fontType = $ShellLabelFont; + fontSize = $ShellLabelFontSize; + fontColor = "169 215 250"; + justify = "center"; +}; + +new GuiControlProfile ("ShellLoadFrameProfile" ) +{ + border = true; + borderColor = "78 88 120"; +}; + +new GuiControlProfile ("ShellSubHeaderProfile" ) +{ + fontType = "Univers Condensed Bold"; + fontSize = 28; + fontColor = "66 219 234"; + justify = "left"; + autoSizeWidth = true; + autoSizeHeight = true; +}; + +new GuiControlProfile( "DlgBackProfile" ) +{ + opaque = true; + fillColor = "0 0 0 160"; +}; + +new GuiControlProfile( "MotdCProfile" ) +{ + justify = "center"; + opaque = true; + autoSizeWidth = true; + fillColor = "0 0 0 160"; + fontType = "Univers Condensed"; + fontSize = 14; + fontColor = "000 219 234"; +}; + +new GuiControlProfile( "GuiInputCtrlProfile" ) +{ + tab = true; + canKeyFocus = true; +}; + +new GuiControlProfile( "TesterProfile" ) +{ + border = true; + borderColor = "255 255 0"; +}; + +new GuiControlProfile ("TaskHudProfile") +{ + fontType = $ShellFont; + fontSize = $ShellFontSize; + fontColor = "66 229 244"; + autoSizeWidth = true; + autoSizeHeight = true; + fontColors[1] = "0 200 0 200"; + fontColors[2] = "200 0 0 200"; + fontColors[3] = "0 0 200 200"; + fontColors[6] = $PlayerNameColor; + fontColors[7] = $TribeTagColor; + fontColors[8] = $SmurfNameColor; + fontColors[9] = $BotNameColor; +}; + +new GuiControlProfile ("TaskHudTextProfile") +{ + fontType = $ShellLabelFont; + fontSize = $ShellFontSize; + fontColor = "66 229 244"; + autoSizeWidth = true; + autoSizeHeight = true; +}; + +new GuiControlProfile ("ShellChatMemberListProfile") +{ + fontType = $ShellFont; + fontSize = $ShellFontSize; + fontColor = "60 180 180"; + fontColorHL = "6 245 215"; + fontColorNA = "128 128 128"; + fontColorSEL = "25 68 56"; + fontColors[4] = "255 255 255"; // nick font color + fontColors[5] = "200 255 255"; // nick highlighted color + fontColors[6] = "0 0 0"; // nick selected color + fontColors[7] = "255 255 0"; // tribe font color + fontColors[8] = "200 255 0"; // tribe highlighted color + fontColors[9] = "0 0 255"; // tribe selected color + bitmapBase = "gui/shll_bar"; + tab = true; + canKeyFocus = true; +}; + +new GuiControlProfile ("GuiChannelVectorProfile") +{ + fontType = $ShellFont; + fontSize = $ShellFontSize; + fontColor = "249 250 194"; // default font color + fontColors[1] = "255 255 255"; // nick font color + fontColors[2] = "255 255 0"; // tribe font color + fontColors[3] = "0 200 0"; // server font color + fontColors[4] = "4 235 105"; // client join/drop, tournament mode + fontColors[5] = "219 200 128"; // gameplay, admin/voting, pack/deployable + fontColors[6] = "77 253 95"; // team chat, spam protection message, client tasks + fontColors[7] = "40 231 240"; // global chat + fontColors[8] = "200 200 50 200"; // used in single player game + fontColors[9] = "66 219 234"; + autoSizeWidth = false; + autoSizeHeight = true; +}; + +new GuiControlProfile ("GuiTempHeatProfile") +{ + fontType = $ShellButtonFont; + fontSize = $ShellFontSize; + fontColor = "230 40 230"; + justify = "center"; +}; + +new GuiControlProfile ("GuiBubblePopupProfile") +{ + border = false; + opaque = true; + fillColor = "3 144 156 200"; +}; + +new GuiControlProfile ("GuiBubbleTextProfile") +{ + fontType = $ShellFont; + fontSize = $ShellMediumFontSize; + fontColor = "100 200 200"; + autoSizeWidth = false; + autoSizeHeight = true; +}; + diff --git a/missions/AlphaSector.cs b/missions/AlphaSector.cs index c1db4a0..b778ff9 100644 --- a/missions/AlphaSector.cs +++ b/missions/AlphaSector.cs @@ -1,37 +1,37 @@ -//Alpha Sector (broke) script -package AlphaSector //Package is our mission Name -{ - function defineGeneralAI() - { - //These arrays are for general bots - $Bot[0,"Name"] = "Jeff Harding"; //ftl, Jeff. - $Bot[0,"Race"] = "Human"; - - //Very important or the console will get spammed. - //Bioderms and Criollos MUST be Male. - //Draakans can be types A, B, or C. - $Bot[0,"Sex"] = "Male"; - $Bot[0,"Skin"] = "Beagle"; //Skin. Don't use the actual team name. (Blood Eagle for example) - $Bot[0,"Voice"] = "Male1"; //Voice. Don't use the fancy name (Psycho for example). - $Bot[0,"VoicePitch"] = 1; - $Bot[0,"Team"] = 1; //Human - $Bot[0,"Weapons"] = "Blaster"; //List the weapons with spaces. The first weapon listed will be the one he has out on spawn. - $Bot[0,"Pack"] = "MiningTool"; - $Bot[0,"Armor"] = "Light"; - $Bot[0,"Objectives"] = false; //The bot goes NOWHERE! - - //The ammo for each weapon in "Weapons", make sure it's in the same spot in the string as the weapon. - //If the weapon doesn't use ammo, just place a zero. - $Bot[0,"Ammo"] = "0"; - $Bot[0,"RepairKits"] = 1; //Yea.. rep kits - $Bot[0,"Mines"] = 0; //Mines!! - $Bot[0,"Grenades"] = 0; //Grenades. I'll make it so you can tell which kind of nades. - $Bot[0,"Transform"] = "-159.193 -131.751 277.517 0 0 -1 1.1602"; //First 3 numbers are the position. The rest is the rotation. - - //These are for detailing on the bots.. shouldn't really be used unless you got a good reason to. - $Bot[0,"Health"] = 1; //I'm pretty sure 1 is the max for all armors. - - $BotCount = 1; //Tell the game how many general AI's there are. - } - -}; +//Alpha Sector (broke) script +package AlphaSector //Package is our mission Name +{ + function defineGeneralAI() + { + //These arrays are for general bots + $Bot[0,"Name"] = "Jeff Harding"; //ftl, Jeff. + $Bot[0,"Race"] = "Human"; + + //Very important or the console will get spammed. + //Bioderms and Criollos MUST be Male. + //Draakans can be types A, B, or C. + $Bot[0,"Sex"] = "Male"; + $Bot[0,"Skin"] = "Beagle"; //Skin. Don't use the actual team name. (Blood Eagle for example) + $Bot[0,"Voice"] = "Male1"; //Voice. Don't use the fancy name (Psycho for example). + $Bot[0,"VoicePitch"] = 1; + $Bot[0,"Team"] = 1; //Human + $Bot[0,"Weapons"] = "Blaster"; //List the weapons with spaces. The first weapon listed will be the one he has out on spawn. + $Bot[0,"Pack"] = "MiningTool"; + $Bot[0,"Armor"] = "Light"; + $Bot[0,"Objectives"] = false; //The bot goes NOWHERE! + + //The ammo for each weapon in "Weapons", make sure it's in the same spot in the string as the weapon. + //If the weapon doesn't use ammo, just place a zero. + $Bot[0,"Ammo"] = "0"; + $Bot[0,"RepairKits"] = 1; //Yea.. rep kits + $Bot[0,"Mines"] = 0; //Mines!! + $Bot[0,"Grenades"] = 0; //Grenades. I'll make it so you can tell which kind of nades. + $Bot[0,"Transform"] = "-159.193 -131.751 277.517 0 0 -1 1.1602"; //First 3 numbers are the position. The rest is the rotation. + + //These are for detailing on the bots.. shouldn't really be used unless you got a good reason to. + $Bot[0,"Health"] = 1; //I'm pretty sure 1 is the max for all armors. + + $BotCount = 1; //Tell the game how many general AI's there are. + } + +}; diff --git a/missions/AlphaSector.mis b/missions/AlphaSector.mis index 3514f48..03009b9 100644 --- a/missions/AlphaSector.mis +++ b/missions/AlphaSector.mis @@ -1,1648 +1,1648 @@ -// DisplayName = Alpha Sector -// MissionTypes = RPG - -//--- MISSION QUOTE BEGIN --- -// Is it so arrogant to think 'we' as Humans are special? -// -- Dark Dragon DX -//--- MISSION QUOTE END --- - -//--- MISSION STRING BEGIN --- -// -// Role play time..? -// -//--- MISSION STRING END --- - -//--- OBJECT WRITE BEGIN --- -new SimGroup(MissionGroup) { - - musicTrack = "lush"; - CTF_timeLimit = "25"; - CTF_scoreLimit = "6"; - cdTrack = "2"; - powerCount = "0"; - - new MissionArea(MissionArea) { - area = "-1000 -1016 2064 2000"; - flightCeiling = "600"; - flightCeilingRange = "20"; - - locked = "true"; - }; - new Sky(Sky) { - position = "936 -456 0"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - cloudHeightPer[0] = "0.349971"; - cloudHeightPer[1] = "0.25"; - cloudHeightPer[2] = "0.199973"; - cloudSpeed1 = "0.0001"; - cloudSpeed2 = "0.0002"; - cloudSpeed3 = "0.0003"; - visibleDistance = "400"; - useSkyTextures = "1"; - renderBottomTexture = "0"; - SkySolidColor = "0.365000 0.390000 0.420000 0.000000"; - fogDistance = "999"; - fogColor = "0.450000 0.500000 0.500000 1.000000"; - fogVolume1 = "40 0 258"; - fogVolume2 = "0 0 0"; - fogVolume3 = "0 0 0"; - materialList = "sky_lush_blue.dml"; - windVelocity = "0 0 0"; - windEffectPrecipitation = "0"; - fogVolumeColor1 = "128.000000 128.000000 128.000000 0.000000"; - fogVolumeColor2 = "128.000000 128.000000 128.000000 0.000000"; - fogVolumeColor3 = "128.000000 128.000000 128.000000 0.000000"; - high_visibleDistance = "450"; - high_fogDistance = "200"; - high_fogVolume1 = "50 0 245"; - high_fogVolume2 = "75 245 258"; - high_fogVolume3 = "-1 5.06317e-33 6.64552e-37"; - - locked = "true"; - cloudSpeed0 = "0.000150 0.000050"; - }; - new Sun() { - position = "0 0 0"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - direction = "0.57735 0.57735 -0.57735"; - color = "0.800000 0.800000 0.800000 1.000000"; - ambient = "0.450000 0.450000 0.450000 1.000000"; - texture[0] = "special/sunFlare"; - texture[1] = "special/sunFlare02"; - texture[2] = "special/LensFlare/flare01"; - texture[3] = "special/LensFlare/flare02"; - texture[4] = "special/LensFlare/flare03"; - lensFlareScale = "0.7"; - lensFlareIntensity = "1"; - frontFlareSize = "300"; - backFlareSize = "450"; - flareColor = "1.000000 1.000000 1.000000 1.000000"; - - locked = "true"; - }; - new TerrainBlock(Terrain) { - rotation = "1 0 0 0"; - scale = "1 1 1"; - detailTexture = "details/desertdet1"; - terrainFile = "AlphaFix.ter"; - squareSize = "8"; - emptySquares = "352871 484198 615525 615781 681572 681828 682084 616804 617060 486245 355430 94302 187279 188303 188556 188559 582028 582284 385935 190606"; - - locked = "true"; - position = "-1024 -1024 0"; - }; - new NavigationGraph(NavGraph) { - conjoinAngleDev = "65"; - cullDensity = "0.1"; - customArea = "0 0 0 0"; - - locked = "true"; - position = "0 0 0 1"; - conjoinBowlDev = "20"; - rotation = "0 0 0 0"; - coverage = "0"; - scale = "1 1 1"; - GraphFile = "AlphaSector.nav"; - }; - new WaterBlock() { - position = "-1016 -1024 7.51567"; - rotation = "1 0 0 0"; - scale = "2048 2048 239.416"; - liquidType = "RiverWater"; - density = "1"; - viscosity = "5"; - waveMagnitude = "1"; - surfaceTexture = "LiquidTiles/IslandWater02"; - surfaceOpacity = "0.9"; - envMapTexture = "lush/skies/lush_day_emap"; - envMapIntensity = "0.15"; - removeWetEdges = "0"; - AudioEnvironment = "Underwater"; - - params3 = "1.21 -0.61 0.13 -0.33"; - textureSize = "32 32"; - floodFill = "1"; - params2 = "0.39 0.39 0.2 0.133"; - extent = "100 100 10"; - params0 = "0.32 -0.67 0.066 0.5"; - params1 = "0.63 -2.41 0.33 0.21"; - seedPoints = "0 0 1 0 1 1 0 1"; - }; - new AudioEmitter() { - position = "788.243 -120.742 93.2821"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - fileName = "fx/environment/drywind2.wav"; - useProfileDescription = "0"; - outsideAmbient = "1"; - volume = "0.3"; - isLooping = "1"; - is3D = "0"; - minDistance = "20"; - maxDistance = "1280"; - coneInsideAngle = "360"; - coneOutsideAngle = "360"; - coneOutsideVolume = "1"; - coneVector = "0 0 1"; - loopCount = "-1"; - minLoopGap = "0"; - maxLoopGap = "0"; - type = "EffectAudioType"; - }; - new SimGroup(Teams) { - - powerCount = "0"; - - new SimGroup(Team1) { - - powerCount = "0"; - - new SimGroup(base0) { - - powerCount = "1"; - - new InteriorInstance() { - position = "126.762 783.378 249.732"; - rotation = "0 0 1 84.2248"; - scale = "1 1 1"; - interiorFile = "bbase1.dif"; - showTerrainInside = "0"; - - team = "1"; - }; - new WayPoint() { - position = "127.381 782.671 264.332"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "WayPointMarker"; - lockCount = "0"; - homingCount = "0"; - name = "Rome"; - team = "1"; - }; - new StaticShape(TeamGeneratorLarge1) { - position = "77.3165 736.16 240.194"; - rotation = "0 0 1 174.179"; - scale = "1 1 1"; - nameTag = "\x01807"; - dataBlock = "GeneratorLarge"; - lockCount = "0"; - homingCount = "0"; - - team = "1"; - Target = "33"; - }; - new Item() { - position = "96.5223 780.314 238.371"; - rotation = "0 0 1 80.7871"; - scale = "1 1 1"; - dataBlock = "RepairPack"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - - team = "1"; - Target = "-1"; - }; - new StaticShape(TeamStationInventory1) { - position = "125.487 797.433 238.277"; - rotation = "0 0 -1 6.8755"; - scale = "1 1 1"; - nameTag = "\x01811"; - dataBlock = "StationInventory"; - lockCount = "0"; - homingCount = "0"; - - Trigger = "13625"; - team = "1"; - Target = "34"; - }; - new StaticShape(TeamStationInventory2) { - position = "127.77 769.515 238.441"; - rotation = "0 0 1 171.887"; - scale = "1 1 1"; - nameTag = "\x01811"; - dataBlock = "StationInventory"; - lockCount = "0"; - homingCount = "0"; - - Trigger = "13627"; - team = "1"; - Target = "35"; - }; - new Turret(TeamSentryTurret1) { - position = "124.69 782.99 246.187"; - rotation = "0 0 1 1.71869"; - scale = "1 1 1"; - nameTag = "\x01811"; - dataBlock = "SentryTurret"; - lockCount = "0"; - homingCount = "0"; - initialBarrel = "SentryTurretBarrel"; - - team = "1"; - Target = "36"; - }; - new Turret(TeamSentryTurret2) { - position = "127.035 783.395 254.135"; - rotation = "0 0 -1 4.58384"; - scale = "1 1 1"; - nameTag = "\x01810"; - dataBlock = "SentryTurret"; - lockCount = "0"; - homingCount = "0"; - initialBarrel = "SentryTurretBarrel"; - - team = "1"; - Target = "37"; - }; - new StaticShape() { - position = "35.4267 771.282 247.957"; - rotation = "0 0 1 52.1391"; - scale = "1 1 1"; - nameTag = "\x01808"; - dataBlock = "StationVehiclePad"; - lockCount = "0"; - homingCount = "0"; - - team = "1"; - Ready = "1"; - station = "13740"; - Target = "38"; - }; - new Trigger() { - position = "1.15816 850.519 200.084"; - rotation = "1 0 0 0"; - scale = "164.503 130.425 94.1307"; - dataBlock = "gameTrigger"; - lockCount = "0"; - homingCount = "0"; - polyhedron = "0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 -0.0000000 -1.0000000 -0.0000000 -0.0000000 -0.0000000 1.0000000"; - - type = "Territory"; - team = "1"; - race = "Human"; - location = "Rome"; - }; - }; - new SimGroup(spawnspheres) { - - powerCount = "0"; - - new SpawnSphere() { - position = "126.83 783.227 248.132"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "SpawnSphereMarker"; - lockCount = "0"; - homingCount = "0"; - radius = "100"; - sphereWeight = "100"; - indoorWeight = "100"; - outdoorWeight = "100"; - }; - }; - new SimGroup(AIObjectives) { - - powerCount = "0"; - - new AIObjective(AIORepairObject) { - position = "76.8566 738.062 241.637"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Repair the GeneratorLarge"; - targetObject = "TeamGeneratorLarge1"; - targetClientId = "-1"; - targetObjectId = "13622"; - location = "76.8566 738.062 241.637"; - weightLevel1 = "3200"; - weightLevel2 = "1600"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "0"; - defense = "1"; - equipment = "RepairPack"; - buyEquipmentSet = "MediumRepairSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - - team = "1"; - isInvalid = "0"; - }; - new AIObjective(AIOAttackObject) { - position = "76.8566 738.062 241.637"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Attack the GeneratorLarge"; - targetObject = "TeamGeneratorLarge1"; - targetClientId = "-1"; - targetObjectId = "13622"; - location = "76.8566 738.062 241.637"; - weightLevel1 = "3100"; - weightLevel2 = "1600"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "1"; - defense = "0"; - desiredEquipment = "ShieldPack"; - buyEquipmentSet = "HeavyAmmoSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - - team = "1"; - isInvalid = "0"; - }; - new AIObjective(AIODefendLocation) { - position = "76.8566 738.062 241.637"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Defend the GeneratorLarge"; - targetObject = "TeamGeneratorLarge1"; - targetClientId = "-1"; - targetObjectId = "13622"; - location = "76.8566 738.062 241.637"; - weightLevel1 = "3100"; - weightLevel2 = "1500"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "0"; - defense = "1"; - desiredEquipment = "ShieldPack Plasma PlasmaAmmo"; - buyEquipmentSet = "HeavyShieldSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - - team = "1"; - isInvalid = "0"; - }; - new AIObjective(AIORepairObject) { - position = "125.487 797.433 239.843"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Repair the StationInventory"; - targetObject = "TeamStationInventory1"; - targetClientId = "-1"; - targetObjectId = "13624"; - location = "125.487 797.433 239.843"; - weightLevel1 = "2900"; - weightLevel2 = "1400"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "0"; - defense = "1"; - equipment = "RepairPack"; - buyEquipmentSet = "MediumRepairSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - - team = "1"; - isInvalid = "0"; - }; - new AIObjective(AIOAttackObject) { - position = "125.487 797.433 239.843"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Attack the StationInventory"; - targetObject = "TeamStationInventory1"; - targetClientId = "-1"; - targetObjectId = "13624"; - location = "125.487 797.433 239.843"; - weightLevel1 = "2900"; - weightLevel2 = "1400"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "1"; - defense = "0"; - desiredEquipment = "ShieldPack"; - buyEquipmentSet = "HeavyAmmoSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - - team = "1"; - isInvalid = "0"; - }; - new AIObjective(AIORepairObject) { - position = "127.77 769.515 240.007"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Repair the StationInventory"; - targetObject = "TeamStationInventory2"; - targetClientId = "-1"; - targetObjectId = "13626"; - location = "127.77 769.515 240.007"; - weightLevel1 = "2900"; - weightLevel2 = "1400"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "0"; - defense = "1"; - equipment = "RepairPack"; - buyEquipmentSet = "MediumRepairSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - - team = "1"; - isInvalid = "0"; - }; - new AIObjective(AIOAttackObject) { - position = "127.77 769.515 240.007"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Attack the StationInventory"; - targetObject = "TeamStationInventory2"; - targetClientId = "-1"; - targetObjectId = "13626"; - location = "127.77 769.515 240.007"; - weightLevel1 = "2900"; - weightLevel2 = "1400"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "1"; - defense = "0"; - desiredEquipment = "ShieldPack"; - buyEquipmentSet = "HeavyAmmoSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - - team = "1"; - isInvalid = "0"; - }; - new AIObjective(AIORepairObject) { - position = "124.66 782.991 245.856"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Repair the SentryTurret"; - targetObject = "TeamSentryTurret1"; - targetClientId = "-1"; - targetObjectId = "13628"; - location = "124.66 782.991 245.856"; - weightLevel1 = "3100"; - weightLevel2 = "1000"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "0"; - defense = "1"; - equipment = "RepairPack"; - buyEquipmentSet = "MediumRepairSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - - team = "1"; - isInvalid = "0"; - }; - new AIObjective(AIOMortarObject) { - position = "124.66 782.991 245.856"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Mortar the SentryTurret"; - targetObject = "TeamSentryTurret1"; - targetClientId = "-1"; - targetObjectId = "13628"; - location = "124.66 782.991 245.856"; - weightLevel1 = "3400"; - weightLevel2 = "1000"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "1"; - defense = "0"; - equipment = "Mortar MortarAmmo"; - buyEquipmentSet = "HeavyAmmoSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - - team = "1"; - isInvalid = "0"; - }; - new AIObjective(AIORepairObject) { - position = "127.005 783.392 253.804"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Repair the SentryTurret"; - targetObject = "TeamSentryTurret2"; - targetClientId = "-1"; - targetObjectId = "13629"; - location = "127.005 783.392 253.804"; - weightLevel1 = "3100"; - weightLevel2 = "1000"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "0"; - defense = "1"; - equipment = "RepairPack"; - buyEquipmentSet = "MediumRepairSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - - team = "1"; - isInvalid = "0"; - }; - new AIObjective(AIOMortarObject) { - position = "127.005 783.392 253.804"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Mortar the SentryTurret"; - targetObject = "TeamSentryTurret2"; - targetClientId = "-1"; - targetObjectId = "13629"; - location = "127.005 783.392 253.804"; - weightLevel1 = "3400"; - weightLevel2 = "1000"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "1"; - defense = "0"; - equipment = "Mortar MortarAmmo"; - buyEquipmentSet = "HeavyAmmoSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - - team = "1"; - isInvalid = "0"; - }; - new AIObjective(AIORepairObject) { - position = "-885.549 92.9889 264.437"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Repair the GeneratorLarge"; - targetObject = "TeamGeneratorLarge2"; - targetClientId = "-1"; - targetObjectId = "13691"; - location = "-885.549 92.9889 264.437"; - weightLevel1 = "3200"; - weightLevel2 = "1600"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "0"; - defense = "1"; - equipment = "RepairPack"; - buyEquipmentSet = "MediumRepairSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - - team = "1"; - isInvalid = "0"; - }; - new AIObjective(AIOAttackObject) { - position = "-885.549 92.9889 264.437"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Attack the GeneratorLarge"; - targetObject = "TeamGeneratorLarge2"; - targetClientId = "-1"; - targetObjectId = "13691"; - location = "-885.549 92.9889 264.437"; - weightLevel1 = "3100"; - weightLevel2 = "1600"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "1"; - defense = "0"; - desiredEquipment = "ShieldPack"; - buyEquipmentSet = "HeavyAmmoSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - - team = "1"; - isInvalid = "0"; - }; - new AIObjective(AIODefendLocation) { - position = "-885.549 92.9889 264.437"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Defend the GeneratorLarge"; - targetObject = "TeamGeneratorLarge2"; - targetClientId = "-1"; - targetObjectId = "13691"; - location = "-885.549 92.9889 264.437"; - weightLevel1 = "3100"; - weightLevel2 = "1500"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "0"; - defense = "1"; - desiredEquipment = "ShieldPack Plasma PlasmaAmmo"; - buyEquipmentSet = "HeavyShieldSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - - team = "1"; - isInvalid = "0"; - }; - new AIObjective(AIORepairObject) { - position = "-893.491 82.7459 254.315"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Repair the StationInventory"; - targetObject = "TeamStationInventory3"; - targetClientId = "-1"; - targetObjectId = "13692"; - location = "-893.491 82.7459 254.315"; - weightLevel1 = "2900"; - weightLevel2 = "1400"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "0"; - defense = "1"; - equipment = "RepairPack"; - buyEquipmentSet = "MediumRepairSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - - team = "1"; - isInvalid = "0"; - }; - new AIObjective(AIOAttackObject) { - position = "-893.491 82.7459 254.315"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Attack the StationInventory"; - targetObject = "TeamStationInventory3"; - targetClientId = "-1"; - targetObjectId = "13692"; - location = "-893.491 82.7459 254.315"; - weightLevel1 = "2900"; - weightLevel2 = "1400"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "1"; - defense = "0"; - desiredEquipment = "ShieldPack"; - buyEquipmentSet = "HeavyAmmoSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - - team = "1"; - isInvalid = "0"; - }; - new AIObjective(AIORepairObject) { - position = "-877.704 104.344 254.312"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Repair the StationInventory"; - targetObject = "TeamStationInventory4"; - targetClientId = "-1"; - targetObjectId = "13694"; - location = "-877.704 104.344 254.312"; - weightLevel1 = "2900"; - weightLevel2 = "1400"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "0"; - defense = "1"; - equipment = "RepairPack"; - buyEquipmentSet = "MediumRepairSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - - team = "1"; - isInvalid = "0"; - }; - new AIObjective(AIOAttackObject) { - position = "-877.704 104.344 254.312"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Attack the StationInventory"; - targetObject = "TeamStationInventory4"; - targetClientId = "-1"; - targetObjectId = "13694"; - location = "-877.704 104.344 254.312"; - weightLevel1 = "2900"; - weightLevel2 = "1400"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "1"; - defense = "0"; - desiredEquipment = "ShieldPack"; - buyEquipmentSet = "HeavyAmmoSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - - team = "1"; - isInvalid = "0"; - }; - new AIObjective(AIORepairObject) { - position = "29.6799 -672.635 264.558"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Repair the GeneratorLarge"; - targetObject = "TeamGeneratorLarge3"; - targetClientId = "-1"; - targetObjectId = "13676"; - location = "29.6799 -672.635 264.558"; - weightLevel1 = "3200"; - weightLevel2 = "1600"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "0"; - defense = "1"; - equipment = "RepairPack"; - buyEquipmentSet = "MediumRepairSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - - team = "1"; - isInvalid = "0"; - }; - new AIObjective(AIOAttackObject) { - position = "29.6799 -672.635 264.558"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Attack the GeneratorLarge"; - targetObject = "TeamGeneratorLarge3"; - targetClientId = "-1"; - targetObjectId = "13676"; - location = "29.6799 -672.635 264.558"; - weightLevel1 = "3100"; - weightLevel2 = "1600"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "1"; - defense = "0"; - desiredEquipment = "ShieldPack"; - buyEquipmentSet = "HeavyAmmoSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - - team = "1"; - isInvalid = "0"; - }; - new AIObjective(AIODefendLocation) { - position = "29.6799 -672.635 264.558"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Defend the GeneratorLarge"; - targetObject = "TeamGeneratorLarge3"; - targetClientId = "-1"; - targetObjectId = "13676"; - location = "29.6799 -672.635 264.558"; - weightLevel1 = "3100"; - weightLevel2 = "1500"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "0"; - defense = "1"; - desiredEquipment = "ShieldPack Plasma PlasmaAmmo"; - buyEquipmentSet = "HeavyShieldSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - - team = "1"; - isInvalid = "0"; - }; - new AIObjective(AIORepairObject) { - position = "26.8453 -663.692 264.715"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Repair the StationInventory"; - targetObject = "TeamStationInventory5"; - targetClientId = "-1"; - targetObjectId = "13677"; - location = "26.8453 -663.692 264.715"; - weightLevel1 = "2900"; - weightLevel2 = "1400"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "0"; - defense = "1"; - equipment = "RepairPack"; - buyEquipmentSet = "MediumRepairSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - - team = "1"; - isInvalid = "0"; - }; - new AIObjective(AIOAttackObject) { - position = "26.8453 -663.692 264.715"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Attack the StationInventory"; - targetObject = "TeamStationInventory5"; - targetClientId = "-1"; - targetObjectId = "13677"; - location = "26.8453 -663.692 264.715"; - weightLevel1 = "2900"; - weightLevel2 = "1400"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "1"; - defense = "0"; - desiredEquipment = "ShieldPack"; - buyEquipmentSet = "HeavyAmmoSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - - team = "1"; - isInvalid = "0"; - }; - new AIObjective(AIORepairObject) { - position = "818.839 114.828 255.551"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Repair the StationInventory"; - targetObject = "TeamStationInventory6"; - targetClientId = "-1"; - targetObjectId = "13706"; - location = "818.839 114.828 255.551"; - weightLevel1 = "2900"; - weightLevel2 = "1400"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "0"; - defense = "1"; - equipment = "RepairPack"; - buyEquipmentSet = "MediumRepairSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - - team = "1"; - isInvalid = "0"; - }; - new AIObjective(AIOAttackObject) { - position = "818.839 114.828 255.551"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Attack the StationInventory"; - targetObject = "TeamStationInventory6"; - targetClientId = "-1"; - targetObjectId = "13706"; - location = "818.839 114.828 255.551"; - weightLevel1 = "2900"; - weightLevel2 = "1400"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "1"; - defense = "0"; - desiredEquipment = "ShieldPack"; - buyEquipmentSet = "HeavyAmmoSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - - team = "1"; - isInvalid = "0"; - }; - new AIObjective(AIORepairObject) { - position = "807.925 78.3969 272.415"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Repair the GeneratorLarge"; - targetObject = "TeamGeneratorLarge4"; - targetClientId = "-1"; - targetObjectId = "13709"; - location = "807.925 78.3969 272.415"; - weightLevel1 = "3200"; - weightLevel2 = "1600"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "0"; - defense = "1"; - equipment = "RepairPack"; - buyEquipmentSet = "MediumRepairSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - - team = "1"; - isInvalid = "0"; - }; - new AIObjective(AIOAttackObject) { - position = "807.925 78.3969 272.415"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Attack the GeneratorLarge"; - targetObject = "TeamGeneratorLarge4"; - targetClientId = "-1"; - targetObjectId = "13709"; - location = "807.925 78.3969 272.415"; - weightLevel1 = "3100"; - weightLevel2 = "1600"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "1"; - defense = "0"; - desiredEquipment = "ShieldPack"; - buyEquipmentSet = "HeavyAmmoSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - - team = "1"; - isInvalid = "0"; - }; - new AIObjective(AIODefendLocation) { - position = "807.925 78.3969 272.415"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Defend the GeneratorLarge"; - targetObject = "TeamGeneratorLarge4"; - targetClientId = "-1"; - targetObjectId = "13709"; - location = "807.925 78.3969 272.415"; - weightLevel1 = "3100"; - weightLevel2 = "1500"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "0"; - defense = "1"; - desiredEquipment = "ShieldPack Plasma PlasmaAmmo"; - buyEquipmentSet = "HeavyShieldSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - - team = "1"; - isInvalid = "0"; - }; - new AIObjective(AIORepairObject) { - position = "799.147 115.411 255.595"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Repair the StationInventory"; - targetObject = "TeamStationInventory7"; - targetClientId = "-1"; - targetObjectId = "13710"; - location = "799.147 115.411 255.595"; - weightLevel1 = "2900"; - weightLevel2 = "1400"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "0"; - defense = "1"; - equipment = "RepairPack"; - buyEquipmentSet = "MediumRepairSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - - team = "1"; - isInvalid = "0"; - }; - new AIObjective(AIOAttackObject) { - position = "799.147 115.411 255.595"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Attack the StationInventory"; - targetObject = "TeamStationInventory7"; - targetClientId = "-1"; - targetObjectId = "13710"; - location = "799.147 115.411 255.595"; - weightLevel1 = "2900"; - weightLevel2 = "1400"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "1"; - defense = "0"; - desiredEquipment = "ShieldPack"; - buyEquipmentSet = "HeavyAmmoSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - - team = "1"; - isInvalid = "0"; - }; - }; - }; - new SimGroup(team0) { - - powerCount = "0"; - - new SimGroup(base0) { - - powerCount = "0"; - - new InteriorInstance() { - position = "-252.637 -109.087 175.668"; - rotation = "0 0 1 92.4541"; - scale = "1 1 1"; - interiorFile = "mines.dif"; - showTerrainInside = "0"; - - team = "0"; - }; - new WayPoint() { - position = "-267.845 -125.609 287.649"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "WayPointMarker"; - lockCount = "0"; - homingCount = "0"; - name = "Keldrin Mines"; - team = "0"; - }; - new Item() { - position = "-217.704 -186.591 256.882"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "MiningTool"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - - team = "0"; - Target = "-1"; - }; - }; - new SimGroup(spawnsphres) { - - powerCount = "0"; - }; - new SimGroup(AIObjectives) { - - powerCount = "0"; - }; - }; - new SimGroup(team3) { - - powerCount = "0"; - - new SimGroup(base0) { - - powerCount = "1"; - - new InteriorInstance() { - position = "35.2699 -665.895 260.397"; - rotation = "0 0 1 72.7656"; - scale = "1 1 1"; - interiorFile = "bbunk1.dif"; - showTerrainInside = "0"; - - team = "3"; - }; - new WayPoint() { - position = "27.0806 -668.413 272.197"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "WayPointMarker"; - lockCount = "0"; - homingCount = "0"; - name = "Iguana Bay"; - team = "3"; - }; - new StaticShape(TeamGeneratorLarge3) { - position = "28.8718 -670.852 263.115"; - rotation = "0 0 -1 16.6158"; - scale = "1 1 1"; - nameTag = "\x01810"; - dataBlock = "GeneratorLarge"; - lockCount = "0"; - homingCount = "0"; - - team = "3"; - Target = "39"; - }; - new StaticShape(TeamStationInventory5) { - position = "26.8453 -663.692 263.149"; - rotation = "0 0 -1 17.7617"; - scale = "1 1 1"; - nameTag = "\x01810"; - dataBlock = "StationInventory"; - lockCount = "0"; - homingCount = "0"; - - Trigger = "13678"; - team = "3"; - Target = "40"; - }; - new Item() { - position = "28.232 -668.077 254.842"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "RepairPack"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - - team = "3"; - Target = "-1"; - }; - new StaticShape() { - position = "74.1981 -675.792 252.759"; - rotation = "0 0 -1 80.3966"; - scale = "1 1 1"; - nameTag = "\x01805"; - dataBlock = "StationVehiclePad"; - lockCount = "0"; - homingCount = "0"; - - team = "3"; - Ready = "1"; - station = "13743"; - Target = "41"; - }; - new Trigger() { - position = "2.71913 -636.476 252.333"; - rotation = "1 0 0 0"; - scale = "114.468 65.715 55.3526"; - dataBlock = "gameTrigger"; - lockCount = "0"; - homingCount = "0"; - polyhedron = "0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 -0.0000000 -1.0000000 -0.0000000 -0.0000000 -0.0000000 1.0000000"; - - type = "Territory"; - team = "3"; - race = "Draakan"; - location = "Iguana Bay"; - }; - }; - new SimGroup(spawnspheres) { - - powerCount = "0"; - - new SpawnSphere() { - position = "28.2794 -668.091 254.592"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "SpawnSphereMarker"; - lockCount = "0"; - homingCount = "0"; - radius = "50"; - sphereWeight = "100"; - indoorWeight = "100"; - outdoorWeight = "100"; - }; - }; - new SimGroup(AIObjectives) { - - powerCount = "0"; - }; - new SimGroup(DarkDragonDX) { - - powerCount = "0"; - }; - }; - new SimGroup(Team2) { - - powerCount = "0"; - - new SimGroup(base0) { - - powerCount = "1"; - - new InteriorInstance() { - position = "-890.926 97.3695 259.202"; - rotation = "0 0 1 126.051"; - scale = "1 1 1"; - interiorFile = "bbunk2.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new WayPoint() { - position = "-888.447 95.7277 290.702"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "WayPointMarker"; - lockCount = "0"; - homingCount = "0"; - name = "Dead Alley"; - team = "2"; - }; - new StaticShape(TeamGeneratorLarge2) { - position = "-887.262 93.9359 262.994"; - rotation = "0 0 -1 53.2851"; - scale = "1 1 1"; - nameTag = "\x01702"; - dataBlock = "GeneratorLarge"; - lockCount = "0"; - homingCount = "0"; - - team = "2"; - Target = "42"; - }; - new StaticShape(TeamStationInventory3) { - position = "-893.491 82.7459 252.749"; - rotation = "0 0 1 210.848"; - scale = "1 1 1"; - nameTag = "\x01811"; - dataBlock = "StationInventory"; - lockCount = "0"; - homingCount = "0"; - - Trigger = "13693"; - team = "2"; - Target = "43"; - }; - new StaticShape(TeamStationInventory4) { - position = "-877.704 104.344 252.746"; - rotation = "0 0 1 35.5234"; - scale = "1 1 1"; - nameTag = "\x01811"; - dataBlock = "StationInventory"; - lockCount = "0"; - homingCount = "0"; - - Trigger = "13695"; - team = "2"; - Target = "44"; - }; - new Item() { - position = "-882.999 97.3961 263.17"; - rotation = "0 0 1 81.36"; - scale = "1 1 1"; - dataBlock = "RepairPack"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - - team = "2"; - Target = "-1"; - }; - new StaticShape() { - position = "-933.996 91.6465 250.168"; - rotation = "0 0 1 17.1887"; - scale = "1 1 1"; - nameTag = "\x01701"; - dataBlock = "StationVehiclePad"; - lockCount = "0"; - homingCount = "0"; - - team = "2"; - Ready = "1"; - station = "13746"; - Target = "45"; - }; - new Trigger() { - position = "-973.205 129.616 251.023"; - rotation = "1 0 0 0"; - scale = "124.339 69.2113 57.6628"; - dataBlock = "gameTrigger"; - lockCount = "0"; - homingCount = "0"; - polyhedron = "0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 -0.0000000 -1.0000000 -0.0000000 -0.0000000 -0.0000000 1.0000000"; - - type = "Territory"; - team = "2"; - race = "bioderm"; - location = "Dead Alley"; - }; - }; - new SimGroup(spawnspheres) { - - powerCount = "0"; - - new SpawnSphere() { - position = "-887.111 94.6878 252.648"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "SpawnSphereMarker"; - lockCount = "0"; - homingCount = "0"; - radius = "50"; - sphereWeight = "100"; - indoorWeight = "100"; - outdoorWeight = "100"; - }; - }; - new SimGroup(AIObjectives) { - - powerCount = "0"; - }; - }; - new SimGroup(team4) { - - powerCount = "0"; - - new SimGroup(base0) { - - powerCount = "1"; - - new InteriorInstance(InteriorInstance) { - position = "808.471 103.478 266.02"; - rotation = "0 0 1 182.201"; - scale = "1 1 1"; - interiorFile = "bbase6.dif"; - showTerrainInside = "1"; - - team = "4"; - }; - new WayPoint() { - position = "808.474 105.751 302.904"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "WayPointMarker"; - lockCount = "0"; - homingCount = "0"; - name = "Hammurabi\'s Den"; - team = "4"; - }; - new StaticShape(TeamStationInventory6) { - position = "818.839 114.828 253.985"; - rotation = "0 0 -1 88.991"; - scale = "1 1 1"; - nameTag = "\x01811"; - dataBlock = "StationInventory"; - lockCount = "0"; - homingCount = "0"; - - Trigger = "13707"; - team = "4"; - Target = "46"; - }; - new Item() { - position = "824.886 94.5054 254.005"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "RepairPack"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - - team = "4"; - Target = "-1"; - }; - new StaticShape(TeamGeneratorLarge4) { - position = "807.718 80.343 270.972"; - rotation = "0 0 1 1.71915"; - scale = "1 1 1"; - nameTag = "\x01810"; - dataBlock = "GeneratorLarge"; - lockCount = "0"; - homingCount = "0"; - - team = "4"; - Target = "47"; - }; - new StaticShape(TeamStationInventory7) { - position = "799.147 115.411 254.029"; - rotation = "0 0 1 89.3814"; - scale = "1 1 1"; - nameTag = "\x01811"; - dataBlock = "StationInventory"; - lockCount = "0"; - homingCount = "0"; - - Trigger = "13711"; - team = "4"; - Target = "48"; - }; - new Item() { - position = "790.776 96.0756 254.07"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "RepairPack"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - - team = "4"; - Target = "-1"; - }; - new StaticShape() { - position = "750.574 160.107 253.842"; - rotation = "0 0 1 88.8084"; - scale = "1 1 1"; - nameTag = "\x01805"; - dataBlock = "StationVehiclePad"; - lockCount = "0"; - homingCount = "0"; - - team = "4"; - Ready = "1"; - station = "13749"; - Target = "49"; - }; - new InteriorInstance(InteriorInstance) { - position = "-221.09 -175.315 258.292"; - rotation = "0.53998 0.493839 0.681575 116.127"; - scale = "0.1 0.1 0.1"; - interiorFile = "brockc.dif"; - showTerrainInside = "0"; - - team = "4"; - }; - new StaticShape() { - position = "-220.722 -174.595 256.5"; - rotation = "1 0 0 0"; - scale = "1 1 8.39636"; - dataBlock = "MiningBox"; - lockCount = "0"; - homingCount = "0"; - - team = "4"; - mineral = "Steel"; - wasDisabled = "1"; - }; - new Trigger() { - position = "706.414 205.278 253.953"; - rotation = "1 0 0 0"; - scale = "165.508 183.667 78.0676"; - dataBlock = "gameTrigger"; - lockCount = "0"; - homingCount = "0"; - polyhedron = "0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 -0.0000000 -1.0000000 -0.0000000 -0.0000000 -0.0000000 1.0000000"; - - type = "Territory"; - team = "4"; - race = "Criollos"; - location = "Hammurabi\'s Den"; - }; - }; - new SimGroup(spawnspheres) { - - powerCount = "0"; - - new SpawnSphere() { - position = "808.348 99.3234 253.765"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "SpawnSphereMarker"; - lockCount = "0"; - homingCount = "0"; - radius = "100"; - sphereWeight = "100"; - indoorWeight = "100"; - outdoorWeight = "100"; - }; - }; - new SimGroup(AIObjectives) { - - powerCount = "0"; - }; - }; - }; - new SimGroup(ObserverDropPoints) { - - powerCount = "0"; - - new Camera(cam01) { - position = "-282.149 -124.278 280.392"; - rotation = "-0.0288998 0.0302843 0.999123 92.73"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - - team = "0"; - }; - new PhysicalZone(cam02) { - position = "55.6452 827.19 346.458"; - rotation = "0.184386 -0.355257 0.916403 129.125"; - scale = "1 1 1"; - velocityMod = "1"; - gravityMod = "1"; - appliedForce = "0 0 0"; - polyhedron = "0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 -0.0000000 -1.0000000 -0.0000000 -0.0000000 -0.0000000 1.0000000"; - }; - }; -}; -//--- OBJECT WRITE END --- +// DisplayName = Alpha Sector +// MissionTypes = RPG + +//--- MISSION QUOTE BEGIN --- +// Is it so arrogant to think 'we' as Humans are special? +// -- Dark Dragon DX +//--- MISSION QUOTE END --- + +//--- MISSION STRING BEGIN --- +// +// Role play time..? +// +//--- MISSION STRING END --- + +//--- OBJECT WRITE BEGIN --- +new SimGroup(MissionGroup) { + + musicTrack = "lush"; + CTF_timeLimit = "25"; + CTF_scoreLimit = "6"; + cdTrack = "2"; + powerCount = "0"; + + new MissionArea(MissionArea) { + area = "-1000 -1016 2064 2000"; + flightCeiling = "600"; + flightCeilingRange = "20"; + + locked = "true"; + }; + new Sky(Sky) { + position = "936 -456 0"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + cloudHeightPer[0] = "0.349971"; + cloudHeightPer[1] = "0.25"; + cloudHeightPer[2] = "0.199973"; + cloudSpeed1 = "0.0001"; + cloudSpeed2 = "0.0002"; + cloudSpeed3 = "0.0003"; + visibleDistance = "400"; + useSkyTextures = "1"; + renderBottomTexture = "0"; + SkySolidColor = "0.365000 0.390000 0.420000 0.000000"; + fogDistance = "999"; + fogColor = "0.450000 0.500000 0.500000 1.000000"; + fogVolume1 = "40 0 258"; + fogVolume2 = "0 0 0"; + fogVolume3 = "0 0 0"; + materialList = "sky_lush_blue.dml"; + windVelocity = "0 0 0"; + windEffectPrecipitation = "0"; + fogVolumeColor1 = "128.000000 128.000000 128.000000 0.000000"; + fogVolumeColor2 = "128.000000 128.000000 128.000000 0.000000"; + fogVolumeColor3 = "128.000000 128.000000 128.000000 0.000000"; + high_visibleDistance = "450"; + high_fogDistance = "200"; + high_fogVolume1 = "50 0 245"; + high_fogVolume2 = "75 245 258"; + high_fogVolume3 = "-1 5.06317e-33 6.64552e-37"; + + locked = "true"; + cloudSpeed0 = "0.000150 0.000050"; + }; + new Sun() { + position = "0 0 0"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + direction = "0.57735 0.57735 -0.57735"; + color = "0.800000 0.800000 0.800000 1.000000"; + ambient = "0.450000 0.450000 0.450000 1.000000"; + texture[0] = "special/sunFlare"; + texture[1] = "special/sunFlare02"; + texture[2] = "special/LensFlare/flare01"; + texture[3] = "special/LensFlare/flare02"; + texture[4] = "special/LensFlare/flare03"; + lensFlareScale = "0.7"; + lensFlareIntensity = "1"; + frontFlareSize = "300"; + backFlareSize = "450"; + flareColor = "1.000000 1.000000 1.000000 1.000000"; + + locked = "true"; + }; + new TerrainBlock(Terrain) { + rotation = "1 0 0 0"; + scale = "1 1 1"; + detailTexture = "details/desertdet1"; + terrainFile = "AlphaFix.ter"; + squareSize = "8"; + emptySquares = "352871 484198 615525 615781 681572 681828 682084 616804 617060 486245 355430 94302 187279 188303 188556 188559 582028 582284 385935 190606"; + + locked = "true"; + position = "-1024 -1024 0"; + }; + new NavigationGraph(NavGraph) { + conjoinAngleDev = "65"; + cullDensity = "0.1"; + customArea = "0 0 0 0"; + + locked = "true"; + position = "0 0 0 1"; + conjoinBowlDev = "20"; + rotation = "0 0 0 0"; + coverage = "0"; + scale = "1 1 1"; + GraphFile = "AlphaSector.nav"; + }; + new WaterBlock() { + position = "-1016 -1024 7.51567"; + rotation = "1 0 0 0"; + scale = "2048 2048 239.416"; + liquidType = "RiverWater"; + density = "1"; + viscosity = "5"; + waveMagnitude = "1"; + surfaceTexture = "LiquidTiles/IslandWater02"; + surfaceOpacity = "0.9"; + envMapTexture = "lush/skies/lush_day_emap"; + envMapIntensity = "0.15"; + removeWetEdges = "0"; + AudioEnvironment = "Underwater"; + + params3 = "1.21 -0.61 0.13 -0.33"; + textureSize = "32 32"; + floodFill = "1"; + params2 = "0.39 0.39 0.2 0.133"; + extent = "100 100 10"; + params0 = "0.32 -0.67 0.066 0.5"; + params1 = "0.63 -2.41 0.33 0.21"; + seedPoints = "0 0 1 0 1 1 0 1"; + }; + new AudioEmitter() { + position = "788.243 -120.742 93.2821"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + fileName = "fx/environment/drywind2.wav"; + useProfileDescription = "0"; + outsideAmbient = "1"; + volume = "0.3"; + isLooping = "1"; + is3D = "0"; + minDistance = "20"; + maxDistance = "1280"; + coneInsideAngle = "360"; + coneOutsideAngle = "360"; + coneOutsideVolume = "1"; + coneVector = "0 0 1"; + loopCount = "-1"; + minLoopGap = "0"; + maxLoopGap = "0"; + type = "EffectAudioType"; + }; + new SimGroup(Teams) { + + powerCount = "0"; + + new SimGroup(Team1) { + + powerCount = "0"; + + new SimGroup(base0) { + + powerCount = "1"; + + new InteriorInstance() { + position = "126.762 783.378 249.732"; + rotation = "0 0 1 84.2248"; + scale = "1 1 1"; + interiorFile = "bbase1.dif"; + showTerrainInside = "0"; + + team = "1"; + }; + new WayPoint() { + position = "127.381 782.671 264.332"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "WayPointMarker"; + lockCount = "0"; + homingCount = "0"; + name = "Rome"; + team = "1"; + }; + new StaticShape(TeamGeneratorLarge1) { + position = "77.3165 736.16 240.194"; + rotation = "0 0 1 174.179"; + scale = "1 1 1"; + nameTag = "\x01807"; + dataBlock = "GeneratorLarge"; + lockCount = "0"; + homingCount = "0"; + + team = "1"; + Target = "33"; + }; + new Item() { + position = "96.5223 780.314 238.371"; + rotation = "0 0 1 80.7871"; + scale = "1 1 1"; + dataBlock = "RepairPack"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + + team = "1"; + Target = "-1"; + }; + new StaticShape(TeamStationInventory1) { + position = "125.487 797.433 238.277"; + rotation = "0 0 -1 6.8755"; + scale = "1 1 1"; + nameTag = "\x01811"; + dataBlock = "StationInventory"; + lockCount = "0"; + homingCount = "0"; + + Trigger = "13625"; + team = "1"; + Target = "34"; + }; + new StaticShape(TeamStationInventory2) { + position = "127.77 769.515 238.441"; + rotation = "0 0 1 171.887"; + scale = "1 1 1"; + nameTag = "\x01811"; + dataBlock = "StationInventory"; + lockCount = "0"; + homingCount = "0"; + + Trigger = "13627"; + team = "1"; + Target = "35"; + }; + new Turret(TeamSentryTurret1) { + position = "124.69 782.99 246.187"; + rotation = "0 0 1 1.71869"; + scale = "1 1 1"; + nameTag = "\x01811"; + dataBlock = "SentryTurret"; + lockCount = "0"; + homingCount = "0"; + initialBarrel = "SentryTurretBarrel"; + + team = "1"; + Target = "36"; + }; + new Turret(TeamSentryTurret2) { + position = "127.035 783.395 254.135"; + rotation = "0 0 -1 4.58384"; + scale = "1 1 1"; + nameTag = "\x01810"; + dataBlock = "SentryTurret"; + lockCount = "0"; + homingCount = "0"; + initialBarrel = "SentryTurretBarrel"; + + team = "1"; + Target = "37"; + }; + new StaticShape() { + position = "35.4267 771.282 247.957"; + rotation = "0 0 1 52.1391"; + scale = "1 1 1"; + nameTag = "\x01808"; + dataBlock = "StationVehiclePad"; + lockCount = "0"; + homingCount = "0"; + + team = "1"; + Ready = "1"; + station = "13740"; + Target = "38"; + }; + new Trigger() { + position = "1.15816 850.519 200.084"; + rotation = "1 0 0 0"; + scale = "164.503 130.425 94.1307"; + dataBlock = "gameTrigger"; + lockCount = "0"; + homingCount = "0"; + polyhedron = "0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 -0.0000000 -1.0000000 -0.0000000 -0.0000000 -0.0000000 1.0000000"; + + type = "Territory"; + team = "1"; + race = "Human"; + location = "Rome"; + }; + }; + new SimGroup(spawnspheres) { + + powerCount = "0"; + + new SpawnSphere() { + position = "126.83 783.227 248.132"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "SpawnSphereMarker"; + lockCount = "0"; + homingCount = "0"; + radius = "100"; + sphereWeight = "100"; + indoorWeight = "100"; + outdoorWeight = "100"; + }; + }; + new SimGroup(AIObjectives) { + + powerCount = "0"; + + new AIObjective(AIORepairObject) { + position = "76.8566 738.062 241.637"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Repair the GeneratorLarge"; + targetObject = "TeamGeneratorLarge1"; + targetClientId = "-1"; + targetObjectId = "13622"; + location = "76.8566 738.062 241.637"; + weightLevel1 = "3200"; + weightLevel2 = "1600"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "0"; + defense = "1"; + equipment = "RepairPack"; + buyEquipmentSet = "MediumRepairSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + + team = "1"; + isInvalid = "0"; + }; + new AIObjective(AIOAttackObject) { + position = "76.8566 738.062 241.637"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Attack the GeneratorLarge"; + targetObject = "TeamGeneratorLarge1"; + targetClientId = "-1"; + targetObjectId = "13622"; + location = "76.8566 738.062 241.637"; + weightLevel1 = "3100"; + weightLevel2 = "1600"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "1"; + defense = "0"; + desiredEquipment = "ShieldPack"; + buyEquipmentSet = "HeavyAmmoSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + + team = "1"; + isInvalid = "0"; + }; + new AIObjective(AIODefendLocation) { + position = "76.8566 738.062 241.637"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Defend the GeneratorLarge"; + targetObject = "TeamGeneratorLarge1"; + targetClientId = "-1"; + targetObjectId = "13622"; + location = "76.8566 738.062 241.637"; + weightLevel1 = "3100"; + weightLevel2 = "1500"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "0"; + defense = "1"; + desiredEquipment = "ShieldPack Plasma PlasmaAmmo"; + buyEquipmentSet = "HeavyShieldSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + + team = "1"; + isInvalid = "0"; + }; + new AIObjective(AIORepairObject) { + position = "125.487 797.433 239.843"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Repair the StationInventory"; + targetObject = "TeamStationInventory1"; + targetClientId = "-1"; + targetObjectId = "13624"; + location = "125.487 797.433 239.843"; + weightLevel1 = "2900"; + weightLevel2 = "1400"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "0"; + defense = "1"; + equipment = "RepairPack"; + buyEquipmentSet = "MediumRepairSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + + team = "1"; + isInvalid = "0"; + }; + new AIObjective(AIOAttackObject) { + position = "125.487 797.433 239.843"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Attack the StationInventory"; + targetObject = "TeamStationInventory1"; + targetClientId = "-1"; + targetObjectId = "13624"; + location = "125.487 797.433 239.843"; + weightLevel1 = "2900"; + weightLevel2 = "1400"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "1"; + defense = "0"; + desiredEquipment = "ShieldPack"; + buyEquipmentSet = "HeavyAmmoSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + + team = "1"; + isInvalid = "0"; + }; + new AIObjective(AIORepairObject) { + position = "127.77 769.515 240.007"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Repair the StationInventory"; + targetObject = "TeamStationInventory2"; + targetClientId = "-1"; + targetObjectId = "13626"; + location = "127.77 769.515 240.007"; + weightLevel1 = "2900"; + weightLevel2 = "1400"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "0"; + defense = "1"; + equipment = "RepairPack"; + buyEquipmentSet = "MediumRepairSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + + team = "1"; + isInvalid = "0"; + }; + new AIObjective(AIOAttackObject) { + position = "127.77 769.515 240.007"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Attack the StationInventory"; + targetObject = "TeamStationInventory2"; + targetClientId = "-1"; + targetObjectId = "13626"; + location = "127.77 769.515 240.007"; + weightLevel1 = "2900"; + weightLevel2 = "1400"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "1"; + defense = "0"; + desiredEquipment = "ShieldPack"; + buyEquipmentSet = "HeavyAmmoSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + + team = "1"; + isInvalid = "0"; + }; + new AIObjective(AIORepairObject) { + position = "124.66 782.991 245.856"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Repair the SentryTurret"; + targetObject = "TeamSentryTurret1"; + targetClientId = "-1"; + targetObjectId = "13628"; + location = "124.66 782.991 245.856"; + weightLevel1 = "3100"; + weightLevel2 = "1000"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "0"; + defense = "1"; + equipment = "RepairPack"; + buyEquipmentSet = "MediumRepairSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + + team = "1"; + isInvalid = "0"; + }; + new AIObjective(AIOMortarObject) { + position = "124.66 782.991 245.856"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Mortar the SentryTurret"; + targetObject = "TeamSentryTurret1"; + targetClientId = "-1"; + targetObjectId = "13628"; + location = "124.66 782.991 245.856"; + weightLevel1 = "3400"; + weightLevel2 = "1000"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "1"; + defense = "0"; + equipment = "Mortar MortarAmmo"; + buyEquipmentSet = "HeavyAmmoSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + + team = "1"; + isInvalid = "0"; + }; + new AIObjective(AIORepairObject) { + position = "127.005 783.392 253.804"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Repair the SentryTurret"; + targetObject = "TeamSentryTurret2"; + targetClientId = "-1"; + targetObjectId = "13629"; + location = "127.005 783.392 253.804"; + weightLevel1 = "3100"; + weightLevel2 = "1000"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "0"; + defense = "1"; + equipment = "RepairPack"; + buyEquipmentSet = "MediumRepairSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + + team = "1"; + isInvalid = "0"; + }; + new AIObjective(AIOMortarObject) { + position = "127.005 783.392 253.804"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Mortar the SentryTurret"; + targetObject = "TeamSentryTurret2"; + targetClientId = "-1"; + targetObjectId = "13629"; + location = "127.005 783.392 253.804"; + weightLevel1 = "3400"; + weightLevel2 = "1000"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "1"; + defense = "0"; + equipment = "Mortar MortarAmmo"; + buyEquipmentSet = "HeavyAmmoSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + + team = "1"; + isInvalid = "0"; + }; + new AIObjective(AIORepairObject) { + position = "-885.549 92.9889 264.437"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Repair the GeneratorLarge"; + targetObject = "TeamGeneratorLarge2"; + targetClientId = "-1"; + targetObjectId = "13691"; + location = "-885.549 92.9889 264.437"; + weightLevel1 = "3200"; + weightLevel2 = "1600"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "0"; + defense = "1"; + equipment = "RepairPack"; + buyEquipmentSet = "MediumRepairSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + + team = "1"; + isInvalid = "0"; + }; + new AIObjective(AIOAttackObject) { + position = "-885.549 92.9889 264.437"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Attack the GeneratorLarge"; + targetObject = "TeamGeneratorLarge2"; + targetClientId = "-1"; + targetObjectId = "13691"; + location = "-885.549 92.9889 264.437"; + weightLevel1 = "3100"; + weightLevel2 = "1600"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "1"; + defense = "0"; + desiredEquipment = "ShieldPack"; + buyEquipmentSet = "HeavyAmmoSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + + team = "1"; + isInvalid = "0"; + }; + new AIObjective(AIODefendLocation) { + position = "-885.549 92.9889 264.437"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Defend the GeneratorLarge"; + targetObject = "TeamGeneratorLarge2"; + targetClientId = "-1"; + targetObjectId = "13691"; + location = "-885.549 92.9889 264.437"; + weightLevel1 = "3100"; + weightLevel2 = "1500"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "0"; + defense = "1"; + desiredEquipment = "ShieldPack Plasma PlasmaAmmo"; + buyEquipmentSet = "HeavyShieldSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + + team = "1"; + isInvalid = "0"; + }; + new AIObjective(AIORepairObject) { + position = "-893.491 82.7459 254.315"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Repair the StationInventory"; + targetObject = "TeamStationInventory3"; + targetClientId = "-1"; + targetObjectId = "13692"; + location = "-893.491 82.7459 254.315"; + weightLevel1 = "2900"; + weightLevel2 = "1400"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "0"; + defense = "1"; + equipment = "RepairPack"; + buyEquipmentSet = "MediumRepairSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + + team = "1"; + isInvalid = "0"; + }; + new AIObjective(AIOAttackObject) { + position = "-893.491 82.7459 254.315"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Attack the StationInventory"; + targetObject = "TeamStationInventory3"; + targetClientId = "-1"; + targetObjectId = "13692"; + location = "-893.491 82.7459 254.315"; + weightLevel1 = "2900"; + weightLevel2 = "1400"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "1"; + defense = "0"; + desiredEquipment = "ShieldPack"; + buyEquipmentSet = "HeavyAmmoSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + + team = "1"; + isInvalid = "0"; + }; + new AIObjective(AIORepairObject) { + position = "-877.704 104.344 254.312"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Repair the StationInventory"; + targetObject = "TeamStationInventory4"; + targetClientId = "-1"; + targetObjectId = "13694"; + location = "-877.704 104.344 254.312"; + weightLevel1 = "2900"; + weightLevel2 = "1400"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "0"; + defense = "1"; + equipment = "RepairPack"; + buyEquipmentSet = "MediumRepairSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + + team = "1"; + isInvalid = "0"; + }; + new AIObjective(AIOAttackObject) { + position = "-877.704 104.344 254.312"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Attack the StationInventory"; + targetObject = "TeamStationInventory4"; + targetClientId = "-1"; + targetObjectId = "13694"; + location = "-877.704 104.344 254.312"; + weightLevel1 = "2900"; + weightLevel2 = "1400"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "1"; + defense = "0"; + desiredEquipment = "ShieldPack"; + buyEquipmentSet = "HeavyAmmoSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + + team = "1"; + isInvalid = "0"; + }; + new AIObjective(AIORepairObject) { + position = "29.6799 -672.635 264.558"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Repair the GeneratorLarge"; + targetObject = "TeamGeneratorLarge3"; + targetClientId = "-1"; + targetObjectId = "13676"; + location = "29.6799 -672.635 264.558"; + weightLevel1 = "3200"; + weightLevel2 = "1600"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "0"; + defense = "1"; + equipment = "RepairPack"; + buyEquipmentSet = "MediumRepairSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + + team = "1"; + isInvalid = "0"; + }; + new AIObjective(AIOAttackObject) { + position = "29.6799 -672.635 264.558"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Attack the GeneratorLarge"; + targetObject = "TeamGeneratorLarge3"; + targetClientId = "-1"; + targetObjectId = "13676"; + location = "29.6799 -672.635 264.558"; + weightLevel1 = "3100"; + weightLevel2 = "1600"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "1"; + defense = "0"; + desiredEquipment = "ShieldPack"; + buyEquipmentSet = "HeavyAmmoSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + + team = "1"; + isInvalid = "0"; + }; + new AIObjective(AIODefendLocation) { + position = "29.6799 -672.635 264.558"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Defend the GeneratorLarge"; + targetObject = "TeamGeneratorLarge3"; + targetClientId = "-1"; + targetObjectId = "13676"; + location = "29.6799 -672.635 264.558"; + weightLevel1 = "3100"; + weightLevel2 = "1500"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "0"; + defense = "1"; + desiredEquipment = "ShieldPack Plasma PlasmaAmmo"; + buyEquipmentSet = "HeavyShieldSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + + team = "1"; + isInvalid = "0"; + }; + new AIObjective(AIORepairObject) { + position = "26.8453 -663.692 264.715"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Repair the StationInventory"; + targetObject = "TeamStationInventory5"; + targetClientId = "-1"; + targetObjectId = "13677"; + location = "26.8453 -663.692 264.715"; + weightLevel1 = "2900"; + weightLevel2 = "1400"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "0"; + defense = "1"; + equipment = "RepairPack"; + buyEquipmentSet = "MediumRepairSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + + team = "1"; + isInvalid = "0"; + }; + new AIObjective(AIOAttackObject) { + position = "26.8453 -663.692 264.715"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Attack the StationInventory"; + targetObject = "TeamStationInventory5"; + targetClientId = "-1"; + targetObjectId = "13677"; + location = "26.8453 -663.692 264.715"; + weightLevel1 = "2900"; + weightLevel2 = "1400"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "1"; + defense = "0"; + desiredEquipment = "ShieldPack"; + buyEquipmentSet = "HeavyAmmoSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + + team = "1"; + isInvalid = "0"; + }; + new AIObjective(AIORepairObject) { + position = "818.839 114.828 255.551"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Repair the StationInventory"; + targetObject = "TeamStationInventory6"; + targetClientId = "-1"; + targetObjectId = "13706"; + location = "818.839 114.828 255.551"; + weightLevel1 = "2900"; + weightLevel2 = "1400"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "0"; + defense = "1"; + equipment = "RepairPack"; + buyEquipmentSet = "MediumRepairSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + + team = "1"; + isInvalid = "0"; + }; + new AIObjective(AIOAttackObject) { + position = "818.839 114.828 255.551"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Attack the StationInventory"; + targetObject = "TeamStationInventory6"; + targetClientId = "-1"; + targetObjectId = "13706"; + location = "818.839 114.828 255.551"; + weightLevel1 = "2900"; + weightLevel2 = "1400"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "1"; + defense = "0"; + desiredEquipment = "ShieldPack"; + buyEquipmentSet = "HeavyAmmoSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + + team = "1"; + isInvalid = "0"; + }; + new AIObjective(AIORepairObject) { + position = "807.925 78.3969 272.415"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Repair the GeneratorLarge"; + targetObject = "TeamGeneratorLarge4"; + targetClientId = "-1"; + targetObjectId = "13709"; + location = "807.925 78.3969 272.415"; + weightLevel1 = "3200"; + weightLevel2 = "1600"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "0"; + defense = "1"; + equipment = "RepairPack"; + buyEquipmentSet = "MediumRepairSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + + team = "1"; + isInvalid = "0"; + }; + new AIObjective(AIOAttackObject) { + position = "807.925 78.3969 272.415"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Attack the GeneratorLarge"; + targetObject = "TeamGeneratorLarge4"; + targetClientId = "-1"; + targetObjectId = "13709"; + location = "807.925 78.3969 272.415"; + weightLevel1 = "3100"; + weightLevel2 = "1600"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "1"; + defense = "0"; + desiredEquipment = "ShieldPack"; + buyEquipmentSet = "HeavyAmmoSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + + team = "1"; + isInvalid = "0"; + }; + new AIObjective(AIODefendLocation) { + position = "807.925 78.3969 272.415"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Defend the GeneratorLarge"; + targetObject = "TeamGeneratorLarge4"; + targetClientId = "-1"; + targetObjectId = "13709"; + location = "807.925 78.3969 272.415"; + weightLevel1 = "3100"; + weightLevel2 = "1500"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "0"; + defense = "1"; + desiredEquipment = "ShieldPack Plasma PlasmaAmmo"; + buyEquipmentSet = "HeavyShieldSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + + team = "1"; + isInvalid = "0"; + }; + new AIObjective(AIORepairObject) { + position = "799.147 115.411 255.595"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Repair the StationInventory"; + targetObject = "TeamStationInventory7"; + targetClientId = "-1"; + targetObjectId = "13710"; + location = "799.147 115.411 255.595"; + weightLevel1 = "2900"; + weightLevel2 = "1400"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "0"; + defense = "1"; + equipment = "RepairPack"; + buyEquipmentSet = "MediumRepairSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + + team = "1"; + isInvalid = "0"; + }; + new AIObjective(AIOAttackObject) { + position = "799.147 115.411 255.595"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Attack the StationInventory"; + targetObject = "TeamStationInventory7"; + targetClientId = "-1"; + targetObjectId = "13710"; + location = "799.147 115.411 255.595"; + weightLevel1 = "2900"; + weightLevel2 = "1400"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "1"; + defense = "0"; + desiredEquipment = "ShieldPack"; + buyEquipmentSet = "HeavyAmmoSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + + team = "1"; + isInvalid = "0"; + }; + }; + }; + new SimGroup(team0) { + + powerCount = "0"; + + new SimGroup(base0) { + + powerCount = "0"; + + new InteriorInstance() { + position = "-252.637 -109.087 175.668"; + rotation = "0 0 1 92.4541"; + scale = "1 1 1"; + interiorFile = "mines.dif"; + showTerrainInside = "0"; + + team = "0"; + }; + new WayPoint() { + position = "-267.845 -125.609 287.649"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "WayPointMarker"; + lockCount = "0"; + homingCount = "0"; + name = "Keldrin Mines"; + team = "0"; + }; + new Item() { + position = "-217.704 -186.591 256.882"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "MiningTool"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + + team = "0"; + Target = "-1"; + }; + }; + new SimGroup(spawnsphres) { + + powerCount = "0"; + }; + new SimGroup(AIObjectives) { + + powerCount = "0"; + }; + }; + new SimGroup(team3) { + + powerCount = "0"; + + new SimGroup(base0) { + + powerCount = "1"; + + new InteriorInstance() { + position = "35.2699 -665.895 260.397"; + rotation = "0 0 1 72.7656"; + scale = "1 1 1"; + interiorFile = "bbunk1.dif"; + showTerrainInside = "0"; + + team = "3"; + }; + new WayPoint() { + position = "27.0806 -668.413 272.197"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "WayPointMarker"; + lockCount = "0"; + homingCount = "0"; + name = "Iguana Bay"; + team = "3"; + }; + new StaticShape(TeamGeneratorLarge3) { + position = "28.8718 -670.852 263.115"; + rotation = "0 0 -1 16.6158"; + scale = "1 1 1"; + nameTag = "\x01810"; + dataBlock = "GeneratorLarge"; + lockCount = "0"; + homingCount = "0"; + + team = "3"; + Target = "39"; + }; + new StaticShape(TeamStationInventory5) { + position = "26.8453 -663.692 263.149"; + rotation = "0 0 -1 17.7617"; + scale = "1 1 1"; + nameTag = "\x01810"; + dataBlock = "StationInventory"; + lockCount = "0"; + homingCount = "0"; + + Trigger = "13678"; + team = "3"; + Target = "40"; + }; + new Item() { + position = "28.232 -668.077 254.842"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "RepairPack"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + + team = "3"; + Target = "-1"; + }; + new StaticShape() { + position = "74.1981 -675.792 252.759"; + rotation = "0 0 -1 80.3966"; + scale = "1 1 1"; + nameTag = "\x01805"; + dataBlock = "StationVehiclePad"; + lockCount = "0"; + homingCount = "0"; + + team = "3"; + Ready = "1"; + station = "13743"; + Target = "41"; + }; + new Trigger() { + position = "2.71913 -636.476 252.333"; + rotation = "1 0 0 0"; + scale = "114.468 65.715 55.3526"; + dataBlock = "gameTrigger"; + lockCount = "0"; + homingCount = "0"; + polyhedron = "0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 -0.0000000 -1.0000000 -0.0000000 -0.0000000 -0.0000000 1.0000000"; + + type = "Territory"; + team = "3"; + race = "Draakan"; + location = "Iguana Bay"; + }; + }; + new SimGroup(spawnspheres) { + + powerCount = "0"; + + new SpawnSphere() { + position = "28.2794 -668.091 254.592"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "SpawnSphereMarker"; + lockCount = "0"; + homingCount = "0"; + radius = "50"; + sphereWeight = "100"; + indoorWeight = "100"; + outdoorWeight = "100"; + }; + }; + new SimGroup(AIObjectives) { + + powerCount = "0"; + }; + new SimGroup(DarkDragonDX) { + + powerCount = "0"; + }; + }; + new SimGroup(Team2) { + + powerCount = "0"; + + new SimGroup(base0) { + + powerCount = "1"; + + new InteriorInstance() { + position = "-890.926 97.3695 259.202"; + rotation = "0 0 1 126.051"; + scale = "1 1 1"; + interiorFile = "bbunk2.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new WayPoint() { + position = "-888.447 95.7277 290.702"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "WayPointMarker"; + lockCount = "0"; + homingCount = "0"; + name = "Dead Alley"; + team = "2"; + }; + new StaticShape(TeamGeneratorLarge2) { + position = "-887.262 93.9359 262.994"; + rotation = "0 0 -1 53.2851"; + scale = "1 1 1"; + nameTag = "\x01702"; + dataBlock = "GeneratorLarge"; + lockCount = "0"; + homingCount = "0"; + + team = "2"; + Target = "42"; + }; + new StaticShape(TeamStationInventory3) { + position = "-893.491 82.7459 252.749"; + rotation = "0 0 1 210.848"; + scale = "1 1 1"; + nameTag = "\x01811"; + dataBlock = "StationInventory"; + lockCount = "0"; + homingCount = "0"; + + Trigger = "13693"; + team = "2"; + Target = "43"; + }; + new StaticShape(TeamStationInventory4) { + position = "-877.704 104.344 252.746"; + rotation = "0 0 1 35.5234"; + scale = "1 1 1"; + nameTag = "\x01811"; + dataBlock = "StationInventory"; + lockCount = "0"; + homingCount = "0"; + + Trigger = "13695"; + team = "2"; + Target = "44"; + }; + new Item() { + position = "-882.999 97.3961 263.17"; + rotation = "0 0 1 81.36"; + scale = "1 1 1"; + dataBlock = "RepairPack"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + + team = "2"; + Target = "-1"; + }; + new StaticShape() { + position = "-933.996 91.6465 250.168"; + rotation = "0 0 1 17.1887"; + scale = "1 1 1"; + nameTag = "\x01701"; + dataBlock = "StationVehiclePad"; + lockCount = "0"; + homingCount = "0"; + + team = "2"; + Ready = "1"; + station = "13746"; + Target = "45"; + }; + new Trigger() { + position = "-973.205 129.616 251.023"; + rotation = "1 0 0 0"; + scale = "124.339 69.2113 57.6628"; + dataBlock = "gameTrigger"; + lockCount = "0"; + homingCount = "0"; + polyhedron = "0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 -0.0000000 -1.0000000 -0.0000000 -0.0000000 -0.0000000 1.0000000"; + + type = "Territory"; + team = "2"; + race = "bioderm"; + location = "Dead Alley"; + }; + }; + new SimGroup(spawnspheres) { + + powerCount = "0"; + + new SpawnSphere() { + position = "-887.111 94.6878 252.648"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "SpawnSphereMarker"; + lockCount = "0"; + homingCount = "0"; + radius = "50"; + sphereWeight = "100"; + indoorWeight = "100"; + outdoorWeight = "100"; + }; + }; + new SimGroup(AIObjectives) { + + powerCount = "0"; + }; + }; + new SimGroup(team4) { + + powerCount = "0"; + + new SimGroup(base0) { + + powerCount = "1"; + + new InteriorInstance(InteriorInstance) { + position = "808.471 103.478 266.02"; + rotation = "0 0 1 182.201"; + scale = "1 1 1"; + interiorFile = "bbase6.dif"; + showTerrainInside = "1"; + + team = "4"; + }; + new WayPoint() { + position = "808.474 105.751 302.904"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "WayPointMarker"; + lockCount = "0"; + homingCount = "0"; + name = "Hammurabi\'s Den"; + team = "4"; + }; + new StaticShape(TeamStationInventory6) { + position = "818.839 114.828 253.985"; + rotation = "0 0 -1 88.991"; + scale = "1 1 1"; + nameTag = "\x01811"; + dataBlock = "StationInventory"; + lockCount = "0"; + homingCount = "0"; + + Trigger = "13707"; + team = "4"; + Target = "46"; + }; + new Item() { + position = "824.886 94.5054 254.005"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "RepairPack"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + + team = "4"; + Target = "-1"; + }; + new StaticShape(TeamGeneratorLarge4) { + position = "807.718 80.343 270.972"; + rotation = "0 0 1 1.71915"; + scale = "1 1 1"; + nameTag = "\x01810"; + dataBlock = "GeneratorLarge"; + lockCount = "0"; + homingCount = "0"; + + team = "4"; + Target = "47"; + }; + new StaticShape(TeamStationInventory7) { + position = "799.147 115.411 254.029"; + rotation = "0 0 1 89.3814"; + scale = "1 1 1"; + nameTag = "\x01811"; + dataBlock = "StationInventory"; + lockCount = "0"; + homingCount = "0"; + + Trigger = "13711"; + team = "4"; + Target = "48"; + }; + new Item() { + position = "790.776 96.0756 254.07"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "RepairPack"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + + team = "4"; + Target = "-1"; + }; + new StaticShape() { + position = "750.574 160.107 253.842"; + rotation = "0 0 1 88.8084"; + scale = "1 1 1"; + nameTag = "\x01805"; + dataBlock = "StationVehiclePad"; + lockCount = "0"; + homingCount = "0"; + + team = "4"; + Ready = "1"; + station = "13749"; + Target = "49"; + }; + new InteriorInstance(InteriorInstance) { + position = "-221.09 -175.315 258.292"; + rotation = "0.53998 0.493839 0.681575 116.127"; + scale = "0.1 0.1 0.1"; + interiorFile = "brockc.dif"; + showTerrainInside = "0"; + + team = "4"; + }; + new StaticShape() { + position = "-220.722 -174.595 256.5"; + rotation = "1 0 0 0"; + scale = "1 1 8.39636"; + dataBlock = "MiningBox"; + lockCount = "0"; + homingCount = "0"; + + team = "4"; + mineral = "Steel"; + wasDisabled = "1"; + }; + new Trigger() { + position = "706.414 205.278 253.953"; + rotation = "1 0 0 0"; + scale = "165.508 183.667 78.0676"; + dataBlock = "gameTrigger"; + lockCount = "0"; + homingCount = "0"; + polyhedron = "0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 -0.0000000 -1.0000000 -0.0000000 -0.0000000 -0.0000000 1.0000000"; + + type = "Territory"; + team = "4"; + race = "Criollos"; + location = "Hammurabi\'s Den"; + }; + }; + new SimGroup(spawnspheres) { + + powerCount = "0"; + + new SpawnSphere() { + position = "808.348 99.3234 253.765"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "SpawnSphereMarker"; + lockCount = "0"; + homingCount = "0"; + radius = "100"; + sphereWeight = "100"; + indoorWeight = "100"; + outdoorWeight = "100"; + }; + }; + new SimGroup(AIObjectives) { + + powerCount = "0"; + }; + }; + }; + new SimGroup(ObserverDropPoints) { + + powerCount = "0"; + + new Camera(cam01) { + position = "-282.149 -124.278 280.392"; + rotation = "-0.0288998 0.0302843 0.999123 92.73"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + team = "0"; + }; + new PhysicalZone(cam02) { + position = "55.6452 827.19 346.458"; + rotation = "0.184386 -0.355257 0.916403 129.125"; + scale = "1 1 1"; + velocityMod = "1"; + gravityMod = "1"; + appliedForce = "0 0 0"; + polyhedron = "0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 -0.0000000 -1.0000000 -0.0000000 -0.0000000 -0.0000000 1.0000000"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/missions/Beginning.cs b/missions/Beginning.cs index 54a7567..159c070 100644 --- a/missions/Beginning.cs +++ b/missions/Beginning.cs @@ -1,415 +1,415 @@ -// don't want this executing when building graphs -if($OFFLINE_NAV_BUILD) - return; - -// Script for Training -//=================================================================================== -//error("Training 1 script"); - -//Note: Quite messy right now.. I'll organize when it's done -//Not sure why this mission causes lots of console spam.. - -// variables -$numberOfEnemies[1] = 6; -$numberOfEnemies[2] = 6; -$numberOfEnemies[3] = 6; -$numberOfTeammates = 1; -$missionBotSkill[1] = 0.2; -$missionBotSkill[2] = 0.4; -$missionBotSkill[3] = 0.7; - -// package and callbacks - -package Beginning { -//BEGIN BEGINNING PACKAGE ======================================================================= - -function SinglePlayerGame::initGameVars(%game) -{ - echo("initializing beginning (TDS mission 1) game vars"); - Game.captorName = "Alchaldes"; //Main dude speaking - Game.controllerName = "Hammurabi"; //Guy at control panel - Game.guardOneName = "Romulus"; - Game.guardTwoName = "Hercules"; -} - -function PlayGui::onWake(%this) -{ - parent::onWake(%this); - //error("Waking training play gui"); - // okay we know the victim...erm...player is looking - // and we hope they have a body so lets do this - if(!game.playedIntro) { - game.PlayGuiAwake = true; - beginBeginning(); - } - -} - -function getTeammateGlobals() -{ - $TeammateWarnom0 = "Gila"; - $teammateSkill0 = 0.5; - $teammateVoice0 = Derm3; - $teammateEquipment0 = 0; - $teammateGender0 = B; -} - -function MP3Audio::play(%this) -{ - //too bad...no mp3 in training -} - -function toggleCommanderMap(%val) -{ - // No command Circuit fer' you! -} - -function toggleTaskListDlg( %val ) -{ - // Tasks? What tasks? Get the ef out of there when given the chance! -} - -function toggleInventoryHud( %val ) -{ - // Not even a message -} - -function toggleNetDisplayHud( %val ) -{ - // Hello, McFly? This is training! There's no net in training! -} - -function voiceCapture( %val ) -{ - // Uh, who do you think you are talking to? -} - -function giveall() -{ - error("When the going gets tough...wussies like you start cheating!"); - messageClient($player, 0, "Cheating eh? What\'s next? Camping?"); -} - -// get the ball rolling -//------------------------------------------------------------------------------ -function startCurrentMission() -{ - playGui.add(outerChatHud); - - //fade up from black - ServerConnection.setBlackOut(true, 0); - - new actionMap(ModifiedMap); - modifiedMap.bind(mouse0, "xaxis", yaw); - modifiedMap.bind(mouse0, "yaxis", pitch); -} - -function singlePlayerDead() -{ - missionFailed($player.miscMsg[TDSGenericLoss]); - AIMissionEnd(); - $objectiveQ[$enemyTeam].clear(); -} - -function beginBeginning() -{ -if(game.playedIntro) -return; - -$Beginning = ServerConnection.schedule(3000, setBlackOut, false, 4000); -$player.player.setTransform(DP.getTransform()); -$enemy0.stepMove(AlchaldesVisit.getPosition()); -yaw(1); - -return; - -game.playedIntro = true; -lockArmorHack(true); //Don't let our playah move - -//Now set up the victim -turnPlayerToPosition($enemy0.player.getPosition()); -$player.player.schedule(3000,"setInvincibleMode",$InvincibleTime,0.02); -schedule(3200,0,"hideHudHACK",false); -pitch(40); -if(!$firstperson)//Make sure we're in first person every time -toggleFirstPerson($player); -//Although both can't jet.. apparently b0ts need them to get around (even jumping down from stuff) -$player.player.setRechargeRate(0); -$player.player.setEnergyLevel(0); - -$teammate0.player.setTransform(Warnom0.getTransform()); - -//Alchaldes (leader of Criollos) -$enemy0.aimAt($player.player.getPosition()); -$enemy0.player.clearInventory(); -$enemy0.player.setInventory("EnergyPack",1); //Has a med condition; needs energy pack at all times -setName($enemy0,Game.CaptorName); -setSkin($enemy0,"HALO_SKIN"); - -//Hammurabi (Cloning -- lead researcher) -$enemy1.aimAt($player.player.getPosition()); -$enemy1.player.clearInventory(); -$enemy1.player.setInventory("EnergyPack",1); -setName($enemy1,Game.ControllerName); -setVoice($enemy1,"Derm3"); -setSkin($enemy1,"HALO_SKIN"); - -//Guard 1 (Looking at Dolosus) -$enemy2.aimAt($player.player.getPosition()); -setName($enemy2,Game.GuardOneName); -setVoice($enemy2,"Derm3"); -setSkin($enemy2,"HALO_SKIN"); - -//Guard 2 (Looking at Gila) -$enemy3.aimAt($teammate0.player.getPosition()); -setName($enemy3,Game.GuardTwoName); -setVoice($enemy3,"Derm3"); -setSkin($enemy3,"HALO_SKIN"); - -doText(TDS_M101); -doText(TDS_M102,3000); -doText(TDS_M103,3100); -doText(TDS_M104,3200); -doText(TDS_M105,3300); -doText(TDS_M106,3400); -doText(TDS_M107,3500); -doText(TDS_M108,3600); -doText(TDS_M109,3700); -doText(TDS_M101b,3800); -doText(TDS_M102b,3900); -doText(TDS_M103b,4000); -doText(TDS_M104b,4100); -doText(TDS_M105b,4200); -doText(TDS_M106b,4300); -doText(TDS_M107b,4400); -doText(TDS_M108b,4500); -doText(TDS_M109b,4600); -doText(TDS_M101c,4700); -doText(TDS_M102c,4800); -doText(TDS_M103c,4900); -doText(TDS_M104c,5000); -doText(TDS_M105c,5100); -doText(TDS_M106c,5200); -doText(TDS_M107c,5300); -} - -function giveEscortTask(%bot, %target) -{ - %newObjective = new AIObjective(AIOEscortPlayer) - { - dataBlock = "AIObjectiveMarker"; - weightLevel1 = 10000; - description = "Escort Player"; - targetClientId = %target; - offense = true; - }; - //echo(%newObjective); - MissionCleanup.add(%newObjective); - $ObjectiveQ[$playerTeam].add(%newObjective); - %bot.stepEscort(%target); - %bot.escort = %newObjective; - -} - -function detonateAll() -{ -ResearchTurret.applyDamage(400); -SecondaryResearch.applyDamage(400); -MainResearch.applyDamage(400); -Turret1.applyDamage(400); -Turret2.applyDamage(400); -Turret3.applyDamage(400); -BaseSensor.applyDamage(400); -BaseGen2.applyDamage(400); -DefenceGen.applyDamage(400); -ReactorGen2.applyDamage(400); -ReactorGen1.applyDamage(0.5); -InventoryStation1.applyDamage(400); -InventoryStation2.applyDamage(400); -InventoryStation3.applyDamage(400); -InventoryStation5.applyDamage(400); -messageAll('msgAll',"\c4Intercom: Main reactor absorbed most of the energy; high damage has been done to the whole network!"); -schedule(1500,0,"messageAll",'msgAll',"\c4Gila: Good! Sounds like any defences they have is down."); -//Alright, give the guards and other b0ts the objectives -$enemy2.addTask(AIEngageTask); -$enemy3.addTask(AIEngageTask); -$enemy4.addTask(AIEngageTask); -$enemy5.addTask(AIEngageTask); -} - -function storyMoveToHammurabi() -{ -$enemy0.stepMove(AlchaldesWorried.getPosition()); -$enemy0.schedule(2000,"aimAt",$enemy1.player.getPosition()); -$enemy2.aimAt($enemy0.player.getPosition()); -$enemy3.aimAt($enemy0.player.getPosition()); -} - -function storyMoveToGila() -{ -$enemy0.stepMove(AlchaldesObserve.getPosition()); -$enemy1.stepMove(HammurabiObserve.getPosition()); -$enemy0.schedule(2000,"aimAt",$teammate0.player.getPosition()); -$enemy1.schedule(2000,"aimAt",$teammate0.player.getPosition()); -} - -function storyMoveToDolosus() -{ -$enemy0.stepMove(enemy0.getPosition()); -$enemy1.stepMove(enemy1.getPosition()); -$enemy0.schedule(2000,"aimAt",$player.player.getPosition()); -$enemy1.schedule(2000,"aimAt",$player.player.getPosition()); -} - -function hideHudHACK(%bool) -{ -objectiveHud.setVisible(%bool); -hudClusterBack.setVisible(%bool); -inventoryHud.setVisible(%bool); -backPackFrame.setVisible(%bool); -weaponsHud.setVisible(%bool); -clockHUD.setVisible(%bool); -retCenterHUD.setVisible(%bool); -} - -//------------------------------------------------------------------------------ -function SinglePlayerGame::equip(%game, %player) -{ - //ya start with nothing...NOTHING! - %player.clearInventory(); - for(%i =0; %i<$InventoryHudCount; %i++) - %player.client.setInventoryHudItem($InventoryHudData[%i, itemDataName], 0, 1); - %player.client.clearBackpackIcon(); - - %set = %player.client.equipment; - - if (%player.client.race $= "Draakan") - { - %player.setInventory(Flamer,1); - %player.use(Flamer); - } - else - { - %player.setInventory("Chaingun",1,true); - %player.setInventory("ChaingunAmmo",999,true); - %player.setInventory("Disc",1,true); - %player.setInventory("DiscAmmo",999,true); - %player.setInventory("Shocklance",1,true); - %player.setInventory("AmmoPack",1,true); - %player.use("Chaingun"); - } -} - -function spawnSinglePlayer() -{ - resetWildCat(); - parent::spawnSinglePlayer(); -} - -function turnPlayerToPosition(%pos) -{ - %vec = VectorSub($player.player.position, %pos); - %angle = mATan( getWord(%vec, 0), getWord(%vec, 1) ); - %angle = %angle + 3.141529; - %newTransform = $player.player.position SPC "0 0 1" SPC %angle; - $player.player.setTransform(%newTransform); -} - -function singlePlayerGame::onAIRespawn(%game, %client) -{ - // DONT add the default tasks - //error("default tasks not added"); -} - -function singlePlayerGame::playerSpawned(%game, %player) -{ - parent::playerSpawned(%game, %player); -} - -function singlePlayerGame::gameOver(%game) -{ - //enable the voice chat menu again... - if (isObject(training1BlockMap)) - { - training1BlockMap.pop(); - training1BlockMap.delete(); - } - - if(HelpTextGui.isVisible()) - helpTextGui.setVisible(false); - - //Make sure our hidden HUD elements are visible again - hideHudHACK(true); - //Make sure our sounds stopped playing - doSpecialEffect(5); - - //re-enable the use of the settings button... - SinglePlayerEscSettingsBtn.setActive(1); - - Parent::gameOver(); -} - -function trainingPreloads() //Load any skins.. -{ - navGraph.preload("skins/Gecko.lbioderm", true); - navGraph.preload("skins/Gecko.mbioderm", true); - navGraph.preload("skins/Gecko.hbioderm", true); - navGraph.preload("skins/base.lbioderm", true); - navGraph.preload("skins/HALO_Skin.lbioderm", true); - navGraph.preload("skins/HALO_Skin.mbioderm", true); - navGraph.preload("skins/HALO_Skin.hbioderm", true); - navGraph.preload("skins/sensor_pulse_large", true); - navGraph.preload("skins/base.hmale", false); - navGraph.preload("skins/beagle.hmale", false); - navGraph.preload("skins/base.mmale", false); - navGraph.preload("skins/beagle.mmale", false); - navGraph.preload("skins/base.lmale", false); - navGraph.preload("skins/swolf.mmale", false); - navGraph.preload("skins/beagle.lmale", false); -} - -function SinglePlayerGame::missionLoadDone(%game) -{ - Parent::missionLoadDone(%game); - trainingPreloads(); -} - -function serverCmdBuildClientTask(%client, %task, %team) -{ - // player shouldnt be able to use the voice commands to do anything -} - -function cancel(%sched) -{ -parent::Cancel(%sched); -return true; -} - -function lockArmorHack(%val) -{ - if (%val) - { - movemap.pop(); - modifiedmap.push(); - } - else - { - movemap.push(); - modifiedmap.pop(); - } - //$player.player.setMoveState(true); - //$player.player.schedule(1000,"setMoveState", false); -} - -function SinglePlayerGame::enterMissionArea(%game, %player){} -function SinglePlayerGame::leaveMissionArea(%game, %player) -{ - schedule(1000,0,"missionComplete", $player.miscMsg[TDSBeginningWin] ); - moveMap.schedule(1000, "pop"); -} -}; - -activatePackage(Beginning); - - - +// don't want this executing when building graphs +if($OFFLINE_NAV_BUILD) + return; + +// Script for Training +//=================================================================================== +//error("Training 1 script"); + +//Note: Quite messy right now.. I'll organize when it's done +//Not sure why this mission causes lots of console spam.. + +// variables +$numberOfEnemies[1] = 6; +$numberOfEnemies[2] = 6; +$numberOfEnemies[3] = 6; +$numberOfTeammates = 1; +$missionBotSkill[1] = 0.2; +$missionBotSkill[2] = 0.4; +$missionBotSkill[3] = 0.7; + +// package and callbacks + +package Beginning { +//BEGIN BEGINNING PACKAGE ======================================================================= + +function SinglePlayerGame::initGameVars(%game) +{ + echo("initializing beginning (TDS mission 1) game vars"); + Game.captorName = "Alchaldes"; //Main dude speaking + Game.controllerName = "Hammurabi"; //Guy at control panel + Game.guardOneName = "Romulus"; + Game.guardTwoName = "Hercules"; +} + +function PlayGui::onWake(%this) +{ + parent::onWake(%this); + //error("Waking training play gui"); + // okay we know the victim...erm...player is looking + // and we hope they have a body so lets do this + if(!game.playedIntro) { + game.PlayGuiAwake = true; + beginBeginning(); + } + +} + +function getTeammateGlobals() +{ + $TeammateWarnom0 = "Gila"; + $teammateSkill0 = 0.5; + $teammateVoice0 = Derm3; + $teammateEquipment0 = 0; + $teammateGender0 = B; +} + +function MP3Audio::play(%this) +{ + //too bad...no mp3 in training +} + +function toggleCommanderMap(%val) +{ + // No command Circuit fer' you! +} + +function toggleTaskListDlg( %val ) +{ + // Tasks? What tasks? Get the ef out of there when given the chance! +} + +function toggleInventoryHud( %val ) +{ + // Not even a message +} + +function toggleNetDisplayHud( %val ) +{ + // Hello, McFly? This is training! There's no net in training! +} + +function voiceCapture( %val ) +{ + // Uh, who do you think you are talking to? +} + +function giveall() +{ + error("When the going gets tough...wussies like you start cheating!"); + messageClient($player, 0, "Cheating eh? What\'s next? Camping?"); +} + +// get the ball rolling +//------------------------------------------------------------------------------ +function startCurrentMission() +{ + playGui.add(outerChatHud); + + //fade up from black + ServerConnection.setBlackOut(true, 0); + + new actionMap(ModifiedMap); + modifiedMap.bind(mouse0, "xaxis", yaw); + modifiedMap.bind(mouse0, "yaxis", pitch); +} + +function singlePlayerDead() +{ + missionFailed($player.miscMsg[TDSGenericLoss]); + AIMissionEnd(); + $objectiveQ[$enemyTeam].clear(); +} + +function beginBeginning() +{ +if(game.playedIntro) +return; + +$Beginning = ServerConnection.schedule(3000, setBlackOut, false, 4000); +$player.player.setTransform(DP.getTransform()); +$enemy0.stepMove(AlchaldesVisit.getPosition()); +yaw(1); + +return; + +game.playedIntro = true; +lockArmorHack(true); //Don't let our playah move + +//Now set up the victim +turnPlayerToPosition($enemy0.player.getPosition()); +$player.player.schedule(3000,"setInvincibleMode",$InvincibleTime,0.02); +schedule(3200,0,"hideHudHACK",false); +pitch(40); +if(!$firstperson)//Make sure we're in first person every time +toggleFirstPerson($player); +//Although both can't jet.. apparently b0ts need them to get around (even jumping down from stuff) +$player.player.setRechargeRate(0); +$player.player.setEnergyLevel(0); + +$teammate0.player.setTransform(Warnom0.getTransform()); + +//Alchaldes (leader of Criollos) +$enemy0.aimAt($player.player.getPosition()); +$enemy0.player.clearInventory(); +$enemy0.player.setInventory("EnergyPack",1); //Has a med condition; needs energy pack at all times +setName($enemy0,Game.CaptorName); +setSkin($enemy0,"HALO_SKIN"); + +//Hammurabi (Cloning -- lead researcher) +$enemy1.aimAt($player.player.getPosition()); +$enemy1.player.clearInventory(); +$enemy1.player.setInventory("EnergyPack",1); +setName($enemy1,Game.ControllerName); +setVoice($enemy1,"Derm3"); +setSkin($enemy1,"HALO_SKIN"); + +//Guard 1 (Looking at Dolosus) +$enemy2.aimAt($player.player.getPosition()); +setName($enemy2,Game.GuardOneName); +setVoice($enemy2,"Derm3"); +setSkin($enemy2,"HALO_SKIN"); + +//Guard 2 (Looking at Gila) +$enemy3.aimAt($teammate0.player.getPosition()); +setName($enemy3,Game.GuardTwoName); +setVoice($enemy3,"Derm3"); +setSkin($enemy3,"HALO_SKIN"); + +doText(TDS_M101); +doText(TDS_M102,3000); +doText(TDS_M103,3100); +doText(TDS_M104,3200); +doText(TDS_M105,3300); +doText(TDS_M106,3400); +doText(TDS_M107,3500); +doText(TDS_M108,3600); +doText(TDS_M109,3700); +doText(TDS_M101b,3800); +doText(TDS_M102b,3900); +doText(TDS_M103b,4000); +doText(TDS_M104b,4100); +doText(TDS_M105b,4200); +doText(TDS_M106b,4300); +doText(TDS_M107b,4400); +doText(TDS_M108b,4500); +doText(TDS_M109b,4600); +doText(TDS_M101c,4700); +doText(TDS_M102c,4800); +doText(TDS_M103c,4900); +doText(TDS_M104c,5000); +doText(TDS_M105c,5100); +doText(TDS_M106c,5200); +doText(TDS_M107c,5300); +} + +function giveEscortTask(%bot, %target) +{ + %newObjective = new AIObjective(AIOEscortPlayer) + { + dataBlock = "AIObjectiveMarker"; + weightLevel1 = 10000; + description = "Escort Player"; + targetClientId = %target; + offense = true; + }; + //echo(%newObjective); + MissionCleanup.add(%newObjective); + $ObjectiveQ[$playerTeam].add(%newObjective); + %bot.stepEscort(%target); + %bot.escort = %newObjective; + +} + +function detonateAll() +{ +ResearchTurret.applyDamage(400); +SecondaryResearch.applyDamage(400); +MainResearch.applyDamage(400); +Turret1.applyDamage(400); +Turret2.applyDamage(400); +Turret3.applyDamage(400); +BaseSensor.applyDamage(400); +BaseGen2.applyDamage(400); +DefenceGen.applyDamage(400); +ReactorGen2.applyDamage(400); +ReactorGen1.applyDamage(0.5); +InventoryStation1.applyDamage(400); +InventoryStation2.applyDamage(400); +InventoryStation3.applyDamage(400); +InventoryStation5.applyDamage(400); +messageAll('msgAll',"\c4Intercom: Main reactor absorbed most of the energy; high damage has been done to the whole network!"); +schedule(1500,0,"messageAll",'msgAll',"\c4Gila: Good! Sounds like any defences they have is down."); +//Alright, give the guards and other b0ts the objectives +$enemy2.addTask(AIEngageTask); +$enemy3.addTask(AIEngageTask); +$enemy4.addTask(AIEngageTask); +$enemy5.addTask(AIEngageTask); +} + +function storyMoveToHammurabi() +{ +$enemy0.stepMove(AlchaldesWorried.getPosition()); +$enemy0.schedule(2000,"aimAt",$enemy1.player.getPosition()); +$enemy2.aimAt($enemy0.player.getPosition()); +$enemy3.aimAt($enemy0.player.getPosition()); +} + +function storyMoveToGila() +{ +$enemy0.stepMove(AlchaldesObserve.getPosition()); +$enemy1.stepMove(HammurabiObserve.getPosition()); +$enemy0.schedule(2000,"aimAt",$teammate0.player.getPosition()); +$enemy1.schedule(2000,"aimAt",$teammate0.player.getPosition()); +} + +function storyMoveToDolosus() +{ +$enemy0.stepMove(enemy0.getPosition()); +$enemy1.stepMove(enemy1.getPosition()); +$enemy0.schedule(2000,"aimAt",$player.player.getPosition()); +$enemy1.schedule(2000,"aimAt",$player.player.getPosition()); +} + +function hideHudHACK(%bool) +{ +objectiveHud.setVisible(%bool); +hudClusterBack.setVisible(%bool); +inventoryHud.setVisible(%bool); +backPackFrame.setVisible(%bool); +weaponsHud.setVisible(%bool); +clockHUD.setVisible(%bool); +retCenterHUD.setVisible(%bool); +} + +//------------------------------------------------------------------------------ +function SinglePlayerGame::equip(%game, %player) +{ + //ya start with nothing...NOTHING! + %player.clearInventory(); + for(%i =0; %i<$InventoryHudCount; %i++) + %player.client.setInventoryHudItem($InventoryHudData[%i, itemDataName], 0, 1); + %player.client.clearBackpackIcon(); + + %set = %player.client.equipment; + + if (%player.client.race $= "Draakan") + { + %player.setInventory(Flamer,1); + %player.use(Flamer); + } + else + { + %player.setInventory("Chaingun",1,true); + %player.setInventory("ChaingunAmmo",999,true); + %player.setInventory("Disc",1,true); + %player.setInventory("DiscAmmo",999,true); + %player.setInventory("Shocklance",1,true); + %player.setInventory("AmmoPack",1,true); + %player.use("Chaingun"); + } +} + +function spawnSinglePlayer() +{ + resetWildCat(); + parent::spawnSinglePlayer(); +} + +function turnPlayerToPosition(%pos) +{ + %vec = VectorSub($player.player.position, %pos); + %angle = mATan( getWord(%vec, 0), getWord(%vec, 1) ); + %angle = %angle + 3.141529; + %newTransform = $player.player.position SPC "0 0 1" SPC %angle; + $player.player.setTransform(%newTransform); +} + +function singlePlayerGame::onAIRespawn(%game, %client) +{ + // DONT add the default tasks + //error("default tasks not added"); +} + +function singlePlayerGame::playerSpawned(%game, %player) +{ + parent::playerSpawned(%game, %player); +} + +function singlePlayerGame::gameOver(%game) +{ + //enable the voice chat menu again... + if (isObject(training1BlockMap)) + { + training1BlockMap.pop(); + training1BlockMap.delete(); + } + + if(HelpTextGui.isVisible()) + helpTextGui.setVisible(false); + + //Make sure our hidden HUD elements are visible again + hideHudHACK(true); + //Make sure our sounds stopped playing + doSpecialEffect(5); + + //re-enable the use of the settings button... + SinglePlayerEscSettingsBtn.setActive(1); + + Parent::gameOver(); +} + +function trainingPreloads() //Load any skins.. +{ + navGraph.preload("skins/Gecko.lbioderm", true); + navGraph.preload("skins/Gecko.mbioderm", true); + navGraph.preload("skins/Gecko.hbioderm", true); + navGraph.preload("skins/base.lbioderm", true); + navGraph.preload("skins/HALO_Skin.lbioderm", true); + navGraph.preload("skins/HALO_Skin.mbioderm", true); + navGraph.preload("skins/HALO_Skin.hbioderm", true); + navGraph.preload("skins/sensor_pulse_large", true); + navGraph.preload("skins/base.hmale", false); + navGraph.preload("skins/beagle.hmale", false); + navGraph.preload("skins/base.mmale", false); + navGraph.preload("skins/beagle.mmale", false); + navGraph.preload("skins/base.lmale", false); + navGraph.preload("skins/swolf.mmale", false); + navGraph.preload("skins/beagle.lmale", false); +} + +function SinglePlayerGame::missionLoadDone(%game) +{ + Parent::missionLoadDone(%game); + trainingPreloads(); +} + +function serverCmdBuildClientTask(%client, %task, %team) +{ + // player shouldnt be able to use the voice commands to do anything +} + +function cancel(%sched) +{ +parent::Cancel(%sched); +return true; +} + +function lockArmorHack(%val) +{ + if (%val) + { + movemap.pop(); + modifiedmap.push(); + } + else + { + movemap.push(); + modifiedmap.pop(); + } + //$player.player.setMoveState(true); + //$player.player.schedule(1000,"setMoveState", false); +} + +function SinglePlayerGame::enterMissionArea(%game, %player){} +function SinglePlayerGame::leaveMissionArea(%game, %player) +{ + schedule(1000,0,"missionComplete", $player.miscMsg[TDSBeginningWin] ); + moveMap.schedule(1000, "pop"); +} +}; + +activatePackage(Beginning); + + + diff --git a/missions/Beginning.mis b/missions/Beginning.mis index c8f88fc..d6c66f2 100644 --- a/missions/Beginning.mis +++ b/missions/Beginning.mis @@ -1,3259 +1,3259 @@ -// The Beginning (Dolosus Memories 1) -// MissionTypes = CTF -// DisplayName = The Beginning - -//--- MISSION BRIEFING BEGIN --- -//"Sing me a song, you're a singer. Do me a wrong, you're a bringer of evil. The less that you give, you're a taker." -// -Heaven & Hell by Black Sabbath, first three verses -//--- MISSION BRIEFING END --- - -// BriefingWAV = T2BOL_1 -// Bitmap = trn_5draconis - -//--- MISSION STRING BEGIN --- -//OBJECTIVES: -//Escape the facility -//Escape the grasp of the Criollos -//--- MISSION STRING END --- - -// PlanetName = Xeron, 3960 CE -//--- MISSION BLURB BEGIN --- -//You suddenly regain conciousness in an unfamiliar place. Your body temperature sends a large amount of feedback into the system, causing a power failure, -//--- MISSION BLURB END --- - -//--- OBJECT WRITE BEGIN --- -new SimGroup(MissionGroup) { - - powerCount = "0"; - - new MissionArea(MissionArea) { - area = "-760 -688 1664 1472"; - flightCeiling = "2000"; - flightCeilingRange = "50"; - }; - new Sun() { - position = "-1024 -1024 0"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - direction = "0.57735 0.57735 -0.57735"; - color = "1.000000 1.000000 1.000000 1.000000"; - ambient = "0.700000 0.700000 0.700000 1.000000"; - texture[0] = "special/sunFlare"; - texture[1] = "special/sunFlare02"; - texture[2] = "special/LensFlare/flare01"; - texture[3] = "special/LensFlare/flare02"; - texture[4] = "special/LensFlare/flare03"; - lensFlareScale = "0.7"; - lensFlareIntensity = "1"; - frontFlareSize = "300"; - backFlareSize = "450"; - flareColor = "1.000000 1.000000 1.000000 1.000000"; - }; - new TerrainBlock(Terrain) { - rotation = "1 0 0 0"; - scale = "1 1 1"; - detailTexture = "details/lavadet1"; - terrainFile = "Training5.ter"; - squareSize = "8"; - emptySquares = "217661 217676 86852 152390 87108 152646 218429 218444"; - - position = "-1024 -1024 0"; - }; - new NavigationGraph(NavGraph) { - conjoinAngleDev = "67"; - cullDensity = "0.3"; - customArea = "-776 -560 480 496"; - - conjoinBowlDev = "20"; - position = "0 0 0 1"; - GraphFile = "Training5.nav"; - rotation = "0 0 0 0"; - coverage = "0"; - scale = "1 1 1"; - }; - new Sky(Sky) { - position = "692 -352 0"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - cloudHeightPer[0] = "0.349971"; - cloudHeightPer[1] = "0.25"; - cloudHeightPer[2] = "0.199973"; - cloudSpeed1 = "0.0001"; - cloudSpeed2 = "0.0002"; - cloudSpeed3 = "0.0003"; - visibleDistance = "550"; - useSkyTextures = "1"; - renderBottomTexture = "0"; - SkySolidColor = "0.300000 0.100000 0.000000 0.800000"; - fogDistance = "250"; - fogColor = "0.300000 0.100000 0.000000 0.800000"; - fogVolume1 = "100 0 85"; - fogVolume2 = "600 85 270"; - fogVolume3 = "0 0 0"; - materialList = "sky_lava_starrynight.dml"; - windVelocity = "1 0 0"; - windEffectPrecipitation = "0"; - fogVolumeColor1 = "128.000000 128.000000 128.000000 0.000000"; - fogVolumeColor2 = "128.000000 128.000000 128.000000 0.000000"; - fogVolumeColor3 = "128.000000 128.000000 128.000000 0.000000"; - high_visibleDistance = "-1"; - high_fogDistance = "-1"; - high_fogVolume1 = "-1 1.81768e+31 4.33441e+24"; - high_fogVolume2 = "-1 1.10877e+21 5.53399e-11"; - high_fogVolume3 = "-1 1.78604e+25 1.84649e+25"; - - locked = "true"; - }; - new WaterBlock(Lava) { - position = "-224 -264 93.1568"; - rotation = "1 0 0 0"; - scale = "768 608 27.0092"; - liquidType = "Lava"; - density = "1"; - viscosity = "15"; - waveMagnitude = "1"; - surfaceTexture = "LiquidTiles/Lava"; - surfaceOpacity = "1"; - envMapTexture = "lava/skies/lava_starrynite_emap"; - envMapIntensity = "0.2"; - submergeTexture[0] = "special/lavadeath_1"; - submergeTexture[1] = "special/lavadeath_2"; - removeWetEdges = "1"; - - locked = "true"; - }; - new SimGroup(environment) { - - powerCount = "0"; - - new ParticleEmissionDummy(LavaSmoke) { - position = "-462.4 -366.791 5.12867"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "defaultEmissionDummy"; - lockCount = "0"; - homingCount = "0"; - emitter = "BeforeT5"; - velocity = "1"; - }; - new AudioEmitter(SmokeSound) { - position = "-462.61 -365.42 4.67642"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - fileName = "fx/environment/lavahiss.wav"; - useProfileDescription = "0"; - outsideAmbient = "0"; - volume = "0.8"; - isLooping = "1"; - is3D = "1"; - minDistance = "20"; - maxDistance = "120"; - coneInsideAngle = "360"; - coneOutsideAngle = "360"; - coneOutsideVolume = "1"; - coneVector = "0 0 1"; - loopCount = "-1"; - minLoopGap = "0"; - maxLoopGap = "0"; - type = "EffectAudioType"; - }; - new AudioEmitter(Outside1) { - position = "266.262 824.24 137.226"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - fileName = "fx/environment/lavamellow1.wav"; - useProfileDescription = "0"; - outsideAmbient = "1"; - volume = "0.4"; - isLooping = "1"; - is3D = "0"; - minDistance = "20"; - maxDistance = "1280"; - coneInsideAngle = "360"; - coneOutsideAngle = "360"; - coneOutsideVolume = "1"; - coneVector = "0 0 1"; - loopCount = "-1"; - minLoopGap = "0"; - maxLoopGap = "0"; - type = "EffectAudioType"; - }; - new AudioEmitter(Outside2) { - position = "266.262 824.24 137.226"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - fileName = "fx/environment/gravel3.wav"; - useProfileDescription = "0"; - outsideAmbient = "1"; - volume = "0.1"; - isLooping = "1"; - is3D = "0"; - minDistance = "20"; - maxDistance = "1280"; - coneInsideAngle = "360"; - coneOutsideAngle = "360"; - coneOutsideVolume = "1"; - coneVector = "0 0 1"; - loopCount = "-1"; - minLoopGap = "4000"; - maxLoopGap = "15000"; - type = "EffectAudioType"; - }; - new StaticShape(Genhonor) { - position = "-431.785 -366.853 38.3577"; - rotation = "0 0 1 89.3814"; - scale = "1 1 1"; - dataBlock = "Banner_Honor"; - lockCount = "0"; - homingCount = "0"; - - Target = "-1"; - }; - new StaticShape(Genstrength) { - position = "-463.154 -398.109 38.4185"; - rotation = "0 0 1 181.055"; - scale = "1 1 1"; - dataBlock = "Banner_Strength"; - lockCount = "0"; - homingCount = "0"; - - Target = "-1"; - }; - new StaticShape(GenUnity) { - position = "-494.404 -366.856 38.1826"; - rotation = "0 0 -1 89.9544"; - scale = "1 1 1"; - dataBlock = "Banner_Unity"; - lockCount = "0"; - homingCount = "0"; - - Target = "-1"; - }; - new StaticShape(DoorHonor) { - position = "-378.978 -350.28 115"; - rotation = "0 0 -1 89.9544"; - scale = "1 1 1"; - dataBlock = "Banner_Honor"; - lockCount = "0"; - homingCount = "0"; - - Target = "-1"; - }; - new StaticShape(DoorUnity) { - position = "-547.33 -352.238 115"; - rotation = "0 0 1 89.9544"; - scale = "1 1 1"; - dataBlock = "Banner_Unity"; - lockCount = "0"; - homingCount = "0"; - - Target = "-1"; - }; - new StaticShape(DoorStrength) { - position = "-462.751 -380.033 115"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Banner_Strength"; - lockCount = "0"; - homingCount = "0"; - - Target = "-1"; - }; - new StaticShape(WallHonor) { - position = "-372.568 -366.947 20.2877"; - rotation = "0 0 -1 89.9544"; - scale = "1 1 1"; - dataBlock = "Banner_Honor"; - lockCount = "0"; - homingCount = "0"; - - Target = "-1"; - }; - new StaticShape(WallUnity) { - position = "-552.788 -366.854 20.8502"; - rotation = "0 0 1 89.9544"; - scale = "1 1 1"; - dataBlock = "Banner_Unity"; - lockCount = "0"; - homingCount = "0"; - - Target = "-1"; - }; - new StaticShape(WallStrength) { - position = "-463.23 -399.018 35.4212"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Banner_Strength"; - lockCount = "0"; - homingCount = "0"; - - Target = "-1"; - }; - }; - new SimGroup(Teams) { - - powerCount = "0"; - - new SimGroup(Team1) { - - powerCount = "0"; - - new SimGroup(DropPoints) { - - powerCount = "0"; - - new Camera(DP) { - position = "106.622 -7.51593 164.733"; - rotation = "-0.0123037 -0.0124627 -0.999847 90.7445"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - - team = "1"; - }; - }; - new SimGroup(base) { - - powerCount = "1"; - - new StaticShape(station2) { - position = "785.587 532.538 206.108"; - rotation = "0.00499991 0.00471232 0.999976 93.3935"; - scale = "1 1 1"; - nameTag = "\x01720"; - dataBlock = "StationInventory"; - lockCount = "0"; - homingCount = "0"; - - locked = "false"; - Trigger = "14877"; - team = "1"; - Target = "33"; - }; - new StaticShape(Station1) { - position = "786.326 543.704 206.114"; - rotation = "0 0 1 93.3922"; - scale = "1 1 1"; - nameTag = "\x01720"; - dataBlock = "StationInventory"; - lockCount = "0"; - homingCount = "0"; - - locked = "false"; - Trigger = "14879"; - team = "1"; - Target = "34"; - }; - new StaticShape(TowerPower) { - position = "789.671 538.05 169.13"; - rotation = "0 0 1 92.6372"; - scale = "1 1 1"; - nameTag = "\x01719"; - dataBlock = "GeneratorLarge"; - lockCount = "0"; - homingCount = "0"; - - locked = "false"; - team = "1"; - Target = "35"; - }; - new InteriorInstance(DSTower) { - position = "782.299 538.347 205.138"; - rotation = "-0 0 -1 86.6992"; - scale = "1 1 1"; - interiorFile = "dtowr4.dif"; - showTerrainInside = "0"; - AudioProfile = "Universal_Base_1"; - AudioEnvironment = "SmallRoom"; - - locked = "false"; - team = "1"; - }; - }; - }; - new SimGroup(Team2) { - - powerCount = "0"; - - new SimGroup(BasePower) { - - powerCount = "1"; - - new SimGroup(base) { - - powerCount = "2"; - - new InteriorInstance(DBase2) { - position = "-463.118 -366.83 17.0706"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "dbase2.dif"; - showTerrainInside = "0"; - AudioProfile = "Universal_Base_3"; - AudioEnvironment = "BigRoom"; - - locked = "true"; - team = "2"; - }; - new StaticShape(ObjectiveGen1) { - position = "-460.757 -348.913 6.0481"; - rotation = "0 0 1 179.909"; - scale = "1 1 1"; - nameTag = "\x01718"; - dataBlock = "GeneratorLarge"; - lockCount = "0"; - homingCount = "0"; - - team = "2"; - Target = "36"; - }; - }; - new StaticShape(InventoryStation5) { - position = "-387.192 -440.08 14.1387"; - rotation = "0 0 1 89.9544"; - scale = "1 1 1"; - dataBlock = "StationInventory"; - lockCount = "0"; - homingCount = "0"; - - Trigger = "14888"; - team = "2"; - Target = "37"; - }; - new StaticShape(InventoryStation1) { - position = "-387.019 -421.21 14.1507"; - rotation = "0 0 1 89.9544"; - scale = "1 1 1"; - dataBlock = "StationInventory"; - lockCount = "0"; - homingCount = "0"; - - Trigger = "14890"; - team = "2"; - Target = "38"; - }; - new StaticShape(InventoryStation2) { - position = "-402.649 -440.174 14.1592"; - rotation = "0 0 -1 90.1369"; - scale = "1 1 1"; - dataBlock = "StationInventory"; - lockCount = "0"; - homingCount = "0"; - - Trigger = "14892"; - team = "2"; - Target = "39"; - }; - new StaticShape(InventoryStation3) { - position = "-402.755 -421.308 14.112"; - rotation = "0 0 -1 90.1369"; - scale = "1 1 1"; - dataBlock = "StationInventory"; - lockCount = "0"; - homingCount = "0"; - - Trigger = "14894"; - team = "2"; - Target = "40"; - }; - new StaticShape(BaseGen2) { - position = "-380.672 -366.624 29.0406"; - rotation = "0 0 1 89.9544"; - scale = "1 1 1"; - nameTag = "\x01717"; - dataBlock = "GeneratorLarge"; - lockCount = "0"; - homingCount = "0"; - - team = "2"; - Target = "41"; - }; - new StaticShape(FloatingBaseSensor) { - position = "-504.6 -203.122 156.504"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - nameTag = "\x01716"; - dataBlock = "SensorLargePulse"; - lockCount = "0"; - homingCount = "0"; - - team = "2"; - Target = "42"; - }; - new InteriorInstance(BaseSensorPlat) { - position = "-504.631 -203.509 154.979"; - rotation = "1 0 0 0"; - scale = "0.662015 0.662282 0.732005"; - interiorFile = "dplat1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - }; - new SimGroup(DropPoints) { - - powerCount = "0"; - - new Camera(enemy0) { - position = "-214.907 -8.05464 163.71"; - rotation = "0 0 1 89.3814"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - - team = "2"; - }; - }; - new Item(InvRoomRepairPack) { - position = "-403.617 -449.228 16.0153"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "RepairPack"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - - team = "2"; - Target = "-1"; - }; - new Item(SatchelChargePack) { - position = "-463.131 -366.848 41.3416"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "SatchelCharge"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - - team = "2"; - Target = "-1"; - }; - new SimGroup(Perifery) { - - powerCount = "1"; - - new InteriorInstance() { - position = "-672.476 -378.377 93.2107"; - rotation = "0 0 -1 91.8558"; - scale = "1 1 1"; - interiorFile = "dmisc1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new StaticShape(PeriferyGen) { - position = "-547.707 -367.013 29.0564"; - rotation = "0 0 1 89.9544"; - scale = "1 1 1"; - nameTag = "\x01715"; - dataBlock = "GeneratorLarge"; - lockCount = "0"; - homingCount = "0"; - - team = "2"; - Target = "43"; - }; - new Turret(Turret3) { - position = "-482.32 -249.952 111.06"; - rotation = "-0 0 -1 0.181308"; - scale = "1 1 1"; - dataBlock = "TurretBaseLarge"; - lockCount = "0"; - homingCount = "0"; - initialBarrel = "PlasmaBarrelLarge"; - - team = "2"; - Target = "44"; - }; - new InteriorInstance() { - position = "-481.857 -249.119 101.34"; - rotation = "0 0 1 179.909"; - scale = "1 1 1"; - interiorFile = "dmisc1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new Turret(Turret3) { - position = "-257.301 -388.932 93.0956"; - rotation = "0 0 1 127.587"; - scale = "1 1 1"; - dataBlock = "TurretBaseLarge"; - lockCount = "0"; - homingCount = "0"; - initialBarrel = "PlasmaBarrelLarge"; - - team = "2"; - Target = "45"; - }; - new InteriorInstance() { - position = "-256.927 -389.808 83.3756"; - rotation = "-0 0 -1 52.3217"; - scale = "1 1 1"; - interiorFile = "dmisc1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new Turret(Turret3) { - position = "-673.322 -377.939 102.931"; - rotation = "0 0 1 88.0532"; - scale = "1 1 1"; - dataBlock = "TurretBaseLarge"; - lockCount = "0"; - homingCount = "0"; - initialBarrel = "PlasmaBarrelLarge"; - - team = "2"; - Target = "46"; - }; - }; - new SimGroup(base0) { - - providesPower = "1"; - powerCount = "1"; - - new InteriorInstance(InteriorInstance) { - position = "124.542 -12.6592 168.762"; - rotation = "0 0 1 179.909"; - scale = "1 1 1"; - interiorFile = "dbunk_nefsmall.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new ForceFieldBare(IsolationField) { - position = "103.509 -11.7308 162.612"; - rotation = "1 0 0 0"; - scale = "8.10437 8.05813 6.12739"; - dataBlock = "defaultForceFieldBare"; - lockCount = "0"; - homingCount = "0"; - - team = "2"; - Target = "47"; - }; - new StaticShape() { - position = "115.669 -6.75199 162.639"; - rotation = "0 0 1 89.9544"; - scale = "5.24703 1 0.381909"; - nameTag = "\x01714"; - dataBlock = "GeneratorLarge"; - lockCount = "0"; - homingCount = "0"; - - damageTimeMS = "941594"; - lastDamagedBy = "14847"; - team = "2"; - Target = "48"; - isburning = "0"; - lastDamagedByTeam = "1"; - }; - new StaticShape() { - position = "107.518 -7.24103 171.587"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - nameTag = "\x01714"; - dataBlock = "SensorLargePulse"; - lockCount = "0"; - homingCount = "0"; - - damageTimeMS = "925206"; - lastDamagedBy = "14847"; - team = "2"; - Target = "49"; - isburning = "0"; - lastDamagedByTeam = "1"; - }; - }; - new SimGroup(BaseForceFields) { - - powerCount = "1"; - - new StaticShape(ObjectiveGen2) { - position = "-465.911 -348.919 6.0157"; - rotation = "0 0 1 179.909"; - scale = "1 1 1"; - nameTag = "\x01713"; - dataBlock = "GeneratorLarge"; - lockCount = "0"; - homingCount = "0"; - - team = "2"; - Target = "50"; - }; - new ForceFieldBare(CenterEnteranceFF) { - position = "-471.214 -379.6 99.8223"; - rotation = "1 0 0 0"; - scale = "16.6319 0.452235 9.31077"; - dataBlock = "defaultTeamSlowFieldBare"; - lockCount = "0"; - homingCount = "0"; - - team = "2"; - Target = "51"; - color = "0.500000 0.500000 1.000000 1.000000"; - }; - new ForceFieldBare(WestEnteranceFF) { - position = "-546.997 -359.996 99.1512"; - rotation = "1 0 0 0"; - scale = "0.912282 16.3236 11.119"; - dataBlock = "defaultTeamSlowFieldBare"; - lockCount = "0"; - homingCount = "0"; - - team = "2"; - Target = "52"; - color = "0.500000 0.500000 1.000000 1.000000"; - }; - new ForceFieldBare(EastEnteranceFF) { - position = "-379.979 -359.074 100.923"; - rotation = "1 0 0 0"; - scale = "0.782673 16.3247 10.9793"; - dataBlock = "defaultTeamSlowFieldBare"; - lockCount = "0"; - homingCount = "0"; - - team = "2"; - Target = "53"; - color = "0.500000 0.500000 1.000000 1.000000"; - }; - }; - new SimGroup(LavaBridges) { - - powerCount = "0"; - - new InteriorInstance() { - position = "107.398 -7.70099 161.612"; - rotation = "1 0 0 0"; - scale = "2 2 1"; - interiorFile = "dbrdg8.dif"; - showTerrainInside = "0"; - - locked = "true"; - team = "2"; - }; - new InteriorInstance() { - position = "107.383 -31.701 161.612"; - rotation = "0 0 -1 90"; - scale = "2 2 1"; - interiorFile = "dbrdg7.dif"; - showTerrainInside = "0"; - - locked = "true"; - team = "2"; - }; - new InteriorInstance(InteriorInstance) { - position = "107.377 15.9 161.612"; - rotation = "0 0 1 90"; - scale = "2 2 1"; - interiorFile = "dbrdg7.dif"; - showTerrainInside = "0"; - - locked = "true"; - team = "2"; - }; - new InteriorInstance() { - position = "83.403 -7.67801 161.612"; - rotation = "1 0 0 0"; - scale = "2 2 1"; - interiorFile = "dbrdg7.dif"; - showTerrainInside = "0"; - - locked = "true"; - team = "2"; - }; - new InteriorInstance() { - position = "131.364 -7.702 161.612"; - rotation = "0 0 1 180"; - scale = "2 2 1"; - interiorFile = "dbrdg7.dif"; - showTerrainInside = "0"; - - locked = "true"; - team = "2"; - }; - new InteriorInstance() { - position = "51.42 -7.67899 164.359"; - rotation = "1 0 0 0"; - scale = "2 2 1"; - interiorFile = "dbrdg9.dif"; - showTerrainInside = "0"; - - locked = "true"; - team = "2"; - }; - new InteriorInstance() { - position = "107.38 47.897 164.359"; - rotation = "0 0 1 90"; - scale = "2 2 1"; - interiorFile = "dbrdg9.dif"; - showTerrainInside = "0"; - - locked = "true"; - team = "2"; - }; - new InteriorInstance() { - position = "107.382 -63.694 164.359"; - rotation = "0 0 1 90"; - scale = "2 2 1"; - interiorFile = "dbrdg9.dif"; - showTerrainInside = "0"; - - locked = "true"; - team = "2"; - }; - new InteriorInstance() { - position = "163.362 -7.698 164.359"; - rotation = "0 0 1 180"; - scale = "2 2 1"; - interiorFile = "dbrdg9.dif"; - showTerrainInside = "0"; - - locked = "true"; - team = "2"; - }; - new InteriorInstance() { - position = "107.382 -63.694 164.359"; - rotation = "0 0 1 90"; - scale = "2 2 1"; - interiorFile = "dbrdg9.dif"; - showTerrainInside = "0"; - - locked = "true"; - team = "2"; - }; - new InteriorInstance() { - position = "163.364 -47.697 161.608"; - rotation = "0 0 -1 90"; - scale = "1 1 1"; - interiorFile = "dbrdg7a.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "163.366 -63.6898 164.359"; - rotation = "0 0 1 90"; - scale = "1 1 1"; - interiorFile = "dbrdg9a.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "163.379 47.8998 164.359"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "dbrdg9a.dif"; - showTerrainInside = "0"; - - locked = "false"; - team = "2"; - }; - new InteriorInstance() { - position = "147.372 -63.701 161.608"; - rotation = "0 0 1 180"; - scale = "1 1 1"; - interiorFile = "dbrdg7a.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "163.376 31.901 161.608"; - rotation = "0 0 1 90"; - scale = "1 1 1"; - interiorFile = "dbrdg7a.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "147.387 47.897 161.608"; - rotation = "0 0 1 180"; - scale = "1 1 1"; - interiorFile = "dbrdg7a.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "51.4084 48.1443 164.359"; - rotation = "0 0 -1 90"; - scale = "1 1 1"; - interiorFile = "dbrdg9a.dif"; - showTerrainInside = "0"; - - locked = "true"; - team = "2"; - }; - new InteriorInstance() { - position = "51.398 32.214 161.608"; - rotation = "0 0 1 90"; - scale = "1 1 1"; - interiorFile = "dbrdg7a.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "67.365 48.143 161.608"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "dbrdg7a.dif"; - showTerrainInside = "0"; - - locked = "true"; - team = "2"; - }; - new InteriorInstance() { - position = "51.364 -47.734 161.608"; - rotation = "0 0 -1 90"; - scale = "1 1 1"; - interiorFile = "dbrdg7a.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "51.3834 -63.6902 164.359"; - rotation = "0 0 1 180"; - scale = "1 1 1"; - interiorFile = "dbrdg9a.dif"; - showTerrainInside = "0"; - - locked = "true"; - team = "2"; - }; - new InteriorInstance() { - position = "67.378 -63.705 161.608"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "dbrdg7a.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new SimGroup(FFBridges) { - - powerCount = "0"; - - new SimGroup(CatwalkFFs) { - - powerCount = "1"; - - new ForceFieldBare() { - position = "71.293 44.475 161.61"; - rotation = "1 0 0 0"; - scale = "24.126 7.54321 1"; - dataBlock = "defaultNoTeamLavaLightField"; - lockCount = "0"; - homingCount = "0"; - - team = "2"; - Target = "54"; - }; - new ForceFieldBare() { - position = "119.376 44.161 161.61"; - rotation = "1 0 0 0"; - scale = "24.0507 7.54321 1"; - dataBlock = "defaultNoTeamLavaLightField"; - lockCount = "0"; - homingCount = "0"; - - team = "2"; - Target = "55"; - }; - new ForceFieldBare() { - position = "119.389 -67.489 161.61"; - rotation = "1 0 0 0"; - scale = "24.0182 7.54321 1"; - dataBlock = "defaultNoTeamLavaLightField"; - lockCount = "0"; - homingCount = "0"; - - team = "2"; - Target = "56"; - }; - new ForceFieldBare() { - position = "159.57 27.902 161.61"; - rotation = "0 0 1 90"; - scale = "23.6238 7.54321 1"; - dataBlock = "defaultNoTeamLavaLightField"; - lockCount = "0"; - homingCount = "0"; - - team = "2"; - Target = "57"; - }; - new ForceFieldBare() { - position = "159.57 -19.69 161.61"; - rotation = "0 0 1 90"; - scale = "24.0246 7.54321 0.654541"; - dataBlock = "defaultNoTeamLavaLightField"; - lockCount = "0"; - homingCount = "0"; - - team = "2"; - Target = "58"; - }; - new StaticShape(CatwalkFFGen) { - position = "296.902 281.478 82.1046"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - nameTag = "\x01712"; - dataBlock = "GeneratorLarge"; - lockCount = "0"; - homingCount = "0"; - - team = "2"; - Target = "59"; - }; - new ForceFieldBare() { - position = "47.57 28.212 161.61"; - rotation = "0 0 1 90"; - scale = "23.9272 7.54321 1"; - dataBlock = "defaultNoTeamLavaLightField"; - lockCount = "0"; - homingCount = "0"; - - team = "2"; - Target = "60"; - }; - new ForceFieldBare() { - position = "47.57 -19.676 161.61"; - rotation = "0 0 1 90"; - scale = "24.0593 7.54321 1"; - dataBlock = "defaultNoTeamLavaLightField"; - lockCount = "0"; - homingCount = "0"; - - team = "2"; - Target = "61"; - }; - new ForceFieldBare() { - position = "71.358 -67.489 161.61"; - rotation = "1 0 0 0"; - scale = "24.0928 7.54321 1"; - dataBlock = "defaultNoTeamLavaLightField"; - lockCount = "0"; - homingCount = "0"; - - team = "2"; - Target = "62"; - }; - }; - new SimGroup(DrawBridges) { - - powerCount = "0"; - - new SimGroup(WestBridge) { - - powerCount = "1"; - - new StaticShape(WestBridgeGen) { - position = "288.492 280.587 82.0062"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - nameTag = "\x01711"; - dataBlock = "GeneratorLarge"; - lockCount = "0"; - homingCount = "0"; - - team = "2"; - Target = "63"; - }; - new ForceFieldBare() { - position = "39.406 -3.879 161.61"; - rotation = "0 0 1 180"; - scale = "236.773 7.54321 1"; - dataBlock = "defaultNoTeamLavaLightField"; - lockCount = "0"; - homingCount = "0"; - - team = "2"; - Target = "64"; - }; - }; - new SimGroup(EastBridge) { - - powerCount = "1"; - - new StaticShape(EastBridgeGen) { - position = "280.367 280.27 82.0062"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - nameTag = "\x01710"; - dataBlock = "GeneratorLarge"; - lockCount = "0"; - homingCount = "0"; - - team = "2"; - Target = "65"; - }; - new ForceFieldBare() { - position = "440.421 -3.96201 161.954"; - rotation = "0 0 1 180"; - scale = "265.064 7.54321 0.654541"; - dataBlock = "defaultNoTeamLavaLightField"; - lockCount = "0"; - homingCount = "0"; - - team = "2"; - Target = "66"; - }; - }; - new SimGroup(SouthBridge) { - - powerCount = "1"; - - new StaticShape(SouthBridgeGen) { - position = "284.537 280.408 82.0062"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - nameTag = "\x01733"; - dataBlock = "GeneratorLarge"; - lockCount = "0"; - homingCount = "0"; - - team = "2"; - Target = "67"; - }; - new ForceFieldBare() { - position = "103.594 -75.687 161.61"; - rotation = "0 0 1 90"; - scale = "168.54 7.54321 1"; - dataBlock = "defaultNoTeamLavaLightField"; - lockCount = "0"; - homingCount = "0"; - - team = "2"; - Target = "68"; - }; - }; - }; - }; - new InteriorInstance() { - position = "107.31 -260.168 161.61"; - rotation = "0 0 1 89.9544"; - scale = "1 1 1"; - interiorFile = "dbrdg3a.dif"; - showTerrainInside = "0"; - - locked = "true"; - team = "2"; - }; - new InteriorInstance() { - position = "107.343 318.618 161.61"; - rotation = "0 0 1 89.9544"; - scale = "1 1 1"; - interiorFile = "dbrdg7.dif"; - showTerrainInside = "0"; - - locked = "true"; - team = "2"; - }; - new InteriorInstance() { - position = "107.318 -280.154 161.61"; - rotation = "0 0 -1 90"; - scale = "1 1 1"; - interiorFile = "dbrdg7.dif"; - showTerrainInside = "0"; - - locked = "true"; - team = "2"; - }; - new InteriorInstance() { - position = "107.382 298.632 161.61"; - rotation = "0 0 -1 90.0456"; - scale = "1 1 1"; - interiorFile = "dbrdg3a.dif"; - showTerrainInside = "0"; - - locked = "true"; - team = "2"; - }; - new InteriorInstance() { - position = "476.391 -7.707 161.608"; - rotation = "0 0 1 180"; - scale = "1 1 1"; - interiorFile = "dbrdg7.dif"; - showTerrainInside = "0"; - - locked = "false"; - team = "2"; - }; - new InteriorInstance() { - position = "456.405 -7.763 161.608"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "dbrdg3a.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "107.386 49.616 161.534"; - rotation = "1 0 0 0"; - scale = "1 1 1.0262"; - interiorFile = "dpole1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "107.386 49.616 141.03"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "dpole1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "107.439 292.602 161.63"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "dpole1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "450.286 -7.789 162.448"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "dpole1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "450.286 -7.789 142.448"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "dpole1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "107.235 -254.11 142.49"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "dpole1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "107.235 -254.11 162.47"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "dpole1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "106.984 -7.55801 161.01"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "dpole1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "106.984 -7.55801 141.03"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "dpole1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "106.984 -7.55801 121.09"; - rotation = "1 0 0 0"; - scale = "1 1 1.05589"; - interiorFile = "dpole1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "107.394 -65.561 121.09"; - rotation = "1 0 0 0"; - scale = "1 1 1.05589"; - interiorFile = "dpole1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "107.394 -65.561 141.03"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "dpole1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "107.394 -65.561 161.534"; - rotation = "1 0 0 0"; - scale = "1 1 1.0262"; - interiorFile = "dpole1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "51.14 -63.648 161.534"; - rotation = "1 0 0 0"; - scale = "1 1 1.0262"; - interiorFile = "dpole1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "51.14 -63.648 141.03"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "dpole1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "51.14 -63.648 121.09"; - rotation = "1 0 0 0"; - scale = "1 1 1.05589"; - interiorFile = "dpole1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "51.379 48.853 121.09"; - rotation = "1 0 0 0"; - scale = "1 1 1.05589"; - interiorFile = "dpole1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "51.379 48.853 141.03"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "dpole1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "51.379 48.853 161.534"; - rotation = "1 0 0 0"; - scale = "1 1 1.0262"; - interiorFile = "dpole1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "49.864 -7.771 121.09"; - rotation = "1 0 0 0"; - scale = "1 1 1.05589"; - interiorFile = "dpole1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "49.864 -7.771 141.03"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "dpole1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "49.864 -7.771 161.534"; - rotation = "1 0 0 0"; - scale = "1 1 1.0262"; - interiorFile = "dpole1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "163.415 -63.978 121.09"; - rotation = "1 0 0 0"; - scale = "1 1 1.05589"; - interiorFile = "dpole1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "163.415 -63.978 141.03"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "dpole1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "163.415 -63.978 161.534"; - rotation = "1 0 0 0"; - scale = "1 1 1.0262"; - interiorFile = "dpole1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "165.039 -7.49799 121.09"; - rotation = "1 0 0 0"; - scale = "1 1 1.05589"; - interiorFile = "dpole1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "165.039 -7.49799 141.03"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "dpole1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "165.039 -7.49799 161.534"; - rotation = "1 0 0 0"; - scale = "1 1 1.0262"; - interiorFile = "dpole1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "163.423 48.406 121.09"; - rotation = "1 0 0 0"; - scale = "1 1 1.05589"; - interiorFile = "dpole1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "163.423 48.406 141.03"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "dpole1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "163.423 48.406 161.534"; - rotation = "1 0 0 0"; - scale = "1 1 1.0262"; - interiorFile = "dpole1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "107.386 49.616 121.09"; - rotation = "1 0 0 0"; - scale = "1 1 1.05589"; - interiorFile = "dpole1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - }; - new SimGroup(TeamDrops) { - - powerCount = "0"; - - new SpawnSphere(respawnSphere) { - position = "-445.99 -376.448 66.8051"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "SpawnSphereMarker"; - lockCount = "0"; - homingCount = "0"; - radius = "140"; - sphereWeight = "100"; - indoorWeight = "100"; - outdoorWeight = "50"; - }; - }; - new SimGroup(nodes) { - - powerCount = "0"; - - new Camera(AlchaldesVisit) { - position = "91.398 -6.88843 163.757"; - rotation = "0 0 1 89.3814"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - - team = "2"; - }; - }; - new SimGroup(IsolationGroup) { - - powerCount = "0"; - - new Turret(NWTowerTurret) { - position = "51.4 47.253 162.665"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - nameTag = "\x01734"; - dataBlock = "TurretBaseLarge"; - lockCount = "0"; - homingCount = "0"; - initialBarrel = "MissileBarrelLarge"; - - team = "2"; - Target = "69"; - }; - new Turret(SETowerTurret) { - position = "163.318 -62.732 162.585"; - rotation = "0 0 1 179.909"; - scale = "1 1 1"; - nameTag = "\x01702"; - dataBlock = "TurretBaseLarge"; - lockCount = "0"; - homingCount = "0"; - initialBarrel = "MissileBarrelLarge"; - - team = "2"; - Target = "70"; - }; - new SimGroup(NorthBridge) { - - powerCount = "1"; - - new StaticShape(NorthBridgeGen) { - position = "292.178 280.66 82.0062"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - nameTag = "\x01703"; - dataBlock = "GeneratorLarge"; - lockCount = "0"; - homingCount = "0"; - - team = "2"; - Target = "71"; - }; - new ForceFieldBare() { - position = "103.62 282.64 161.61"; - rotation = "0 0 1 90"; - scale = "222.776 7.54321 1"; - dataBlock = "defaultNoTeamLavaLightField"; - lockCount = "0"; - homingCount = "0"; - - team = "2"; - Target = "72"; - }; - }; - new InteriorInstance() { - position = "-207.261 -7.55701 142.482"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "dpole1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "-207.261 -7.55701 162.482"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "dpole1.dif"; - showTerrainInside = "0"; - - team = "2"; - }; - new InteriorInstance() { - position = "-213.37 -7.668 161.61"; - rotation = "0 0 1 180"; - scale = "1 1 1"; - interiorFile = "dbrdg3a.dif"; - showTerrainInside = "0"; - - locked = "true"; - team = "2"; - }; - new Turret(NETowerTurret) { - position = "163.387 46.947 162.665"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - nameTag = "\x01701"; - dataBlock = "TurretBaseLarge"; - lockCount = "0"; - homingCount = "0"; - initialBarrel = "MissileBarrelLarge"; - - team = "2"; - Target = "73"; - }; - new InteriorInstance() { - position = "-233.356 -7.69101 161.61"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "dbrdg7.dif"; - showTerrainInside = "0"; - - locked = "true"; - team = "2"; - }; - new Turret(SWTowerTurret) { - position = "51.473 -62.791 162.565"; - rotation = "0 0 1 179.909"; - scale = "1 1 1"; - nameTag = "\x01738"; - dataBlock = "TurretBaseLarge"; - lockCount = "0"; - homingCount = "0"; - initialBarrel = "MissileBarrelLarge"; - - team = "2"; - Target = "74"; - }; - }; - }; - new SimGroup(team0) { - - powerCount = "0"; - }; - }; - new SimGroup(RandomOrganics) { - - powerCount = "0"; - - new SimGroup(Addition1DSPlant16) { - - powerCount = "0"; - - new TSStatic() { - position = "-348 -196 106.781"; - rotation = "0 0 1 167"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-636 -532 150.656"; - rotation = "0 0 1 230"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-428 -260 111.188"; - rotation = "0 0 1 114"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-412 -164 111.656"; - rotation = "0 0 -1 119"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-364 -164 103.953"; - rotation = "0 0 1 120"; - scale = "1 1 1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-292 -188 128.547"; - rotation = "0 0 1 184"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-492 -548 122.672"; - rotation = "0 0 -1 75.0002"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-276 -468 111.969"; - rotation = "0 0 -1 58.0005"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-500 -556 123.344"; - rotation = "0 0 1 61"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-604 -292 115.953"; - rotation = "0 0 1 52"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-636 -188 157.312"; - rotation = "0 0 1 103"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-316 -260 122.5"; - rotation = "0 0 1 58.9998"; - scale = "1 1 1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-572 -284 131.266"; - rotation = "0 0 -1 55.0003"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-636 -492 158.203"; - rotation = "0 0 1 3.99996"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-636 -540 152.703"; - rotation = "0 0 1 219"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-444 -540 129.828"; - rotation = "0 0 -1 19.0001"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-588 -556 106.531"; - rotation = "0 0 -1 92.0004"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-292 -188 128.547"; - rotation = "0 0 1 202"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-620 -252 148.969"; - rotation = "0 0 1 38"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-276 -180 125.922"; - rotation = "0 0 1 43"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-660 -236 138.141"; - rotation = "0 0 1 224"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-556 -196 130.344"; - rotation = "0 0 -1 78.0002"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-564 -228 136.031"; - rotation = "0 0 1 228"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-356 -204 105.172"; - rotation = "0 0 1 19"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-444 -476 96.5469"; - rotation = "0 0 1 206"; - scale = "1 1 1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-380 -188 101.297"; - rotation = "0 0 1 48"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-276 -420 95.9688"; - rotation = "0 0 1 15"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-292 -540 126.203"; - rotation = "0 0 -1 112"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-428 -260 111.188"; - rotation = "0 0 -1 13.0002"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-580 -556 104.781"; - rotation = "0 0 1 147"; - scale = "1 1 1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-508 -548 122.984"; - rotation = "0 0 1 60.0001"; - scale = "1 1 1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-276 -188 124.547"; - rotation = "0 0 1 76.9998"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-284 -484 110.828"; - rotation = "0 0 -1 35"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-412 -172 113.031"; - rotation = "0 0 -1 16.9999"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-412 -172 113.031"; - rotation = "0 0 -1 50.9998"; - scale = "1 1 1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-436 -244 112.297"; - rotation = "0 0 1 78.0002"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-644 -228 141.891"; - rotation = "0 0 1 97.9998"; - scale = "1 1 1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-524 -164 147.094"; - rotation = "0 0 1 142"; - scale = "1 1 1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-292 -492 109.156"; - rotation = "0 0 1 53"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-620 -228 151.547"; - rotation = "0 0 -1 92.0004"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg16.dts"; - }; - }; - new SimGroup(Addition2DSPlant17) { - - powerCount = "0"; - - new TSStatic() { - position = "-500 -548 123.25"; - rotation = "-0.0619038 0.012427 0.998005 146.064"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "-564 -236 137.688"; - rotation = "0.101053 0.144122 0.984387 70.8497"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "-444 -548 127.344"; - rotation = "-0.830265 -0.530269 0.17168 17.3446"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "-492 -524 123.797"; - rotation = "0.477358 -0.532224 -0.69919 26.9199"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "-636 -500 157.062"; - rotation = "-0.749737 0.399268 -0.527712 16.9644"; - scale = "1 1 1"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "-412 -164 111.656"; - rotation = "0.0543937 0.0547673 -0.997016 88.1707"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "-316 -412 79.5"; - rotation = "0.00755817 -0.103259 0.994626 63.2758"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "-444 -196 126.422"; - rotation = "0.175219 -0.324668 -0.929456 39.597"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg17.dts"; - }; - }; - new SimGroup(Addition3DSPlant17) { - - powerCount = "0"; - - new TSStatic() { - position = "12 -412 104.844"; - rotation = "-0.0503551 -0.018623 0.998558 143.05"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "-20 -412 106.25"; - rotation = "0.0761431 -0.110215 -0.990987 88.5186"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "-12 -468 142.812"; - rotation = "0.137513 0.111945 0.984154 97.9076"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "-84 -452 145.703"; - rotation = "0.0935228 0.120898 0.98825 234.447"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "-68 -492 131.578"; - rotation = "-0.0355517 -0.0468571 0.998269 78.0976"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "-12 -412 106.219"; - rotation = "0.0821308 -0.000199039 0.996622 84.1932"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "-4 -412 105.5"; - rotation = "0.0670501 -0.0130461 0.997664 88.134"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "-68 -492 131.578"; - rotation = "-0.495608 -0.154473 0.854699 8.18628"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "-68 -476 133.109"; - rotation = "-0.00379916 0.163641 -0.986513 80.767"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "-76 -484 132.672"; - rotation = "0.108004 0.0352753 0.993524 194.904"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg17.dts"; - }; - }; - new SimGroup(Addition4DSPlant19) { - - powerCount = "0"; - - new TSStatic() { - position = "172 -332 146.234"; - rotation = "0 0 1 16"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "172 -348 148.938"; - rotation = "0 0 -1 73.0006"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "172 -348 148.938"; - rotation = "0 0 1 69.0002"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "140 -452 147.734"; - rotation = "0 0 1 111"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "-4 -412 105.5"; - rotation = "0 0 1 70.9998"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "212 -332 153.156"; - rotation = "0 0 1 104"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "84 -308 164.703"; - rotation = "0 0 1 3.99996"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "204 -380 156.266"; - rotation = "0 0 1 17"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "196 -372 157.594"; - rotation = "0 0 -1 11.9998"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "-12 -476 143.562"; - rotation = "0 0 -1 37.0002"; - scale = "1 1 1"; - shapeName = "dorg19.dts"; - }; - }; - new SimGroup(Addition5DSPlant19) { - - powerCount = "0"; - - new TSStatic() { - position = "-364 28 166"; - rotation = "0 0 -1 60.0001"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "-420 -100 94.5312"; - rotation = "0 0 1 113"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "-292 -172 129.5"; - rotation = "0 0 1 138"; - scale = "1 1 1"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "-204 196 132.141"; - rotation = "0 0 -1 50.9998"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "-364 -172 103.875"; - rotation = "0 0 1 39"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg19.dts"; - }; - }; - new SimGroup(Addition6DSPlant16) { - - powerCount = "0"; - - new TSStatic() { - position = "-524 -212 146.031"; - rotation = "0 0 1 38"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-500 -76 105.25"; - rotation = "0 0 1 126"; - scale = "1 1 1"; - shapeName = "dorg16.dts"; - }; - }; - new SimGroup(Addition11DSPlant16) { - - powerCount = "0"; - - new TSStatic() { - position = "892 476 173.172"; - rotation = "0 0 1 209"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "964 356 99.141"; - rotation = "0 0 -1 97"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "948 812 136.375"; - rotation = "0 0 -1 94"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "964 156 94.0313"; - rotation = "0 0 1 97"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "1148 572 136.016"; - rotation = "0 0 1 118"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "812 420 116.266"; - rotation = "0 0 1 141"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "548 900 161.422"; - rotation = "0 0 -1 50.9998"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "756 612 151.969"; - rotation = "0 0 1 233"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "1140 788 162.828"; - rotation = "0 0 -1 73.0006"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "1028 484 164"; - rotation = "0 0 1 234"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "1044 484 161.5"; - rotation = "0 0 -1 2.9997"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "812 268 89.9687"; - rotation = "0 0 1 238"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "956 812 136.484"; - rotation = "0 0 1 35"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "476 364 194.453"; - rotation = "0 0 1 177"; - scale = "1 1 1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "604 916 149.047"; - rotation = "0 0 -1 4.00015"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "812 748 130.172"; - rotation = "0 0 1 24"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "732 212 76.3593"; - rotation = "0 0 1 51"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "1100 508 149.781"; - rotation = "0 0 -1 29.9998"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "676 764 169.812"; - rotation = "0 0 -1 80.0004"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "1092 876 185.672"; - rotation = "0 0 1 217"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "428 548 211.094"; - rotation = "0 0 1 121"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "932 524 173.125"; - rotation = "0 0 -1 71.0004"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "996 180 97.219"; - rotation = "0 0 1 44"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "636 892 140.578"; - rotation = "0 0 1 54"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "708 252 95.1562"; - rotation = "0 0 1 66.0002"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "420 676 178.266"; - rotation = "0 0 -1 29"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "956 868 153.906"; - rotation = "0 0 1 67.9998"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "908 524 173"; - rotation = "0 0 1 205"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "868 156 94.3594"; - rotation = "0 0 1 117"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "460 516 183.859"; - rotation = "0 0 1 230"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "604 916 149.047"; - rotation = "0 0 -1 119"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "1012 804 150.625"; - rotation = "0 0 -1 37.0002"; - scale = "1 1 1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "980 756 116.422"; - rotation = "0 0 1 28"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "788 668 117.719"; - rotation = "0 0 1 17"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "1012 348 117.969"; - rotation = "0 0 1 217"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "964 700 155.375"; - rotation = "0 0 -1 61.0005"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "756 252 86.9531"; - rotation = "0 0 -1 77.0004"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "1148 380 70.6719"; - rotation = "0 0 1 22"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "428 644 178.656"; - rotation = "0 0 1 161"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "1180 644 160.187"; - rotation = "0 0 1 215"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "908 300 68.1719"; - rotation = "0 0 -1 58.0005"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "924 524 173.031"; - rotation = "0 0 1 69.0002"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "692 364 123.922"; - rotation = "0 0 -1 53.9998"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "1156 796 167.719"; - rotation = "0 0 -1 92.0004"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "524 788 196.734"; - rotation = "0 0 1 141"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg16.dts"; - }; - }; - new SimGroup(Addition12DSPlant17) { - - powerCount = "0"; - - new TSStatic() { - position = "596 604 155.219"; - rotation = "-0.252214 0.0568745 0.965999 52.557"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "676 780 168.969"; - rotation = "0.0644755 0.0918072 -0.993687 79.3563"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "1180 428 100.875"; - rotation = "-0.13555 -0.0513793 0.989437 205.735"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "796 884 150.734"; - rotation = "0.214537 0.335293 -0.917362 31.4878"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "1052 516 172.5"; - rotation = "0.0326082 -0.0612456 0.99759 96.1377"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "700 444 95.7187"; - rotation = "0.0236739 -0.00272442 0.999716 130.013"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "444 364 181.766"; - rotation = "0.182467 -0.00253999 -0.983209 95.9659"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "748 388 124.922"; - rotation = "0.145242 0.0220224 0.989151 227.537"; - scale = "1 1 1"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "684 508 115.016"; - rotation = "0.107873 -0.0904691 0.99004 144.336"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "1012 812 150.656"; - rotation = "-0.436177 -0.113977 -0.892614 22.3487"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "764 268 90.5625"; - rotation = "-0.151402 -0.00972159 0.988424 127.531"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "972 220 99.687"; - rotation = "-0.0666638 0.167378 0.983636 83.9389"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "948 908 112.328"; - rotation = "-0.0115508 -0.143244 0.98962 84.5949"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "1164 772 170.828"; - rotation = "-0.0696701 0.0635217 0.995546 107.245"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "1140 788 162.828"; - rotation = "-0.138555 0.0419806 0.989465 124.501"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "668 484 117.547"; - rotation = "-0.112626 -0.107037 0.987855 147.379"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "1068 468 173.547"; - rotation = "-0.0739407 0.066415 0.995049 182.985"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "572 548 163.734"; - rotation = "0.0235022 -0.0760124 0.99683 188.971"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "932 748 132.016"; - rotation = "0.0157534 0.0466812 -0.998786 97.0689"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "556 636 146.938"; - rotation = "0.00172912 -0.183868 0.982949 61.8651"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "700 380 127.609"; - rotation = "-0.575477 -0.32338 0.751166 26.4206"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "388 844 163.953"; - rotation = "0.0485287 0.0029749 0.998817 109.064"; - scale = "1 1 1"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "812 748 130.172"; - rotation = "-0.121092 0.110974 -0.986418 41.5167"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "932 628 129.078"; - rotation = "0.0144005 -0.0381498 0.999168 167.011"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "964 708 155.375"; - rotation = "-0.0136492 0.313518 -0.949484 37.7824"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "580 604 156.922"; - rotation = "-0.450827 -0.23556 -0.860969 37.971"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "668 484 117.547"; - rotation = "-0.121311 -0.101946 0.987366 140.466"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "764 492 156.484"; - rotation = "0.117335 -0.0381243 0.99236 54.3563"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "588 924 147.562"; - rotation = "0.204729 0.174863 -0.963073 58.8262"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "436 724 168.313"; - rotation = "0.0454692 0.134065 0.989929 209.711"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "908 756 125.5"; - rotation = "0.0625492 -0.146797 0.987187 145.422"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "980 820 135.922"; - rotation = "0.127602 -0.10248 0.986517 223.463"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "748 268 88.3906"; - rotation = "-0.0133015 -0.0530759 0.998502 115.078"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "428 644 178.656"; - rotation = "-0.100363 0.105261 0.989367 146.341"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "1044 468 164.875"; - rotation = "0.0348411 0.150912 -0.987933 116.624"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "1180 572 127.766"; - rotation = "-0.0265204 -0.163439 -0.986197 116.714"; - scale = "1 1 1"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "980 812 135.953"; - rotation = "0.0360907 0.0983098 0.994501 179.006"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "756 228 77.6875"; - rotation = "-0.0980146 0.223292 -0.969811 77.7097"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "1124 772 160.703"; - rotation = "-0.0907992 -0.261222 0.960999 65.0491"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "628 884 140.391"; - rotation = "-0.894358 -0.309023 0.323463 12.3235"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "692 140 113.016"; - rotation = "0.0792873 -0.0294701 0.996416 157.08"; - scale = "1 1 1"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "916 220 72.7969"; - rotation = "0.00019495 0.0903265 0.995912 109.222"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "804 700 108.672"; - rotation = "0.583341 0.0169456 0.81205 28.1309"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "1044 252 125.531"; - rotation = "0.00811237 -0.0415602 0.999103 139.034"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "556 900 159.969"; - rotation = "0.137374 -0.210933 0.967799 61.6371"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "908 228 72.875"; - rotation = "-0.0695661 0.115309 -0.990891 115.474"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg17.dts"; - }; - }; - new SimGroup(Addition13DSPlant18) { - - powerCount = "0"; - - new TSStatic() { - position = "972 156 95.4218"; - rotation = "0 0 -1 74.0004"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "1116 868 181.031"; - rotation = "0 0 1 58.9998"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "428 372 177.891"; - rotation = "0 0 1 79"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "676 388 126.625"; - rotation = "0 0 -1 58.0005"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "828 764 134.531"; - rotation = "0 0 -1 82"; - scale = "1 1 1"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "924 508 173.453"; - rotation = "0 0 -1 14.9998"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "1100 812 157.953"; - rotation = "0 0 1 1.9999"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "404 388 158.766"; - rotation = "0 0 1 205"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "556 884 168.078"; - rotation = "0 0 1 99.0002"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "484 484 178.281"; - rotation = "0 0 -1 81.0002"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "1116 676 142.453"; - rotation = "0 0 1 221"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "676 836 154.063"; - rotation = "0 0 -1 107"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "452 492 179"; - rotation = "0 0 -1 90.0002"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "1068 860 172.672"; - rotation = "0 0 -1 104"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "684 268 90.8593"; - rotation = "0 0 1 160"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "788 308 109.531"; - rotation = "0 0 1 39"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "1012 804 150.625"; - rotation = "0 0 -1 115"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "980 204 104.016"; - rotation = "0 0 1 44"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "924 244 77.6875"; - rotation = "0 0 1 122"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "1020 652 182.672"; - rotation = "0 0 1 18"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "620 204 143.344"; - rotation = "0 0 1 12"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "924 516 173.063"; - rotation = "0 0 1 214"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "492 308 158.859"; - rotation = "0 0 1 143"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "1084 652 152.109"; - rotation = "0 0 1 28"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "620 212 144.453"; - rotation = "0 0 1 156"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "1108 524 155.203"; - rotation = "0 0 1 28"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "844 452 125.641"; - rotation = "0 0 1 136"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "532 428 180.125"; - rotation = "0 0 -1 10.9999"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "684 388 127.75"; - rotation = "0 0 1 109"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "692 276 90.8124"; - rotation = "0 0 1 20"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "1068 820 175.313"; - rotation = "0 0 1 66.0002"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "860 156 94.125"; - rotation = "0 0 -1 107"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "540 428 178.094"; - rotation = "0 0 -1 100"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "940 708 139.703"; - rotation = "0 0 1 60.0001"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "924 252 78.1406"; - rotation = "0 0 1 165"; - scale = "1 1 1"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "772 260 90.8437"; - rotation = "0 0 -1 50.9998"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "692 156 112.984"; - rotation = "0 0 1 148"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "1100 860 183.859"; - rotation = "0 0 1 49"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "1108 628 148.562"; - rotation = "0 0 1 94.9998"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "972 812 136.266"; - rotation = "0 0 1 229"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "972 220 99.687"; - rotation = "0 0 1 222"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "1036 756 151.047"; - rotation = "0 0 1 29"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "596 772 152.672"; - rotation = "0 0 1 235"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "836 452 126.141"; - rotation = "0 0 1 64"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "436 732 167.469"; - rotation = "0 0 1 7.99996"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "988 284 116.016"; - rotation = "0 0 1 57.9999"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "500 756 195.719"; - rotation = "0 0 1 172"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "644 492 118.75"; - rotation = "0 0 1 20"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg18.dts"; - }; - }; - new SimGroup(Addition14DSPlant19) { - - powerCount = "0"; - - new TSStatic() { - position = "756 212 76.8125"; - rotation = "0 0 1 208"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "676 764 169.812"; - rotation = "0 0 -1 110"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "1108 748 157.578"; - rotation = "0 0 1 140"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "572 564 167.922"; - rotation = "0 0 -1 97"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "828 452 126.687"; - rotation = "0 0 1 185"; - scale = "1 1 1"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "460 900 128.109"; - rotation = "0 0 1 51"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "892 876 171.438"; - rotation = "0 0 -1 44"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "1180 860 197.953"; - rotation = "0 0 1 236"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "1100 524 154.406"; - rotation = "0 0 1 236"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "604 164 171.953"; - rotation = "0 0 -1 93.0002"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "780 308 112.078"; - rotation = "0 0 -1 76"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "812 276 91.4532"; - rotation = "0 0 1 49"; - scale = "1 1 1"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "740 892 162.078"; - rotation = "0 0 1 90.0002"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "1028 484 164"; - rotation = "0 0 -1 95.0004"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "452 604 159.688"; - rotation = "0 0 1 153"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "676 876 157.391"; - rotation = "0 0 -1 5.99979"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "572 804 158.656"; - rotation = "0 0 1 204"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "804 692 111.109"; - rotation = "0 0 1 239"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "556 540 157.937"; - rotation = "0 0 -1 112"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "1124 868 180.422"; - rotation = "0 0 -1 38.9999"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "748 276 89.7344"; - rotation = "0 0 1 198"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "844 236 116.266"; - rotation = "0 0 1 169"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "668 532 112.703"; - rotation = "0 0 1 87.0002"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "1124 772 160.703"; - rotation = "0 0 -1 46.0002"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "572 716 204.594"; - rotation = "0 0 -1 32.9998"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "820 460 127.109"; - rotation = "0 0 1 150"; - scale = "1 1 1"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "980 220 100.625"; - rotation = "0 0 1 24"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "772 708 109.203"; - rotation = "0 0 -1 53.9998"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "388 812 156.672"; - rotation = "0 0 -1 23.9998"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "588 932 148.109"; - rotation = "0 0 -1 4.00015"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "956 588 160.734"; - rotation = "0 0 1 152"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "908 436 151.469"; - rotation = "0 0 1 101"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "1004 316 118.219"; - rotation = "0 0 -1 26"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "540 420 178.047"; - rotation = "0 0 -1 32"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "564 212 171.297"; - rotation = "0 0 -1 65.0004"; - scale = "1 1 1"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "596 700 209.375"; - rotation = "0 0 1 1.9999"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "580 932 147"; - rotation = "0 0 1 235"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "572 804 158.656"; - rotation = "0 0 1 128"; - scale = "1 1 1"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "812 900 150.344"; - rotation = "0 0 1 119"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "828 428 120.375"; - rotation = "0 0 1 162"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "604 852 130.406"; - rotation = "0 0 1 224"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "1172 860 197.391"; - rotation = "0 0 1 150"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "668 516 115.172"; - rotation = "0 0 1 67"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "428 380 178.078"; - rotation = "0 0 -1 72.0002"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg19.dts"; - }; - }; - }; -}; -//--- OBJECT WRITE END --- - -//exec("missions/beginning.cs"); - +// The Beginning (Dolosus Memories 1) +// MissionTypes = CTF +// DisplayName = The Beginning + +//--- MISSION BRIEFING BEGIN --- +//"Sing me a song, you're a singer. Do me a wrong, you're a bringer of evil. The less that you give, you're a taker." +// -Heaven & Hell by Black Sabbath, first three verses +//--- MISSION BRIEFING END --- + +// BriefingWAV = T2BOL_1 +// Bitmap = trn_5draconis + +//--- MISSION STRING BEGIN --- +//OBJECTIVES: +//Escape the facility +//Escape the grasp of the Criollos +//--- MISSION STRING END --- + +// PlanetName = Xeron, 3960 CE +//--- MISSION BLURB BEGIN --- +//You suddenly regain conciousness in an unfamiliar place. Your body temperature sends a large amount of feedback into the system, causing a power failure, +//--- MISSION BLURB END --- + +//--- OBJECT WRITE BEGIN --- +new SimGroup(MissionGroup) { + + powerCount = "0"; + + new MissionArea(MissionArea) { + area = "-760 -688 1664 1472"; + flightCeiling = "2000"; + flightCeilingRange = "50"; + }; + new Sun() { + position = "-1024 -1024 0"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + direction = "0.57735 0.57735 -0.57735"; + color = "1.000000 1.000000 1.000000 1.000000"; + ambient = "0.700000 0.700000 0.700000 1.000000"; + texture[0] = "special/sunFlare"; + texture[1] = "special/sunFlare02"; + texture[2] = "special/LensFlare/flare01"; + texture[3] = "special/LensFlare/flare02"; + texture[4] = "special/LensFlare/flare03"; + lensFlareScale = "0.7"; + lensFlareIntensity = "1"; + frontFlareSize = "300"; + backFlareSize = "450"; + flareColor = "1.000000 1.000000 1.000000 1.000000"; + }; + new TerrainBlock(Terrain) { + rotation = "1 0 0 0"; + scale = "1 1 1"; + detailTexture = "details/lavadet1"; + terrainFile = "Training5.ter"; + squareSize = "8"; + emptySquares = "217661 217676 86852 152390 87108 152646 218429 218444"; + + position = "-1024 -1024 0"; + }; + new NavigationGraph(NavGraph) { + conjoinAngleDev = "67"; + cullDensity = "0.3"; + customArea = "-776 -560 480 496"; + + conjoinBowlDev = "20"; + position = "0 0 0 1"; + GraphFile = "Training5.nav"; + rotation = "0 0 0 0"; + coverage = "0"; + scale = "1 1 1"; + }; + new Sky(Sky) { + position = "692 -352 0"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + cloudHeightPer[0] = "0.349971"; + cloudHeightPer[1] = "0.25"; + cloudHeightPer[2] = "0.199973"; + cloudSpeed1 = "0.0001"; + cloudSpeed2 = "0.0002"; + cloudSpeed3 = "0.0003"; + visibleDistance = "550"; + useSkyTextures = "1"; + renderBottomTexture = "0"; + SkySolidColor = "0.300000 0.100000 0.000000 0.800000"; + fogDistance = "250"; + fogColor = "0.300000 0.100000 0.000000 0.800000"; + fogVolume1 = "100 0 85"; + fogVolume2 = "600 85 270"; + fogVolume3 = "0 0 0"; + materialList = "sky_lava_starrynight.dml"; + windVelocity = "1 0 0"; + windEffectPrecipitation = "0"; + fogVolumeColor1 = "128.000000 128.000000 128.000000 0.000000"; + fogVolumeColor2 = "128.000000 128.000000 128.000000 0.000000"; + fogVolumeColor3 = "128.000000 128.000000 128.000000 0.000000"; + high_visibleDistance = "-1"; + high_fogDistance = "-1"; + high_fogVolume1 = "-1 1.81768e+31 4.33441e+24"; + high_fogVolume2 = "-1 1.10877e+21 5.53399e-11"; + high_fogVolume3 = "-1 1.78604e+25 1.84649e+25"; + + locked = "true"; + }; + new WaterBlock(Lava) { + position = "-224 -264 93.1568"; + rotation = "1 0 0 0"; + scale = "768 608 27.0092"; + liquidType = "Lava"; + density = "1"; + viscosity = "15"; + waveMagnitude = "1"; + surfaceTexture = "LiquidTiles/Lava"; + surfaceOpacity = "1"; + envMapTexture = "lava/skies/lava_starrynite_emap"; + envMapIntensity = "0.2"; + submergeTexture[0] = "special/lavadeath_1"; + submergeTexture[1] = "special/lavadeath_2"; + removeWetEdges = "1"; + + locked = "true"; + }; + new SimGroup(environment) { + + powerCount = "0"; + + new ParticleEmissionDummy(LavaSmoke) { + position = "-462.4 -366.791 5.12867"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "defaultEmissionDummy"; + lockCount = "0"; + homingCount = "0"; + emitter = "BeforeT5"; + velocity = "1"; + }; + new AudioEmitter(SmokeSound) { + position = "-462.61 -365.42 4.67642"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + fileName = "fx/environment/lavahiss.wav"; + useProfileDescription = "0"; + outsideAmbient = "0"; + volume = "0.8"; + isLooping = "1"; + is3D = "1"; + minDistance = "20"; + maxDistance = "120"; + coneInsideAngle = "360"; + coneOutsideAngle = "360"; + coneOutsideVolume = "1"; + coneVector = "0 0 1"; + loopCount = "-1"; + minLoopGap = "0"; + maxLoopGap = "0"; + type = "EffectAudioType"; + }; + new AudioEmitter(Outside1) { + position = "266.262 824.24 137.226"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + fileName = "fx/environment/lavamellow1.wav"; + useProfileDescription = "0"; + outsideAmbient = "1"; + volume = "0.4"; + isLooping = "1"; + is3D = "0"; + minDistance = "20"; + maxDistance = "1280"; + coneInsideAngle = "360"; + coneOutsideAngle = "360"; + coneOutsideVolume = "1"; + coneVector = "0 0 1"; + loopCount = "-1"; + minLoopGap = "0"; + maxLoopGap = "0"; + type = "EffectAudioType"; + }; + new AudioEmitter(Outside2) { + position = "266.262 824.24 137.226"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + fileName = "fx/environment/gravel3.wav"; + useProfileDescription = "0"; + outsideAmbient = "1"; + volume = "0.1"; + isLooping = "1"; + is3D = "0"; + minDistance = "20"; + maxDistance = "1280"; + coneInsideAngle = "360"; + coneOutsideAngle = "360"; + coneOutsideVolume = "1"; + coneVector = "0 0 1"; + loopCount = "-1"; + minLoopGap = "4000"; + maxLoopGap = "15000"; + type = "EffectAudioType"; + }; + new StaticShape(Genhonor) { + position = "-431.785 -366.853 38.3577"; + rotation = "0 0 1 89.3814"; + scale = "1 1 1"; + dataBlock = "Banner_Honor"; + lockCount = "0"; + homingCount = "0"; + + Target = "-1"; + }; + new StaticShape(Genstrength) { + position = "-463.154 -398.109 38.4185"; + rotation = "0 0 1 181.055"; + scale = "1 1 1"; + dataBlock = "Banner_Strength"; + lockCount = "0"; + homingCount = "0"; + + Target = "-1"; + }; + new StaticShape(GenUnity) { + position = "-494.404 -366.856 38.1826"; + rotation = "0 0 -1 89.9544"; + scale = "1 1 1"; + dataBlock = "Banner_Unity"; + lockCount = "0"; + homingCount = "0"; + + Target = "-1"; + }; + new StaticShape(DoorHonor) { + position = "-378.978 -350.28 115"; + rotation = "0 0 -1 89.9544"; + scale = "1 1 1"; + dataBlock = "Banner_Honor"; + lockCount = "0"; + homingCount = "0"; + + Target = "-1"; + }; + new StaticShape(DoorUnity) { + position = "-547.33 -352.238 115"; + rotation = "0 0 1 89.9544"; + scale = "1 1 1"; + dataBlock = "Banner_Unity"; + lockCount = "0"; + homingCount = "0"; + + Target = "-1"; + }; + new StaticShape(DoorStrength) { + position = "-462.751 -380.033 115"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Banner_Strength"; + lockCount = "0"; + homingCount = "0"; + + Target = "-1"; + }; + new StaticShape(WallHonor) { + position = "-372.568 -366.947 20.2877"; + rotation = "0 0 -1 89.9544"; + scale = "1 1 1"; + dataBlock = "Banner_Honor"; + lockCount = "0"; + homingCount = "0"; + + Target = "-1"; + }; + new StaticShape(WallUnity) { + position = "-552.788 -366.854 20.8502"; + rotation = "0 0 1 89.9544"; + scale = "1 1 1"; + dataBlock = "Banner_Unity"; + lockCount = "0"; + homingCount = "0"; + + Target = "-1"; + }; + new StaticShape(WallStrength) { + position = "-463.23 -399.018 35.4212"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Banner_Strength"; + lockCount = "0"; + homingCount = "0"; + + Target = "-1"; + }; + }; + new SimGroup(Teams) { + + powerCount = "0"; + + new SimGroup(Team1) { + + powerCount = "0"; + + new SimGroup(DropPoints) { + + powerCount = "0"; + + new Camera(DP) { + position = "106.622 -7.51593 164.733"; + rotation = "-0.0123037 -0.0124627 -0.999847 90.7445"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + team = "1"; + }; + }; + new SimGroup(base) { + + powerCount = "1"; + + new StaticShape(station2) { + position = "785.587 532.538 206.108"; + rotation = "0.00499991 0.00471232 0.999976 93.3935"; + scale = "1 1 1"; + nameTag = "\x01720"; + dataBlock = "StationInventory"; + lockCount = "0"; + homingCount = "0"; + + locked = "false"; + Trigger = "14877"; + team = "1"; + Target = "33"; + }; + new StaticShape(Station1) { + position = "786.326 543.704 206.114"; + rotation = "0 0 1 93.3922"; + scale = "1 1 1"; + nameTag = "\x01720"; + dataBlock = "StationInventory"; + lockCount = "0"; + homingCount = "0"; + + locked = "false"; + Trigger = "14879"; + team = "1"; + Target = "34"; + }; + new StaticShape(TowerPower) { + position = "789.671 538.05 169.13"; + rotation = "0 0 1 92.6372"; + scale = "1 1 1"; + nameTag = "\x01719"; + dataBlock = "GeneratorLarge"; + lockCount = "0"; + homingCount = "0"; + + locked = "false"; + team = "1"; + Target = "35"; + }; + new InteriorInstance(DSTower) { + position = "782.299 538.347 205.138"; + rotation = "-0 0 -1 86.6992"; + scale = "1 1 1"; + interiorFile = "dtowr4.dif"; + showTerrainInside = "0"; + AudioProfile = "Universal_Base_1"; + AudioEnvironment = "SmallRoom"; + + locked = "false"; + team = "1"; + }; + }; + }; + new SimGroup(Team2) { + + powerCount = "0"; + + new SimGroup(BasePower) { + + powerCount = "1"; + + new SimGroup(base) { + + powerCount = "2"; + + new InteriorInstance(DBase2) { + position = "-463.118 -366.83 17.0706"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "dbase2.dif"; + showTerrainInside = "0"; + AudioProfile = "Universal_Base_3"; + AudioEnvironment = "BigRoom"; + + locked = "true"; + team = "2"; + }; + new StaticShape(ObjectiveGen1) { + position = "-460.757 -348.913 6.0481"; + rotation = "0 0 1 179.909"; + scale = "1 1 1"; + nameTag = "\x01718"; + dataBlock = "GeneratorLarge"; + lockCount = "0"; + homingCount = "0"; + + team = "2"; + Target = "36"; + }; + }; + new StaticShape(InventoryStation5) { + position = "-387.192 -440.08 14.1387"; + rotation = "0 0 1 89.9544"; + scale = "1 1 1"; + dataBlock = "StationInventory"; + lockCount = "0"; + homingCount = "0"; + + Trigger = "14888"; + team = "2"; + Target = "37"; + }; + new StaticShape(InventoryStation1) { + position = "-387.019 -421.21 14.1507"; + rotation = "0 0 1 89.9544"; + scale = "1 1 1"; + dataBlock = "StationInventory"; + lockCount = "0"; + homingCount = "0"; + + Trigger = "14890"; + team = "2"; + Target = "38"; + }; + new StaticShape(InventoryStation2) { + position = "-402.649 -440.174 14.1592"; + rotation = "0 0 -1 90.1369"; + scale = "1 1 1"; + dataBlock = "StationInventory"; + lockCount = "0"; + homingCount = "0"; + + Trigger = "14892"; + team = "2"; + Target = "39"; + }; + new StaticShape(InventoryStation3) { + position = "-402.755 -421.308 14.112"; + rotation = "0 0 -1 90.1369"; + scale = "1 1 1"; + dataBlock = "StationInventory"; + lockCount = "0"; + homingCount = "0"; + + Trigger = "14894"; + team = "2"; + Target = "40"; + }; + new StaticShape(BaseGen2) { + position = "-380.672 -366.624 29.0406"; + rotation = "0 0 1 89.9544"; + scale = "1 1 1"; + nameTag = "\x01717"; + dataBlock = "GeneratorLarge"; + lockCount = "0"; + homingCount = "0"; + + team = "2"; + Target = "41"; + }; + new StaticShape(FloatingBaseSensor) { + position = "-504.6 -203.122 156.504"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + nameTag = "\x01716"; + dataBlock = "SensorLargePulse"; + lockCount = "0"; + homingCount = "0"; + + team = "2"; + Target = "42"; + }; + new InteriorInstance(BaseSensorPlat) { + position = "-504.631 -203.509 154.979"; + rotation = "1 0 0 0"; + scale = "0.662015 0.662282 0.732005"; + interiorFile = "dplat1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + }; + new SimGroup(DropPoints) { + + powerCount = "0"; + + new Camera(enemy0) { + position = "-214.907 -8.05464 163.71"; + rotation = "0 0 1 89.3814"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + team = "2"; + }; + }; + new Item(InvRoomRepairPack) { + position = "-403.617 -449.228 16.0153"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "RepairPack"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + + team = "2"; + Target = "-1"; + }; + new Item(SatchelChargePack) { + position = "-463.131 -366.848 41.3416"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "SatchelCharge"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + + team = "2"; + Target = "-1"; + }; + new SimGroup(Perifery) { + + powerCount = "1"; + + new InteriorInstance() { + position = "-672.476 -378.377 93.2107"; + rotation = "0 0 -1 91.8558"; + scale = "1 1 1"; + interiorFile = "dmisc1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new StaticShape(PeriferyGen) { + position = "-547.707 -367.013 29.0564"; + rotation = "0 0 1 89.9544"; + scale = "1 1 1"; + nameTag = "\x01715"; + dataBlock = "GeneratorLarge"; + lockCount = "0"; + homingCount = "0"; + + team = "2"; + Target = "43"; + }; + new Turret(Turret3) { + position = "-482.32 -249.952 111.06"; + rotation = "-0 0 -1 0.181308"; + scale = "1 1 1"; + dataBlock = "TurretBaseLarge"; + lockCount = "0"; + homingCount = "0"; + initialBarrel = "PlasmaBarrelLarge"; + + team = "2"; + Target = "44"; + }; + new InteriorInstance() { + position = "-481.857 -249.119 101.34"; + rotation = "0 0 1 179.909"; + scale = "1 1 1"; + interiorFile = "dmisc1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new Turret(Turret3) { + position = "-257.301 -388.932 93.0956"; + rotation = "0 0 1 127.587"; + scale = "1 1 1"; + dataBlock = "TurretBaseLarge"; + lockCount = "0"; + homingCount = "0"; + initialBarrel = "PlasmaBarrelLarge"; + + team = "2"; + Target = "45"; + }; + new InteriorInstance() { + position = "-256.927 -389.808 83.3756"; + rotation = "-0 0 -1 52.3217"; + scale = "1 1 1"; + interiorFile = "dmisc1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new Turret(Turret3) { + position = "-673.322 -377.939 102.931"; + rotation = "0 0 1 88.0532"; + scale = "1 1 1"; + dataBlock = "TurretBaseLarge"; + lockCount = "0"; + homingCount = "0"; + initialBarrel = "PlasmaBarrelLarge"; + + team = "2"; + Target = "46"; + }; + }; + new SimGroup(base0) { + + providesPower = "1"; + powerCount = "1"; + + new InteriorInstance(InteriorInstance) { + position = "124.542 -12.6592 168.762"; + rotation = "0 0 1 179.909"; + scale = "1 1 1"; + interiorFile = "dbunk_nefsmall.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new ForceFieldBare(IsolationField) { + position = "103.509 -11.7308 162.612"; + rotation = "1 0 0 0"; + scale = "8.10437 8.05813 6.12739"; + dataBlock = "defaultForceFieldBare"; + lockCount = "0"; + homingCount = "0"; + + team = "2"; + Target = "47"; + }; + new StaticShape() { + position = "115.669 -6.75199 162.639"; + rotation = "0 0 1 89.9544"; + scale = "5.24703 1 0.381909"; + nameTag = "\x01714"; + dataBlock = "GeneratorLarge"; + lockCount = "0"; + homingCount = "0"; + + damageTimeMS = "941594"; + lastDamagedBy = "14847"; + team = "2"; + Target = "48"; + isburning = "0"; + lastDamagedByTeam = "1"; + }; + new StaticShape() { + position = "107.518 -7.24103 171.587"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + nameTag = "\x01714"; + dataBlock = "SensorLargePulse"; + lockCount = "0"; + homingCount = "0"; + + damageTimeMS = "925206"; + lastDamagedBy = "14847"; + team = "2"; + Target = "49"; + isburning = "0"; + lastDamagedByTeam = "1"; + }; + }; + new SimGroup(BaseForceFields) { + + powerCount = "1"; + + new StaticShape(ObjectiveGen2) { + position = "-465.911 -348.919 6.0157"; + rotation = "0 0 1 179.909"; + scale = "1 1 1"; + nameTag = "\x01713"; + dataBlock = "GeneratorLarge"; + lockCount = "0"; + homingCount = "0"; + + team = "2"; + Target = "50"; + }; + new ForceFieldBare(CenterEnteranceFF) { + position = "-471.214 -379.6 99.8223"; + rotation = "1 0 0 0"; + scale = "16.6319 0.452235 9.31077"; + dataBlock = "defaultTeamSlowFieldBare"; + lockCount = "0"; + homingCount = "0"; + + team = "2"; + Target = "51"; + color = "0.500000 0.500000 1.000000 1.000000"; + }; + new ForceFieldBare(WestEnteranceFF) { + position = "-546.997 -359.996 99.1512"; + rotation = "1 0 0 0"; + scale = "0.912282 16.3236 11.119"; + dataBlock = "defaultTeamSlowFieldBare"; + lockCount = "0"; + homingCount = "0"; + + team = "2"; + Target = "52"; + color = "0.500000 0.500000 1.000000 1.000000"; + }; + new ForceFieldBare(EastEnteranceFF) { + position = "-379.979 -359.074 100.923"; + rotation = "1 0 0 0"; + scale = "0.782673 16.3247 10.9793"; + dataBlock = "defaultTeamSlowFieldBare"; + lockCount = "0"; + homingCount = "0"; + + team = "2"; + Target = "53"; + color = "0.500000 0.500000 1.000000 1.000000"; + }; + }; + new SimGroup(LavaBridges) { + + powerCount = "0"; + + new InteriorInstance() { + position = "107.398 -7.70099 161.612"; + rotation = "1 0 0 0"; + scale = "2 2 1"; + interiorFile = "dbrdg8.dif"; + showTerrainInside = "0"; + + locked = "true"; + team = "2"; + }; + new InteriorInstance() { + position = "107.383 -31.701 161.612"; + rotation = "0 0 -1 90"; + scale = "2 2 1"; + interiorFile = "dbrdg7.dif"; + showTerrainInside = "0"; + + locked = "true"; + team = "2"; + }; + new InteriorInstance(InteriorInstance) { + position = "107.377 15.9 161.612"; + rotation = "0 0 1 90"; + scale = "2 2 1"; + interiorFile = "dbrdg7.dif"; + showTerrainInside = "0"; + + locked = "true"; + team = "2"; + }; + new InteriorInstance() { + position = "83.403 -7.67801 161.612"; + rotation = "1 0 0 0"; + scale = "2 2 1"; + interiorFile = "dbrdg7.dif"; + showTerrainInside = "0"; + + locked = "true"; + team = "2"; + }; + new InteriorInstance() { + position = "131.364 -7.702 161.612"; + rotation = "0 0 1 180"; + scale = "2 2 1"; + interiorFile = "dbrdg7.dif"; + showTerrainInside = "0"; + + locked = "true"; + team = "2"; + }; + new InteriorInstance() { + position = "51.42 -7.67899 164.359"; + rotation = "1 0 0 0"; + scale = "2 2 1"; + interiorFile = "dbrdg9.dif"; + showTerrainInside = "0"; + + locked = "true"; + team = "2"; + }; + new InteriorInstance() { + position = "107.38 47.897 164.359"; + rotation = "0 0 1 90"; + scale = "2 2 1"; + interiorFile = "dbrdg9.dif"; + showTerrainInside = "0"; + + locked = "true"; + team = "2"; + }; + new InteriorInstance() { + position = "107.382 -63.694 164.359"; + rotation = "0 0 1 90"; + scale = "2 2 1"; + interiorFile = "dbrdg9.dif"; + showTerrainInside = "0"; + + locked = "true"; + team = "2"; + }; + new InteriorInstance() { + position = "163.362 -7.698 164.359"; + rotation = "0 0 1 180"; + scale = "2 2 1"; + interiorFile = "dbrdg9.dif"; + showTerrainInside = "0"; + + locked = "true"; + team = "2"; + }; + new InteriorInstance() { + position = "107.382 -63.694 164.359"; + rotation = "0 0 1 90"; + scale = "2 2 1"; + interiorFile = "dbrdg9.dif"; + showTerrainInside = "0"; + + locked = "true"; + team = "2"; + }; + new InteriorInstance() { + position = "163.364 -47.697 161.608"; + rotation = "0 0 -1 90"; + scale = "1 1 1"; + interiorFile = "dbrdg7a.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "163.366 -63.6898 164.359"; + rotation = "0 0 1 90"; + scale = "1 1 1"; + interiorFile = "dbrdg9a.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "163.379 47.8998 164.359"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "dbrdg9a.dif"; + showTerrainInside = "0"; + + locked = "false"; + team = "2"; + }; + new InteriorInstance() { + position = "147.372 -63.701 161.608"; + rotation = "0 0 1 180"; + scale = "1 1 1"; + interiorFile = "dbrdg7a.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "163.376 31.901 161.608"; + rotation = "0 0 1 90"; + scale = "1 1 1"; + interiorFile = "dbrdg7a.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "147.387 47.897 161.608"; + rotation = "0 0 1 180"; + scale = "1 1 1"; + interiorFile = "dbrdg7a.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "51.4084 48.1443 164.359"; + rotation = "0 0 -1 90"; + scale = "1 1 1"; + interiorFile = "dbrdg9a.dif"; + showTerrainInside = "0"; + + locked = "true"; + team = "2"; + }; + new InteriorInstance() { + position = "51.398 32.214 161.608"; + rotation = "0 0 1 90"; + scale = "1 1 1"; + interiorFile = "dbrdg7a.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "67.365 48.143 161.608"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "dbrdg7a.dif"; + showTerrainInside = "0"; + + locked = "true"; + team = "2"; + }; + new InteriorInstance() { + position = "51.364 -47.734 161.608"; + rotation = "0 0 -1 90"; + scale = "1 1 1"; + interiorFile = "dbrdg7a.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "51.3834 -63.6902 164.359"; + rotation = "0 0 1 180"; + scale = "1 1 1"; + interiorFile = "dbrdg9a.dif"; + showTerrainInside = "0"; + + locked = "true"; + team = "2"; + }; + new InteriorInstance() { + position = "67.378 -63.705 161.608"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "dbrdg7a.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new SimGroup(FFBridges) { + + powerCount = "0"; + + new SimGroup(CatwalkFFs) { + + powerCount = "1"; + + new ForceFieldBare() { + position = "71.293 44.475 161.61"; + rotation = "1 0 0 0"; + scale = "24.126 7.54321 1"; + dataBlock = "defaultNoTeamLavaLightField"; + lockCount = "0"; + homingCount = "0"; + + team = "2"; + Target = "54"; + }; + new ForceFieldBare() { + position = "119.376 44.161 161.61"; + rotation = "1 0 0 0"; + scale = "24.0507 7.54321 1"; + dataBlock = "defaultNoTeamLavaLightField"; + lockCount = "0"; + homingCount = "0"; + + team = "2"; + Target = "55"; + }; + new ForceFieldBare() { + position = "119.389 -67.489 161.61"; + rotation = "1 0 0 0"; + scale = "24.0182 7.54321 1"; + dataBlock = "defaultNoTeamLavaLightField"; + lockCount = "0"; + homingCount = "0"; + + team = "2"; + Target = "56"; + }; + new ForceFieldBare() { + position = "159.57 27.902 161.61"; + rotation = "0 0 1 90"; + scale = "23.6238 7.54321 1"; + dataBlock = "defaultNoTeamLavaLightField"; + lockCount = "0"; + homingCount = "0"; + + team = "2"; + Target = "57"; + }; + new ForceFieldBare() { + position = "159.57 -19.69 161.61"; + rotation = "0 0 1 90"; + scale = "24.0246 7.54321 0.654541"; + dataBlock = "defaultNoTeamLavaLightField"; + lockCount = "0"; + homingCount = "0"; + + team = "2"; + Target = "58"; + }; + new StaticShape(CatwalkFFGen) { + position = "296.902 281.478 82.1046"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + nameTag = "\x01712"; + dataBlock = "GeneratorLarge"; + lockCount = "0"; + homingCount = "0"; + + team = "2"; + Target = "59"; + }; + new ForceFieldBare() { + position = "47.57 28.212 161.61"; + rotation = "0 0 1 90"; + scale = "23.9272 7.54321 1"; + dataBlock = "defaultNoTeamLavaLightField"; + lockCount = "0"; + homingCount = "0"; + + team = "2"; + Target = "60"; + }; + new ForceFieldBare() { + position = "47.57 -19.676 161.61"; + rotation = "0 0 1 90"; + scale = "24.0593 7.54321 1"; + dataBlock = "defaultNoTeamLavaLightField"; + lockCount = "0"; + homingCount = "0"; + + team = "2"; + Target = "61"; + }; + new ForceFieldBare() { + position = "71.358 -67.489 161.61"; + rotation = "1 0 0 0"; + scale = "24.0928 7.54321 1"; + dataBlock = "defaultNoTeamLavaLightField"; + lockCount = "0"; + homingCount = "0"; + + team = "2"; + Target = "62"; + }; + }; + new SimGroup(DrawBridges) { + + powerCount = "0"; + + new SimGroup(WestBridge) { + + powerCount = "1"; + + new StaticShape(WestBridgeGen) { + position = "288.492 280.587 82.0062"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + nameTag = "\x01711"; + dataBlock = "GeneratorLarge"; + lockCount = "0"; + homingCount = "0"; + + team = "2"; + Target = "63"; + }; + new ForceFieldBare() { + position = "39.406 -3.879 161.61"; + rotation = "0 0 1 180"; + scale = "236.773 7.54321 1"; + dataBlock = "defaultNoTeamLavaLightField"; + lockCount = "0"; + homingCount = "0"; + + team = "2"; + Target = "64"; + }; + }; + new SimGroup(EastBridge) { + + powerCount = "1"; + + new StaticShape(EastBridgeGen) { + position = "280.367 280.27 82.0062"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + nameTag = "\x01710"; + dataBlock = "GeneratorLarge"; + lockCount = "0"; + homingCount = "0"; + + team = "2"; + Target = "65"; + }; + new ForceFieldBare() { + position = "440.421 -3.96201 161.954"; + rotation = "0 0 1 180"; + scale = "265.064 7.54321 0.654541"; + dataBlock = "defaultNoTeamLavaLightField"; + lockCount = "0"; + homingCount = "0"; + + team = "2"; + Target = "66"; + }; + }; + new SimGroup(SouthBridge) { + + powerCount = "1"; + + new StaticShape(SouthBridgeGen) { + position = "284.537 280.408 82.0062"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + nameTag = "\x01733"; + dataBlock = "GeneratorLarge"; + lockCount = "0"; + homingCount = "0"; + + team = "2"; + Target = "67"; + }; + new ForceFieldBare() { + position = "103.594 -75.687 161.61"; + rotation = "0 0 1 90"; + scale = "168.54 7.54321 1"; + dataBlock = "defaultNoTeamLavaLightField"; + lockCount = "0"; + homingCount = "0"; + + team = "2"; + Target = "68"; + }; + }; + }; + }; + new InteriorInstance() { + position = "107.31 -260.168 161.61"; + rotation = "0 0 1 89.9544"; + scale = "1 1 1"; + interiorFile = "dbrdg3a.dif"; + showTerrainInside = "0"; + + locked = "true"; + team = "2"; + }; + new InteriorInstance() { + position = "107.343 318.618 161.61"; + rotation = "0 0 1 89.9544"; + scale = "1 1 1"; + interiorFile = "dbrdg7.dif"; + showTerrainInside = "0"; + + locked = "true"; + team = "2"; + }; + new InteriorInstance() { + position = "107.318 -280.154 161.61"; + rotation = "0 0 -1 90"; + scale = "1 1 1"; + interiorFile = "dbrdg7.dif"; + showTerrainInside = "0"; + + locked = "true"; + team = "2"; + }; + new InteriorInstance() { + position = "107.382 298.632 161.61"; + rotation = "0 0 -1 90.0456"; + scale = "1 1 1"; + interiorFile = "dbrdg3a.dif"; + showTerrainInside = "0"; + + locked = "true"; + team = "2"; + }; + new InteriorInstance() { + position = "476.391 -7.707 161.608"; + rotation = "0 0 1 180"; + scale = "1 1 1"; + interiorFile = "dbrdg7.dif"; + showTerrainInside = "0"; + + locked = "false"; + team = "2"; + }; + new InteriorInstance() { + position = "456.405 -7.763 161.608"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "dbrdg3a.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "107.386 49.616 161.534"; + rotation = "1 0 0 0"; + scale = "1 1 1.0262"; + interiorFile = "dpole1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "107.386 49.616 141.03"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "dpole1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "107.439 292.602 161.63"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "dpole1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "450.286 -7.789 162.448"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "dpole1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "450.286 -7.789 142.448"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "dpole1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "107.235 -254.11 142.49"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "dpole1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "107.235 -254.11 162.47"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "dpole1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "106.984 -7.55801 161.01"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "dpole1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "106.984 -7.55801 141.03"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "dpole1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "106.984 -7.55801 121.09"; + rotation = "1 0 0 0"; + scale = "1 1 1.05589"; + interiorFile = "dpole1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "107.394 -65.561 121.09"; + rotation = "1 0 0 0"; + scale = "1 1 1.05589"; + interiorFile = "dpole1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "107.394 -65.561 141.03"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "dpole1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "107.394 -65.561 161.534"; + rotation = "1 0 0 0"; + scale = "1 1 1.0262"; + interiorFile = "dpole1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "51.14 -63.648 161.534"; + rotation = "1 0 0 0"; + scale = "1 1 1.0262"; + interiorFile = "dpole1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "51.14 -63.648 141.03"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "dpole1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "51.14 -63.648 121.09"; + rotation = "1 0 0 0"; + scale = "1 1 1.05589"; + interiorFile = "dpole1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "51.379 48.853 121.09"; + rotation = "1 0 0 0"; + scale = "1 1 1.05589"; + interiorFile = "dpole1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "51.379 48.853 141.03"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "dpole1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "51.379 48.853 161.534"; + rotation = "1 0 0 0"; + scale = "1 1 1.0262"; + interiorFile = "dpole1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "49.864 -7.771 121.09"; + rotation = "1 0 0 0"; + scale = "1 1 1.05589"; + interiorFile = "dpole1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "49.864 -7.771 141.03"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "dpole1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "49.864 -7.771 161.534"; + rotation = "1 0 0 0"; + scale = "1 1 1.0262"; + interiorFile = "dpole1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "163.415 -63.978 121.09"; + rotation = "1 0 0 0"; + scale = "1 1 1.05589"; + interiorFile = "dpole1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "163.415 -63.978 141.03"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "dpole1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "163.415 -63.978 161.534"; + rotation = "1 0 0 0"; + scale = "1 1 1.0262"; + interiorFile = "dpole1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "165.039 -7.49799 121.09"; + rotation = "1 0 0 0"; + scale = "1 1 1.05589"; + interiorFile = "dpole1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "165.039 -7.49799 141.03"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "dpole1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "165.039 -7.49799 161.534"; + rotation = "1 0 0 0"; + scale = "1 1 1.0262"; + interiorFile = "dpole1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "163.423 48.406 121.09"; + rotation = "1 0 0 0"; + scale = "1 1 1.05589"; + interiorFile = "dpole1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "163.423 48.406 141.03"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "dpole1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "163.423 48.406 161.534"; + rotation = "1 0 0 0"; + scale = "1 1 1.0262"; + interiorFile = "dpole1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "107.386 49.616 121.09"; + rotation = "1 0 0 0"; + scale = "1 1 1.05589"; + interiorFile = "dpole1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + }; + new SimGroup(TeamDrops) { + + powerCount = "0"; + + new SpawnSphere(respawnSphere) { + position = "-445.99 -376.448 66.8051"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "SpawnSphereMarker"; + lockCount = "0"; + homingCount = "0"; + radius = "140"; + sphereWeight = "100"; + indoorWeight = "100"; + outdoorWeight = "50"; + }; + }; + new SimGroup(nodes) { + + powerCount = "0"; + + new Camera(AlchaldesVisit) { + position = "91.398 -6.88843 163.757"; + rotation = "0 0 1 89.3814"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + team = "2"; + }; + }; + new SimGroup(IsolationGroup) { + + powerCount = "0"; + + new Turret(NWTowerTurret) { + position = "51.4 47.253 162.665"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + nameTag = "\x01734"; + dataBlock = "TurretBaseLarge"; + lockCount = "0"; + homingCount = "0"; + initialBarrel = "MissileBarrelLarge"; + + team = "2"; + Target = "69"; + }; + new Turret(SETowerTurret) { + position = "163.318 -62.732 162.585"; + rotation = "0 0 1 179.909"; + scale = "1 1 1"; + nameTag = "\x01702"; + dataBlock = "TurretBaseLarge"; + lockCount = "0"; + homingCount = "0"; + initialBarrel = "MissileBarrelLarge"; + + team = "2"; + Target = "70"; + }; + new SimGroup(NorthBridge) { + + powerCount = "1"; + + new StaticShape(NorthBridgeGen) { + position = "292.178 280.66 82.0062"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + nameTag = "\x01703"; + dataBlock = "GeneratorLarge"; + lockCount = "0"; + homingCount = "0"; + + team = "2"; + Target = "71"; + }; + new ForceFieldBare() { + position = "103.62 282.64 161.61"; + rotation = "0 0 1 90"; + scale = "222.776 7.54321 1"; + dataBlock = "defaultNoTeamLavaLightField"; + lockCount = "0"; + homingCount = "0"; + + team = "2"; + Target = "72"; + }; + }; + new InteriorInstance() { + position = "-207.261 -7.55701 142.482"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "dpole1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "-207.261 -7.55701 162.482"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "dpole1.dif"; + showTerrainInside = "0"; + + team = "2"; + }; + new InteriorInstance() { + position = "-213.37 -7.668 161.61"; + rotation = "0 0 1 180"; + scale = "1 1 1"; + interiorFile = "dbrdg3a.dif"; + showTerrainInside = "0"; + + locked = "true"; + team = "2"; + }; + new Turret(NETowerTurret) { + position = "163.387 46.947 162.665"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + nameTag = "\x01701"; + dataBlock = "TurretBaseLarge"; + lockCount = "0"; + homingCount = "0"; + initialBarrel = "MissileBarrelLarge"; + + team = "2"; + Target = "73"; + }; + new InteriorInstance() { + position = "-233.356 -7.69101 161.61"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "dbrdg7.dif"; + showTerrainInside = "0"; + + locked = "true"; + team = "2"; + }; + new Turret(SWTowerTurret) { + position = "51.473 -62.791 162.565"; + rotation = "0 0 1 179.909"; + scale = "1 1 1"; + nameTag = "\x01738"; + dataBlock = "TurretBaseLarge"; + lockCount = "0"; + homingCount = "0"; + initialBarrel = "MissileBarrelLarge"; + + team = "2"; + Target = "74"; + }; + }; + }; + new SimGroup(team0) { + + powerCount = "0"; + }; + }; + new SimGroup(RandomOrganics) { + + powerCount = "0"; + + new SimGroup(Addition1DSPlant16) { + + powerCount = "0"; + + new TSStatic() { + position = "-348 -196 106.781"; + rotation = "0 0 1 167"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-636 -532 150.656"; + rotation = "0 0 1 230"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-428 -260 111.188"; + rotation = "0 0 1 114"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-412 -164 111.656"; + rotation = "0 0 -1 119"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-364 -164 103.953"; + rotation = "0 0 1 120"; + scale = "1 1 1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-292 -188 128.547"; + rotation = "0 0 1 184"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-492 -548 122.672"; + rotation = "0 0 -1 75.0002"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-276 -468 111.969"; + rotation = "0 0 -1 58.0005"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-500 -556 123.344"; + rotation = "0 0 1 61"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-604 -292 115.953"; + rotation = "0 0 1 52"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-636 -188 157.312"; + rotation = "0 0 1 103"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-316 -260 122.5"; + rotation = "0 0 1 58.9998"; + scale = "1 1 1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-572 -284 131.266"; + rotation = "0 0 -1 55.0003"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-636 -492 158.203"; + rotation = "0 0 1 3.99996"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-636 -540 152.703"; + rotation = "0 0 1 219"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-444 -540 129.828"; + rotation = "0 0 -1 19.0001"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-588 -556 106.531"; + rotation = "0 0 -1 92.0004"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-292 -188 128.547"; + rotation = "0 0 1 202"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-620 -252 148.969"; + rotation = "0 0 1 38"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-276 -180 125.922"; + rotation = "0 0 1 43"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-660 -236 138.141"; + rotation = "0 0 1 224"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-556 -196 130.344"; + rotation = "0 0 -1 78.0002"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-564 -228 136.031"; + rotation = "0 0 1 228"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-356 -204 105.172"; + rotation = "0 0 1 19"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-444 -476 96.5469"; + rotation = "0 0 1 206"; + scale = "1 1 1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-380 -188 101.297"; + rotation = "0 0 1 48"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-276 -420 95.9688"; + rotation = "0 0 1 15"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-292 -540 126.203"; + rotation = "0 0 -1 112"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-428 -260 111.188"; + rotation = "0 0 -1 13.0002"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-580 -556 104.781"; + rotation = "0 0 1 147"; + scale = "1 1 1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-508 -548 122.984"; + rotation = "0 0 1 60.0001"; + scale = "1 1 1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-276 -188 124.547"; + rotation = "0 0 1 76.9998"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-284 -484 110.828"; + rotation = "0 0 -1 35"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-412 -172 113.031"; + rotation = "0 0 -1 16.9999"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-412 -172 113.031"; + rotation = "0 0 -1 50.9998"; + scale = "1 1 1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-436 -244 112.297"; + rotation = "0 0 1 78.0002"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-644 -228 141.891"; + rotation = "0 0 1 97.9998"; + scale = "1 1 1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-524 -164 147.094"; + rotation = "0 0 1 142"; + scale = "1 1 1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-292 -492 109.156"; + rotation = "0 0 1 53"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-620 -228 151.547"; + rotation = "0 0 -1 92.0004"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg16.dts"; + }; + }; + new SimGroup(Addition2DSPlant17) { + + powerCount = "0"; + + new TSStatic() { + position = "-500 -548 123.25"; + rotation = "-0.0619038 0.012427 0.998005 146.064"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "-564 -236 137.688"; + rotation = "0.101053 0.144122 0.984387 70.8497"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "-444 -548 127.344"; + rotation = "-0.830265 -0.530269 0.17168 17.3446"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "-492 -524 123.797"; + rotation = "0.477358 -0.532224 -0.69919 26.9199"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "-636 -500 157.062"; + rotation = "-0.749737 0.399268 -0.527712 16.9644"; + scale = "1 1 1"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "-412 -164 111.656"; + rotation = "0.0543937 0.0547673 -0.997016 88.1707"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "-316 -412 79.5"; + rotation = "0.00755817 -0.103259 0.994626 63.2758"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "-444 -196 126.422"; + rotation = "0.175219 -0.324668 -0.929456 39.597"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg17.dts"; + }; + }; + new SimGroup(Addition3DSPlant17) { + + powerCount = "0"; + + new TSStatic() { + position = "12 -412 104.844"; + rotation = "-0.0503551 -0.018623 0.998558 143.05"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "-20 -412 106.25"; + rotation = "0.0761431 -0.110215 -0.990987 88.5186"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "-12 -468 142.812"; + rotation = "0.137513 0.111945 0.984154 97.9076"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "-84 -452 145.703"; + rotation = "0.0935228 0.120898 0.98825 234.447"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "-68 -492 131.578"; + rotation = "-0.0355517 -0.0468571 0.998269 78.0976"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "-12 -412 106.219"; + rotation = "0.0821308 -0.000199039 0.996622 84.1932"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "-4 -412 105.5"; + rotation = "0.0670501 -0.0130461 0.997664 88.134"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "-68 -492 131.578"; + rotation = "-0.495608 -0.154473 0.854699 8.18628"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "-68 -476 133.109"; + rotation = "-0.00379916 0.163641 -0.986513 80.767"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "-76 -484 132.672"; + rotation = "0.108004 0.0352753 0.993524 194.904"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg17.dts"; + }; + }; + new SimGroup(Addition4DSPlant19) { + + powerCount = "0"; + + new TSStatic() { + position = "172 -332 146.234"; + rotation = "0 0 1 16"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "172 -348 148.938"; + rotation = "0 0 -1 73.0006"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "172 -348 148.938"; + rotation = "0 0 1 69.0002"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "140 -452 147.734"; + rotation = "0 0 1 111"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "-4 -412 105.5"; + rotation = "0 0 1 70.9998"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "212 -332 153.156"; + rotation = "0 0 1 104"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "84 -308 164.703"; + rotation = "0 0 1 3.99996"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "204 -380 156.266"; + rotation = "0 0 1 17"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "196 -372 157.594"; + rotation = "0 0 -1 11.9998"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "-12 -476 143.562"; + rotation = "0 0 -1 37.0002"; + scale = "1 1 1"; + shapeName = "dorg19.dts"; + }; + }; + new SimGroup(Addition5DSPlant19) { + + powerCount = "0"; + + new TSStatic() { + position = "-364 28 166"; + rotation = "0 0 -1 60.0001"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "-420 -100 94.5312"; + rotation = "0 0 1 113"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "-292 -172 129.5"; + rotation = "0 0 1 138"; + scale = "1 1 1"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "-204 196 132.141"; + rotation = "0 0 -1 50.9998"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "-364 -172 103.875"; + rotation = "0 0 1 39"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg19.dts"; + }; + }; + new SimGroup(Addition6DSPlant16) { + + powerCount = "0"; + + new TSStatic() { + position = "-524 -212 146.031"; + rotation = "0 0 1 38"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-500 -76 105.25"; + rotation = "0 0 1 126"; + scale = "1 1 1"; + shapeName = "dorg16.dts"; + }; + }; + new SimGroup(Addition11DSPlant16) { + + powerCount = "0"; + + new TSStatic() { + position = "892 476 173.172"; + rotation = "0 0 1 209"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "964 356 99.141"; + rotation = "0 0 -1 97"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "948 812 136.375"; + rotation = "0 0 -1 94"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "964 156 94.0313"; + rotation = "0 0 1 97"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "1148 572 136.016"; + rotation = "0 0 1 118"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "812 420 116.266"; + rotation = "0 0 1 141"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "548 900 161.422"; + rotation = "0 0 -1 50.9998"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "756 612 151.969"; + rotation = "0 0 1 233"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "1140 788 162.828"; + rotation = "0 0 -1 73.0006"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "1028 484 164"; + rotation = "0 0 1 234"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "1044 484 161.5"; + rotation = "0 0 -1 2.9997"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "812 268 89.9687"; + rotation = "0 0 1 238"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "956 812 136.484"; + rotation = "0 0 1 35"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "476 364 194.453"; + rotation = "0 0 1 177"; + scale = "1 1 1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "604 916 149.047"; + rotation = "0 0 -1 4.00015"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "812 748 130.172"; + rotation = "0 0 1 24"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "732 212 76.3593"; + rotation = "0 0 1 51"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "1100 508 149.781"; + rotation = "0 0 -1 29.9998"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "676 764 169.812"; + rotation = "0 0 -1 80.0004"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "1092 876 185.672"; + rotation = "0 0 1 217"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "428 548 211.094"; + rotation = "0 0 1 121"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "932 524 173.125"; + rotation = "0 0 -1 71.0004"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "996 180 97.219"; + rotation = "0 0 1 44"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "636 892 140.578"; + rotation = "0 0 1 54"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "708 252 95.1562"; + rotation = "0 0 1 66.0002"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "420 676 178.266"; + rotation = "0 0 -1 29"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "956 868 153.906"; + rotation = "0 0 1 67.9998"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "908 524 173"; + rotation = "0 0 1 205"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "868 156 94.3594"; + rotation = "0 0 1 117"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "460 516 183.859"; + rotation = "0 0 1 230"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "604 916 149.047"; + rotation = "0 0 -1 119"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "1012 804 150.625"; + rotation = "0 0 -1 37.0002"; + scale = "1 1 1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "980 756 116.422"; + rotation = "0 0 1 28"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "788 668 117.719"; + rotation = "0 0 1 17"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "1012 348 117.969"; + rotation = "0 0 1 217"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "964 700 155.375"; + rotation = "0 0 -1 61.0005"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "756 252 86.9531"; + rotation = "0 0 -1 77.0004"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "1148 380 70.6719"; + rotation = "0 0 1 22"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "428 644 178.656"; + rotation = "0 0 1 161"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "1180 644 160.187"; + rotation = "0 0 1 215"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "908 300 68.1719"; + rotation = "0 0 -1 58.0005"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "924 524 173.031"; + rotation = "0 0 1 69.0002"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "692 364 123.922"; + rotation = "0 0 -1 53.9998"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "1156 796 167.719"; + rotation = "0 0 -1 92.0004"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "524 788 196.734"; + rotation = "0 0 1 141"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg16.dts"; + }; + }; + new SimGroup(Addition12DSPlant17) { + + powerCount = "0"; + + new TSStatic() { + position = "596 604 155.219"; + rotation = "-0.252214 0.0568745 0.965999 52.557"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "676 780 168.969"; + rotation = "0.0644755 0.0918072 -0.993687 79.3563"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "1180 428 100.875"; + rotation = "-0.13555 -0.0513793 0.989437 205.735"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "796 884 150.734"; + rotation = "0.214537 0.335293 -0.917362 31.4878"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "1052 516 172.5"; + rotation = "0.0326082 -0.0612456 0.99759 96.1377"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "700 444 95.7187"; + rotation = "0.0236739 -0.00272442 0.999716 130.013"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "444 364 181.766"; + rotation = "0.182467 -0.00253999 -0.983209 95.9659"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "748 388 124.922"; + rotation = "0.145242 0.0220224 0.989151 227.537"; + scale = "1 1 1"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "684 508 115.016"; + rotation = "0.107873 -0.0904691 0.99004 144.336"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "1012 812 150.656"; + rotation = "-0.436177 -0.113977 -0.892614 22.3487"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "764 268 90.5625"; + rotation = "-0.151402 -0.00972159 0.988424 127.531"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "972 220 99.687"; + rotation = "-0.0666638 0.167378 0.983636 83.9389"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "948 908 112.328"; + rotation = "-0.0115508 -0.143244 0.98962 84.5949"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "1164 772 170.828"; + rotation = "-0.0696701 0.0635217 0.995546 107.245"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "1140 788 162.828"; + rotation = "-0.138555 0.0419806 0.989465 124.501"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "668 484 117.547"; + rotation = "-0.112626 -0.107037 0.987855 147.379"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "1068 468 173.547"; + rotation = "-0.0739407 0.066415 0.995049 182.985"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "572 548 163.734"; + rotation = "0.0235022 -0.0760124 0.99683 188.971"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "932 748 132.016"; + rotation = "0.0157534 0.0466812 -0.998786 97.0689"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "556 636 146.938"; + rotation = "0.00172912 -0.183868 0.982949 61.8651"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "700 380 127.609"; + rotation = "-0.575477 -0.32338 0.751166 26.4206"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "388 844 163.953"; + rotation = "0.0485287 0.0029749 0.998817 109.064"; + scale = "1 1 1"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "812 748 130.172"; + rotation = "-0.121092 0.110974 -0.986418 41.5167"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "932 628 129.078"; + rotation = "0.0144005 -0.0381498 0.999168 167.011"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "964 708 155.375"; + rotation = "-0.0136492 0.313518 -0.949484 37.7824"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "580 604 156.922"; + rotation = "-0.450827 -0.23556 -0.860969 37.971"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "668 484 117.547"; + rotation = "-0.121311 -0.101946 0.987366 140.466"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "764 492 156.484"; + rotation = "0.117335 -0.0381243 0.99236 54.3563"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "588 924 147.562"; + rotation = "0.204729 0.174863 -0.963073 58.8262"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "436 724 168.313"; + rotation = "0.0454692 0.134065 0.989929 209.711"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "908 756 125.5"; + rotation = "0.0625492 -0.146797 0.987187 145.422"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "980 820 135.922"; + rotation = "0.127602 -0.10248 0.986517 223.463"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "748 268 88.3906"; + rotation = "-0.0133015 -0.0530759 0.998502 115.078"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "428 644 178.656"; + rotation = "-0.100363 0.105261 0.989367 146.341"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "1044 468 164.875"; + rotation = "0.0348411 0.150912 -0.987933 116.624"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "1180 572 127.766"; + rotation = "-0.0265204 -0.163439 -0.986197 116.714"; + scale = "1 1 1"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "980 812 135.953"; + rotation = "0.0360907 0.0983098 0.994501 179.006"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "756 228 77.6875"; + rotation = "-0.0980146 0.223292 -0.969811 77.7097"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "1124 772 160.703"; + rotation = "-0.0907992 -0.261222 0.960999 65.0491"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "628 884 140.391"; + rotation = "-0.894358 -0.309023 0.323463 12.3235"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "692 140 113.016"; + rotation = "0.0792873 -0.0294701 0.996416 157.08"; + scale = "1 1 1"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "916 220 72.7969"; + rotation = "0.00019495 0.0903265 0.995912 109.222"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "804 700 108.672"; + rotation = "0.583341 0.0169456 0.81205 28.1309"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "1044 252 125.531"; + rotation = "0.00811237 -0.0415602 0.999103 139.034"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "556 900 159.969"; + rotation = "0.137374 -0.210933 0.967799 61.6371"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "908 228 72.875"; + rotation = "-0.0695661 0.115309 -0.990891 115.474"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg17.dts"; + }; + }; + new SimGroup(Addition13DSPlant18) { + + powerCount = "0"; + + new TSStatic() { + position = "972 156 95.4218"; + rotation = "0 0 -1 74.0004"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "1116 868 181.031"; + rotation = "0 0 1 58.9998"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "428 372 177.891"; + rotation = "0 0 1 79"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "676 388 126.625"; + rotation = "0 0 -1 58.0005"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "828 764 134.531"; + rotation = "0 0 -1 82"; + scale = "1 1 1"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "924 508 173.453"; + rotation = "0 0 -1 14.9998"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "1100 812 157.953"; + rotation = "0 0 1 1.9999"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "404 388 158.766"; + rotation = "0 0 1 205"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "556 884 168.078"; + rotation = "0 0 1 99.0002"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "484 484 178.281"; + rotation = "0 0 -1 81.0002"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "1116 676 142.453"; + rotation = "0 0 1 221"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "676 836 154.063"; + rotation = "0 0 -1 107"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "452 492 179"; + rotation = "0 0 -1 90.0002"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "1068 860 172.672"; + rotation = "0 0 -1 104"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "684 268 90.8593"; + rotation = "0 0 1 160"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "788 308 109.531"; + rotation = "0 0 1 39"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "1012 804 150.625"; + rotation = "0 0 -1 115"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "980 204 104.016"; + rotation = "0 0 1 44"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "924 244 77.6875"; + rotation = "0 0 1 122"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "1020 652 182.672"; + rotation = "0 0 1 18"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "620 204 143.344"; + rotation = "0 0 1 12"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "924 516 173.063"; + rotation = "0 0 1 214"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "492 308 158.859"; + rotation = "0 0 1 143"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "1084 652 152.109"; + rotation = "0 0 1 28"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "620 212 144.453"; + rotation = "0 0 1 156"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "1108 524 155.203"; + rotation = "0 0 1 28"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "844 452 125.641"; + rotation = "0 0 1 136"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "532 428 180.125"; + rotation = "0 0 -1 10.9999"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "684 388 127.75"; + rotation = "0 0 1 109"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "692 276 90.8124"; + rotation = "0 0 1 20"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "1068 820 175.313"; + rotation = "0 0 1 66.0002"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "860 156 94.125"; + rotation = "0 0 -1 107"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "540 428 178.094"; + rotation = "0 0 -1 100"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "940 708 139.703"; + rotation = "0 0 1 60.0001"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "924 252 78.1406"; + rotation = "0 0 1 165"; + scale = "1 1 1"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "772 260 90.8437"; + rotation = "0 0 -1 50.9998"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "692 156 112.984"; + rotation = "0 0 1 148"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "1100 860 183.859"; + rotation = "0 0 1 49"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "1108 628 148.562"; + rotation = "0 0 1 94.9998"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "972 812 136.266"; + rotation = "0 0 1 229"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "972 220 99.687"; + rotation = "0 0 1 222"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "1036 756 151.047"; + rotation = "0 0 1 29"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "596 772 152.672"; + rotation = "0 0 1 235"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "836 452 126.141"; + rotation = "0 0 1 64"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "436 732 167.469"; + rotation = "0 0 1 7.99996"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "988 284 116.016"; + rotation = "0 0 1 57.9999"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "500 756 195.719"; + rotation = "0 0 1 172"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "644 492 118.75"; + rotation = "0 0 1 20"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg18.dts"; + }; + }; + new SimGroup(Addition14DSPlant19) { + + powerCount = "0"; + + new TSStatic() { + position = "756 212 76.8125"; + rotation = "0 0 1 208"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "676 764 169.812"; + rotation = "0 0 -1 110"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "1108 748 157.578"; + rotation = "0 0 1 140"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "572 564 167.922"; + rotation = "0 0 -1 97"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "828 452 126.687"; + rotation = "0 0 1 185"; + scale = "1 1 1"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "460 900 128.109"; + rotation = "0 0 1 51"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "892 876 171.438"; + rotation = "0 0 -1 44"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "1180 860 197.953"; + rotation = "0 0 1 236"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "1100 524 154.406"; + rotation = "0 0 1 236"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "604 164 171.953"; + rotation = "0 0 -1 93.0002"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "780 308 112.078"; + rotation = "0 0 -1 76"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "812 276 91.4532"; + rotation = "0 0 1 49"; + scale = "1 1 1"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "740 892 162.078"; + rotation = "0 0 1 90.0002"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "1028 484 164"; + rotation = "0 0 -1 95.0004"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "452 604 159.688"; + rotation = "0 0 1 153"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "676 876 157.391"; + rotation = "0 0 -1 5.99979"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "572 804 158.656"; + rotation = "0 0 1 204"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "804 692 111.109"; + rotation = "0 0 1 239"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "556 540 157.937"; + rotation = "0 0 -1 112"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "1124 868 180.422"; + rotation = "0 0 -1 38.9999"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "748 276 89.7344"; + rotation = "0 0 1 198"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "844 236 116.266"; + rotation = "0 0 1 169"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "668 532 112.703"; + rotation = "0 0 1 87.0002"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "1124 772 160.703"; + rotation = "0 0 -1 46.0002"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "572 716 204.594"; + rotation = "0 0 -1 32.9998"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "820 460 127.109"; + rotation = "0 0 1 150"; + scale = "1 1 1"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "980 220 100.625"; + rotation = "0 0 1 24"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "772 708 109.203"; + rotation = "0 0 -1 53.9998"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "388 812 156.672"; + rotation = "0 0 -1 23.9998"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "588 932 148.109"; + rotation = "0 0 -1 4.00015"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "956 588 160.734"; + rotation = "0 0 1 152"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "908 436 151.469"; + rotation = "0 0 1 101"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "1004 316 118.219"; + rotation = "0 0 -1 26"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "540 420 178.047"; + rotation = "0 0 -1 32"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "564 212 171.297"; + rotation = "0 0 -1 65.0004"; + scale = "1 1 1"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "596 700 209.375"; + rotation = "0 0 1 1.9999"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "580 932 147"; + rotation = "0 0 1 235"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "572 804 158.656"; + rotation = "0 0 1 128"; + scale = "1 1 1"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "812 900 150.344"; + rotation = "0 0 1 119"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "828 428 120.375"; + rotation = "0 0 1 162"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "604 852 130.406"; + rotation = "0 0 1 224"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "1172 860 197.391"; + rotation = "0 0 1 150"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "668 516 115.172"; + rotation = "0 0 1 67"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "428 380 178.078"; + rotation = "0 0 -1 72.0002"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg19.dts"; + }; + }; + }; +}; +//--- OBJECT WRITE END --- + +//exec("missions/beginning.cs"); + diff --git a/missions/Deployment.cs b/missions/Deployment.cs index ad20627..2e3b2bd 100644 --- a/missions/Deployment.cs +++ b/missions/Deployment.cs @@ -1,370 +1,370 @@ -// don't want this executing when building graphs -if($OFFLINE_NAV_BUILD) - return; - -// Script for Training -//=================================================================================== -//error("Training 1 script"); - -//Note: Quite messy right now.. I'll organize when it's done - -// package and callbacks -activatePackage(HotZone); - -// variables -$numberOfEnemies[1] = 1; -$numberOfEnemies[2] = 1; -$numberOfEnemies[3] = 1; -$numberOfTeammates = 1; -$missionBotSkill[1] = 0.0; -$missionBotSkill[2] = 0.4; -$missionBotSkill[3] = 0.7; - -// additional mission Audio -datablock AudioProfile(HeartbeatSound) -{ - filename = "fx/misc/heartbeat.wav"; - description = Audio2D; - preload = true; - looping = false; -}; - -package HotZone { -//BEGIN TRAINING PACKAGE ======================================================================= - -function SinglePlayerGame::initGameVars(%game) -{ - echo("initializing training1 game vars"); -} - -function getTeammateGlobals() -{ - $TeammateWarnom0 = "Raptor"; - $teammateskill0 = 0.5; - $teammateVoice0 = Derm3; - $teammateEquipment0 = 0; - $teammateGender0 = Male; - - $TeammateWarnom1 = "Cobra"; - $teammateSkill1 = 0.5; - $teammateVoice1 = Derm3; - $teammateEquipment1 = 0; - $teammateGender1 = C; - - $TeammateWarnom2 = "Sharp Tooth"; - $teammateSkill2 = 0.5; - $teammateVoice2 = Derm3; - $teammateEquipment2 = 0; - $teammateGender2 = A; - - $TeammateWarnom3 = "Snake"; - $teammateSkill3 = 0.5; - $teammateVoice3 = Derm3; - $teammateEquipment3 = 0; - $teammateGender3 = A; - - $TeammateWarnom4 = "Gila"; - $teammateSkill4 = 0.5; - $teammateVoice4 = Derm3; - $teammateEquipment4 = 0; - $teammateGender4 = B; -} - - -function AIFollowPath::assume(%task, %client) -{ - %task.setWeightFreq(30); - %task.setMonitorFreq(10); - - -// //next, start the pilot on his way to mounting the vehicle -// %client.pilotVehicle = true; -// %client.stepMove($player.flyer.position, 0.25, $AIModeMountVehicle); -} - -function AIFollowPath::weight(%task, %client) -{ - %task.setWeight(10000); -} - -function AIFollowPath::monitor(%task, %client) -{ - //messageall(0, " AITraining1Pilot::monitor "@%task.locationIndex); - %group = nameToId(FlightPath); - if(!%task.locationIndex) - %task.locationIndex = 0; - - //HACK ALERT!!! - //since the path for this mission is completely straight, always head for the end of the path - //%location = %group.getObject(%task.locationIndex); - %location = %group.getObject(%group.getCount() - 1); - - //see if we've mounted yet - if(%client.vehicleMounted) - { - %client.setPilotDestination(%location.position); - - //else see if we're close enough to the current destination to choose the next - %pos = %client.vehicleMounted.position; - %pos2D = getWord(%pos, 0) SPC getWord(%pos, 1) SPC "0"; - %dest = %group.getObject(%task.locationIndex).position; - %dest2D = getWord(%dest, 0) SPC getWord(%dest, 1) SPC "0"; - - if (VectorDist(%dest2D, %pos2D) < 20) - { - if(%group.getCount() > %task.locationIndex + 1) { - %task.locationIndex++; - cinematicEvent(%task.locationIndex); - } - //else messageAll(0, "Ride Over"); - } - } - else - %client.stepMove($player.flyer.position, 0.25, $AIModeExpress); -} - -function PlayGui::onWake(%this) -{ - parent::onWake(%this); - //error("Waking training play gui"); - // okay we know the victim...erm...player is looking - // and we hope they have a body so lets do this - if(!game.playedIntro) { - game.PlayGuiAwake = true; - beginMission(); - } - -} - -function aiSetLoadout(%client) -{ -%client.player.clearInventory(); -%client.player.setArmor("heavy"); -%client.player.setInventory("Chaingun",1,true); -%client.player.setInventory("ChaingunAmmo",999,true); -%client.player.setInventory("Disc",1,true); -%client.player.setInventory("Discammo",999,true); -%client.player.setInventory("Shocklance",1,true); -%client.player.setInventory("MissileLauncher",1,true); -%client.player.setInventory("MissileLauncherAmmo",999,true); -%client.player.setInventory("Mortar",1,true); -%client.player.setInventory("MortarAmmo",999,true); -%client.player.setInventory("AmmoPack",1,true); -%client.player.use("Mortar"); -} - -function beginHotZone() //Don't let the game reset itself a bunch of times -{ -if (Game.playedIntro) -return; -%spawn = nameToId(introFlyerSP); - -$player.flyer = new FlyingVehicle(Flyer) { - position = %spawn.position; - rotation = %spawn.rotation; - scale = "1 1 1"; - dataBlock = "HAPCFlyer"; - }; - -%pilot = $teammate0; -game.playedIntro = true; -$player.flyer.pilot = $teammate0; -setTargetSkin(%pilot.target, $teamSkin[$playerTeam]); -%pilot.player.setArmor(light); -%pilot.pilotVehicle = false; -$player.flyer.mountObject(%pilot.player, 0); -%pilot.setControlObject($player.flyer); -%pilot.setPilotPitchRange(-0.2, 0.05, 0.05); -%pilot.addTask(AIFollowPath); - -$player.flyer.mountObject($player.player, 1); -$player.flyer.mountObject($teammate1.player, 2); -$player.flyer.mountObject($teammate2.player, 3); -$player.flyer.mountObject($teammate3.player, 4); -$player.flyer.mountObject($teammate4.player, 5); -aiSetLoadout($teammate1); -aiSetLoadout($teammate2); -aiSetLoadout($teammate3); -aiSetLoadout($teammate4); -$player.player.setTransform($player.player.position SPC %spawn.rotation); -$HotZoneBlackout = ServerConnection.schedule(3000, setBlackOut, false, 4000); - -//Has to be added after all the bots.. otherwise they die by lava somehow -new WaterBlock(Lava) { -position = "-224 -264 93.1568"; -rotation = "1 0 0 0"; -scale = "768 608 27.0092"; -liquidType = "Lava"; -density = "1"; -viscosity = "15"; -waveMagnitude = "1"; -surfaceTexture = "LiquidTiles/Lava"; -surfaceOpacity = "1"; -envMapTexture = "lava/skies/lava_starrynite_emap"; -envMapIntensity = "0.2"; -submergeTexture[0] = "special/lavadeath_1"; -submergeTexture[1] = "special/lavadeath_2"; -removeWetEdges = "1"; - -locked = "true"; -}; - -} - -function MP3Audio::play(%this) -{ - //too bad...no mp3 in training -} - -function toggleCommanderMap(%val) -{ - if ( %val ) - messageClient($player, 0, $player.miscMsg[noCC]); -} - -function toggleTaskListDlg( %val ) -{ - if ( %val ) - messageClient( $player, 0, $player.miscMsg[noTaskListDlg] ); -} - -function toggleInventoryHud( %val ) -{ - if ( %val ) - messageClient( $player, 0, $player.miscMsg[noInventoryHUD] ); -} - -function toggleNetDisplayHud( %val ) -{ - // Hello, McFly? This is training! There's no net in training! -} - -function voiceCapture( %val ) -{ - // Uh, who do you think you are talking to? -} - -function giveall() -{ - error("When the going gets tough...wussies like you start cheating!"); - messageClient($player, 0, "Cheating eh? What\'s next? Camping?"); -} - -// get the ball rolling -//------------------------------------------------------------------------------ -function startCurrentMission() -{ - playGui.add(outerChatHud); - - //fade up from black - ServerConnection.setBlackOut(true, 0); -} - -//------------------------------------------------------------------------------ -function SinglePlayerGame::equip(%game, %player) -{ - //ya start with nothing...NOTHING! - %player.clearInventory(); - for(%i =0; %i<$InventoryHudCount; %i++) - %player.client.setInventoryHudItem($InventoryHudData[%i, itemDataName], 0, 1); - %player.client.clearBackpackIcon(); - - %set = %player.client.equipment; - - echo("using default equipment"); - - %player.setArmor("Light"); - %player.setInventory(RepairKit,1); - %player.setInventory(Chaingun, 1); - %player.setInventory(ChaingunAmmo, 100); - %player.setInventory(Disc,1); - %player.setInventory(DiscAmmo, 20); - %player.setInventory(Shocklance, 1); - %player.setInventory(AmmoPack, 1); - - //DefaultGame.cs does not assign flamer.. - %player.setInventory(flamer, 1); - %player.weaponCount = 4; - - %player.use(Chaingun); -} - -function spawnSinglePlayer() -{ - resetWildCat(); - parent::spawnSinglePlayer(); -} - -function singlePlayerGame::onAIRespawn(%game, %client) -{ - // DONT add the default tasks - //error("default tasks not added"); -} - -function singlePlayerGame::playerSpawned(%game, %player) -{ - parent::playerSpawned(%game, %player); -} - -function singlePlayerGame::gameOver(%game) -{ - //enable the voice chat menu again... - if (isObject(training1BlockMap)) - { - training1BlockMap.pop(); - training1BlockMap.delete(); - } - - if(HelpTextGui.isVisible()) - helpTextGui.setVisible(false); - - //re-enable the use of the settings button... - SinglePlayerEscSettingsBtn.setActive(1); - - Parent::gameOver(); -} - -function trainingPreloads() //Load any skins.. -{ - navGraph.preload("skins/Gecko.lbioderm", true); - navGraph.preload("skins/Gecko.mbioderm", true); - navGraph.preload("skins/Gecko.hbioderm", true); - navGraph.preload("skins/base.lbioderm", true); - navGraph.preload("skins/HALO_Skin.lbioderm", true); - navGraph.preload("skins/HALO_Skin.mbioderm", true); - navGraph.preload("skins/HALO_Skin.hbioderm", true); - navGraph.preload("skins/sensor_pulse_large", true); - navGraph.preload("skins/base.hmale", false); - navGraph.preload("skins/beagle.hmale", false); - navGraph.preload("skins/base.mmale", false); - navGraph.preload("skins/beagle.mmale", false); - navGraph.preload("skins/base.lmale", false); - navGraph.preload("skins/swolf.mmale", false); - navGraph.preload("skins/beagle.lmale", false); -} - -function SinglePlayerGame::missionLoadDone(%game) -{ - Parent::missionLoadDone(%game); - trainingPreloads(); -} - -function serverCmdBuildClientTask(%client, %task, %team) -{ - // player shouldnt be able to use the voice commands to do anything -} -}; - -package vehicleHack -{ -function AIConnection::isMountingVehicle(%client){ return true; } -}; -activatePackage(vehicleHack); - -function setActionThread(%player,%anim,%bool) -{ -%player.setActionThread(%anim,%bool); -} - - - +// don't want this executing when building graphs +if($OFFLINE_NAV_BUILD) + return; + +// Script for Training +//=================================================================================== +//error("Training 1 script"); + +//Note: Quite messy right now.. I'll organize when it's done + +// package and callbacks +activatePackage(HotZone); + +// variables +$numberOfEnemies[1] = 1; +$numberOfEnemies[2] = 1; +$numberOfEnemies[3] = 1; +$numberOfTeammates = 1; +$missionBotSkill[1] = 0.0; +$missionBotSkill[2] = 0.4; +$missionBotSkill[3] = 0.7; + +// additional mission Audio +datablock AudioProfile(HeartbeatSound) +{ + filename = "fx/misc/heartbeat.wav"; + description = Audio2D; + preload = true; + looping = false; +}; + +package HotZone { +//BEGIN TRAINING PACKAGE ======================================================================= + +function SinglePlayerGame::initGameVars(%game) +{ + echo("initializing training1 game vars"); +} + +function getTeammateGlobals() +{ + $TeammateWarnom0 = "Raptor"; + $teammateskill0 = 0.5; + $teammateVoice0 = Derm3; + $teammateEquipment0 = 0; + $teammateGender0 = Male; + + $TeammateWarnom1 = "Cobra"; + $teammateSkill1 = 0.5; + $teammateVoice1 = Derm3; + $teammateEquipment1 = 0; + $teammateGender1 = C; + + $TeammateWarnom2 = "Sharp Tooth"; + $teammateSkill2 = 0.5; + $teammateVoice2 = Derm3; + $teammateEquipment2 = 0; + $teammateGender2 = A; + + $TeammateWarnom3 = "Snake"; + $teammateSkill3 = 0.5; + $teammateVoice3 = Derm3; + $teammateEquipment3 = 0; + $teammateGender3 = A; + + $TeammateWarnom4 = "Gila"; + $teammateSkill4 = 0.5; + $teammateVoice4 = Derm3; + $teammateEquipment4 = 0; + $teammateGender4 = B; +} + + +function AIFollowPath::assume(%task, %client) +{ + %task.setWeightFreq(30); + %task.setMonitorFreq(10); + + +// //next, start the pilot on his way to mounting the vehicle +// %client.pilotVehicle = true; +// %client.stepMove($player.flyer.position, 0.25, $AIModeMountVehicle); +} + +function AIFollowPath::weight(%task, %client) +{ + %task.setWeight(10000); +} + +function AIFollowPath::monitor(%task, %client) +{ + //messageall(0, " AITraining1Pilot::monitor "@%task.locationIndex); + %group = nameToId(FlightPath); + if(!%task.locationIndex) + %task.locationIndex = 0; + + //HACK ALERT!!! + //since the path for this mission is completely straight, always head for the end of the path + //%location = %group.getObject(%task.locationIndex); + %location = %group.getObject(%group.getCount() - 1); + + //see if we've mounted yet + if(%client.vehicleMounted) + { + %client.setPilotDestination(%location.position); + + //else see if we're close enough to the current destination to choose the next + %pos = %client.vehicleMounted.position; + %pos2D = getWord(%pos, 0) SPC getWord(%pos, 1) SPC "0"; + %dest = %group.getObject(%task.locationIndex).position; + %dest2D = getWord(%dest, 0) SPC getWord(%dest, 1) SPC "0"; + + if (VectorDist(%dest2D, %pos2D) < 20) + { + if(%group.getCount() > %task.locationIndex + 1) { + %task.locationIndex++; + cinematicEvent(%task.locationIndex); + } + //else messageAll(0, "Ride Over"); + } + } + else + %client.stepMove($player.flyer.position, 0.25, $AIModeExpress); +} + +function PlayGui::onWake(%this) +{ + parent::onWake(%this); + //error("Waking training play gui"); + // okay we know the victim...erm...player is looking + // and we hope they have a body so lets do this + if(!game.playedIntro) { + game.PlayGuiAwake = true; + beginMission(); + } + +} + +function aiSetLoadout(%client) +{ +%client.player.clearInventory(); +%client.player.setArmor("heavy"); +%client.player.setInventory("Chaingun",1,true); +%client.player.setInventory("ChaingunAmmo",999,true); +%client.player.setInventory("Disc",1,true); +%client.player.setInventory("Discammo",999,true); +%client.player.setInventory("Shocklance",1,true); +%client.player.setInventory("MissileLauncher",1,true); +%client.player.setInventory("MissileLauncherAmmo",999,true); +%client.player.setInventory("Mortar",1,true); +%client.player.setInventory("MortarAmmo",999,true); +%client.player.setInventory("AmmoPack",1,true); +%client.player.use("Mortar"); +} + +function beginHotZone() //Don't let the game reset itself a bunch of times +{ +if (Game.playedIntro) +return; +%spawn = nameToId(introFlyerSP); + +$player.flyer = new FlyingVehicle(Flyer) { + position = %spawn.position; + rotation = %spawn.rotation; + scale = "1 1 1"; + dataBlock = "HAPCFlyer"; + }; + +%pilot = $teammate0; +game.playedIntro = true; +$player.flyer.pilot = $teammate0; +setTargetSkin(%pilot.target, $teamSkin[$playerTeam]); +%pilot.player.setArmor(light); +%pilot.pilotVehicle = false; +$player.flyer.mountObject(%pilot.player, 0); +%pilot.setControlObject($player.flyer); +%pilot.setPilotPitchRange(-0.2, 0.05, 0.05); +%pilot.addTask(AIFollowPath); + +$player.flyer.mountObject($player.player, 1); +$player.flyer.mountObject($teammate1.player, 2); +$player.flyer.mountObject($teammate2.player, 3); +$player.flyer.mountObject($teammate3.player, 4); +$player.flyer.mountObject($teammate4.player, 5); +aiSetLoadout($teammate1); +aiSetLoadout($teammate2); +aiSetLoadout($teammate3); +aiSetLoadout($teammate4); +$player.player.setTransform($player.player.position SPC %spawn.rotation); +$HotZoneBlackout = ServerConnection.schedule(3000, setBlackOut, false, 4000); + +//Has to be added after all the bots.. otherwise they die by lava somehow +new WaterBlock(Lava) { +position = "-224 -264 93.1568"; +rotation = "1 0 0 0"; +scale = "768 608 27.0092"; +liquidType = "Lava"; +density = "1"; +viscosity = "15"; +waveMagnitude = "1"; +surfaceTexture = "LiquidTiles/Lava"; +surfaceOpacity = "1"; +envMapTexture = "lava/skies/lava_starrynite_emap"; +envMapIntensity = "0.2"; +submergeTexture[0] = "special/lavadeath_1"; +submergeTexture[1] = "special/lavadeath_2"; +removeWetEdges = "1"; + +locked = "true"; +}; + +} + +function MP3Audio::play(%this) +{ + //too bad...no mp3 in training +} + +function toggleCommanderMap(%val) +{ + if ( %val ) + messageClient($player, 0, $player.miscMsg[noCC]); +} + +function toggleTaskListDlg( %val ) +{ + if ( %val ) + messageClient( $player, 0, $player.miscMsg[noTaskListDlg] ); +} + +function toggleInventoryHud( %val ) +{ + if ( %val ) + messageClient( $player, 0, $player.miscMsg[noInventoryHUD] ); +} + +function toggleNetDisplayHud( %val ) +{ + // Hello, McFly? This is training! There's no net in training! +} + +function voiceCapture( %val ) +{ + // Uh, who do you think you are talking to? +} + +function giveall() +{ + error("When the going gets tough...wussies like you start cheating!"); + messageClient($player, 0, "Cheating eh? What\'s next? Camping?"); +} + +// get the ball rolling +//------------------------------------------------------------------------------ +function startCurrentMission() +{ + playGui.add(outerChatHud); + + //fade up from black + ServerConnection.setBlackOut(true, 0); +} + +//------------------------------------------------------------------------------ +function SinglePlayerGame::equip(%game, %player) +{ + //ya start with nothing...NOTHING! + %player.clearInventory(); + for(%i =0; %i<$InventoryHudCount; %i++) + %player.client.setInventoryHudItem($InventoryHudData[%i, itemDataName], 0, 1); + %player.client.clearBackpackIcon(); + + %set = %player.client.equipment; + + echo("using default equipment"); + + %player.setArmor("Light"); + %player.setInventory(RepairKit,1); + %player.setInventory(Chaingun, 1); + %player.setInventory(ChaingunAmmo, 100); + %player.setInventory(Disc,1); + %player.setInventory(DiscAmmo, 20); + %player.setInventory(Shocklance, 1); + %player.setInventory(AmmoPack, 1); + + //DefaultGame.cs does not assign flamer.. + %player.setInventory(flamer, 1); + %player.weaponCount = 4; + + %player.use(Chaingun); +} + +function spawnSinglePlayer() +{ + resetWildCat(); + parent::spawnSinglePlayer(); +} + +function singlePlayerGame::onAIRespawn(%game, %client) +{ + // DONT add the default tasks + //error("default tasks not added"); +} + +function singlePlayerGame::playerSpawned(%game, %player) +{ + parent::playerSpawned(%game, %player); +} + +function singlePlayerGame::gameOver(%game) +{ + //enable the voice chat menu again... + if (isObject(training1BlockMap)) + { + training1BlockMap.pop(); + training1BlockMap.delete(); + } + + if(HelpTextGui.isVisible()) + helpTextGui.setVisible(false); + + //re-enable the use of the settings button... + SinglePlayerEscSettingsBtn.setActive(1); + + Parent::gameOver(); +} + +function trainingPreloads() //Load any skins.. +{ + navGraph.preload("skins/Gecko.lbioderm", true); + navGraph.preload("skins/Gecko.mbioderm", true); + navGraph.preload("skins/Gecko.hbioderm", true); + navGraph.preload("skins/base.lbioderm", true); + navGraph.preload("skins/HALO_Skin.lbioderm", true); + navGraph.preload("skins/HALO_Skin.mbioderm", true); + navGraph.preload("skins/HALO_Skin.hbioderm", true); + navGraph.preload("skins/sensor_pulse_large", true); + navGraph.preload("skins/base.hmale", false); + navGraph.preload("skins/beagle.hmale", false); + navGraph.preload("skins/base.mmale", false); + navGraph.preload("skins/beagle.mmale", false); + navGraph.preload("skins/base.lmale", false); + navGraph.preload("skins/swolf.mmale", false); + navGraph.preload("skins/beagle.lmale", false); +} + +function SinglePlayerGame::missionLoadDone(%game) +{ + Parent::missionLoadDone(%game); + trainingPreloads(); +} + +function serverCmdBuildClientTask(%client, %task, %team) +{ + // player shouldnt be able to use the voice commands to do anything +} +}; + +package vehicleHack +{ +function AIConnection::isMountingVehicle(%client){ return true; } +}; +activatePackage(vehicleHack); + +function setActionThread(%player,%anim,%bool) +{ +%player.setActionThread(%anim,%bool); +} + + + diff --git a/missions/Deployment.mis b/missions/Deployment.mis index 96ec8a3..33715e4 100644 --- a/missions/Deployment.mis +++ b/missions/Deployment.mis @@ -1,1204 +1,1204 @@ -// Deployment (TDS - Opposing Force Mission 1) -// DisplayName = Deployment -// MissionTypes = CTF - -//--- MISSION BRIEFING BEGIN --- -//Not working. -//--- MISSION BRIEFING END --- - -// BriefingWAV = T2BOL_1 -// Bitmap = trn_5draconis - -//--- MISSION STRING BEGIN --- -//OBJECTIVES: -//Bleck -//--- MISSION STRING END --- - -// PlanetName = Xeron, 3960 CE -//--- MISSION BLURB BEGIN --- -// You are Roman; a part of the original Criollos task force sent to Xeron to take over a small area for a base setup. -//--- MISSION BLURB END --- - -//--- OBJECT WRITE BEGIN --- -new SimGroup(MissionGroup) { - - musicTrack = "desert"; - powerCount = "0"; - cdTrack = "6"; - - new MissionArea(MissionArea) { - area = "-768 64 1024 800"; - flightCeiling = "300"; - flightCeilingRange = "20"; - - locked = "true"; - }; - new Sky(Sky) { - position = "0 0 0"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - cloudHeightPer[0] = "0.349971"; - cloudHeightPer[1] = "0.25"; - cloudHeightPer[2] = "0.199973"; - cloudSpeed1 = "0.0001"; - cloudSpeed2 = "0.0002"; - cloudSpeed3 = "0.0003"; - visibleDistance = "500"; - useSkyTextures = "1"; - renderBottomTexture = "0"; - SkySolidColor = "0.365000 0.390000 0.420000 0.000000"; - fogDistance = "200"; - fogColor = "0.550000 0.450000 0.380000 1.000000"; - fogVolume1 = "0 0 0"; - fogVolume2 = "0 0 0"; - fogVolume3 = "0 0 0"; - materialList = "sky_desert_blue.dml"; - windVelocity = "1 0 0"; - windEffectPrecipitation = "0"; - fogVolumeColor1 = "128.000000 128.000000 128.000000 0.000000"; - fogVolumeColor2 = "128.000000 128.000000 128.000000 0.000000"; - fogVolumeColor3 = "128.000000 128.000000 128.000000 0.000000"; - high_visibleDistance = "-1"; - high_fogDistance = "-1"; - high_fogVolume1 = "-1 0 0"; - high_fogVolume2 = "-1 0 0"; - high_fogVolume3 = "-1 0 0"; - - cloudSpeed0 = "0.000503 0.000020"; - locked = "true"; - }; - new Sun() { - position = "0 0 0"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - direction = "0.57735 0.57735 -0.57735"; - color = "0.900000 0.900000 0.900000 1.000000"; - ambient = "0.600000 0.600000 0.600000 1.000000"; - texture[0] = "special/sunFlare"; - texture[1] = "special/sunFlare02"; - texture[2] = "special/LensFlare/flare01"; - texture[3] = "special/LensFlare/flare02"; - texture[4] = "special/LensFlare/flare03"; - lensFlareScale = "0.7"; - lensFlareIntensity = "1"; - frontFlareSize = "300"; - backFlareSize = "450"; - flareColor = "1.000000 1.000000 1.000000 1.000000"; - - locked = "true"; - }; - new TerrainBlock(Terrain) { - rotation = "1 0 0 0"; - scale = "1 1 1"; - detailTexture = "details/desertdet1"; - terrainFile = "SunDried.ter"; - squareSize = "8"; - - position = "-1024 -1024 0"; - locked = "true"; - }; - new NavigationGraph(NavGraph) { - conjoinAngleDev = "50"; - cullDensity = "0.3"; - customArea = "0 0 0 0"; - - coverage = "0"; - position = "0 0 0 1"; - conjoinBowlDev = "20"; - rotation = "0 0 0 0"; - GraphFile = "SunDried.nav"; - locked = "true"; - scale = "1 1 1"; - }; - new SimGroup(ObserverDropPoints) { - - powerCount = "0"; - - new Camera() { - position = "-190.054 402.516 134.059"; - rotation = "0 0 1 121.942"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - - locked = "true"; - }; - new Camera() { - position = "-591.86 507.222 118.24"; - rotation = "-0.0675751 -0.168796 0.983332 222.976"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - - locked = "true"; - }; - new Camera() { - position = "-205.317 672.457 113.525"; - rotation = "0.919055 -0.0935562 0.382865 29.7787"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - - locked = "true"; - }; - new Camera() { - position = "107.001 155.043 84.8555"; - rotation = "0.317652 0.108804 -0.941944 39.9662"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - - locked = "true"; - }; - }; - new SimGroup(Teams) { - - powerCount = "0"; - - new SimGroup(Team1) { - - powerCount = "0"; - - new SimGroup(vehiclePath) { - - new SimSet(ActiveActionMapSet) { - - new ActionMap(GlobalActionMap) { - }; - new ActionMap(moveMap) { - }; - new ActionMap(EditorMap) { - }; - }; - new Camera(3) { - position = "-569.795 696.403 633.109"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - - team = "1"; - }; - new Camera(2) { - position = "-620.655 731.29 721.313"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - - team = "1"; - }; - new Camera(1) { - position = "-671.461 800.219 828.191"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - - team = "1"; - }; - }; - }; - new SimGroup(team0) { - - providesPower = "1"; - powerCount = "1"; - - new InteriorInstance() { - position = "109.864 449.038 117.362"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "pplat2.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "true"; - }; - new InteriorInstance() { - position = "-531.228 141.792 119.641"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "pplat2.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "true"; - }; - new InteriorInstance() { - position = "-198.269 767.314 49.4307"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "pbunk8.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "true"; - }; - new InteriorInstance() { - position = "-657.156 448.654 48.465"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "pbunk8.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "true"; - }; - new InteriorInstance() { - position = "89.53 185.821 53.7832"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "pbunk8.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "true"; - }; - new InteriorInstance() { - position = "-507.451 836.499 107.579"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "pplat2.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "true"; - }; - new InteriorInstance() { - position = "-363.513 213.64 73.8112"; - rotation = "0.105914 0.766908 0.632957 194.625"; - scale = "1 1 1"; - interiorFile = "prock8.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "true"; - }; - new InteriorInstance() { - position = "-138.357 589.646 60.8018"; - rotation = "0 0 1 40.68"; - scale = "1 1 1"; - interiorFile = "prockc.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "true"; - }; - new StaticShape(Team0StationInventory3) { - position = "83.7679 192.52 83.2818"; - rotation = "0 0 -1 45"; - scale = "1 1 1"; - nameTag = "\x01712"; - dataBlock = "StationInventory"; - lockCount = "0"; - homingCount = "0"; - - Trigger = "5040"; - team = "0"; - Target = "33"; - locked = "true"; - }; - new StaticShape(Team0StationInventory4) { - position = "95.9562 193.255 83.2872"; - rotation = "0 0 1 45"; - scale = "1 1 1"; - nameTag = "\x01712"; - dataBlock = "StationInventory"; - lockCount = "0"; - homingCount = "0"; - - Trigger = "5042"; - team = "0"; - Target = "34"; - locked = "true"; - }; - new StaticShape(Team0StationInventory3) { - position = "83.7438 192.587 75.7831"; - rotation = "0 0 -1 45"; - scale = "1 1 1"; - nameTag = "\x01713"; - dataBlock = "StationInventory"; - lockCount = "0"; - homingCount = "0"; - - Trigger = "5044"; - team = "0"; - Target = "35"; - locked = "true"; - }; - new StaticShape(Team0StationInventory4) { - position = "95.2651 192.587 75.7793"; - rotation = "0 0 1 45"; - scale = "1 1 1"; - nameTag = "\x01713"; - dataBlock = "StationInventory"; - lockCount = "0"; - homingCount = "0"; - - Trigger = "5046"; - team = "0"; - Target = "36"; - locked = "true"; - }; - new Item() { - position = "110.029 443.01 120.666"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "RepairPatch"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - - team = "0"; - Target = "-1"; - locked = "true"; - }; - new Item() { - position = "110.029 455.01 120.666"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "RepairPatch"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - - team = "0"; - Target = "-1"; - locked = "true"; - }; - new Item() { - position = "104.029 448.01 120.666"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "RepairPatch"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - - team = "0"; - Target = "-1"; - locked = "true"; - }; - new Item() { - position = "116.029 448.01 120.666"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "RepairPatch"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - - team = "0"; - Target = "-1"; - locked = "true"; - }; - new Item() { - position = "-218.297 412.027 122.012"; - rotation = "0 0 1 8.02137"; - scale = "1 1 1"; - dataBlock = "Nexus"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - - team = "0"; - missionTypesList = "Hunters"; - Target = "37"; - locked = "true"; - }; - new InteriorInstance() { - position = "-218.297 412.027 120.057"; - rotation = "-0 0 -1 82.1154"; - scale = "1 1 1"; - interiorFile = "pplat1.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "true"; - }; - new StaticShape() { - position = "-218.297 412.027 130.012"; - rotation = "0 0 1 8.02137"; - scale = "1 1 1"; - dataBlock = "NexusCap"; - lockCount = "0"; - homingCount = "0"; - - team = "0"; - missionTypesList = "Hunters"; - Target = "-1"; - locked = "true"; - }; - new StaticShape() { - position = "-218.297 412.027 122.057"; - rotation = "0 0 1 8.02137"; - scale = "1 1 1"; - dataBlock = "NexusBase"; - lockCount = "0"; - homingCount = "0"; - - team = "0"; - missionTypesList = "Hunters"; - Target = "-1"; - locked = "true"; - }; - new Item(Team0flag1) { - position = "-218.297 412.027 122.075"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "FLAG"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - - team = "0"; - WayPoint = "5133"; - Trigger = "5134"; - missionTypesList = "Rabbit"; - originalPosition = "-218.297 412.027 122.075 1 0 0 0"; - Target = "38"; - locked = "true"; - isHome = "1"; - }; - new InteriorInstance() { - position = "-328.184 502.073 42.1114"; - rotation = "0.64833 0.759915 -0.0468717 104.509"; - scale = "3 3 3"; - interiorFile = "prock8.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "true"; - }; - new Item() { - position = "-513.5 835.534 111"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "RepairPatch"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - - team = "0"; - Target = "-1"; - locked = "true"; - }; - new Item() { - position = "-501.5 835.534 111"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "RepairPatch"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - - team = "0"; - Target = "-1"; - locked = "true"; - }; - new Item() { - position = "-507.5 842.534 111"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "RepairPatch"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - - team = "0"; - Target = "-1"; - locked = "true"; - }; - new Item() { - position = "-507.5 830.534 111"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "RepairPatch"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - - team = "0"; - Target = "-1"; - locked = "true"; - }; - new Item() { - position = "-531.118 135.761 123.008"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "RepairPatch"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - - team = "0"; - Target = "-1"; - locked = "true"; - }; - new Item() { - position = "-531.118 147.761 123.008"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "RepairPatch"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - - team = "0"; - Target = "-1"; - locked = "true"; - }; - new Item() { - position = "-525.118 140.761 123.008"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "RepairPatch"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - - team = "0"; - Target = "-1"; - locked = "true"; - }; - new Item() { - position = "-537.118 140.761 123.008"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "RepairPatch"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - - team = "0"; - Target = "-1"; - locked = "true"; - }; - }; - new SimGroup(Team2) { - - new SimGroup(dropPoints) { - }; - new Camera(enemy0) { - position = "-198.736 767.044 86.9062"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - - skillLevel = "0.56"; - team = "2"; - }; - }; - }; - new InteriorInstance() { - position = "-348.024 748.713 81.7243"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "pspir5.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance() { - position = "-577.965 240.315 82.0099"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "pspir3.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new SimGroup(RandomRocks) { - - powerCount = "0"; - - new SimGroup(Addition1prock6) { - - powerCount = "0"; - - new InteriorInstance(SmallRock) { - position = "-93.8033 303.628 83.5842"; - rotation = "0.984991 0.145917 0.0922034 182.432"; - scale = "0.5 0.5 0.5"; - interiorFile = "prock6.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "-747.803 589.628 99.5202"; - rotation = "0.988282 0.121265 0.0927005 182.167"; - scale = "0.5 0.5 0.5"; - interiorFile = "prock6.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance() { - position = "-9.80328 261.628 73.7824"; - rotation = "0 0 1 1.92003"; - scale = "1.5 1.5 1.5"; - interiorFile = "prock6.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance() { - position = "-731.803 454.628 84.7368"; - rotation = "0.0737592 -0.741289 0.667121 91.4882"; - scale = "1.5 1.5 1.5"; - interiorFile = "prock6.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "52.1967 589.628 70.7921"; - rotation = "0 0 1 5.23602"; - scale = "0.5 0.5 0.5"; - interiorFile = "prock6.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance() { - position = "118.197 547.628 87.7468"; - rotation = "0.243106 0.374176 -0.894926 89.8593"; - scale = "1.5 1.5 1.5"; - interiorFile = "prock6.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "-659.803 407.628 65.5203"; - rotation = "0 0 1 1.08208"; - scale = "0.5 0.5 0.5"; - interiorFile = "prock6.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "118.197 486.628 106.541"; - rotation = "0 0 1 2.583"; - scale = "0.5 0.5 0.5"; - interiorFile = "prock6.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance() { - position = "116.197 538.628 87.9292"; - rotation = "0.458129 0.88868 0.019141 176.533"; - scale = "1.5 1.5 1.5"; - interiorFile = "prock6.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "117.197 659.628 83.4012"; - rotation = "0 0 1 3.01947"; - scale = "0.5 0.5 0.5"; - interiorFile = "prock6.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance() { - position = "-173.803 918.628 101.344"; - rotation = "0.0819133 -0.732532 0.675786 92.1946"; - scale = "1.5 1.5 1.5"; - interiorFile = "prock6.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "-332.803 688.628 87.8587"; - rotation = "0.0823159 -0.732093 0.676213 92.2302"; - scale = "0.5 0.5 0.5"; - interiorFile = "prock6.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance() { - position = "-69.8033 911.628 104.285"; - rotation = "0.999508 0.0207068 0.0235741 82.6183"; - scale = "1.5 1.5 1.5"; - interiorFile = "prock6.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance() { - position = "-95.8033 451.628 94.6557"; - rotation = "0 0 1 3.70004"; - scale = "1.5 1.5 1.5"; - interiorFile = "prock6.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "33.1967 504.628 81.9941"; - rotation = "0.998816 0.0306324 -0.0377965 194.225"; - scale = "0.5 0.5 0.5"; - interiorFile = "prock6.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance() { - position = "-244.803 553.628 83.8193"; - rotation = "0 0 1 1.29178"; - scale = "1.5 1.5 1.5"; - interiorFile = "prock6.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance() { - position = "-33.8033 528.628 83.7467"; - rotation = "0.990757 0.0986532 0.0931048 181.924"; - scale = "1.5 1.5 1.5"; - interiorFile = "prock6.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance() { - position = "-601.803 896.628 101.156"; - rotation = "0.243059 0.374352 -0.894865 89.8278"; - scale = "1.5 1.5 1.5"; - interiorFile = "prock6.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance() { - position = "225.197 905.628 99.9014"; - rotation = "0 0 1 0.611656"; - scale = "1.5 1.5 1.5"; - interiorFile = "prock6.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "38.1967 286.628 78.685"; - rotation = "0.998543 0.0376283 -0.0386684 194.194"; - scale = "0.5 0.5 0.5"; - interiorFile = "prock6.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance() { - position = "138.197 73.6284 96.3749"; - rotation = "0.241518 0.380039 -0.892883 88.8291"; - scale = "1.5 1.5 1.5"; - interiorFile = "prock6.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "37.1967 756.628 90.9971"; - rotation = "0.466772 0.884177 0.0188452 176.512"; - scale = "0.5 0.5 0.5"; - interiorFile = "prock6.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "-522.803 468.628 87.6694"; - rotation = "0.99939 0.0049159 -0.0345766 194.331"; - scale = "0.5 0.5 0.5"; - interiorFile = "prock6.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "168.197 785.628 86.5531"; - rotation = "0.0700253 -0.745212 0.663141 91.1737"; - scale = "0.5 0.5 0.5"; - interiorFile = "prock6.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "-738.803 758.628 85.061"; - rotation = "0.08502 -0.729125 0.679079 92.4702"; - scale = "0.5 0.5 0.5"; - interiorFile = "prock6.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance() { - position = "56.1967 -7.37158 103.219"; - rotation = "0 0 1 2.07708"; - scale = "1.5 1.5 1.5"; - interiorFile = "prock6.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "-498.803 -23.3716 101.313"; - rotation = "0.999072 0.0224173 -0.0367704 194.26"; - scale = "0.5 0.5 0.5"; - interiorFile = "prock6.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance() { - position = "-136.803 801.628 85.6176"; - rotation = "0.0904589 -0.723065 0.684832 92.9636"; - scale = "1.5 1.5 1.5"; - interiorFile = "prock6.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance() { - position = "-125.803 56.6284 110.201"; - rotation = "0.999254 0.0145045 -0.0357798 194.292"; - scale = "1.5 1.5 1.5"; - interiorFile = "prock6.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance() { - position = "-692.803 625.628 85.3489"; - rotation = "0 0 1 6.16103"; - scale = "1.5 1.5 1.5"; - interiorFile = "prock6.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - }; - new SimGroup(Addition2prock7) { - - powerCount = "0"; - - new InteriorInstance(SmallRock) { - position = "-679.803 6.62842 101.344"; - rotation = "0.242076 0.377986 -0.893603 89.1878"; - scale = "0.5 0.5 0.5"; - interiorFile = "prock7.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance() { - position = "-507.803 173.628 87.6393"; - rotation = "0.989333 0.112227 0.0928681 182.07"; - scale = "1.5 1.5 1.5"; - interiorFile = "prock7.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance() { - position = "-413.803 628.628 75.2727"; - rotation = "0.469867 0.882538 0.0187385 176.504"; - scale = "1.5 1.5 1.5"; - interiorFile = "prock7.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "141.197 777.628 83.9062"; - rotation = "0.494023 0.869265 0.0178906 176.446"; - scale = "0.5 0.5 0.5"; - interiorFile = "prock7.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance() { - position = "-437.803 868.628 100.505"; - rotation = "0.999099 0.0280069 0.0318852 82.6411"; - scale = "1.5 1.5 1.5"; - interiorFile = "prock7.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "-686.803 940.628 102.372"; - rotation = "0 0 1 5.88183"; - scale = "0.5 0.5 0.5"; - interiorFile = "prock7.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance() { - position = "189.197 411.628 101.333"; - rotation = "0.999948 0.00670135 0.00762931 82.593"; - scale = "1.5 1.5 1.5"; - interiorFile = "prock7.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "-730.803 282.628 104.955"; - rotation = "0.987246 0.129542 0.0925401 182.256"; - scale = "0.5 0.5 0.5"; - interiorFile = "prock7.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance() { - position = "63.1967 234.628 77.3064"; - rotation = "0 0 1 0.0884693"; - scale = "1.5 1.5 1.5"; - interiorFile = "prock7.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance() { - position = "-8.80328 34.6284 101.344"; - rotation = "0 0 1 2.02441"; - scale = "1.5 1.5 1.5"; - interiorFile = "prock7.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance() { - position = "-243.803 239.628 70.1262"; - rotation = "0.459753 0.887842 0.0190857 176.529"; - scale = "1.5 1.5 1.5"; - interiorFile = "prock7.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance() { - position = "-134.803 -8.37158 101.161"; - rotation = "0.999101 0.0213523 -0.0366372 194.264"; - scale = "1.5 1.5 1.5"; - interiorFile = "prock7.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance() { - position = "-292.803 690.628 83.8688"; - rotation = "0.24592 0.363658 -0.898486 91.7532"; - scale = "1.5 1.5 1.5"; - interiorFile = "prock7.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "-575.803 -10.3716 101.29"; - rotation = "0.989061 0.114638 0.0928241 182.096"; - scale = "0.5 0.5 0.5"; - interiorFile = "prock7.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance() { - position = "-229.803 865.628 101.288"; - rotation = "0.999425 -0.00787068 -0.0329672 194.381"; - scale = "1.5 1.5 1.5"; - interiorFile = "prock7.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance() { - position = "135.197 249.628 83.7685"; - rotation = "0.987031 0.131196 0.0925073 182.274"; - scale = "1.5 1.5 1.5"; - interiorFile = "prock7.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "-165.803 843.628 101.224"; - rotation = "0.999275 0.025118 0.0285961 82.6314"; - scale = "0.5 0.5 0.5"; - interiorFile = "prock7.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "9.19672 523.628 83.9016"; - rotation = "0 0 1 1.72777"; - scale = "0.5 0.5 0.5"; - interiorFile = "prock7.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "-342.803 935.628 101.173"; - rotation = "0.489514 0.871809 0.0180509 176.457"; - scale = "0.5 0.5 0.5"; - interiorFile = "prock7.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "14.1967 926.628 101.344"; - rotation = "0.987801 0.125179 0.0926255 182.209"; - scale = "0.5 0.5 0.5"; - interiorFile = "prock7.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "-383.803 434.628 83.9062"; - rotation = "0.245211 0.366324 -0.897596 91.267"; - scale = "0.5 0.5 0.5"; - interiorFile = "prock7.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance() { - position = "-638.803 267.628 83.9062"; - rotation = "0.999039 0.028919 0.0329235 82.6445"; - scale = "1.5 1.5 1.5"; - interiorFile = "prock7.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "-72.8033 881.628 101.909"; - rotation = "0.472286 0.881248 0.0186548 176.499"; - scale = "0.5 0.5 0.5"; - interiorFile = "prock7.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "-492.803 39.6284 101.344"; - rotation = "0.46448 0.885381 0.018924 176.517"; - scale = "0.5 0.5 0.5"; - interiorFile = "prock7.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance() { - position = "-685.803 592.628 91.6676"; - rotation = "0.459482 0.887982 0.0190949 176.53"; - scale = "1.5 1.5 1.5"; - interiorFile = "prock7.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance() { - position = "-214.803 793.628 76.2821"; - rotation = "0.999877 0.010356 0.0117901 82.597"; - scale = "1.5 1.5 1.5"; - interiorFile = "prock7.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "99.1967 864.628 101.323"; - rotation = "0.99709 0.0503099 0.0572765 82.7557"; - scale = "0.5 0.5 0.5"; - interiorFile = "prock7.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "-331.803 117.628 99.9051"; - rotation = "0.999393 0.00461145 -0.0345384 194.332"; - scale = "0.5 0.5 0.5"; - interiorFile = "prock7.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "-423.803 825.628 92.6656"; - rotation = "0 0 1 4.66006"; - scale = "0.5 0.5 0.5"; - interiorFile = "prock7.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "209.197 741.628 94.7785"; - rotation = "0.10068 -0.711332 0.695608 93.925"; - scale = "0.5 0.5 0.5"; - interiorFile = "prock7.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - }; - }; -}; -//--- OBJECT WRITE END --- +// Deployment (TDS - Opposing Force Mission 1) +// DisplayName = Deployment +// MissionTypes = CTF + +//--- MISSION BRIEFING BEGIN --- +//Not working. +//--- MISSION BRIEFING END --- + +// BriefingWAV = T2BOL_1 +// Bitmap = trn_5draconis + +//--- MISSION STRING BEGIN --- +//OBJECTIVES: +//Bleck +//--- MISSION STRING END --- + +// PlanetName = Xeron, 3960 CE +//--- MISSION BLURB BEGIN --- +// You are Roman; a part of the original Criollos task force sent to Xeron to take over a small area for a base setup. +//--- MISSION BLURB END --- + +//--- OBJECT WRITE BEGIN --- +new SimGroup(MissionGroup) { + + musicTrack = "desert"; + powerCount = "0"; + cdTrack = "6"; + + new MissionArea(MissionArea) { + area = "-768 64 1024 800"; + flightCeiling = "300"; + flightCeilingRange = "20"; + + locked = "true"; + }; + new Sky(Sky) { + position = "0 0 0"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + cloudHeightPer[0] = "0.349971"; + cloudHeightPer[1] = "0.25"; + cloudHeightPer[2] = "0.199973"; + cloudSpeed1 = "0.0001"; + cloudSpeed2 = "0.0002"; + cloudSpeed3 = "0.0003"; + visibleDistance = "500"; + useSkyTextures = "1"; + renderBottomTexture = "0"; + SkySolidColor = "0.365000 0.390000 0.420000 0.000000"; + fogDistance = "200"; + fogColor = "0.550000 0.450000 0.380000 1.000000"; + fogVolume1 = "0 0 0"; + fogVolume2 = "0 0 0"; + fogVolume3 = "0 0 0"; + materialList = "sky_desert_blue.dml"; + windVelocity = "1 0 0"; + windEffectPrecipitation = "0"; + fogVolumeColor1 = "128.000000 128.000000 128.000000 0.000000"; + fogVolumeColor2 = "128.000000 128.000000 128.000000 0.000000"; + fogVolumeColor3 = "128.000000 128.000000 128.000000 0.000000"; + high_visibleDistance = "-1"; + high_fogDistance = "-1"; + high_fogVolume1 = "-1 0 0"; + high_fogVolume2 = "-1 0 0"; + high_fogVolume3 = "-1 0 0"; + + cloudSpeed0 = "0.000503 0.000020"; + locked = "true"; + }; + new Sun() { + position = "0 0 0"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + direction = "0.57735 0.57735 -0.57735"; + color = "0.900000 0.900000 0.900000 1.000000"; + ambient = "0.600000 0.600000 0.600000 1.000000"; + texture[0] = "special/sunFlare"; + texture[1] = "special/sunFlare02"; + texture[2] = "special/LensFlare/flare01"; + texture[3] = "special/LensFlare/flare02"; + texture[4] = "special/LensFlare/flare03"; + lensFlareScale = "0.7"; + lensFlareIntensity = "1"; + frontFlareSize = "300"; + backFlareSize = "450"; + flareColor = "1.000000 1.000000 1.000000 1.000000"; + + locked = "true"; + }; + new TerrainBlock(Terrain) { + rotation = "1 0 0 0"; + scale = "1 1 1"; + detailTexture = "details/desertdet1"; + terrainFile = "SunDried.ter"; + squareSize = "8"; + + position = "-1024 -1024 0"; + locked = "true"; + }; + new NavigationGraph(NavGraph) { + conjoinAngleDev = "50"; + cullDensity = "0.3"; + customArea = "0 0 0 0"; + + coverage = "0"; + position = "0 0 0 1"; + conjoinBowlDev = "20"; + rotation = "0 0 0 0"; + GraphFile = "SunDried.nav"; + locked = "true"; + scale = "1 1 1"; + }; + new SimGroup(ObserverDropPoints) { + + powerCount = "0"; + + new Camera() { + position = "-190.054 402.516 134.059"; + rotation = "0 0 1 121.942"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + locked = "true"; + }; + new Camera() { + position = "-591.86 507.222 118.24"; + rotation = "-0.0675751 -0.168796 0.983332 222.976"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + locked = "true"; + }; + new Camera() { + position = "-205.317 672.457 113.525"; + rotation = "0.919055 -0.0935562 0.382865 29.7787"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + locked = "true"; + }; + new Camera() { + position = "107.001 155.043 84.8555"; + rotation = "0.317652 0.108804 -0.941944 39.9662"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + locked = "true"; + }; + }; + new SimGroup(Teams) { + + powerCount = "0"; + + new SimGroup(Team1) { + + powerCount = "0"; + + new SimGroup(vehiclePath) { + + new SimSet(ActiveActionMapSet) { + + new ActionMap(GlobalActionMap) { + }; + new ActionMap(moveMap) { + }; + new ActionMap(EditorMap) { + }; + }; + new Camera(3) { + position = "-569.795 696.403 633.109"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + team = "1"; + }; + new Camera(2) { + position = "-620.655 731.29 721.313"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + team = "1"; + }; + new Camera(1) { + position = "-671.461 800.219 828.191"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + team = "1"; + }; + }; + }; + new SimGroup(team0) { + + providesPower = "1"; + powerCount = "1"; + + new InteriorInstance() { + position = "109.864 449.038 117.362"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "pplat2.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "true"; + }; + new InteriorInstance() { + position = "-531.228 141.792 119.641"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "pplat2.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "true"; + }; + new InteriorInstance() { + position = "-198.269 767.314 49.4307"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "pbunk8.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "true"; + }; + new InteriorInstance() { + position = "-657.156 448.654 48.465"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "pbunk8.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "true"; + }; + new InteriorInstance() { + position = "89.53 185.821 53.7832"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "pbunk8.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "true"; + }; + new InteriorInstance() { + position = "-507.451 836.499 107.579"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "pplat2.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "true"; + }; + new InteriorInstance() { + position = "-363.513 213.64 73.8112"; + rotation = "0.105914 0.766908 0.632957 194.625"; + scale = "1 1 1"; + interiorFile = "prock8.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "true"; + }; + new InteriorInstance() { + position = "-138.357 589.646 60.8018"; + rotation = "0 0 1 40.68"; + scale = "1 1 1"; + interiorFile = "prockc.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "true"; + }; + new StaticShape(Team0StationInventory3) { + position = "83.7679 192.52 83.2818"; + rotation = "0 0 -1 45"; + scale = "1 1 1"; + nameTag = "\x01712"; + dataBlock = "StationInventory"; + lockCount = "0"; + homingCount = "0"; + + Trigger = "5040"; + team = "0"; + Target = "33"; + locked = "true"; + }; + new StaticShape(Team0StationInventory4) { + position = "95.9562 193.255 83.2872"; + rotation = "0 0 1 45"; + scale = "1 1 1"; + nameTag = "\x01712"; + dataBlock = "StationInventory"; + lockCount = "0"; + homingCount = "0"; + + Trigger = "5042"; + team = "0"; + Target = "34"; + locked = "true"; + }; + new StaticShape(Team0StationInventory3) { + position = "83.7438 192.587 75.7831"; + rotation = "0 0 -1 45"; + scale = "1 1 1"; + nameTag = "\x01713"; + dataBlock = "StationInventory"; + lockCount = "0"; + homingCount = "0"; + + Trigger = "5044"; + team = "0"; + Target = "35"; + locked = "true"; + }; + new StaticShape(Team0StationInventory4) { + position = "95.2651 192.587 75.7793"; + rotation = "0 0 1 45"; + scale = "1 1 1"; + nameTag = "\x01713"; + dataBlock = "StationInventory"; + lockCount = "0"; + homingCount = "0"; + + Trigger = "5046"; + team = "0"; + Target = "36"; + locked = "true"; + }; + new Item() { + position = "110.029 443.01 120.666"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "RepairPatch"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + + team = "0"; + Target = "-1"; + locked = "true"; + }; + new Item() { + position = "110.029 455.01 120.666"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "RepairPatch"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + + team = "0"; + Target = "-1"; + locked = "true"; + }; + new Item() { + position = "104.029 448.01 120.666"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "RepairPatch"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + + team = "0"; + Target = "-1"; + locked = "true"; + }; + new Item() { + position = "116.029 448.01 120.666"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "RepairPatch"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + + team = "0"; + Target = "-1"; + locked = "true"; + }; + new Item() { + position = "-218.297 412.027 122.012"; + rotation = "0 0 1 8.02137"; + scale = "1 1 1"; + dataBlock = "Nexus"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + + team = "0"; + missionTypesList = "Hunters"; + Target = "37"; + locked = "true"; + }; + new InteriorInstance() { + position = "-218.297 412.027 120.057"; + rotation = "-0 0 -1 82.1154"; + scale = "1 1 1"; + interiorFile = "pplat1.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "true"; + }; + new StaticShape() { + position = "-218.297 412.027 130.012"; + rotation = "0 0 1 8.02137"; + scale = "1 1 1"; + dataBlock = "NexusCap"; + lockCount = "0"; + homingCount = "0"; + + team = "0"; + missionTypesList = "Hunters"; + Target = "-1"; + locked = "true"; + }; + new StaticShape() { + position = "-218.297 412.027 122.057"; + rotation = "0 0 1 8.02137"; + scale = "1 1 1"; + dataBlock = "NexusBase"; + lockCount = "0"; + homingCount = "0"; + + team = "0"; + missionTypesList = "Hunters"; + Target = "-1"; + locked = "true"; + }; + new Item(Team0flag1) { + position = "-218.297 412.027 122.075"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "FLAG"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + + team = "0"; + WayPoint = "5133"; + Trigger = "5134"; + missionTypesList = "Rabbit"; + originalPosition = "-218.297 412.027 122.075 1 0 0 0"; + Target = "38"; + locked = "true"; + isHome = "1"; + }; + new InteriorInstance() { + position = "-328.184 502.073 42.1114"; + rotation = "0.64833 0.759915 -0.0468717 104.509"; + scale = "3 3 3"; + interiorFile = "prock8.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "true"; + }; + new Item() { + position = "-513.5 835.534 111"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "RepairPatch"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + + team = "0"; + Target = "-1"; + locked = "true"; + }; + new Item() { + position = "-501.5 835.534 111"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "RepairPatch"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + + team = "0"; + Target = "-1"; + locked = "true"; + }; + new Item() { + position = "-507.5 842.534 111"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "RepairPatch"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + + team = "0"; + Target = "-1"; + locked = "true"; + }; + new Item() { + position = "-507.5 830.534 111"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "RepairPatch"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + + team = "0"; + Target = "-1"; + locked = "true"; + }; + new Item() { + position = "-531.118 135.761 123.008"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "RepairPatch"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + + team = "0"; + Target = "-1"; + locked = "true"; + }; + new Item() { + position = "-531.118 147.761 123.008"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "RepairPatch"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + + team = "0"; + Target = "-1"; + locked = "true"; + }; + new Item() { + position = "-525.118 140.761 123.008"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "RepairPatch"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + + team = "0"; + Target = "-1"; + locked = "true"; + }; + new Item() { + position = "-537.118 140.761 123.008"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "RepairPatch"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + + team = "0"; + Target = "-1"; + locked = "true"; + }; + }; + new SimGroup(Team2) { + + new SimGroup(dropPoints) { + }; + new Camera(enemy0) { + position = "-198.736 767.044 86.9062"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + skillLevel = "0.56"; + team = "2"; + }; + }; + }; + new InteriorInstance() { + position = "-348.024 748.713 81.7243"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "pspir5.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance() { + position = "-577.965 240.315 82.0099"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "pspir3.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new SimGroup(RandomRocks) { + + powerCount = "0"; + + new SimGroup(Addition1prock6) { + + powerCount = "0"; + + new InteriorInstance(SmallRock) { + position = "-93.8033 303.628 83.5842"; + rotation = "0.984991 0.145917 0.0922034 182.432"; + scale = "0.5 0.5 0.5"; + interiorFile = "prock6.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "-747.803 589.628 99.5202"; + rotation = "0.988282 0.121265 0.0927005 182.167"; + scale = "0.5 0.5 0.5"; + interiorFile = "prock6.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance() { + position = "-9.80328 261.628 73.7824"; + rotation = "0 0 1 1.92003"; + scale = "1.5 1.5 1.5"; + interiorFile = "prock6.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance() { + position = "-731.803 454.628 84.7368"; + rotation = "0.0737592 -0.741289 0.667121 91.4882"; + scale = "1.5 1.5 1.5"; + interiorFile = "prock6.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "52.1967 589.628 70.7921"; + rotation = "0 0 1 5.23602"; + scale = "0.5 0.5 0.5"; + interiorFile = "prock6.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance() { + position = "118.197 547.628 87.7468"; + rotation = "0.243106 0.374176 -0.894926 89.8593"; + scale = "1.5 1.5 1.5"; + interiorFile = "prock6.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "-659.803 407.628 65.5203"; + rotation = "0 0 1 1.08208"; + scale = "0.5 0.5 0.5"; + interiorFile = "prock6.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "118.197 486.628 106.541"; + rotation = "0 0 1 2.583"; + scale = "0.5 0.5 0.5"; + interiorFile = "prock6.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance() { + position = "116.197 538.628 87.9292"; + rotation = "0.458129 0.88868 0.019141 176.533"; + scale = "1.5 1.5 1.5"; + interiorFile = "prock6.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "117.197 659.628 83.4012"; + rotation = "0 0 1 3.01947"; + scale = "0.5 0.5 0.5"; + interiorFile = "prock6.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance() { + position = "-173.803 918.628 101.344"; + rotation = "0.0819133 -0.732532 0.675786 92.1946"; + scale = "1.5 1.5 1.5"; + interiorFile = "prock6.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "-332.803 688.628 87.8587"; + rotation = "0.0823159 -0.732093 0.676213 92.2302"; + scale = "0.5 0.5 0.5"; + interiorFile = "prock6.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance() { + position = "-69.8033 911.628 104.285"; + rotation = "0.999508 0.0207068 0.0235741 82.6183"; + scale = "1.5 1.5 1.5"; + interiorFile = "prock6.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance() { + position = "-95.8033 451.628 94.6557"; + rotation = "0 0 1 3.70004"; + scale = "1.5 1.5 1.5"; + interiorFile = "prock6.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "33.1967 504.628 81.9941"; + rotation = "0.998816 0.0306324 -0.0377965 194.225"; + scale = "0.5 0.5 0.5"; + interiorFile = "prock6.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance() { + position = "-244.803 553.628 83.8193"; + rotation = "0 0 1 1.29178"; + scale = "1.5 1.5 1.5"; + interiorFile = "prock6.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance() { + position = "-33.8033 528.628 83.7467"; + rotation = "0.990757 0.0986532 0.0931048 181.924"; + scale = "1.5 1.5 1.5"; + interiorFile = "prock6.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance() { + position = "-601.803 896.628 101.156"; + rotation = "0.243059 0.374352 -0.894865 89.8278"; + scale = "1.5 1.5 1.5"; + interiorFile = "prock6.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance() { + position = "225.197 905.628 99.9014"; + rotation = "0 0 1 0.611656"; + scale = "1.5 1.5 1.5"; + interiorFile = "prock6.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "38.1967 286.628 78.685"; + rotation = "0.998543 0.0376283 -0.0386684 194.194"; + scale = "0.5 0.5 0.5"; + interiorFile = "prock6.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance() { + position = "138.197 73.6284 96.3749"; + rotation = "0.241518 0.380039 -0.892883 88.8291"; + scale = "1.5 1.5 1.5"; + interiorFile = "prock6.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "37.1967 756.628 90.9971"; + rotation = "0.466772 0.884177 0.0188452 176.512"; + scale = "0.5 0.5 0.5"; + interiorFile = "prock6.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "-522.803 468.628 87.6694"; + rotation = "0.99939 0.0049159 -0.0345766 194.331"; + scale = "0.5 0.5 0.5"; + interiorFile = "prock6.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "168.197 785.628 86.5531"; + rotation = "0.0700253 -0.745212 0.663141 91.1737"; + scale = "0.5 0.5 0.5"; + interiorFile = "prock6.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "-738.803 758.628 85.061"; + rotation = "0.08502 -0.729125 0.679079 92.4702"; + scale = "0.5 0.5 0.5"; + interiorFile = "prock6.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance() { + position = "56.1967 -7.37158 103.219"; + rotation = "0 0 1 2.07708"; + scale = "1.5 1.5 1.5"; + interiorFile = "prock6.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "-498.803 -23.3716 101.313"; + rotation = "0.999072 0.0224173 -0.0367704 194.26"; + scale = "0.5 0.5 0.5"; + interiorFile = "prock6.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance() { + position = "-136.803 801.628 85.6176"; + rotation = "0.0904589 -0.723065 0.684832 92.9636"; + scale = "1.5 1.5 1.5"; + interiorFile = "prock6.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance() { + position = "-125.803 56.6284 110.201"; + rotation = "0.999254 0.0145045 -0.0357798 194.292"; + scale = "1.5 1.5 1.5"; + interiorFile = "prock6.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance() { + position = "-692.803 625.628 85.3489"; + rotation = "0 0 1 6.16103"; + scale = "1.5 1.5 1.5"; + interiorFile = "prock6.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + }; + new SimGroup(Addition2prock7) { + + powerCount = "0"; + + new InteriorInstance(SmallRock) { + position = "-679.803 6.62842 101.344"; + rotation = "0.242076 0.377986 -0.893603 89.1878"; + scale = "0.5 0.5 0.5"; + interiorFile = "prock7.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance() { + position = "-507.803 173.628 87.6393"; + rotation = "0.989333 0.112227 0.0928681 182.07"; + scale = "1.5 1.5 1.5"; + interiorFile = "prock7.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance() { + position = "-413.803 628.628 75.2727"; + rotation = "0.469867 0.882538 0.0187385 176.504"; + scale = "1.5 1.5 1.5"; + interiorFile = "prock7.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "141.197 777.628 83.9062"; + rotation = "0.494023 0.869265 0.0178906 176.446"; + scale = "0.5 0.5 0.5"; + interiorFile = "prock7.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance() { + position = "-437.803 868.628 100.505"; + rotation = "0.999099 0.0280069 0.0318852 82.6411"; + scale = "1.5 1.5 1.5"; + interiorFile = "prock7.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "-686.803 940.628 102.372"; + rotation = "0 0 1 5.88183"; + scale = "0.5 0.5 0.5"; + interiorFile = "prock7.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance() { + position = "189.197 411.628 101.333"; + rotation = "0.999948 0.00670135 0.00762931 82.593"; + scale = "1.5 1.5 1.5"; + interiorFile = "prock7.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "-730.803 282.628 104.955"; + rotation = "0.987246 0.129542 0.0925401 182.256"; + scale = "0.5 0.5 0.5"; + interiorFile = "prock7.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance() { + position = "63.1967 234.628 77.3064"; + rotation = "0 0 1 0.0884693"; + scale = "1.5 1.5 1.5"; + interiorFile = "prock7.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance() { + position = "-8.80328 34.6284 101.344"; + rotation = "0 0 1 2.02441"; + scale = "1.5 1.5 1.5"; + interiorFile = "prock7.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance() { + position = "-243.803 239.628 70.1262"; + rotation = "0.459753 0.887842 0.0190857 176.529"; + scale = "1.5 1.5 1.5"; + interiorFile = "prock7.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance() { + position = "-134.803 -8.37158 101.161"; + rotation = "0.999101 0.0213523 -0.0366372 194.264"; + scale = "1.5 1.5 1.5"; + interiorFile = "prock7.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance() { + position = "-292.803 690.628 83.8688"; + rotation = "0.24592 0.363658 -0.898486 91.7532"; + scale = "1.5 1.5 1.5"; + interiorFile = "prock7.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "-575.803 -10.3716 101.29"; + rotation = "0.989061 0.114638 0.0928241 182.096"; + scale = "0.5 0.5 0.5"; + interiorFile = "prock7.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance() { + position = "-229.803 865.628 101.288"; + rotation = "0.999425 -0.00787068 -0.0329672 194.381"; + scale = "1.5 1.5 1.5"; + interiorFile = "prock7.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance() { + position = "135.197 249.628 83.7685"; + rotation = "0.987031 0.131196 0.0925073 182.274"; + scale = "1.5 1.5 1.5"; + interiorFile = "prock7.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "-165.803 843.628 101.224"; + rotation = "0.999275 0.025118 0.0285961 82.6314"; + scale = "0.5 0.5 0.5"; + interiorFile = "prock7.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "9.19672 523.628 83.9016"; + rotation = "0 0 1 1.72777"; + scale = "0.5 0.5 0.5"; + interiorFile = "prock7.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "-342.803 935.628 101.173"; + rotation = "0.489514 0.871809 0.0180509 176.457"; + scale = "0.5 0.5 0.5"; + interiorFile = "prock7.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "14.1967 926.628 101.344"; + rotation = "0.987801 0.125179 0.0926255 182.209"; + scale = "0.5 0.5 0.5"; + interiorFile = "prock7.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "-383.803 434.628 83.9062"; + rotation = "0.245211 0.366324 -0.897596 91.267"; + scale = "0.5 0.5 0.5"; + interiorFile = "prock7.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance() { + position = "-638.803 267.628 83.9062"; + rotation = "0.999039 0.028919 0.0329235 82.6445"; + scale = "1.5 1.5 1.5"; + interiorFile = "prock7.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "-72.8033 881.628 101.909"; + rotation = "0.472286 0.881248 0.0186548 176.499"; + scale = "0.5 0.5 0.5"; + interiorFile = "prock7.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "-492.803 39.6284 101.344"; + rotation = "0.46448 0.885381 0.018924 176.517"; + scale = "0.5 0.5 0.5"; + interiorFile = "prock7.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance() { + position = "-685.803 592.628 91.6676"; + rotation = "0.459482 0.887982 0.0190949 176.53"; + scale = "1.5 1.5 1.5"; + interiorFile = "prock7.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance() { + position = "-214.803 793.628 76.2821"; + rotation = "0.999877 0.010356 0.0117901 82.597"; + scale = "1.5 1.5 1.5"; + interiorFile = "prock7.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "99.1967 864.628 101.323"; + rotation = "0.99709 0.0503099 0.0572765 82.7557"; + scale = "0.5 0.5 0.5"; + interiorFile = "prock7.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "-331.803 117.628 99.9051"; + rotation = "0.999393 0.00461145 -0.0345384 194.332"; + scale = "0.5 0.5 0.5"; + interiorFile = "prock7.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "-423.803 825.628 92.6656"; + rotation = "0 0 1 4.66006"; + scale = "0.5 0.5 0.5"; + interiorFile = "prock7.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "209.197 741.628 94.7785"; + rotation = "0.10068 -0.711332 0.695608 93.925"; + scale = "0.5 0.5 0.5"; + interiorFile = "prock7.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/missions/Earth.cs b/missions/Earth.cs index e4cb4b6..d632a1f 100644 --- a/missions/Earth.cs +++ b/missions/Earth.cs @@ -1,44 +1,44 @@ -package Earth -{ - function defineGeneralAI() - { - $Bot[0,"Name"] = "Jake Marvin"; - $Bot[0,"Race"] = "Human"; - $Bot[0,"Sex"] = "Male"; - $Bot[0,"Skin"] = "Beagle"; - $Bot[0,"Voice"] = "Male1"; - $Bot[0,"VoicePitch"] = 1; - $Bot[0,"Team"] = 1; - $Bot[0,"Weapons"] = "Chaingun Disc Shocklance"; - $Bot[0,"Pack"] = "AmmoPack"; - $Bot[0,"Armor"] = "Light"; - $Bot[0,"Objectives"] = false; - $Bot[0,"Ammo"] = "200 20 0"; - $Bot[0,"RepairKits"] = 2; - $Bot[0,"Mines"] = 3; - $Bot[0,"Grenades"] = 3; - $Bot[0,"Transform"] = "442.099 -133.969 117.073 0 0 1 221.735"; - $Bot[0,"Health"] = 1; - - $Bot[1,"Name"] = "Luke Maverick"; - $Bot[1,"Race"] = "Human"; - $Bot[1,"Sex"] = "Male"; - $Bot[1,"Skin"] = "Storm"; - $Bot[1,"Voice"] = "Male3"; - $Bot[1,"VoicePitch"] = 1; - $Bot[1,"Team"] = 1; - $Bot[1,"Weapons"] = "Blaster Shocklance"; - $Bot[1,"Pack"] = "MiningTool"; - $Bot[1,"UsePack"] = true; - $Bot[1,"Armor"] = "Light"; - $Bot[1,"Objectives"] = false; - $Bot[1,"Ammo"] = ""; - $Bot[1,"RepairKits"] = 2; - $Bot[1,"Mines"] = 0; - $Bot[1,"Grenades"] = 0; - $Bot[1,"Transform"] = "-1051.55 483.736 134.086 0 0 1 173.942"; - $Bot[1,"Health"] = 1; - - $BotCount = 2; - } -}; +package Earth +{ + function defineGeneralAI() + { + $Bot[0,"Name"] = "Jake Marvin"; + $Bot[0,"Race"] = "Human"; + $Bot[0,"Sex"] = "Male"; + $Bot[0,"Skin"] = "Beagle"; + $Bot[0,"Voice"] = "Male1"; + $Bot[0,"VoicePitch"] = 1; + $Bot[0,"Team"] = 1; + $Bot[0,"Weapons"] = "Chaingun Disc Shocklance"; + $Bot[0,"Pack"] = "AmmoPack"; + $Bot[0,"Armor"] = "Light"; + $Bot[0,"Objectives"] = false; + $Bot[0,"Ammo"] = "200 20 0"; + $Bot[0,"RepairKits"] = 2; + $Bot[0,"Mines"] = 3; + $Bot[0,"Grenades"] = 3; + $Bot[0,"Transform"] = "442.099 -133.969 117.073 0 0 1 221.735"; + $Bot[0,"Health"] = 1; + + $Bot[1,"Name"] = "Luke Maverick"; + $Bot[1,"Race"] = "Human"; + $Bot[1,"Sex"] = "Male"; + $Bot[1,"Skin"] = "Storm"; + $Bot[1,"Voice"] = "Male3"; + $Bot[1,"VoicePitch"] = 1; + $Bot[1,"Team"] = 1; + $Bot[1,"Weapons"] = "Blaster Shocklance"; + $Bot[1,"Pack"] = "MiningTool"; + $Bot[1,"UsePack"] = true; + $Bot[1,"Armor"] = "Light"; + $Bot[1,"Objectives"] = false; + $Bot[1,"Ammo"] = ""; + $Bot[1,"RepairKits"] = 2; + $Bot[1,"Mines"] = 0; + $Bot[1,"Grenades"] = 0; + $Bot[1,"Transform"] = "-1051.55 483.736 134.086 0 0 1 173.942"; + $Bot[1,"Health"] = 1; + + $BotCount = 2; + } +}; diff --git a/missions/Earth.mis b/missions/Earth.mis index d0e6fe1..4889223 100644 --- a/missions/Earth.mis +++ b/missions/Earth.mis @@ -1,1564 +1,1564 @@ -// DisplayName = Earth -// MissionTypes = RPG - -//--- OBJECT WRITE BEGIN --- -new SimGroup(MissionGroup) { - - CTF_timeLimit = "25"; - musicTrack = "lush"; - cdTrack = "2"; - powerCount = "0"; - CTF_scoreLimit = "6"; - - new MissionArea(MissionArea) { - area = "-2488 -4584 6848 5840"; - flightCeiling = "600"; - flightCeilingRange = "20"; - - locked = "true"; - }; - new Sky(Sky) { - position = "0 0 0"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - cloudHeightPer[0] = "0.349971"; - cloudHeightPer[1] = "0.25"; - cloudHeightPer[2] = "0.199973"; - cloudSpeed1 = "0.0001"; - cloudSpeed2 = "0.0002"; - cloudSpeed3 = "0.0003"; - visibleDistance = "800"; - useSkyTextures = "0"; - renderBottomTexture = "0"; - SkySolidColor = "0.250000 0.750000 1.000000 1.000000"; - fogDistance = "750"; - fogColor = "0.600000 0.600000 0.600000 1.000000"; - fogVolume1 = "200 99 101"; - fogVolume2 = "0 0 0"; - fogVolume3 = "0 0 0"; - materialList = "sky_desert_blue.dml"; - windVelocity = "1 0 0"; - windEffectPrecipitation = "0"; - fogVolumeColor1 = "128.000000 128.000000 128.000000 0.000000"; - fogVolumeColor2 = "128.000000 128.000000 128.000000 0.000000"; - fogVolumeColor3 = "128.000000 128.000000 128.000000 0.000000"; - high_visibleDistance = "-1"; - high_fogDistance = "-1"; - high_fogVolume1 = "-1 2.33105e-09 6.40969e-10"; - high_fogVolume2 = "-1 1.07461e-38 0"; - high_fogVolume3 = "-1 7.9874e-44 5.9061e-32"; - - cloudSpeed0 = "0.000503 0.000020"; - locked = "true"; - }; - new Sun() { - position = "0 0 0"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - direction = "0.57735 0.57735 -0.57735"; - color = "0.800000 0.800000 0.800000 1.000000"; - ambient = "0.450000 0.450000 0.450000 1.000000"; - texture[0] = "special/sunFlare"; - texture[1] = "special/sunFlare02"; - texture[2] = "special/LensFlare/flare01"; - texture[3] = "special/LensFlare/flare02"; - texture[4] = "special/LensFlare/flare03"; - lensFlareScale = "0.7"; - lensFlareIntensity = "1"; - frontFlareSize = "300"; - backFlareSize = "450"; - flareColor = "1.000000 1.000000 1.000000 1.000000"; - - locked = "true"; - }; - new TerrainBlock(Terrain) { - rotation = "1 0 0 0"; - scale = "1 1 1"; - detailTexture = "details/Detail02"; - terrainFile = "z0r Revisited.ter"; - squareSize = "8"; - emptySquares = "65558 156754 157010 158035 92752 158291 551760 552016 93520 159059 93527 160082 160338 118018 118274"; - - visibleDistance = "1200"; - locked = "true"; - hazeDistance = "250"; - position = "-1024 -1024 0"; - }; - new WaterBlock(Water) { - position = "248 -184 -22.9"; - rotation = "1 0 0 0"; - scale = "2048 2048 69"; - liquidType = "Water"; - density = "1"; - viscosity = "10"; - waveMagnitude = "1"; - surfaceTexture = "terrain/wateregypt1"; - surfaceOpacity = "0.7"; - envMapTexture = "LiquidTiles/archipelago_emap_cloudsground"; - envMapIntensity = "0.4"; - removeWetEdges = "0"; - - params1 = "0.63 -2.41 0.33 0.21"; - seedPoints = "0 0 1 0 1 1 0 1"; - params0 = "0.32 -0.67 0.066 0.5"; - floodFill = "1"; - params3 = "1.21 -0.61 0.13 -0.33"; - extent = "100 100 10"; - params2 = "0.39 0.39 0.2 0.133"; - locked = "1"; - textureSize = "32 32"; - }; - new NavigationGraph(NavGraph) { - conjoinAngleDev = "45"; - cullDensity = "0.3"; - customArea = "0 0 0 0"; - - XDimOverSize = "0"; - rotation = "0 0 0 0"; - conjoinBowlDev = "20"; - scale = "1 1 1"; - coverage = "0"; - YDimOverSize = "0"; - GraphFile = "MissionBlank.nav"; - locked = "true"; - position = "0 0 0 1"; - }; - new SimGroup(Teams) { - - powerCount = "0"; - - new SimGroup(Team1) { - - powerCount = "0"; - - new SimGroup(base0) { - - powerCount = "0"; - - new InteriorInstance() { - position = "-470.556 752.438 25.6702"; - rotation = "0 0 1 37.2423"; - scale = "1 2 1"; - interiorFile = "sbrdg1.dif"; - showTerrainInside = "0"; - - team = "1"; - locked = "1"; - }; - new Trigger() { - position = "-447.029 951.775 51.5999"; - rotation = "0 0 -1 28.6479"; - scale = "169.88 142.408 900"; - dataBlock = "gameTrigger"; - lockCount = "0"; - homingCount = "0"; - polyhedron = "0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 -0.0000000 -1.0000000 -0.0000000 -0.0000000 -0.0000000 1.0000000"; - - type = "Territory"; - team = "1"; - race = "Human"; - locked = "1"; - }; - new InteriorInstance() { - position = "-299.626 1008.26 47.75"; - rotation = "-6.05329e-09 -2.5853e-08 -1 26.3561"; - scale = "1 1 1"; - interiorFile = "bwall4.dif"; - showTerrainInside = "0"; - - team = "1"; - locked = "1"; - }; - new InteriorInstance() { - position = "-357.333 977.976 47.75"; - rotation = "-6.05329e-09 -2.5853e-08 -1 26.3561"; - scale = "1 1 1"; - interiorFile = "bwall4.dif"; - showTerrainInside = "0"; - - team = "1"; - locked = "1"; - }; - new InteriorInstance() { - position = "-401.624 954.344 49.6532"; - rotation = "0 0 1 62.4524"; - scale = "1 1 1"; - interiorFile = "bwall3.dif"; - showTerrainInside = "0"; - - team = "1"; - locked = "1"; - }; - new InteriorInstance() { - position = "-373.709 852.641 47.75"; - rotation = "-6.05329e-09 -2.5853e-08 -1 26.3561"; - scale = "1 1 1"; - interiorFile = "bwall4.dif"; - showTerrainInside = "0"; - - team = "1"; - locked = "1"; - }; - new InteriorInstance() { - position = "-410.791 927.527 49.6532"; - rotation = "0 0 -1 26.3561"; - scale = "1 1 1"; - interiorFile = "bwall3.dif"; - showTerrainInside = "0"; - - team = "1"; - locked = "1"; - }; - new InteriorInstance() { - position = "-396.588 898.852 49.6532"; - rotation = "0 0 -1 26.3561"; - scale = "1 1 1"; - interiorFile = "bwall3.dif"; - showTerrainInside = "0"; - - team = "1"; - locked = "1"; - }; - new InteriorInstance() { - position = "-382.383 870.179 49.6532"; - rotation = "0 0 -1 26.3561"; - scale = "1 1 1"; - interiorFile = "bwall3.dif"; - showTerrainInside = "0"; - - team = "1"; - locked = "1"; - }; - new InteriorInstance() { - position = "-419.307 945.184 47.75"; - rotation = "-6.05329e-09 -2.5853e-08 -1 26.3561"; - scale = "1 1 1"; - interiorFile = "bwall4.dif"; - showTerrainInside = "0"; - - team = "1"; - locked = "1"; - }; - new InteriorInstance() { - position = "-356.146 861.663 49.6532"; - rotation = "0 0 1 62.4524"; - scale = "1 1 1"; - interiorFile = "bwall3.dif"; - showTerrainInside = "0"; - - team = "1"; - locked = "1"; - }; - new InteriorInstance() { - position = "-327.775 876.461 49.6532"; - rotation = "0 0 1 62.4562"; - scale = "1 1 1"; - interiorFile = "bwall3.dif"; - showTerrainInside = "0"; - - team = "1"; - locked = "1"; - }; - new InteriorInstance() { - position = "-299.403 891.258 49.6532"; - rotation = "0 0 1 62.4562"; - scale = "1 1 1"; - interiorFile = "bwall3.dif"; - showTerrainInside = "0"; - - team = "1"; - locked = "1"; - }; - new InteriorInstance() { - position = "-271.031 906.056 49.6532"; - rotation = "0 0 1 62.4524"; - scale = "1 1 1"; - interiorFile = "bwall3.dif"; - showTerrainInside = "0"; - - team = "1"; - locked = "1"; - }; - new InteriorInstance() { - position = "-384.147 963.283 47.75"; - rotation = "-6.05329e-09 -2.5853e-08 -1 26.3561"; - scale = "1 1 1"; - interiorFile = "bwall4.dif"; - showTerrainInside = "0"; - - team = "1"; - locked = "1"; - }; - new InteriorInstance() { - position = "-262.268 933.082 49.6532"; - rotation = "0 0 -1 26.3561"; - scale = "1 1 1"; - interiorFile = "bwall3.dif"; - showTerrainInside = "0"; - - team = "1"; - locked = "1"; - }; - new InteriorInstance() { - position = "-276.473 961.754 49.6532"; - rotation = "0 0 -1 26.3561"; - scale = "1 1 1"; - interiorFile = "bwall3.dif"; - showTerrainInside = "0"; - - team = "1"; - locked = "1"; - }; - new InteriorInstance() { - position = "-290.677 990.429 49.6532"; - rotation = "0 0 -1 26.3561"; - scale = "1 1 1"; - interiorFile = "bwall3.dif"; - showTerrainInside = "0"; - - team = "1"; - locked = "1"; - }; - new InteriorInstance() { - position = "-253.444 915.312 47.75"; - rotation = "-6.05329e-09 -2.5853e-08 -1 26.3561"; - scale = "1 1 1"; - interiorFile = "bwall4.dif"; - showTerrainInside = "0"; - - team = "1"; - locked = "1"; - }; - new InteriorInstance() { - position = "-317.262 998.87 49.6532"; - rotation = "0 0 1 62.4524"; - scale = "1 1 1"; - interiorFile = "bwall3.dif"; - showTerrainInside = "0"; - - team = "1"; - locked = "1"; - }; - new InteriorInstance() { - position = "-342.635 985.635 49.6532"; - rotation = "0 0 1 62.4524"; - scale = "1 0.788578 1"; - interiorFile = "bwall3.dif"; - showTerrainInside = "0"; - - team = "1"; - locked = "1"; - }; - new InteriorInstance() { - position = "112.436 -216.188 49.1219"; - rotation = "0 0 1 180.664"; - scale = "1 1 1"; - interiorFile = "bwall3.dif"; - showTerrainInside = "0"; - - team = "1"; - locked = "1"; - }; - new InteriorInstance() { - position = "112.399 -288.619 49.121"; - rotation = "0 0 1 180.664"; - scale = "1 1 1"; - interiorFile = "bwall3.dif"; - showTerrainInside = "0"; - - team = "1"; - locked = "1"; - }; - }; - new SimGroup(base1) { - - powerCount = "0"; - - new InteriorInstance() { - position = "462.539 -111.849 130.5"; - rotation = "0 0 1 222.308"; - scale = "1 1 1"; - interiorFile = "bbase6.dif"; - showTerrainInside = "0"; - - team = "1"; - locked = "1"; - }; - new InteriorInstance() { - position = "360.581 -177.594 145.688"; - rotation = "0 0 1 83.6518"; - scale = "1 1 1"; - interiorFile = "bmisc9.dif"; - showTerrainInside = "0"; - - team = "1"; - locked = "1"; - }; - new InteriorInstance() { - position = "112.357 -235.178 48.8669"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "bwall4.dif"; - showTerrainInside = "0"; - - team = "1"; - locked = "1"; - }; - new InteriorInstance() { - position = "112.37 -269.598 48.8663"; - rotation = "0 0 1 1.71915"; - scale = "1 1 1"; - interiorFile = "bwall4.dif"; - showTerrainInside = "0"; - - team = "1"; - locked = "1"; - }; - new Trigger() { - position = "65.7148 -1.98538 39.6507"; - rotation = "1 0 0 0"; - scale = "518.836 345.191 900"; - dataBlock = "gameTrigger"; - lockCount = "0"; - homingCount = "0"; - polyhedron = "0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 -0.0000000 -1.0000000 -0.0000000 -0.0000000 -0.0000000 1.0000000"; - - type = "Territory"; - team = "1"; - race = "Human"; - locked = "1"; - }; - new TSStatic() { - position = "253.285 -154.94 42.3445"; - rotation = "0.837621 -0.187308 0.513134 47.0943"; - scale = "1 1 1"; - shapeName = "vehicle_land_assault_wreck.dts"; - - team = "1"; - locked = "1"; - }; - }; - new SimGroup(spawnspheres) { - - powerCount = "0"; - - new SpawnSphere() { - position = "454.253 -119.446 116.876"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "SpawnSphereMarker"; - lockCount = "0"; - homingCount = "0"; - radius = "70"; - sphereWeight = "100"; - indoorWeight = "100"; - outdoorWeight = "100"; - - locked = "1"; - }; - }; - }; - new SimGroup(team4) { - - powerCount = "0"; - - new SimGroup(base0) { - - powerCount = "0"; - - new InteriorInstance() { - position = "433.611 1931.43 124.066"; - rotation = "0 0 -1 7.44831"; - scale = "1 1 1"; - interiorFile = "bbunk1.dif"; - showTerrainInside = "0"; - - team = "4"; - locked = "1"; - }; - }; - new SimGroup(spawnspheres) { - - powerCount = "0"; - - new SpawnSphere() { - position = "435.77 1925.38 135.899"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "SpawnSphereMarker"; - lockCount = "0"; - homingCount = "0"; - radius = "100"; - sphereWeight = "100"; - indoorWeight = "100"; - outdoorWeight = "100"; - - locked = "1"; - }; - }; - new SimGroup(AIObjectives) { - - powerCount = "0"; - }; - }; - new SimGroup(team0) { - - powerCount = "0"; - - new SimGroup(base0) { - - powerCount = "0"; - - new InteriorInstance() { - position = "-1070.27 589.218 135.923"; - rotation = "0 0 -1 88.8085"; - scale = "1 1 1"; - interiorFile = "trpg_mine.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "true"; - }; - new InteriorInstance() { - position = "-377.106 -111.774 103.734"; - rotation = "-0.903865 -0.136606 -0.405421 40.8894"; - scale = "1 1 1"; - interiorFile = "brock8.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "1"; - }; - new InteriorInstance() { - position = "-365.439 -114.45 101.698"; - rotation = "-0.421356 0.146307 0.895016 145.472"; - scale = "1 1 1"; - interiorFile = "brock7.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "1"; - }; - new InteriorInstance() { - position = "-367.365 -115.996 102.367"; - rotation = "0 -1 0 45.2636"; - scale = "1 1 1"; - interiorFile = "brock6.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "1"; - }; - new InteriorInstance() { - position = "-358.225 -127.034 100.141"; - rotation = "0 0 -1 110.008"; - scale = "1 1 1"; - interiorFile = "brock8.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "1"; - }; - new InteriorInstance() { - position = "-354.71 -116.258 103.257"; - rotation = "-0.903184 0.425862 -0.0538564 42.157"; - scale = "1 1 1"; - interiorFile = "brock7.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "1"; - }; - new InteriorInstance() { - position = "-353.704 -118.688 102.93"; - rotation = "0 -1 0 68.7549"; - scale = "1 1 1"; - interiorFile = "brock6.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "1"; - }; - new InteriorInstance() { - position = "-353.064 -117.142 101.948"; - rotation = "-0.330175 0.532535 -0.779353 86.7847"; - scale = "1 1 1"; - interiorFile = "brock7.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "1"; - }; - new InteriorInstance() { - position = "-352.634 -114.684 103.079"; - rotation = "0.177072 -0.0106371 -0.98414 49.9722"; - scale = "1 1 1"; - interiorFile = "brock6.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "1"; - }; - new InteriorInstance() { - position = "-353.258 -104.492 106.904"; - rotation = "-0.498883 -0.781179 -0.375332 71.8445"; - scale = "1 1 1"; - interiorFile = "brock7.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "1"; - }; - new InteriorInstance() { - position = "-364.251 -104.363 109.09"; - rotation = "0.409184 -0.705766 0.578327 53.1408"; - scale = "1 1 1"; - interiorFile = "brock6.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "1"; - }; - new InteriorInstance() { - position = "-373.755 -217 101.951"; - rotation = "0.845589 0.280219 -0.454376 36.7965"; - scale = "1 1 1"; - interiorFile = "brock8.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "1"; - }; - new InteriorInstance() { - position = "-355.982 -225.445 107.792"; - rotation = "0.0920027 0.99332 0.0696462 172.938"; - scale = "1 1 1"; - interiorFile = "brock8.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "1"; - }; - new InteriorInstance() { - position = "-365.615 -219.911 109.904"; - rotation = "0.744523 -0.235177 -0.624802 36.3903"; - scale = "1 1 1"; - interiorFile = "brock7.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "1"; - }; - new InteriorInstance() { - position = "-367.246 -221.156 111.89"; - rotation = "0 1 0 95.111"; - scale = "1 1 1"; - interiorFile = "brock6.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "1"; - }; - new InteriorInstance() { - position = "-370.362 -228.671 116.84"; - rotation = "0.85184 -0.225245 -0.472899 63.4856"; - scale = "1 1 1"; - interiorFile = "brock8.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "1"; - }; - new InteriorInstance() { - position = "-366.109 -224.857 118.533"; - rotation = "0.975883 -0.218226 0.00551889 182.7"; - scale = "1 1 1"; - interiorFile = "brock7.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "1"; - }; - new InteriorInstance() { - position = "-367.517 -221.919 114.407"; - rotation = "-0.780324 0.399765 -0.480918 112.7"; - scale = "1 1 1"; - interiorFile = "brock6.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "1"; - }; - new InteriorInstance() { - position = "-367.41 -224.177 118.868"; - rotation = "0.148062 0.13541 0.979664 96.2823"; - scale = "1 1 1"; - interiorFile = "brock6.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "1"; - }; - new InteriorInstance() { - position = "-367.984 -222.147 115.715"; - rotation = "0.356696 -0.0270395 -0.933829 52.7103"; - scale = "1 1 1"; - interiorFile = "brock7.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "1"; - }; - new InteriorInstance() { - position = "-363.879 -223.042 108.22"; - rotation = "0.574074 0.345392 0.74239 67.7181"; - scale = "1 1 1"; - interiorFile = "brock8.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "1"; - }; - new InteriorInstance() { - position = "-359.85 -224.554 109.156"; - rotation = "0.999662 -0.00375378 -0.0257064 45.2774"; - scale = "1 1 1"; - interiorFile = "brock8.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "1"; - }; - new InteriorInstance() { - position = "-349.621 -217.638 104.483"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "brock7.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "1"; - }; - new InteriorInstance() { - position = "-351.406 -209.15 101.984"; - rotation = "0 0 1 8.02127"; - scale = "1 1 1"; - interiorFile = "brock7.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "1"; - }; - new InteriorInstance() { - position = "-361.692 -208.298 102.208"; - rotation = "0 0 1 165.194"; - scale = "1 1 1"; - interiorFile = "brock6.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "1"; - }; - new TSStatic() { - position = "-296.017 378.18 -2.37616"; - rotation = "0.402885 0.105022 -0.909205 31.9958"; - scale = "1 1 1"; - shapeName = "vehicle_air_scout_wreck.dts"; - - team = "0"; - locked = "1"; - }; - new InteriorInstance() { - position = "-326.649 -562.107 28.2"; - rotation = "0 0 -1 63.5983"; - scale = "1 2.07163 1"; - interiorFile = "sbrdg1.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "1"; - }; - new InteriorInstance() { - position = "-313.923 1506.95 27.6"; - rotation = "0 0 -1 50.9932"; - scale = "1 2.11791 1"; - interiorFile = "sbrdg1.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "1"; - }; - }; - new SimGroup(spawnsphres) { - - powerCount = "0"; - }; - new SimGroup(AIObjectives) { - - powerCount = "0"; - }; - }; - new SimGroup(team3) { - - powerCount = "0"; - - new SimGroup(base0) { - - powerCount = "0"; - - new InteriorInstance() { - position = "-354.049 -161.721 100.881"; - rotation = "0 0 1 89.3814"; - scale = "1 1 1"; - interiorFile = "bbase1.dif"; - showTerrainInside = "0"; - - team = "3"; - locked = "1"; - }; - new Trigger() { - position = "-490.546 12.8916 -23.0157"; - rotation = "1 0 0 0"; - scale = "262.087 256.957 1019.71"; - dataBlock = "gameTrigger"; - lockCount = "0"; - homingCount = "0"; - polyhedron = "0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 -0.0000000 -1.0000000 -0.0000000 -0.0000000 -0.0000000 1.0000000"; - - type = "Territory"; - team = "3"; - race = "Draakan"; - locked = "1"; - }; - new WayPoint(VehiclePad_Drake) { - position = "-371.915 -34.1391 139.312"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "WayPointMarker"; - lockCount = "0"; - homingCount = "0"; - team = "3"; - - locked = "1"; - }; - new InteriorInstance() { - position = "-83.0508 -218.399 27.4"; - rotation = "0 0 1 41.253"; - scale = "1 2.65302 1"; - interiorFile = "sbrdg1.dif"; - showTerrainInside = "0"; - - team = "3"; - locked = "1"; - }; - }; - new SimGroup(spawnspheres) { - - powerCount = "0"; - - new SpawnSphere() { - position = "-359.678 -162.775 115.281"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "SpawnSphereMarker"; - lockCount = "0"; - homingCount = "0"; - radius = "70"; - sphereWeight = "100"; - indoorWeight = "100"; - outdoorWeight = "100"; - - locked = "1"; - }; - }; - new SimGroup(AIObjectives) { - - powerCount = "0"; - }; - }; - new SimGroup(Team2) { - - powerCount = "0"; - - new SimGroup(base0) { - - powerCount = "0"; - - new InteriorInstance() { - position = "-1164 1827.93 218.573"; - rotation = "0 0 1 135.218"; - scale = "1 1 1"; - interiorFile = "xbunk9.dif"; - showTerrainInside = "0"; - - team = "2"; - locked = "1"; - }; - new InteriorInstance() { - position = "-1328.23 1521.97 66.6"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "sbrdg1.dif"; - showTerrainInside = "0"; - - team = "2"; - locked = "1"; - }; - new WayPoint(OMFG_FIX_THIS_BRIDGE) { - position = "-1326.06 1504.9 126.6"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "WayPointMarker"; - lockCount = "0"; - homingCount = "0"; - team = "2"; - - locked = "1"; - }; - new InteriorInstance() { - position = "-1328.15 1522.13 28.8"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "sbrdg1.dif"; - showTerrainInside = "0"; - - team = "2"; - locked = "1"; - }; - new InteriorInstance() { - position = "-1454.4 2082.3 210.721"; - rotation = "0 0 1 13.751"; - scale = "1 1 1"; - interiorFile = "xwall1.dif"; - showTerrainInside = "0"; - - team = "2"; - locked = "1"; - }; - new InteriorInstance() { - position = "-1450.6 2097.84 210.721"; - rotation = "0 0 1 13.751"; - scale = "1 1 1"; - interiorFile = "xwall1.dif"; - showTerrainInside = "0"; - - team = "2"; - locked = "1"; - }; - new InteriorInstance(InteriorInstance) { - position = "-1446.79 2113.38 210.721"; - rotation = "0 0 1 13.751"; - scale = "1 1 1"; - interiorFile = "xwall1.dif"; - showTerrainInside = "0"; - - team = "2"; - locked = "1"; - }; - new InteriorInstance(InteriorInstance) { - position = "-1328.21 1486.09 104.6"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "sbrdg1.dif"; - showTerrainInside = "0"; - - team = "2"; - locked = "1"; - }; - new InteriorInstance(InteriorInstance) { - position = "-1328.21 1562.28 104.6"; - rotation = "1 0 0 0"; - scale = "1 1.07232 1"; - interiorFile = "sbrdg1.dif"; - showTerrainInside = "0"; - - team = "2"; - locked = "1"; - }; - new InteriorInstance() { - position = "-296.401 1616.16 26.4"; - rotation = "0 0 1 25.2101"; - scale = "1 1.42859 1"; - interiorFile = "sbrdg1.dif"; - showTerrainInside = "0"; - - team = "2"; - locked = "1"; - }; - new Trigger() { - position = "-1530.29 2161.83 -5.6767"; - rotation = "1 0 0 0"; - scale = "704.205 602.061 900"; - dataBlock = "gameTrigger"; - lockCount = "0"; - homingCount = "0"; - polyhedron = "0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 -0.0000000 -1.0000000 -0.0000000 -0.0000000 -0.0000000 1.0000000"; - - type = "Territory"; - team = "2"; - race = "bioderm"; - locked = "1"; - }; - }; - new SimGroup(spawnspheres) { - - powerCount = "0"; - - new SpawnSphere() { - position = "-1161.28 1825.13 228.423"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "SpawnSphereMarker"; - lockCount = "0"; - homingCount = "0"; - radius = "70"; - sphereWeight = "100"; - indoorWeight = "100"; - outdoorWeight = "100"; - - locked = "1"; - }; - }; - new SimGroup(AIObjectives) { - - powerCount = "0"; - }; - }; - }; - new StaticShape() { - position = "-1093.57 603.616 117.811"; - rotation = "0 0 1 103.705"; - scale = "1 1 1"; - dataBlock = "LightMaleHuman_Dead"; - lockCount = "0"; - homingCount = "0"; - - locked = "1"; - Target = "-1"; - }; - new StaticShape() { - position = "-1068.56 628.036 117.388"; - rotation = "1 0 0 0"; - scale = "1 1 10.183"; - dataBlock = "MiningBox"; - lockCount = "0"; - homingCount = "0"; - - mineral = "Silver"; - wasDisabled = "1"; - locked = "1"; - }; - new StaticShape() { - position = "-1028.73 513.275 94.5294"; - rotation = "1 0 0 0"; - scale = "0.2276 0.138534 1.41644"; - dataBlock = "MiningBox"; - lockCount = "0"; - homingCount = "0"; - - mineral = "Gem"; - wasDisabled = "1"; - locked = "1"; - pDesc = "Set my mineral.."; - }; - new StaticShape() { - position = "-1016.1 523.434 91.9845"; - rotation = "1 0 0 0"; - scale = "0.989212 0.414657 11.1624"; - dataBlock = "MiningBox"; - lockCount = "0"; - homingCount = "0"; - - mineral = "Gem"; - wasDisabled = "1"; - locked = "1"; - pDesc = "Set my mineral.."; - }; - new StaticShape() { - position = "-1055.08 502.345 92.7845"; - rotation = "1 0 0 0"; - scale = "0.1 0.269252 1.26103"; - dataBlock = "MiningBox"; - lockCount = "0"; - homingCount = "0"; - - mineral = "Gem"; - wasDisabled = "1"; - locked = "1"; - pDesc = "Set my mineral.."; - }; - new StaticShape() { - position = "-1063.58 493.322 94.1557"; - rotation = "1 0 0 0"; - scale = "0.2276 0.61061 3.98388"; - dataBlock = "MiningBox"; - lockCount = "0"; - homingCount = "0"; - - mineral = "Gem"; - wasDisabled = "1"; - locked = "1"; - pDesc = "Set my mineral.."; - }; - new StaticShape() { - position = "-1055.64 475.155 95.7549"; - rotation = "1 0 0 0"; - scale = "0.1 0.217906 1.56999"; - dataBlock = "MiningBox"; - lockCount = "0"; - homingCount = "0"; - - mineral = "Gem"; - wasDisabled = "1"; - locked = "1"; - pDesc = "Set my mineral.."; - }; - new StaticShape() { - position = "-1059.41 462.901 94.2362"; - rotation = "1 0 0 0"; - scale = "0.19726 0.187931 1"; - dataBlock = "MiningBox"; - lockCount = "0"; - homingCount = "0"; - - mineral = "Gem"; - wasDisabled = "1"; - locked = "1"; - pDesc = "Set my mineral.."; - }; - new StaticShape() { - position = "-1076.1 472.004 94.9547"; - rotation = "1 0 0 0"; - scale = "0.207733 0.348236 1.51683"; - dataBlock = "MiningBox"; - lockCount = "0"; - homingCount = "0"; - - mineral = "Gem"; - wasDisabled = "1"; - locked = "1"; - pDesc = "Set my mineral.."; - }; - new StaticShape() { - position = "-1032.29 505.958 98.4778"; - rotation = "1 0 0 0"; - scale = "0.535278 0.704081 1.98302"; - dataBlock = "MiningBox"; - lockCount = "0"; - homingCount = "0"; - - mineral = "Gem"; - wasDisabled = "1"; - locked = "1"; - pDesc = "Set my mineral.."; - }; - new StaticShape() { - position = "-1065 505.083 93.1874"; - rotation = "1 0 0 0"; - scale = "0.49408 0.402028 3.88171"; - dataBlock = "MiningBox"; - lockCount = "0"; - homingCount = "0"; - - mineral = "Gem"; - wasDisabled = "1"; - locked = "1"; - pDesc = "Set my mineral.."; - }; - new StaticShape() { - position = "-1068.67 513.114 98.3049"; - rotation = "1 0 0 0"; - scale = "0.285156 0.667053 1.94992"; - dataBlock = "MiningBox"; - lockCount = "0"; - homingCount = "0"; - - mineral = "Gem"; - wasDisabled = "1"; - locked = "1"; - pDesc = "Set my mineral.."; - }; - new StaticShape() { - position = "-1076.83 514.521 93.3816"; - rotation = "1 0 0 0"; - scale = "0.465515 0.436971 3.54662"; - dataBlock = "MiningBox"; - lockCount = "0"; - homingCount = "0"; - - mineral = "Gem"; - wasDisabled = "1"; - locked = "1"; - pDesc = "Set my mineral.."; - }; - new StaticShape() { - position = "-1087.5 506.192 94.2351"; - rotation = "1 0 0 0"; - scale = "0.470093 0.295603 3.65455"; - dataBlock = "MiningBox"; - lockCount = "0"; - homingCount = "0"; - - mineral = "Gem"; - wasDisabled = "1"; - locked = "1"; - pDesc = "Set my mineral.."; - }; - new StaticShape() { - position = "-1098.67 507.377 92.4363"; - rotation = "1 0 0 0"; - scale = "0.46933 0.714142 1.27818"; - dataBlock = "MiningBox"; - lockCount = "0"; - homingCount = "0"; - - mineral = "Gem"; - wasDisabled = "1"; - locked = "1"; - pDesc = "Set my mineral.."; - }; - new StaticShape() { - position = "-1109.79 513.981 98.6638"; - rotation = "1 0 0 0"; - scale = "0.563599 0.690359 1.33957"; - dataBlock = "MiningBox"; - lockCount = "0"; - homingCount = "0"; - - mineral = "Gem"; - wasDisabled = "1"; - locked = "1"; - pDesc = "Set my mineral.."; - }; - new StaticShape() { - position = "-1045.58 513.912 93.297"; - rotation = "1 0 0 0"; - scale = "0.47171 0.368174 3.95471"; - dataBlock = "MiningBox"; - lockCount = "0"; - homingCount = "0"; - - mineral = "Gem"; - wasDisabled = "1"; - locked = "1"; - pDesc = "Set my mineral.."; - }; - new StaticShape() { - position = "-1085.3 465.744 92.4406"; - rotation = "1 0 0 0"; - scale = "0.218445 0.313537 0.409158"; - dataBlock = "MiningBox"; - lockCount = "0"; - homingCount = "0"; - - mineral = "Gem"; - wasDisabled = "1"; - locked = "1"; - pDesc = "Set my mineral.."; - }; - new StaticShape() { - position = "-1062.09 524.739 92.368"; - rotation = "1 0 0 0"; - scale = "0.450684 0.65389 1.22284"; - dataBlock = "MiningBox"; - lockCount = "0"; - homingCount = "0"; - - mineral = "Gem"; - wasDisabled = "1"; - locked = "1"; - pDesc = "Set my mineral.."; - }; - new StaticShape() { - position = "-1062.78 534.846 92.6981"; - rotation = "1 0 0 0"; - scale = "0.175934 0.602885 3.32562"; - dataBlock = "MiningBox"; - lockCount = "0"; - homingCount = "0"; - - mineral = "Gem"; - wasDisabled = "1"; - locked = "1"; - pDesc = "Set my mineral.."; - }; - new StaticShape() { - position = "-1054.52 550.27 94.3173"; - rotation = "1 0 0 0"; - scale = "0.348206 1.10693 3.46191"; - dataBlock = "MiningBox"; - lockCount = "0"; - homingCount = "0"; - - mineral = "Gem"; - wasDisabled = "1"; - locked = "1"; - pDesc = "Set my mineral.."; - }; - new StaticShape() { - position = "-1058.37 567.186 95.3873"; - rotation = "1 0 0 0"; - scale = "0.466583 0.336487 3.57619"; - dataBlock = "MiningBox"; - lockCount = "0"; - homingCount = "0"; - - mineral = "Gem"; - wasDisabled = "1"; - locked = "1"; - pDesc = "Set my mineral.."; - }; - new StaticShape() { - position = "-1142.04 496.292 93.3373"; - rotation = "1 0 0 0"; - scale = "0.47226 0.29301 3.49713"; - dataBlock = "MiningBox"; - lockCount = "0"; - homingCount = "0"; - - mineral = "Gem"; - wasDisabled = "1"; - locked = "1"; - pDesc = "Set my mineral.."; - }; - new StaticShape() { - position = "-1148.19 509.829 93.8726"; - rotation = "1 0 0 0"; - scale = "0.47226 0.29301 3.49713"; - dataBlock = "MiningBox"; - lockCount = "0"; - homingCount = "0"; - - mineral = "Gem"; - wasDisabled = "1"; - locked = "1"; - pDesc = "Set my mineral.."; - }; - new StaticShape() { - position = "-1128.31 507.072 95.4624"; - rotation = "1 0 0 0"; - scale = "0.471558 0.575317 4.1662"; - dataBlock = "MiningBox"; - lockCount = "0"; - homingCount = "0"; - - mineral = "Gem"; - wasDisabled = "1"; - locked = "1"; - pDesc = "Set my mineral.."; - }; - new StaticShape() { - position = "-1082.01 567.828 96.0331"; - rotation = "1 0 0 0"; - scale = "0.166046 0.1 1.68872"; - dataBlock = "MiningBox"; - lockCount = "0"; - homingCount = "0"; - - mineral = "Gem"; - wasDisabled = "1"; - locked = "1"; - pDesc = "Set my mineral.."; - }; - new StaticShape() { - position = "-1087.84 559.529 95.4327"; - rotation = "1 0 0 0"; - scale = "0.49173 0.243673 3.26553"; - dataBlock = "MiningBox"; - lockCount = "0"; - homingCount = "0"; - - mineral = "Gem"; - wasDisabled = "1"; - locked = "1"; - pDesc = "Set my mineral.."; - }; - new StaticShape() { - position = "-1103.64 559.455 96.1256"; - rotation = "1 0 0 0"; - scale = "0.293335 0.316223 2.30223"; - dataBlock = "MiningBox"; - lockCount = "0"; - homingCount = "0"; - - mineral = "Gem"; - wasDisabled = "1"; - locked = "1"; - pDesc = "Set my mineral.."; - }; - new StaticShape() { - position = "-1106.89 568.471 95.8961"; - rotation = "1 0 0 0"; - scale = "0.21463 0.327799 1.96655"; - dataBlock = "MiningBox"; - lockCount = "0"; - homingCount = "0"; - - mineral = "Gem"; - wasDisabled = "1"; - locked = "1"; - pDesc = "Set my mineral.."; - }; - new StaticShape() { - position = "-1116.96 559.967 93.8314"; - rotation = "1 0 0 0"; - scale = "0.401154 0.29421 3.15295"; - dataBlock = "MiningBox"; - lockCount = "0"; - homingCount = "0"; - - mineral = "Gem"; - wasDisabled = "1"; - locked = "1"; - pDesc = "Set my mineral.."; - }; - new StaticShape() { - position = "-1128.55 568.855 93.3634"; - rotation = "1 0 0 0"; - scale = "0.185974 0.229045 1"; - dataBlock = "MiningBox"; - lockCount = "0"; - homingCount = "0"; - - mineral = "Gem"; - wasDisabled = "1"; - locked = "1"; - pDesc = "Set my mineral.."; - }; - new StaticShape() { - position = "-1163.29 582.469 105.67"; - rotation = "1 0 0 0"; - scale = "1 1 2.59875"; - dataBlock = "MiningBox"; - lockCount = "0"; - homingCount = "0"; - - mineral = "Gem"; - wasDisabled = "1"; - locked = "1"; - pDesc = "Set my mineral.."; - }; - new StaticShape() { - position = "-1074.99 602.397 117.864"; - rotation = "0 0 -1 53.2851"; - scale = "0.240631 0.700714 4.71143"; - dataBlock = "MiningBox"; - lockCount = "0"; - homingCount = "0"; - - mineral = "Steel"; - wasDisabled = "1"; - locked = "1"; - }; - new StaticShape() { - position = "-1075.01 593.412 117.467"; - rotation = "1 0 0 0"; - scale = "1.75943 1.97791 37.4574"; - dataBlock = "MiningBox"; - lockCount = "0"; - homingCount = "0"; - - mineral = "Gold"; - wasDisabled = "1"; - locked = "1"; - }; - new WayPoint(IdeaMarker1) { - position = "589.05 1060.81 153.103"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - nameTag = "A spot for something."; - dataBlock = "WayPointMarker"; - lockCount = "0"; - homingCount = "0"; - team = "1"; - - locked = "1"; - }; - new SimGroup(observerDropPoints) { - - powerCount = "0"; - - new Camera(camera1) { - position = "387.469 -155.397 179.559"; - rotation = "0.343278 -0.234887 0.909389 73.9173"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - - team = "1"; - locked = "1"; - }; - new Camera(camera2) { - position = "-434.776 998.772 109.708"; - rotation = "0.116405 -0.239522 0.963887 129.8"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - - team = "1"; - locked = "1"; - }; - new Camera(camera3) { - position = "-441.633 -102.007 176.768"; - rotation = "0.140072 -0.270121 0.952583 127.425"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - - team = "3"; - locked = "1"; - }; - new Camera(camera4) { - position = "-1249.32 1538.45 204.386"; - rotation = "0.264832 0.394028 -0.880117 118.788"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - - team = "2"; - locked = "1"; - }; - new Camera(camera5) { - position = "-1022.15 1874.11 294.405"; - rotation = "0.276336 0.252912 -0.927186 89.2565"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - - team = "2"; - locked = "1"; - }; - }; - new WayPoint(MiningCommunity) { - position = "-1127.85 611.14 280.781"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "WayPointMarker"; - lockCount = "0"; - homingCount = "0"; - team = "0"; - - locked = "1"; - pDesc = "A little mining community will thrive here."; - }; - new Trigger() { - position = "-1097.73 480.386 125.8"; - rotation = "1 0 0 0"; - scale = "46.1831 19.6776 1"; - dataBlock = "gameTrigger"; - lockCount = "0"; - homingCount = "0"; - polyhedron = "0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 -0.0000000 -1.0000000 -0.0000000 -0.0000000 -0.0000000 1.0000000"; - - type = "DAMAGE"; - damageType = "Lava"; - DAMAGE = "0.09"; //For Drakes too o_O' - locked = "1"; - }; -}; -//--- OBJECT WRITE END --- +// DisplayName = Earth +// MissionTypes = RPG + +//--- OBJECT WRITE BEGIN --- +new SimGroup(MissionGroup) { + + CTF_timeLimit = "25"; + musicTrack = "lush"; + cdTrack = "2"; + powerCount = "0"; + CTF_scoreLimit = "6"; + + new MissionArea(MissionArea) { + area = "-2488 -4584 6848 5840"; + flightCeiling = "600"; + flightCeilingRange = "20"; + + locked = "true"; + }; + new Sky(Sky) { + position = "0 0 0"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + cloudHeightPer[0] = "0.349971"; + cloudHeightPer[1] = "0.25"; + cloudHeightPer[2] = "0.199973"; + cloudSpeed1 = "0.0001"; + cloudSpeed2 = "0.0002"; + cloudSpeed3 = "0.0003"; + visibleDistance = "800"; + useSkyTextures = "0"; + renderBottomTexture = "0"; + SkySolidColor = "0.250000 0.750000 1.000000 1.000000"; + fogDistance = "750"; + fogColor = "0.600000 0.600000 0.600000 1.000000"; + fogVolume1 = "200 99 101"; + fogVolume2 = "0 0 0"; + fogVolume3 = "0 0 0"; + materialList = "sky_desert_blue.dml"; + windVelocity = "1 0 0"; + windEffectPrecipitation = "0"; + fogVolumeColor1 = "128.000000 128.000000 128.000000 0.000000"; + fogVolumeColor2 = "128.000000 128.000000 128.000000 0.000000"; + fogVolumeColor3 = "128.000000 128.000000 128.000000 0.000000"; + high_visibleDistance = "-1"; + high_fogDistance = "-1"; + high_fogVolume1 = "-1 2.33105e-09 6.40969e-10"; + high_fogVolume2 = "-1 1.07461e-38 0"; + high_fogVolume3 = "-1 7.9874e-44 5.9061e-32"; + + cloudSpeed0 = "0.000503 0.000020"; + locked = "true"; + }; + new Sun() { + position = "0 0 0"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + direction = "0.57735 0.57735 -0.57735"; + color = "0.800000 0.800000 0.800000 1.000000"; + ambient = "0.450000 0.450000 0.450000 1.000000"; + texture[0] = "special/sunFlare"; + texture[1] = "special/sunFlare02"; + texture[2] = "special/LensFlare/flare01"; + texture[3] = "special/LensFlare/flare02"; + texture[4] = "special/LensFlare/flare03"; + lensFlareScale = "0.7"; + lensFlareIntensity = "1"; + frontFlareSize = "300"; + backFlareSize = "450"; + flareColor = "1.000000 1.000000 1.000000 1.000000"; + + locked = "true"; + }; + new TerrainBlock(Terrain) { + rotation = "1 0 0 0"; + scale = "1 1 1"; + detailTexture = "details/Detail02"; + terrainFile = "z0r Revisited.ter"; + squareSize = "8"; + emptySquares = "65558 156754 157010 158035 92752 158291 551760 552016 93520 159059 93527 160082 160338 118018 118274"; + + visibleDistance = "1200"; + locked = "true"; + hazeDistance = "250"; + position = "-1024 -1024 0"; + }; + new WaterBlock(Water) { + position = "248 -184 -22.9"; + rotation = "1 0 0 0"; + scale = "2048 2048 69"; + liquidType = "Water"; + density = "1"; + viscosity = "10"; + waveMagnitude = "1"; + surfaceTexture = "terrain/wateregypt1"; + surfaceOpacity = "0.7"; + envMapTexture = "LiquidTiles/archipelago_emap_cloudsground"; + envMapIntensity = "0.4"; + removeWetEdges = "0"; + + params1 = "0.63 -2.41 0.33 0.21"; + seedPoints = "0 0 1 0 1 1 0 1"; + params0 = "0.32 -0.67 0.066 0.5"; + floodFill = "1"; + params3 = "1.21 -0.61 0.13 -0.33"; + extent = "100 100 10"; + params2 = "0.39 0.39 0.2 0.133"; + locked = "1"; + textureSize = "32 32"; + }; + new NavigationGraph(NavGraph) { + conjoinAngleDev = "45"; + cullDensity = "0.3"; + customArea = "0 0 0 0"; + + XDimOverSize = "0"; + rotation = "0 0 0 0"; + conjoinBowlDev = "20"; + scale = "1 1 1"; + coverage = "0"; + YDimOverSize = "0"; + GraphFile = "MissionBlank.nav"; + locked = "true"; + position = "0 0 0 1"; + }; + new SimGroup(Teams) { + + powerCount = "0"; + + new SimGroup(Team1) { + + powerCount = "0"; + + new SimGroup(base0) { + + powerCount = "0"; + + new InteriorInstance() { + position = "-470.556 752.438 25.6702"; + rotation = "0 0 1 37.2423"; + scale = "1 2 1"; + interiorFile = "sbrdg1.dif"; + showTerrainInside = "0"; + + team = "1"; + locked = "1"; + }; + new Trigger() { + position = "-447.029 951.775 51.5999"; + rotation = "0 0 -1 28.6479"; + scale = "169.88 142.408 900"; + dataBlock = "gameTrigger"; + lockCount = "0"; + homingCount = "0"; + polyhedron = "0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 -0.0000000 -1.0000000 -0.0000000 -0.0000000 -0.0000000 1.0000000"; + + type = "Territory"; + team = "1"; + race = "Human"; + locked = "1"; + }; + new InteriorInstance() { + position = "-299.626 1008.26 47.75"; + rotation = "-6.05329e-09 -2.5853e-08 -1 26.3561"; + scale = "1 1 1"; + interiorFile = "bwall4.dif"; + showTerrainInside = "0"; + + team = "1"; + locked = "1"; + }; + new InteriorInstance() { + position = "-357.333 977.976 47.75"; + rotation = "-6.05329e-09 -2.5853e-08 -1 26.3561"; + scale = "1 1 1"; + interiorFile = "bwall4.dif"; + showTerrainInside = "0"; + + team = "1"; + locked = "1"; + }; + new InteriorInstance() { + position = "-401.624 954.344 49.6532"; + rotation = "0 0 1 62.4524"; + scale = "1 1 1"; + interiorFile = "bwall3.dif"; + showTerrainInside = "0"; + + team = "1"; + locked = "1"; + }; + new InteriorInstance() { + position = "-373.709 852.641 47.75"; + rotation = "-6.05329e-09 -2.5853e-08 -1 26.3561"; + scale = "1 1 1"; + interiorFile = "bwall4.dif"; + showTerrainInside = "0"; + + team = "1"; + locked = "1"; + }; + new InteriorInstance() { + position = "-410.791 927.527 49.6532"; + rotation = "0 0 -1 26.3561"; + scale = "1 1 1"; + interiorFile = "bwall3.dif"; + showTerrainInside = "0"; + + team = "1"; + locked = "1"; + }; + new InteriorInstance() { + position = "-396.588 898.852 49.6532"; + rotation = "0 0 -1 26.3561"; + scale = "1 1 1"; + interiorFile = "bwall3.dif"; + showTerrainInside = "0"; + + team = "1"; + locked = "1"; + }; + new InteriorInstance() { + position = "-382.383 870.179 49.6532"; + rotation = "0 0 -1 26.3561"; + scale = "1 1 1"; + interiorFile = "bwall3.dif"; + showTerrainInside = "0"; + + team = "1"; + locked = "1"; + }; + new InteriorInstance() { + position = "-419.307 945.184 47.75"; + rotation = "-6.05329e-09 -2.5853e-08 -1 26.3561"; + scale = "1 1 1"; + interiorFile = "bwall4.dif"; + showTerrainInside = "0"; + + team = "1"; + locked = "1"; + }; + new InteriorInstance() { + position = "-356.146 861.663 49.6532"; + rotation = "0 0 1 62.4524"; + scale = "1 1 1"; + interiorFile = "bwall3.dif"; + showTerrainInside = "0"; + + team = "1"; + locked = "1"; + }; + new InteriorInstance() { + position = "-327.775 876.461 49.6532"; + rotation = "0 0 1 62.4562"; + scale = "1 1 1"; + interiorFile = "bwall3.dif"; + showTerrainInside = "0"; + + team = "1"; + locked = "1"; + }; + new InteriorInstance() { + position = "-299.403 891.258 49.6532"; + rotation = "0 0 1 62.4562"; + scale = "1 1 1"; + interiorFile = "bwall3.dif"; + showTerrainInside = "0"; + + team = "1"; + locked = "1"; + }; + new InteriorInstance() { + position = "-271.031 906.056 49.6532"; + rotation = "0 0 1 62.4524"; + scale = "1 1 1"; + interiorFile = "bwall3.dif"; + showTerrainInside = "0"; + + team = "1"; + locked = "1"; + }; + new InteriorInstance() { + position = "-384.147 963.283 47.75"; + rotation = "-6.05329e-09 -2.5853e-08 -1 26.3561"; + scale = "1 1 1"; + interiorFile = "bwall4.dif"; + showTerrainInside = "0"; + + team = "1"; + locked = "1"; + }; + new InteriorInstance() { + position = "-262.268 933.082 49.6532"; + rotation = "0 0 -1 26.3561"; + scale = "1 1 1"; + interiorFile = "bwall3.dif"; + showTerrainInside = "0"; + + team = "1"; + locked = "1"; + }; + new InteriorInstance() { + position = "-276.473 961.754 49.6532"; + rotation = "0 0 -1 26.3561"; + scale = "1 1 1"; + interiorFile = "bwall3.dif"; + showTerrainInside = "0"; + + team = "1"; + locked = "1"; + }; + new InteriorInstance() { + position = "-290.677 990.429 49.6532"; + rotation = "0 0 -1 26.3561"; + scale = "1 1 1"; + interiorFile = "bwall3.dif"; + showTerrainInside = "0"; + + team = "1"; + locked = "1"; + }; + new InteriorInstance() { + position = "-253.444 915.312 47.75"; + rotation = "-6.05329e-09 -2.5853e-08 -1 26.3561"; + scale = "1 1 1"; + interiorFile = "bwall4.dif"; + showTerrainInside = "0"; + + team = "1"; + locked = "1"; + }; + new InteriorInstance() { + position = "-317.262 998.87 49.6532"; + rotation = "0 0 1 62.4524"; + scale = "1 1 1"; + interiorFile = "bwall3.dif"; + showTerrainInside = "0"; + + team = "1"; + locked = "1"; + }; + new InteriorInstance() { + position = "-342.635 985.635 49.6532"; + rotation = "0 0 1 62.4524"; + scale = "1 0.788578 1"; + interiorFile = "bwall3.dif"; + showTerrainInside = "0"; + + team = "1"; + locked = "1"; + }; + new InteriorInstance() { + position = "112.436 -216.188 49.1219"; + rotation = "0 0 1 180.664"; + scale = "1 1 1"; + interiorFile = "bwall3.dif"; + showTerrainInside = "0"; + + team = "1"; + locked = "1"; + }; + new InteriorInstance() { + position = "112.399 -288.619 49.121"; + rotation = "0 0 1 180.664"; + scale = "1 1 1"; + interiorFile = "bwall3.dif"; + showTerrainInside = "0"; + + team = "1"; + locked = "1"; + }; + }; + new SimGroup(base1) { + + powerCount = "0"; + + new InteriorInstance() { + position = "462.539 -111.849 130.5"; + rotation = "0 0 1 222.308"; + scale = "1 1 1"; + interiorFile = "bbase6.dif"; + showTerrainInside = "0"; + + team = "1"; + locked = "1"; + }; + new InteriorInstance() { + position = "360.581 -177.594 145.688"; + rotation = "0 0 1 83.6518"; + scale = "1 1 1"; + interiorFile = "bmisc9.dif"; + showTerrainInside = "0"; + + team = "1"; + locked = "1"; + }; + new InteriorInstance() { + position = "112.357 -235.178 48.8669"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "bwall4.dif"; + showTerrainInside = "0"; + + team = "1"; + locked = "1"; + }; + new InteriorInstance() { + position = "112.37 -269.598 48.8663"; + rotation = "0 0 1 1.71915"; + scale = "1 1 1"; + interiorFile = "bwall4.dif"; + showTerrainInside = "0"; + + team = "1"; + locked = "1"; + }; + new Trigger() { + position = "65.7148 -1.98538 39.6507"; + rotation = "1 0 0 0"; + scale = "518.836 345.191 900"; + dataBlock = "gameTrigger"; + lockCount = "0"; + homingCount = "0"; + polyhedron = "0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 -0.0000000 -1.0000000 -0.0000000 -0.0000000 -0.0000000 1.0000000"; + + type = "Territory"; + team = "1"; + race = "Human"; + locked = "1"; + }; + new TSStatic() { + position = "253.285 -154.94 42.3445"; + rotation = "0.837621 -0.187308 0.513134 47.0943"; + scale = "1 1 1"; + shapeName = "vehicle_land_assault_wreck.dts"; + + team = "1"; + locked = "1"; + }; + }; + new SimGroup(spawnspheres) { + + powerCount = "0"; + + new SpawnSphere() { + position = "454.253 -119.446 116.876"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "SpawnSphereMarker"; + lockCount = "0"; + homingCount = "0"; + radius = "70"; + sphereWeight = "100"; + indoorWeight = "100"; + outdoorWeight = "100"; + + locked = "1"; + }; + }; + }; + new SimGroup(team4) { + + powerCount = "0"; + + new SimGroup(base0) { + + powerCount = "0"; + + new InteriorInstance() { + position = "433.611 1931.43 124.066"; + rotation = "0 0 -1 7.44831"; + scale = "1 1 1"; + interiorFile = "bbunk1.dif"; + showTerrainInside = "0"; + + team = "4"; + locked = "1"; + }; + }; + new SimGroup(spawnspheres) { + + powerCount = "0"; + + new SpawnSphere() { + position = "435.77 1925.38 135.899"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "SpawnSphereMarker"; + lockCount = "0"; + homingCount = "0"; + radius = "100"; + sphereWeight = "100"; + indoorWeight = "100"; + outdoorWeight = "100"; + + locked = "1"; + }; + }; + new SimGroup(AIObjectives) { + + powerCount = "0"; + }; + }; + new SimGroup(team0) { + + powerCount = "0"; + + new SimGroup(base0) { + + powerCount = "0"; + + new InteriorInstance() { + position = "-1070.27 589.218 135.923"; + rotation = "0 0 -1 88.8085"; + scale = "1 1 1"; + interiorFile = "trpg_mine.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "true"; + }; + new InteriorInstance() { + position = "-377.106 -111.774 103.734"; + rotation = "-0.903865 -0.136606 -0.405421 40.8894"; + scale = "1 1 1"; + interiorFile = "brock8.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "1"; + }; + new InteriorInstance() { + position = "-365.439 -114.45 101.698"; + rotation = "-0.421356 0.146307 0.895016 145.472"; + scale = "1 1 1"; + interiorFile = "brock7.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "1"; + }; + new InteriorInstance() { + position = "-367.365 -115.996 102.367"; + rotation = "0 -1 0 45.2636"; + scale = "1 1 1"; + interiorFile = "brock6.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "1"; + }; + new InteriorInstance() { + position = "-358.225 -127.034 100.141"; + rotation = "0 0 -1 110.008"; + scale = "1 1 1"; + interiorFile = "brock8.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "1"; + }; + new InteriorInstance() { + position = "-354.71 -116.258 103.257"; + rotation = "-0.903184 0.425862 -0.0538564 42.157"; + scale = "1 1 1"; + interiorFile = "brock7.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "1"; + }; + new InteriorInstance() { + position = "-353.704 -118.688 102.93"; + rotation = "0 -1 0 68.7549"; + scale = "1 1 1"; + interiorFile = "brock6.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "1"; + }; + new InteriorInstance() { + position = "-353.064 -117.142 101.948"; + rotation = "-0.330175 0.532535 -0.779353 86.7847"; + scale = "1 1 1"; + interiorFile = "brock7.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "1"; + }; + new InteriorInstance() { + position = "-352.634 -114.684 103.079"; + rotation = "0.177072 -0.0106371 -0.98414 49.9722"; + scale = "1 1 1"; + interiorFile = "brock6.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "1"; + }; + new InteriorInstance() { + position = "-353.258 -104.492 106.904"; + rotation = "-0.498883 -0.781179 -0.375332 71.8445"; + scale = "1 1 1"; + interiorFile = "brock7.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "1"; + }; + new InteriorInstance() { + position = "-364.251 -104.363 109.09"; + rotation = "0.409184 -0.705766 0.578327 53.1408"; + scale = "1 1 1"; + interiorFile = "brock6.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "1"; + }; + new InteriorInstance() { + position = "-373.755 -217 101.951"; + rotation = "0.845589 0.280219 -0.454376 36.7965"; + scale = "1 1 1"; + interiorFile = "brock8.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "1"; + }; + new InteriorInstance() { + position = "-355.982 -225.445 107.792"; + rotation = "0.0920027 0.99332 0.0696462 172.938"; + scale = "1 1 1"; + interiorFile = "brock8.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "1"; + }; + new InteriorInstance() { + position = "-365.615 -219.911 109.904"; + rotation = "0.744523 -0.235177 -0.624802 36.3903"; + scale = "1 1 1"; + interiorFile = "brock7.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "1"; + }; + new InteriorInstance() { + position = "-367.246 -221.156 111.89"; + rotation = "0 1 0 95.111"; + scale = "1 1 1"; + interiorFile = "brock6.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "1"; + }; + new InteriorInstance() { + position = "-370.362 -228.671 116.84"; + rotation = "0.85184 -0.225245 -0.472899 63.4856"; + scale = "1 1 1"; + interiorFile = "brock8.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "1"; + }; + new InteriorInstance() { + position = "-366.109 -224.857 118.533"; + rotation = "0.975883 -0.218226 0.00551889 182.7"; + scale = "1 1 1"; + interiorFile = "brock7.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "1"; + }; + new InteriorInstance() { + position = "-367.517 -221.919 114.407"; + rotation = "-0.780324 0.399765 -0.480918 112.7"; + scale = "1 1 1"; + interiorFile = "brock6.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "1"; + }; + new InteriorInstance() { + position = "-367.41 -224.177 118.868"; + rotation = "0.148062 0.13541 0.979664 96.2823"; + scale = "1 1 1"; + interiorFile = "brock6.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "1"; + }; + new InteriorInstance() { + position = "-367.984 -222.147 115.715"; + rotation = "0.356696 -0.0270395 -0.933829 52.7103"; + scale = "1 1 1"; + interiorFile = "brock7.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "1"; + }; + new InteriorInstance() { + position = "-363.879 -223.042 108.22"; + rotation = "0.574074 0.345392 0.74239 67.7181"; + scale = "1 1 1"; + interiorFile = "brock8.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "1"; + }; + new InteriorInstance() { + position = "-359.85 -224.554 109.156"; + rotation = "0.999662 -0.00375378 -0.0257064 45.2774"; + scale = "1 1 1"; + interiorFile = "brock8.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "1"; + }; + new InteriorInstance() { + position = "-349.621 -217.638 104.483"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "brock7.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "1"; + }; + new InteriorInstance() { + position = "-351.406 -209.15 101.984"; + rotation = "0 0 1 8.02127"; + scale = "1 1 1"; + interiorFile = "brock7.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "1"; + }; + new InteriorInstance() { + position = "-361.692 -208.298 102.208"; + rotation = "0 0 1 165.194"; + scale = "1 1 1"; + interiorFile = "brock6.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "1"; + }; + new TSStatic() { + position = "-296.017 378.18 -2.37616"; + rotation = "0.402885 0.105022 -0.909205 31.9958"; + scale = "1 1 1"; + shapeName = "vehicle_air_scout_wreck.dts"; + + team = "0"; + locked = "1"; + }; + new InteriorInstance() { + position = "-326.649 -562.107 28.2"; + rotation = "0 0 -1 63.5983"; + scale = "1 2.07163 1"; + interiorFile = "sbrdg1.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "1"; + }; + new InteriorInstance() { + position = "-313.923 1506.95 27.6"; + rotation = "0 0 -1 50.9932"; + scale = "1 2.11791 1"; + interiorFile = "sbrdg1.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "1"; + }; + }; + new SimGroup(spawnsphres) { + + powerCount = "0"; + }; + new SimGroup(AIObjectives) { + + powerCount = "0"; + }; + }; + new SimGroup(team3) { + + powerCount = "0"; + + new SimGroup(base0) { + + powerCount = "0"; + + new InteriorInstance() { + position = "-354.049 -161.721 100.881"; + rotation = "0 0 1 89.3814"; + scale = "1 1 1"; + interiorFile = "bbase1.dif"; + showTerrainInside = "0"; + + team = "3"; + locked = "1"; + }; + new Trigger() { + position = "-490.546 12.8916 -23.0157"; + rotation = "1 0 0 0"; + scale = "262.087 256.957 1019.71"; + dataBlock = "gameTrigger"; + lockCount = "0"; + homingCount = "0"; + polyhedron = "0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 -0.0000000 -1.0000000 -0.0000000 -0.0000000 -0.0000000 1.0000000"; + + type = "Territory"; + team = "3"; + race = "Draakan"; + locked = "1"; + }; + new WayPoint(VehiclePad_Drake) { + position = "-371.915 -34.1391 139.312"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "WayPointMarker"; + lockCount = "0"; + homingCount = "0"; + team = "3"; + + locked = "1"; + }; + new InteriorInstance() { + position = "-83.0508 -218.399 27.4"; + rotation = "0 0 1 41.253"; + scale = "1 2.65302 1"; + interiorFile = "sbrdg1.dif"; + showTerrainInside = "0"; + + team = "3"; + locked = "1"; + }; + }; + new SimGroup(spawnspheres) { + + powerCount = "0"; + + new SpawnSphere() { + position = "-359.678 -162.775 115.281"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "SpawnSphereMarker"; + lockCount = "0"; + homingCount = "0"; + radius = "70"; + sphereWeight = "100"; + indoorWeight = "100"; + outdoorWeight = "100"; + + locked = "1"; + }; + }; + new SimGroup(AIObjectives) { + + powerCount = "0"; + }; + }; + new SimGroup(Team2) { + + powerCount = "0"; + + new SimGroup(base0) { + + powerCount = "0"; + + new InteriorInstance() { + position = "-1164 1827.93 218.573"; + rotation = "0 0 1 135.218"; + scale = "1 1 1"; + interiorFile = "xbunk9.dif"; + showTerrainInside = "0"; + + team = "2"; + locked = "1"; + }; + new InteriorInstance() { + position = "-1328.23 1521.97 66.6"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "sbrdg1.dif"; + showTerrainInside = "0"; + + team = "2"; + locked = "1"; + }; + new WayPoint(OMFG_FIX_THIS_BRIDGE) { + position = "-1326.06 1504.9 126.6"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "WayPointMarker"; + lockCount = "0"; + homingCount = "0"; + team = "2"; + + locked = "1"; + }; + new InteriorInstance() { + position = "-1328.15 1522.13 28.8"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "sbrdg1.dif"; + showTerrainInside = "0"; + + team = "2"; + locked = "1"; + }; + new InteriorInstance() { + position = "-1454.4 2082.3 210.721"; + rotation = "0 0 1 13.751"; + scale = "1 1 1"; + interiorFile = "xwall1.dif"; + showTerrainInside = "0"; + + team = "2"; + locked = "1"; + }; + new InteriorInstance() { + position = "-1450.6 2097.84 210.721"; + rotation = "0 0 1 13.751"; + scale = "1 1 1"; + interiorFile = "xwall1.dif"; + showTerrainInside = "0"; + + team = "2"; + locked = "1"; + }; + new InteriorInstance(InteriorInstance) { + position = "-1446.79 2113.38 210.721"; + rotation = "0 0 1 13.751"; + scale = "1 1 1"; + interiorFile = "xwall1.dif"; + showTerrainInside = "0"; + + team = "2"; + locked = "1"; + }; + new InteriorInstance(InteriorInstance) { + position = "-1328.21 1486.09 104.6"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "sbrdg1.dif"; + showTerrainInside = "0"; + + team = "2"; + locked = "1"; + }; + new InteriorInstance(InteriorInstance) { + position = "-1328.21 1562.28 104.6"; + rotation = "1 0 0 0"; + scale = "1 1.07232 1"; + interiorFile = "sbrdg1.dif"; + showTerrainInside = "0"; + + team = "2"; + locked = "1"; + }; + new InteriorInstance() { + position = "-296.401 1616.16 26.4"; + rotation = "0 0 1 25.2101"; + scale = "1 1.42859 1"; + interiorFile = "sbrdg1.dif"; + showTerrainInside = "0"; + + team = "2"; + locked = "1"; + }; + new Trigger() { + position = "-1530.29 2161.83 -5.6767"; + rotation = "1 0 0 0"; + scale = "704.205 602.061 900"; + dataBlock = "gameTrigger"; + lockCount = "0"; + homingCount = "0"; + polyhedron = "0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 -0.0000000 -1.0000000 -0.0000000 -0.0000000 -0.0000000 1.0000000"; + + type = "Territory"; + team = "2"; + race = "bioderm"; + locked = "1"; + }; + }; + new SimGroup(spawnspheres) { + + powerCount = "0"; + + new SpawnSphere() { + position = "-1161.28 1825.13 228.423"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "SpawnSphereMarker"; + lockCount = "0"; + homingCount = "0"; + radius = "70"; + sphereWeight = "100"; + indoorWeight = "100"; + outdoorWeight = "100"; + + locked = "1"; + }; + }; + new SimGroup(AIObjectives) { + + powerCount = "0"; + }; + }; + }; + new StaticShape() { + position = "-1093.57 603.616 117.811"; + rotation = "0 0 1 103.705"; + scale = "1 1 1"; + dataBlock = "LightMaleHuman_Dead"; + lockCount = "0"; + homingCount = "0"; + + locked = "1"; + Target = "-1"; + }; + new StaticShape() { + position = "-1068.56 628.036 117.388"; + rotation = "1 0 0 0"; + scale = "1 1 10.183"; + dataBlock = "MiningBox"; + lockCount = "0"; + homingCount = "0"; + + mineral = "Silver"; + wasDisabled = "1"; + locked = "1"; + }; + new StaticShape() { + position = "-1028.73 513.275 94.5294"; + rotation = "1 0 0 0"; + scale = "0.2276 0.138534 1.41644"; + dataBlock = "MiningBox"; + lockCount = "0"; + homingCount = "0"; + + mineral = "Gem"; + wasDisabled = "1"; + locked = "1"; + pDesc = "Set my mineral.."; + }; + new StaticShape() { + position = "-1016.1 523.434 91.9845"; + rotation = "1 0 0 0"; + scale = "0.989212 0.414657 11.1624"; + dataBlock = "MiningBox"; + lockCount = "0"; + homingCount = "0"; + + mineral = "Gem"; + wasDisabled = "1"; + locked = "1"; + pDesc = "Set my mineral.."; + }; + new StaticShape() { + position = "-1055.08 502.345 92.7845"; + rotation = "1 0 0 0"; + scale = "0.1 0.269252 1.26103"; + dataBlock = "MiningBox"; + lockCount = "0"; + homingCount = "0"; + + mineral = "Gem"; + wasDisabled = "1"; + locked = "1"; + pDesc = "Set my mineral.."; + }; + new StaticShape() { + position = "-1063.58 493.322 94.1557"; + rotation = "1 0 0 0"; + scale = "0.2276 0.61061 3.98388"; + dataBlock = "MiningBox"; + lockCount = "0"; + homingCount = "0"; + + mineral = "Gem"; + wasDisabled = "1"; + locked = "1"; + pDesc = "Set my mineral.."; + }; + new StaticShape() { + position = "-1055.64 475.155 95.7549"; + rotation = "1 0 0 0"; + scale = "0.1 0.217906 1.56999"; + dataBlock = "MiningBox"; + lockCount = "0"; + homingCount = "0"; + + mineral = "Gem"; + wasDisabled = "1"; + locked = "1"; + pDesc = "Set my mineral.."; + }; + new StaticShape() { + position = "-1059.41 462.901 94.2362"; + rotation = "1 0 0 0"; + scale = "0.19726 0.187931 1"; + dataBlock = "MiningBox"; + lockCount = "0"; + homingCount = "0"; + + mineral = "Gem"; + wasDisabled = "1"; + locked = "1"; + pDesc = "Set my mineral.."; + }; + new StaticShape() { + position = "-1076.1 472.004 94.9547"; + rotation = "1 0 0 0"; + scale = "0.207733 0.348236 1.51683"; + dataBlock = "MiningBox"; + lockCount = "0"; + homingCount = "0"; + + mineral = "Gem"; + wasDisabled = "1"; + locked = "1"; + pDesc = "Set my mineral.."; + }; + new StaticShape() { + position = "-1032.29 505.958 98.4778"; + rotation = "1 0 0 0"; + scale = "0.535278 0.704081 1.98302"; + dataBlock = "MiningBox"; + lockCount = "0"; + homingCount = "0"; + + mineral = "Gem"; + wasDisabled = "1"; + locked = "1"; + pDesc = "Set my mineral.."; + }; + new StaticShape() { + position = "-1065 505.083 93.1874"; + rotation = "1 0 0 0"; + scale = "0.49408 0.402028 3.88171"; + dataBlock = "MiningBox"; + lockCount = "0"; + homingCount = "0"; + + mineral = "Gem"; + wasDisabled = "1"; + locked = "1"; + pDesc = "Set my mineral.."; + }; + new StaticShape() { + position = "-1068.67 513.114 98.3049"; + rotation = "1 0 0 0"; + scale = "0.285156 0.667053 1.94992"; + dataBlock = "MiningBox"; + lockCount = "0"; + homingCount = "0"; + + mineral = "Gem"; + wasDisabled = "1"; + locked = "1"; + pDesc = "Set my mineral.."; + }; + new StaticShape() { + position = "-1076.83 514.521 93.3816"; + rotation = "1 0 0 0"; + scale = "0.465515 0.436971 3.54662"; + dataBlock = "MiningBox"; + lockCount = "0"; + homingCount = "0"; + + mineral = "Gem"; + wasDisabled = "1"; + locked = "1"; + pDesc = "Set my mineral.."; + }; + new StaticShape() { + position = "-1087.5 506.192 94.2351"; + rotation = "1 0 0 0"; + scale = "0.470093 0.295603 3.65455"; + dataBlock = "MiningBox"; + lockCount = "0"; + homingCount = "0"; + + mineral = "Gem"; + wasDisabled = "1"; + locked = "1"; + pDesc = "Set my mineral.."; + }; + new StaticShape() { + position = "-1098.67 507.377 92.4363"; + rotation = "1 0 0 0"; + scale = "0.46933 0.714142 1.27818"; + dataBlock = "MiningBox"; + lockCount = "0"; + homingCount = "0"; + + mineral = "Gem"; + wasDisabled = "1"; + locked = "1"; + pDesc = "Set my mineral.."; + }; + new StaticShape() { + position = "-1109.79 513.981 98.6638"; + rotation = "1 0 0 0"; + scale = "0.563599 0.690359 1.33957"; + dataBlock = "MiningBox"; + lockCount = "0"; + homingCount = "0"; + + mineral = "Gem"; + wasDisabled = "1"; + locked = "1"; + pDesc = "Set my mineral.."; + }; + new StaticShape() { + position = "-1045.58 513.912 93.297"; + rotation = "1 0 0 0"; + scale = "0.47171 0.368174 3.95471"; + dataBlock = "MiningBox"; + lockCount = "0"; + homingCount = "0"; + + mineral = "Gem"; + wasDisabled = "1"; + locked = "1"; + pDesc = "Set my mineral.."; + }; + new StaticShape() { + position = "-1085.3 465.744 92.4406"; + rotation = "1 0 0 0"; + scale = "0.218445 0.313537 0.409158"; + dataBlock = "MiningBox"; + lockCount = "0"; + homingCount = "0"; + + mineral = "Gem"; + wasDisabled = "1"; + locked = "1"; + pDesc = "Set my mineral.."; + }; + new StaticShape() { + position = "-1062.09 524.739 92.368"; + rotation = "1 0 0 0"; + scale = "0.450684 0.65389 1.22284"; + dataBlock = "MiningBox"; + lockCount = "0"; + homingCount = "0"; + + mineral = "Gem"; + wasDisabled = "1"; + locked = "1"; + pDesc = "Set my mineral.."; + }; + new StaticShape() { + position = "-1062.78 534.846 92.6981"; + rotation = "1 0 0 0"; + scale = "0.175934 0.602885 3.32562"; + dataBlock = "MiningBox"; + lockCount = "0"; + homingCount = "0"; + + mineral = "Gem"; + wasDisabled = "1"; + locked = "1"; + pDesc = "Set my mineral.."; + }; + new StaticShape() { + position = "-1054.52 550.27 94.3173"; + rotation = "1 0 0 0"; + scale = "0.348206 1.10693 3.46191"; + dataBlock = "MiningBox"; + lockCount = "0"; + homingCount = "0"; + + mineral = "Gem"; + wasDisabled = "1"; + locked = "1"; + pDesc = "Set my mineral.."; + }; + new StaticShape() { + position = "-1058.37 567.186 95.3873"; + rotation = "1 0 0 0"; + scale = "0.466583 0.336487 3.57619"; + dataBlock = "MiningBox"; + lockCount = "0"; + homingCount = "0"; + + mineral = "Gem"; + wasDisabled = "1"; + locked = "1"; + pDesc = "Set my mineral.."; + }; + new StaticShape() { + position = "-1142.04 496.292 93.3373"; + rotation = "1 0 0 0"; + scale = "0.47226 0.29301 3.49713"; + dataBlock = "MiningBox"; + lockCount = "0"; + homingCount = "0"; + + mineral = "Gem"; + wasDisabled = "1"; + locked = "1"; + pDesc = "Set my mineral.."; + }; + new StaticShape() { + position = "-1148.19 509.829 93.8726"; + rotation = "1 0 0 0"; + scale = "0.47226 0.29301 3.49713"; + dataBlock = "MiningBox"; + lockCount = "0"; + homingCount = "0"; + + mineral = "Gem"; + wasDisabled = "1"; + locked = "1"; + pDesc = "Set my mineral.."; + }; + new StaticShape() { + position = "-1128.31 507.072 95.4624"; + rotation = "1 0 0 0"; + scale = "0.471558 0.575317 4.1662"; + dataBlock = "MiningBox"; + lockCount = "0"; + homingCount = "0"; + + mineral = "Gem"; + wasDisabled = "1"; + locked = "1"; + pDesc = "Set my mineral.."; + }; + new StaticShape() { + position = "-1082.01 567.828 96.0331"; + rotation = "1 0 0 0"; + scale = "0.166046 0.1 1.68872"; + dataBlock = "MiningBox"; + lockCount = "0"; + homingCount = "0"; + + mineral = "Gem"; + wasDisabled = "1"; + locked = "1"; + pDesc = "Set my mineral.."; + }; + new StaticShape() { + position = "-1087.84 559.529 95.4327"; + rotation = "1 0 0 0"; + scale = "0.49173 0.243673 3.26553"; + dataBlock = "MiningBox"; + lockCount = "0"; + homingCount = "0"; + + mineral = "Gem"; + wasDisabled = "1"; + locked = "1"; + pDesc = "Set my mineral.."; + }; + new StaticShape() { + position = "-1103.64 559.455 96.1256"; + rotation = "1 0 0 0"; + scale = "0.293335 0.316223 2.30223"; + dataBlock = "MiningBox"; + lockCount = "0"; + homingCount = "0"; + + mineral = "Gem"; + wasDisabled = "1"; + locked = "1"; + pDesc = "Set my mineral.."; + }; + new StaticShape() { + position = "-1106.89 568.471 95.8961"; + rotation = "1 0 0 0"; + scale = "0.21463 0.327799 1.96655"; + dataBlock = "MiningBox"; + lockCount = "0"; + homingCount = "0"; + + mineral = "Gem"; + wasDisabled = "1"; + locked = "1"; + pDesc = "Set my mineral.."; + }; + new StaticShape() { + position = "-1116.96 559.967 93.8314"; + rotation = "1 0 0 0"; + scale = "0.401154 0.29421 3.15295"; + dataBlock = "MiningBox"; + lockCount = "0"; + homingCount = "0"; + + mineral = "Gem"; + wasDisabled = "1"; + locked = "1"; + pDesc = "Set my mineral.."; + }; + new StaticShape() { + position = "-1128.55 568.855 93.3634"; + rotation = "1 0 0 0"; + scale = "0.185974 0.229045 1"; + dataBlock = "MiningBox"; + lockCount = "0"; + homingCount = "0"; + + mineral = "Gem"; + wasDisabled = "1"; + locked = "1"; + pDesc = "Set my mineral.."; + }; + new StaticShape() { + position = "-1163.29 582.469 105.67"; + rotation = "1 0 0 0"; + scale = "1 1 2.59875"; + dataBlock = "MiningBox"; + lockCount = "0"; + homingCount = "0"; + + mineral = "Gem"; + wasDisabled = "1"; + locked = "1"; + pDesc = "Set my mineral.."; + }; + new StaticShape() { + position = "-1074.99 602.397 117.864"; + rotation = "0 0 -1 53.2851"; + scale = "0.240631 0.700714 4.71143"; + dataBlock = "MiningBox"; + lockCount = "0"; + homingCount = "0"; + + mineral = "Steel"; + wasDisabled = "1"; + locked = "1"; + }; + new StaticShape() { + position = "-1075.01 593.412 117.467"; + rotation = "1 0 0 0"; + scale = "1.75943 1.97791 37.4574"; + dataBlock = "MiningBox"; + lockCount = "0"; + homingCount = "0"; + + mineral = "Gold"; + wasDisabled = "1"; + locked = "1"; + }; + new WayPoint(IdeaMarker1) { + position = "589.05 1060.81 153.103"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + nameTag = "A spot for something."; + dataBlock = "WayPointMarker"; + lockCount = "0"; + homingCount = "0"; + team = "1"; + + locked = "1"; + }; + new SimGroup(observerDropPoints) { + + powerCount = "0"; + + new Camera(camera1) { + position = "387.469 -155.397 179.559"; + rotation = "0.343278 -0.234887 0.909389 73.9173"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + team = "1"; + locked = "1"; + }; + new Camera(camera2) { + position = "-434.776 998.772 109.708"; + rotation = "0.116405 -0.239522 0.963887 129.8"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + team = "1"; + locked = "1"; + }; + new Camera(camera3) { + position = "-441.633 -102.007 176.768"; + rotation = "0.140072 -0.270121 0.952583 127.425"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + team = "3"; + locked = "1"; + }; + new Camera(camera4) { + position = "-1249.32 1538.45 204.386"; + rotation = "0.264832 0.394028 -0.880117 118.788"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + team = "2"; + locked = "1"; + }; + new Camera(camera5) { + position = "-1022.15 1874.11 294.405"; + rotation = "0.276336 0.252912 -0.927186 89.2565"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + team = "2"; + locked = "1"; + }; + }; + new WayPoint(MiningCommunity) { + position = "-1127.85 611.14 280.781"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "WayPointMarker"; + lockCount = "0"; + homingCount = "0"; + team = "0"; + + locked = "1"; + pDesc = "A little mining community will thrive here."; + }; + new Trigger() { + position = "-1097.73 480.386 125.8"; + rotation = "1 0 0 0"; + scale = "46.1831 19.6776 1"; + dataBlock = "gameTrigger"; + lockCount = "0"; + homingCount = "0"; + polyhedron = "0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 -0.0000000 -1.0000000 -0.0000000 -0.0000000 -0.0000000 1.0000000"; + + type = "DAMAGE"; + damageType = "Lava"; + DAMAGE = "0.09"; //For Drakes too o_O' + locked = "1"; + }; +}; +//--- OBJECT WRITE END --- diff --git a/missions/Example_MapScript.cs b/missions/Example_MapScript.cs index 35228ab..f511517 100644 --- a/missions/Example_MapScript.cs +++ b/missions/Example_MapScript.cs @@ -1,36 +1,36 @@ -//Example for map Script -package Example //Must be our mission name for package to activate before the functions are called. -{ - function defineGeneralAI() //Called to load all general AI's for this map -- will be moved so it's stored in a BASIC file - { - //These arrays are for general bots - $Bot[0,"Name"] = "A bot."; - $Bot[0,"Race"] = "Human"; - - //Very important or the console will get spammed. - //Bioderms and Criollos MUST be Male. - //Draakans can be types A, B, or C. - $Bot[0,"Sex"] = "Male"; - $Bot[0,"Skin"] = "Beagle"; //Skin. Don't use the actual team name. (Blood Eagle for example) - $Bot[0,"Voice"] = "Male1"; //Voice. Don't use the fancy name (Psycho for example). - $Bot[0,"VoicePitch"] = 1; - $Bot[0,"Team"] = 1; //Human - $Bot[0,"Weapons"] = "Chaingun Disc Shocklance"; //List the weapons with spaces. The first weapon listed will be the one he has out on spawn. - $Bot[0,"Pack"] = "AmmoPack"; - - //The ammo for each weapon in "Weapons", make sure it's in the same spot in the string as the weapon. - //If the weapon doesn't use ammo, just place a zero. - $Bot[0,"Ammo"] = "200 30 0"; - $Bot[0,"RepairKits"] = 1; //Yea.. rep kits - $Bot[0,"Mines"] = 1; //Mines!! - $Bot[0,"Grenades"] = 3; //Grenades. I'll make it so you can tell which kind of nades. - $Bot[0,"Transform"] = "0 0 0 1 0 0 0"; //First 3 numbers are the position. The rest is the rotation. - - //These are for detailing on the bots.. shouldn't really be used unless you got a good reason to. - $Bot[0,"Health"] = 1; //I'm pretty sure 1 is the max for all armors. - - - $BotCount = 1; //Tell the game how many general AI's there are. - } -}; -//You don't have to activate this package yourself, the game activates it just before loading AI's +//Example for map Script +package Example //Must be our mission name for package to activate before the functions are called. +{ + function defineGeneralAI() //Called to load all general AI's for this map -- will be moved so it's stored in a BASIC file + { + //These arrays are for general bots + $Bot[0,"Name"] = "A bot."; + $Bot[0,"Race"] = "Human"; + + //Very important or the console will get spammed. + //Bioderms and Criollos MUST be Male. + //Draakans can be types A, B, or C. + $Bot[0,"Sex"] = "Male"; + $Bot[0,"Skin"] = "Beagle"; //Skin. Don't use the actual team name. (Blood Eagle for example) + $Bot[0,"Voice"] = "Male1"; //Voice. Don't use the fancy name (Psycho for example). + $Bot[0,"VoicePitch"] = 1; + $Bot[0,"Team"] = 1; //Human + $Bot[0,"Weapons"] = "Chaingun Disc Shocklance"; //List the weapons with spaces. The first weapon listed will be the one he has out on spawn. + $Bot[0,"Pack"] = "AmmoPack"; + + //The ammo for each weapon in "Weapons", make sure it's in the same spot in the string as the weapon. + //If the weapon doesn't use ammo, just place a zero. + $Bot[0,"Ammo"] = "200 30 0"; + $Bot[0,"RepairKits"] = 1; //Yea.. rep kits + $Bot[0,"Mines"] = 1; //Mines!! + $Bot[0,"Grenades"] = 3; //Grenades. I'll make it so you can tell which kind of nades. + $Bot[0,"Transform"] = "0 0 0 1 0 0 0"; //First 3 numbers are the position. The rest is the rotation. + + //These are for detailing on the bots.. shouldn't really be used unless you got a good reason to. + $Bot[0,"Health"] = 1; //I'm pretty sure 1 is the max for all armors. + + + $BotCount = 1; //Tell the game how many general AI's there are. + } +}; +//You don't have to activate this package yourself, the game activates it just before loading AI's diff --git a/missions/HotZone.cs b/missions/HotZone.cs index 872f729..78d3c30 100644 --- a/missions/HotZone.cs +++ b/missions/HotZone.cs @@ -1,370 +1,370 @@ -// don't want this executing when building graphs -if($OFFLINE_NAV_BUILD) - return; - -// Script for Training -//=================================================================================== -//error("Training 1 script"); - -//Note: Quite messy right now.. I'll organize when it's done - -// package and callbacks -activatePackage(HotZone); - -// variables -$numberOfEnemies[1] = 0; -$numberOfEnemies[2] = 0; -$numberOfEnemies[3] = 0; -$numberOfTeammates = 5; -$missionBotSkill[1] = 0.0; -$missionBotSkill[2] = 0.4; -$missionBotSkill[3] = 0.7; - -// additional mission Audio -datablock AudioProfile(HeartbeatSound) -{ - filename = "fx/misc/heartbeat.wav"; - description = Audio2D; - preload = true; - looping = false; -}; - -package HotZone { -//BEGIN TRAINING PACKAGE ======================================================================= - -function SinglePlayerGame::initGameVars(%game) -{ - echo("initializing training1 game vars"); -} - -function getTeammateGlobals() -{ - $TeammateWarnom0 = "Raptor"; - $teammateskill0 = 0.5; - $teammateVoice0 = Derm3; - $teammateEquipment0 = 0; - $teammateGender0 = A; - - $TeammateWarnom1 = "Cobra"; - $teammateSkill1 = 0.5; - $teammateVoice1 = Derm3; - $teammateEquipment1 = 0; - $teammateGender1 = C; - - $TeammateWarnom2 = "Sharp Tooth"; - $teammateSkill2 = 0.5; - $teammateVoice2 = Derm3; - $teammateEquipment2 = 0; - $teammateGender2 = A; - - $TeammateWarnom3 = "Snake"; - $teammateSkill3 = 0.5; - $teammateVoice3 = Derm3; - $teammateEquipment3 = 0; - $teammateGender3 = A; - - $TeammateWarnom4 = "Gila"; - $teammateSkill4 = 0.5; - $teammateVoice4 = Derm3; - $teammateEquipment4 = 0; - $teammateGender4 = B; -} - - -function AIFollowPath::assume(%task, %client) -{ - %task.setWeightFreq(30); - %task.setMonitorFreq(10); - - -// //next, start the pilot on his way to mounting the vehicle -// %client.pilotVehicle = true; -// %client.stepMove($player.flyer.position, 0.25, $AIModeMountVehicle); -} - -function AIFollowPath::weight(%task, %client) -{ - %task.setWeight(10000); -} - -function AIFollowPath::monitor(%task, %client) -{ - //messageall(0, " AITraining1Pilot::monitor "@%task.locationIndex); - %group = nameToId(FlightPath); - if(!%task.locationIndex) - %task.locationIndex = 0; - - //HACK ALERT!!! - //since the path for this mission is completely straight, always head for the end of the path - //%location = %group.getObject(%task.locationIndex); - %location = %group.getObject(%group.getCount() - 1); - - //see if we've mounted yet - if(%client.vehicleMounted) - { - %client.setPilotDestination(%location.position); - - //else see if we're close enough to the current destination to choose the next - %pos = %client.vehicleMounted.position; - %pos2D = getWord(%pos, 0) SPC getWord(%pos, 1) SPC "0"; - %dest = %group.getObject(%task.locationIndex).position; - %dest2D = getWord(%dest, 0) SPC getWord(%dest, 1) SPC "0"; - - if (VectorDist(%dest2D, %pos2D) < 20) - { - if(%group.getCount() > %task.locationIndex + 1) { - %task.locationIndex++; - cinematicEvent(%task.locationIndex); - } - //else messageAll(0, "Ride Over"); - } - } - else - %client.stepMove($player.flyer.position, 0.25, $AIModeExpress); -} - -function PlayGui::onWake(%this) -{ - parent::onWake(%this); - //error("Waking training play gui"); - // okay we know the victim...erm...player is looking - // and we hope they have a body so lets do this - if(!game.playedIntro) { - game.PlayGuiAwake = true; - beginHotZone(); - } - -} - -function aiSetLoadout(%client) -{ -%client.player.clearInventory(); -%client.player.setArmor("heavy"); -%client.player.setInventory("Chaingun",1,true); -%client.player.setInventory("ChaingunAmmo",999,true); -%client.player.setInventory("Disc",1,true); -%client.player.setInventory("Discammo",999,true); -%client.player.setInventory("Shocklance",1,true); -%client.player.setInventory("MissileLauncher",1,true); -%client.player.setInventory("MissileLauncherAmmo",999,true); -%client.player.setInventory("Mortar",1,true); -%client.player.setInventory("MortarAmmo",999,true); -%client.player.setInventory("AmmoPack",1,true); -%client.player.use("Mortar"); -} - -function beginHotZone() //Don't let the game reset itself a bunch of times -{ -if (Game.playedIntro) -return; -%spawn = nameToId(); - -$player.flyer = new FlyingVehicle(Flyer) { - position = %spawn.position; - rotation = %spawn.rotation; - scale = "1 1 1"; - dataBlock = "HAPCFlyer"; - }; - -%pilot = $teammate0; -game.playedIntro = true; -$player.flyer.pilot = $teammate0; -setTargetSkin(%pilot.target, $teamSkin[$playerTeam]); -%pilot.player.setArmor(light); -%pilot.pilotVehicle = false; -$player.flyer.mountObject(%pilot.player, 0); -%pilot.setControlObject($player.flyer); -%pilot.setPilotPitchRange(-0.2, 0.05, 0.05); -%pilot.addTask(AIFollowPath); - -$player.flyer.mountObject($player.player, 1); -$player.flyer.mountObject($teammate1.player, 2); -$player.flyer.mountObject($teammate2.player, 3); -$player.flyer.mountObject($teammate3.player, 4); -$player.flyer.mountObject($teammate4.player, 5); -aiSetLoadout($teammate1); -aiSetLoadout($teammate2); -aiSetLoadout($teammate3); -aiSetLoadout($teammate4); -$player.player.setTransform($player.player.position SPC %spawn.rotation); -$HotZoneBlackout = ServerConnection.schedule(3000, setBlackOut, false, 4000); - -//Has to be added after all the bots.. otherwise they die by lava somehow -new WaterBlock(Lava) { -position = "-224 -264 93.1568"; -rotation = "1 0 0 0"; -scale = "768 608 27.0092"; -liquidType = "Lava"; -density = "1"; -viscosity = "15"; -waveMagnitude = "1"; -surfaceTexture = "LiquidTiles/Lava"; -surfaceOpacity = "1"; -envMapTexture = "lava/skies/lava_starrynite_emap"; -envMapIntensity = "0.2"; -submergeTexture[0] = "special/lavadeath_1"; -submergeTexture[1] = "special/lavadeath_2"; -removeWetEdges = "1"; - -locked = "true"; -}; - -} - -function MP3Audio::play(%this) -{ - //too bad...no mp3 in training -} - -function toggleCommanderMap(%val) -{ - if ( %val ) - messageClient($player, 0, $player.miscMsg[noCC]); -} - -function toggleTaskListDlg( %val ) -{ - if ( %val ) - messageClient( $player, 0, $player.miscMsg[noTaskListDlg] ); -} - -function toggleInventoryHud( %val ) -{ - if ( %val ) - messageClient( $player, 0, $player.miscMsg[noInventoryHUD] ); -} - -function toggleNetDisplayHud( %val ) -{ - // Hello, McFly? This is training! There's no net in training! -} - -function voiceCapture( %val ) -{ - // Uh, who do you think you are talking to? -} - -function giveall() -{ - error("When the going gets tough...wussies like you start cheating!"); - messageClient($player, 0, "Cheating eh? What\'s next? Camping?"); -} - -// get the ball rolling -//------------------------------------------------------------------------------ -function startCurrentMission() -{ - playGui.add(outerChatHud); - - //fade up from black - ServerConnection.setBlackOut(true, 0); -} - -//------------------------------------------------------------------------------ -function SinglePlayerGame::equip(%game, %player) -{ - //ya start with nothing...NOTHING! - %player.clearInventory(); - for(%i =0; %i<$InventoryHudCount; %i++) - %player.client.setInventoryHudItem($InventoryHudData[%i, itemDataName], 0, 1); - %player.client.clearBackpackIcon(); - - %set = %player.client.equipment; - - echo("using default equipment"); - - %player.setArmor("Light"); - %player.setInventory(RepairKit,1); - %player.setInventory(Chaingun, 1); - %player.setInventory(ChaingunAmmo, 100); - %player.setInventory(Disc,1); - %player.setInventory(DiscAmmo, 20); - %player.setInventory(Shocklance, 1); - %player.setInventory(AmmoPack, 1); - - //DefaultGame.cs does not assign flamer.. - %player.setInventory(flamer, 1); - %player.weaponCount = 4; - - %player.use(Chaingun); -} - -function spawnSinglePlayer() -{ - resetWildCat(); - parent::spawnSinglePlayer(); -} - -function singlePlayerGame::onAIRespawn(%game, %client) -{ - // DONT add the default tasks - //error("default tasks not added"); -} - -function singlePlayerGame::playerSpawned(%game, %player) -{ - parent::playerSpawned(%game, %player); -} - -function singlePlayerGame::gameOver(%game) -{ - //enable the voice chat menu again... - if (isObject(training1BlockMap)) - { - training1BlockMap.pop(); - training1BlockMap.delete(); - } - - if(HelpTextGui.isVisible()) - helpTextGui.setVisible(false); - - //re-enable the use of the settings button... - SinglePlayerEscSettingsBtn.setActive(1); - - Parent::gameOver(); -} - -function trainingPreloads() //Load any skins.. -{ - navGraph.preload("skins/Gecko.lbioderm", true); - navGraph.preload("skins/Gecko.mbioderm", true); - navGraph.preload("skins/Gecko.hbioderm", true); - navGraph.preload("skins/base.lbioderm", true); - navGraph.preload("skins/HALO_Skin.lbioderm", true); - navGraph.preload("skins/HALO_Skin.mbioderm", true); - navGraph.preload("skins/HALO_Skin.hbioderm", true); - navGraph.preload("skins/sensor_pulse_large", true); - navGraph.preload("skins/base.hmale", false); - navGraph.preload("skins/beagle.hmale", false); - navGraph.preload("skins/base.mmale", false); - navGraph.preload("skins/beagle.mmale", false); - navGraph.preload("skins/base.lmale", false); - navGraph.preload("skins/swolf.mmale", false); - navGraph.preload("skins/beagle.lmale", false); -} - -function SinglePlayerGame::missionLoadDone(%game) -{ - Parent::missionLoadDone(%game); - trainingPreloads(); -} - -function serverCmdBuildClientTask(%client, %task, %team) -{ - // player shouldnt be able to use the voice commands to do anything -} -}; - -package vehicleHack -{ -function AIConnection::isMountingVehicle(%client){ return true; } -}; -activatePackage(vehicleHack); - -function setActionThread(%player,%anim,%bool) -{ -%player.setActionThread(%anim,%bool); -} - - - +// don't want this executing when building graphs +if($OFFLINE_NAV_BUILD) + return; + +// Script for Training +//=================================================================================== +//error("Training 1 script"); + +//Note: Quite messy right now.. I'll organize when it's done + +// package and callbacks +activatePackage(HotZone); + +// variables +$numberOfEnemies[1] = 0; +$numberOfEnemies[2] = 0; +$numberOfEnemies[3] = 0; +$numberOfTeammates = 5; +$missionBotSkill[1] = 0.0; +$missionBotSkill[2] = 0.4; +$missionBotSkill[3] = 0.7; + +// additional mission Audio +datablock AudioProfile(HeartbeatSound) +{ + filename = "fx/misc/heartbeat.wav"; + description = Audio2D; + preload = true; + looping = false; +}; + +package HotZone { +//BEGIN TRAINING PACKAGE ======================================================================= + +function SinglePlayerGame::initGameVars(%game) +{ + echo("initializing training1 game vars"); +} + +function getTeammateGlobals() +{ + $TeammateWarnom0 = "Raptor"; + $teammateskill0 = 0.5; + $teammateVoice0 = Derm3; + $teammateEquipment0 = 0; + $teammateGender0 = A; + + $TeammateWarnom1 = "Cobra"; + $teammateSkill1 = 0.5; + $teammateVoice1 = Derm3; + $teammateEquipment1 = 0; + $teammateGender1 = C; + + $TeammateWarnom2 = "Sharp Tooth"; + $teammateSkill2 = 0.5; + $teammateVoice2 = Derm3; + $teammateEquipment2 = 0; + $teammateGender2 = A; + + $TeammateWarnom3 = "Snake"; + $teammateSkill3 = 0.5; + $teammateVoice3 = Derm3; + $teammateEquipment3 = 0; + $teammateGender3 = A; + + $TeammateWarnom4 = "Gila"; + $teammateSkill4 = 0.5; + $teammateVoice4 = Derm3; + $teammateEquipment4 = 0; + $teammateGender4 = B; +} + + +function AIFollowPath::assume(%task, %client) +{ + %task.setWeightFreq(30); + %task.setMonitorFreq(10); + + +// //next, start the pilot on his way to mounting the vehicle +// %client.pilotVehicle = true; +// %client.stepMove($player.flyer.position, 0.25, $AIModeMountVehicle); +} + +function AIFollowPath::weight(%task, %client) +{ + %task.setWeight(10000); +} + +function AIFollowPath::monitor(%task, %client) +{ + //messageall(0, " AITraining1Pilot::monitor "@%task.locationIndex); + %group = nameToId(FlightPath); + if(!%task.locationIndex) + %task.locationIndex = 0; + + //HACK ALERT!!! + //since the path for this mission is completely straight, always head for the end of the path + //%location = %group.getObject(%task.locationIndex); + %location = %group.getObject(%group.getCount() - 1); + + //see if we've mounted yet + if(%client.vehicleMounted) + { + %client.setPilotDestination(%location.position); + + //else see if we're close enough to the current destination to choose the next + %pos = %client.vehicleMounted.position; + %pos2D = getWord(%pos, 0) SPC getWord(%pos, 1) SPC "0"; + %dest = %group.getObject(%task.locationIndex).position; + %dest2D = getWord(%dest, 0) SPC getWord(%dest, 1) SPC "0"; + + if (VectorDist(%dest2D, %pos2D) < 20) + { + if(%group.getCount() > %task.locationIndex + 1) { + %task.locationIndex++; + cinematicEvent(%task.locationIndex); + } + //else messageAll(0, "Ride Over"); + } + } + else + %client.stepMove($player.flyer.position, 0.25, $AIModeExpress); +} + +function PlayGui::onWake(%this) +{ + parent::onWake(%this); + //error("Waking training play gui"); + // okay we know the victim...erm...player is looking + // and we hope they have a body so lets do this + if(!game.playedIntro) { + game.PlayGuiAwake = true; + beginHotZone(); + } + +} + +function aiSetLoadout(%client) +{ +%client.player.clearInventory(); +%client.player.setArmor("heavy"); +%client.player.setInventory("Chaingun",1,true); +%client.player.setInventory("ChaingunAmmo",999,true); +%client.player.setInventory("Disc",1,true); +%client.player.setInventory("Discammo",999,true); +%client.player.setInventory("Shocklance",1,true); +%client.player.setInventory("MissileLauncher",1,true); +%client.player.setInventory("MissileLauncherAmmo",999,true); +%client.player.setInventory("Mortar",1,true); +%client.player.setInventory("MortarAmmo",999,true); +%client.player.setInventory("AmmoPack",1,true); +%client.player.use("Mortar"); +} + +function beginHotZone() //Don't let the game reset itself a bunch of times +{ +if (Game.playedIntro) +return; +%spawn = nameToId(); + +$player.flyer = new FlyingVehicle(Flyer) { + position = %spawn.position; + rotation = %spawn.rotation; + scale = "1 1 1"; + dataBlock = "HAPCFlyer"; + }; + +%pilot = $teammate0; +game.playedIntro = true; +$player.flyer.pilot = $teammate0; +setTargetSkin(%pilot.target, $teamSkin[$playerTeam]); +%pilot.player.setArmor(light); +%pilot.pilotVehicle = false; +$player.flyer.mountObject(%pilot.player, 0); +%pilot.setControlObject($player.flyer); +%pilot.setPilotPitchRange(-0.2, 0.05, 0.05); +%pilot.addTask(AIFollowPath); + +$player.flyer.mountObject($player.player, 1); +$player.flyer.mountObject($teammate1.player, 2); +$player.flyer.mountObject($teammate2.player, 3); +$player.flyer.mountObject($teammate3.player, 4); +$player.flyer.mountObject($teammate4.player, 5); +aiSetLoadout($teammate1); +aiSetLoadout($teammate2); +aiSetLoadout($teammate3); +aiSetLoadout($teammate4); +$player.player.setTransform($player.player.position SPC %spawn.rotation); +$HotZoneBlackout = ServerConnection.schedule(3000, setBlackOut, false, 4000); + +//Has to be added after all the bots.. otherwise they die by lava somehow +new WaterBlock(Lava) { +position = "-224 -264 93.1568"; +rotation = "1 0 0 0"; +scale = "768 608 27.0092"; +liquidType = "Lava"; +density = "1"; +viscosity = "15"; +waveMagnitude = "1"; +surfaceTexture = "LiquidTiles/Lava"; +surfaceOpacity = "1"; +envMapTexture = "lava/skies/lava_starrynite_emap"; +envMapIntensity = "0.2"; +submergeTexture[0] = "special/lavadeath_1"; +submergeTexture[1] = "special/lavadeath_2"; +removeWetEdges = "1"; + +locked = "true"; +}; + +} + +function MP3Audio::play(%this) +{ + //too bad...no mp3 in training +} + +function toggleCommanderMap(%val) +{ + if ( %val ) + messageClient($player, 0, $player.miscMsg[noCC]); +} + +function toggleTaskListDlg( %val ) +{ + if ( %val ) + messageClient( $player, 0, $player.miscMsg[noTaskListDlg] ); +} + +function toggleInventoryHud( %val ) +{ + if ( %val ) + messageClient( $player, 0, $player.miscMsg[noInventoryHUD] ); +} + +function toggleNetDisplayHud( %val ) +{ + // Hello, McFly? This is training! There's no net in training! +} + +function voiceCapture( %val ) +{ + // Uh, who do you think you are talking to? +} + +function giveall() +{ + error("When the going gets tough...wussies like you start cheating!"); + messageClient($player, 0, "Cheating eh? What\'s next? Camping?"); +} + +// get the ball rolling +//------------------------------------------------------------------------------ +function startCurrentMission() +{ + playGui.add(outerChatHud); + + //fade up from black + ServerConnection.setBlackOut(true, 0); +} + +//------------------------------------------------------------------------------ +function SinglePlayerGame::equip(%game, %player) +{ + //ya start with nothing...NOTHING! + %player.clearInventory(); + for(%i =0; %i<$InventoryHudCount; %i++) + %player.client.setInventoryHudItem($InventoryHudData[%i, itemDataName], 0, 1); + %player.client.clearBackpackIcon(); + + %set = %player.client.equipment; + + echo("using default equipment"); + + %player.setArmor("Light"); + %player.setInventory(RepairKit,1); + %player.setInventory(Chaingun, 1); + %player.setInventory(ChaingunAmmo, 100); + %player.setInventory(Disc,1); + %player.setInventory(DiscAmmo, 20); + %player.setInventory(Shocklance, 1); + %player.setInventory(AmmoPack, 1); + + //DefaultGame.cs does not assign flamer.. + %player.setInventory(flamer, 1); + %player.weaponCount = 4; + + %player.use(Chaingun); +} + +function spawnSinglePlayer() +{ + resetWildCat(); + parent::spawnSinglePlayer(); +} + +function singlePlayerGame::onAIRespawn(%game, %client) +{ + // DONT add the default tasks + //error("default tasks not added"); +} + +function singlePlayerGame::playerSpawned(%game, %player) +{ + parent::playerSpawned(%game, %player); +} + +function singlePlayerGame::gameOver(%game) +{ + //enable the voice chat menu again... + if (isObject(training1BlockMap)) + { + training1BlockMap.pop(); + training1BlockMap.delete(); + } + + if(HelpTextGui.isVisible()) + helpTextGui.setVisible(false); + + //re-enable the use of the settings button... + SinglePlayerEscSettingsBtn.setActive(1); + + Parent::gameOver(); +} + +function trainingPreloads() //Load any skins.. +{ + navGraph.preload("skins/Gecko.lbioderm", true); + navGraph.preload("skins/Gecko.mbioderm", true); + navGraph.preload("skins/Gecko.hbioderm", true); + navGraph.preload("skins/base.lbioderm", true); + navGraph.preload("skins/HALO_Skin.lbioderm", true); + navGraph.preload("skins/HALO_Skin.mbioderm", true); + navGraph.preload("skins/HALO_Skin.hbioderm", true); + navGraph.preload("skins/sensor_pulse_large", true); + navGraph.preload("skins/base.hmale", false); + navGraph.preload("skins/beagle.hmale", false); + navGraph.preload("skins/base.mmale", false); + navGraph.preload("skins/beagle.mmale", false); + navGraph.preload("skins/base.lmale", false); + navGraph.preload("skins/swolf.mmale", false); + navGraph.preload("skins/beagle.lmale", false); +} + +function SinglePlayerGame::missionLoadDone(%game) +{ + Parent::missionLoadDone(%game); + trainingPreloads(); +} + +function serverCmdBuildClientTask(%client, %task, %team) +{ + // player shouldnt be able to use the voice commands to do anything +} +}; + +package vehicleHack +{ +function AIConnection::isMountingVehicle(%client){ return true; } +}; +activatePackage(vehicleHack); + +function setActionThread(%player,%anim,%bool) +{ +%player.setActionThread(%anim,%bool); +} + + + diff --git a/missions/Hotzone.mis b/missions/Hotzone.mis index 462ac7b..f76225f 100644 --- a/missions/Hotzone.mis +++ b/missions/Hotzone.mis @@ -1,1928 +1,1928 @@ -// HotZone (Mission 1) -// MissionTypes = DM -// DisplayName = Hotzone - -//--- MISSION BRIEFING BEGIN --- -//Not working. -//--- MISSION BRIEFING END --- - -// BriefingWAV = T2BOL_1 -// Bitmap = trn_5draconis - -//--- MISSION STRING BEGIN --- -//OBJECTIVES: -//Bleck -//--- MISSION STRING END --- - -// PlanetName = Xeron, 3960 CE -//--- MISSION BLURB BEGIN --- -//You are aboard the Draakan Dropship USS Cerebus heading to drop off soldiers at the hotzone. You are having a quick training session before you land. -//--- MISSION BLURB END --- - -//--- OBJECT WRITE BEGIN --- -new SimGroup(MissionGroup) { - - cdTrack = "6"; - powerCount = "0"; - musicTrack = "desert"; - - new MissionArea(MissionArea) { - area = "-1024 -1024 2048 2048"; - flightCeiling = "4000"; - flightCeilingRange = "20"; - - locked = "true"; - }; - new SimGroup(Teams) { - - powerCount = "0"; - - new SimGroup(Team1) { - - powerCount = "0"; - }; - new SimGroup(team0) { - - powerCount = "0"; - }; - new Sun(Sun) { - position = "0 0 0"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - direction = "0.57735 0.57735 -0.57735"; - color = "1.000000 1.000000 1.000000 1.000000"; - ambient = "0.500000 0.500000 0.500000 1.000000"; - texture[0] = "special/sunFlare"; - texture[1] = "special/sunFlare02"; - texture[2] = "special/LensFlare/flare01"; - texture[3] = "special/LensFlare/flare02"; - texture[4] = "special/LensFlare/flare03"; - lensFlareScale = "0.7"; - lensFlareIntensity = "1"; - frontFlareSize = "300"; - backFlareSize = "450"; - flareColor = "1.000000 1.000000 1.000000 1.000000"; - - locked = "true"; - }; - new TerrainBlock(Terrain) { - rotation = "1 0 0 0"; - scale = "1 1 1"; - detailTexture = "details/lavadet1"; - terrainFile = "Training.ter"; - squareSize = "8"; - emptySquares = "217661 217676 86852 152390 87108 152646 218429 218444 232883 233139 364467 299189 364981 299702 234423"; - - position = "-1024 -1024 0"; - }; - new Sky(Sky) { - position = "692 -352 0"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - cloudHeightPer[0] = "0.349971"; - cloudHeightPer[1] = "0.25"; - cloudHeightPer[2] = "0.199973"; - cloudSpeed1 = "0.0001"; - cloudSpeed2 = "0.0002"; - cloudSpeed3 = "0.0003"; - visibleDistance = "550"; - useSkyTextures = "1"; - renderBottomTexture = "0"; - SkySolidColor = "0.300000 0.100000 0.000000 0.800000"; - fogDistance = "250"; - fogColor = "0.300000 0.100000 0.000000 0.800000"; - fogVolume1 = "100 0 85"; - fogVolume2 = "600 85 270"; - fogVolume3 = "0 0 0"; - materialList = "sky_lava_starrynight.dml"; - windVelocity = "1 0 0"; - windEffectPrecipitation = "0"; - fogVolumeColor1 = "128.000000 128.000000 128.000000 0.000000"; - fogVolumeColor2 = "128.000000 128.000000 128.000000 0.000000"; - fogVolumeColor3 = "128.000000 128.000000 128.000000 0.000000"; - high_visibleDistance = "-1"; - high_fogDistance = "-1"; - high_fogVolume1 = "-1 5.98911e+07 1.03256e-38"; - high_fogVolume2 = "-1 4.39735e+21 1.1119e-16"; - high_fogVolume3 = "-1 6.71258e+22 1.21749e+22"; - - locked = "true"; - }; - new NavigationGraph(NavGraph) { - conjoinAngleDev = "50"; - cullDensity = "0.3"; - customArea = "0 0 0 0"; - - coverage = "0"; - position = "0 0 0 1"; - conjoinBowlDev = "20"; - rotation = "0 0 0 0"; - locked = "true"; - scale = "1 1 1"; - GraphFile = "Training.nav"; - }; - new SimGroup(team2) { - - powerCount = "0"; - - new SimGroup(base0) { - - powerCount = "0"; - - new InteriorInstance(CriollosBase) { - position = "-463.118 -366.83 17.0706"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "dbase2.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "1"; - }; - new InteriorInstance() { - position = "-481.857 -249.119 101.34"; - rotation = "0 0 1 179.909"; - scale = "1 1 1"; - interiorFile = "dmisc1.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "1"; - }; - new InteriorInstance() { - position = "-256.927 -389.808 83.3756"; - rotation = "-0 0 -1 52.3217"; - scale = "1 1 1"; - interiorFile = "dmisc1.dif"; - showTerrainInside = "0"; - - team = "0"; - locked = "1"; - }; - }; - }; - }; - new SimGroup(RandomOrganics) { - - powerCount = "0"; - - new SimGroup(Addition1DSPlant16) { - - powerCount = "0"; - - new TSStatic() { - position = "-348 -196 106.781"; - rotation = "0 0 1 167"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-636 -532 150.656"; - rotation = "0 0 1 230"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-428 -260 111.188"; - rotation = "0 0 1 114"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-412 -164 111.656"; - rotation = "0 0 -1 119"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-364 -164 103.953"; - rotation = "0 0 1 120"; - scale = "1 1 1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-292 -188 128.547"; - rotation = "0 0 1 184"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-492 -548 122.672"; - rotation = "0 0 -1 75.0002"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-276 -468 111.969"; - rotation = "0 0 -1 58.0005"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-500 -556 123.344"; - rotation = "0 0 1 61"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-604 -292 115.953"; - rotation = "0 0 1 52"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-636 -188 157.312"; - rotation = "0 0 1 103"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-316 -260 122.5"; - rotation = "0 0 1 58.9998"; - scale = "1 1 1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-572 -284 131.266"; - rotation = "0 0 -1 55.0003"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-636 -492 158.203"; - rotation = "0 0 1 3.99996"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-636 -540 152.703"; - rotation = "0 0 1 219"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-444 -540 129.828"; - rotation = "0 0 -1 19.0001"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-588 -556 106.531"; - rotation = "0 0 -1 92.0004"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-292 -188 128.547"; - rotation = "0 0 1 202"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-620 -252 148.969"; - rotation = "0 0 1 38"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-276 -180 125.922"; - rotation = "0 0 1 43"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-660 -236 138.141"; - rotation = "0 0 1 224"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-556 -196 130.344"; - rotation = "0 0 -1 78.0002"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-564 -228 136.031"; - rotation = "0 0 1 228"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-356 -204 105.172"; - rotation = "0 0 1 19"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-444 -476 96.5469"; - rotation = "0 0 1 206"; - scale = "1 1 1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-380 -188 101.297"; - rotation = "0 0 1 48"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-276 -420 95.9688"; - rotation = "0 0 1 15"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-292 -540 126.203"; - rotation = "0 0 -1 112"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-428 -260 111.188"; - rotation = "0 0 -1 13.0002"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-580 -556 104.781"; - rotation = "0 0 1 147"; - scale = "1 1 1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-508 -548 122.984"; - rotation = "0 0 1 60.0001"; - scale = "1 1 1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-276 -188 124.547"; - rotation = "0 0 1 76.9998"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-284 -484 110.828"; - rotation = "0 0 -1 35"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-412 -172 113.031"; - rotation = "0 0 -1 16.9999"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-412 -172 113.031"; - rotation = "0 0 -1 50.9998"; - scale = "1 1 1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-436 -244 112.297"; - rotation = "0 0 1 78.0002"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-644 -228 141.891"; - rotation = "0 0 1 97.9998"; - scale = "1 1 1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-524 -164 147.094"; - rotation = "0 0 1 142"; - scale = "1 1 1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-292 -492 109.156"; - rotation = "0 0 1 53"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-620 -228 151.547"; - rotation = "0 0 -1 92.0004"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg16.dts"; - }; - }; - new SimGroup(Addition2DSPlant17) { - - powerCount = "0"; - - new TSStatic() { - position = "-500 -548 123.25"; - rotation = "-0.0619038 0.012427 0.998005 146.064"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "-564 -236 137.688"; - rotation = "0.101053 0.144122 0.984387 70.8497"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "-444 -548 127.344"; - rotation = "-0.830265 -0.530269 0.17168 17.3446"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "-492 -524 123.797"; - rotation = "0.477358 -0.532224 -0.69919 26.9199"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "-636 -500 157.062"; - rotation = "-0.749737 0.399268 -0.527712 16.9644"; - scale = "1 1 1"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "-412 -164 111.656"; - rotation = "0.0543937 0.0547673 -0.997016 88.1707"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "-316 -412 79.5"; - rotation = "0.00755817 -0.103259 0.994626 63.2758"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "-444 -196 126.422"; - rotation = "0.175219 -0.324668 -0.929456 39.597"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg17.dts"; - }; - }; - new SimGroup(Addition3DSPlant17) { - - powerCount = "0"; - - new TSStatic() { - position = "12 -412 104.844"; - rotation = "-0.0503551 -0.018623 0.998558 143.05"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "-20 -412 106.25"; - rotation = "0.0761431 -0.110215 -0.990987 88.5186"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "-12 -468 142.812"; - rotation = "0.137513 0.111945 0.984154 97.9076"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "-84 -452 145.703"; - rotation = "0.0935228 0.120898 0.98825 234.447"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "-68 -492 131.578"; - rotation = "-0.0355517 -0.0468571 0.998269 78.0976"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "-12 -412 106.219"; - rotation = "0.0821308 -0.000199039 0.996622 84.1933"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "-4 -412 105.5"; - rotation = "0.0670501 -0.0130461 0.997664 88.134"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "-68 -492 131.578"; - rotation = "-0.495608 -0.154473 0.854699 8.18628"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "-68 -476 133.109"; - rotation = "-0.00379916 0.163641 -0.986513 80.767"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "-76 -484 132.672"; - rotation = "0.108004 0.0352753 0.993524 194.904"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg17.dts"; - }; - }; - new SimGroup(Addition4DSPlant19) { - - powerCount = "0"; - - new TSStatic() { - position = "172 -332 146.234"; - rotation = "0 0 1 16"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "172 -348 148.938"; - rotation = "0 0 -1 73.0006"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "172 -348 148.938"; - rotation = "0 0 1 69.0002"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "140 -452 147.734"; - rotation = "0 0 1 111"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "-4 -412 105.5"; - rotation = "0 0 1 70.9998"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "212 -332 153.156"; - rotation = "0 0 1 104"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "84 -308 164.703"; - rotation = "0 0 1 3.99996"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "204 -380 156.266"; - rotation = "0 0 1 17"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "196 -372 157.594"; - rotation = "0 0 -1 11.9998"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "-12 -476 143.562"; - rotation = "0 0 -1 37.0002"; - scale = "1 1 1"; - shapeName = "dorg19.dts"; - }; - }; - new SimGroup(Addition5DSPlant19) { - - powerCount = "0"; - - new TSStatic() { - position = "-364 28 166"; - rotation = "0 0 -1 60.0001"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "-420 -100 94.5312"; - rotation = "0 0 1 113"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "-292 -172 129.5"; - rotation = "0 0 1 138"; - scale = "1 1 1"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "-204 196 132.141"; - rotation = "0 0 -1 50.9998"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "-364 -172 103.875"; - rotation = "0 0 1 39"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg19.dts"; - }; - }; - new SimGroup(Addition6DSPlant16) { - - powerCount = "0"; - - new TSStatic() { - position = "-524 -212 146.031"; - rotation = "0 0 1 38"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "-500 -76 105.25"; - rotation = "0 0 1 126"; - scale = "1 1 1"; - shapeName = "dorg16.dts"; - }; - }; - new SimGroup(Addition11DSPlant16) { - - powerCount = "0"; - - new TSStatic() { - position = "892 476 173.172"; - rotation = "0 0 1 209"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "964 356 99.141"; - rotation = "0 0 -1 97"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "948 812 136.375"; - rotation = "0 0 -1 94"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "964 156 94.0313"; - rotation = "0 0 1 97"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "1148 572 136.016"; - rotation = "0 0 1 118"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "812 420 116.266"; - rotation = "0 0 1 141"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "548 900 161.422"; - rotation = "0 0 -1 50.9998"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "756 612 151.969"; - rotation = "0 0 1 233"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "1140 788 162.828"; - rotation = "0 0 -1 73.0006"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "1028 484 164"; - rotation = "0 0 1 234"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "1044 484 161.5"; - rotation = "0 0 -1 2.9997"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "812 268 89.9687"; - rotation = "0 0 1 238"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "956 812 136.484"; - rotation = "0 0 1 35"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "476 364 194.453"; - rotation = "0 0 1 177"; - scale = "1 1 1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "604 916 149.047"; - rotation = "0 0 -1 4.00015"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "812 748 130.172"; - rotation = "0 0 1 24"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "732 212 76.3593"; - rotation = "0 0 1 51"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "1100 508 149.781"; - rotation = "0 0 -1 29.9998"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "676 764 169.812"; - rotation = "0 0 -1 80.0004"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "1092 876 185.672"; - rotation = "0 0 1 217"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "428 548 211.094"; - rotation = "0 0 1 121"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "932 524 173.125"; - rotation = "0 0 -1 71.0004"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "996 180 97.219"; - rotation = "0 0 1 44"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "636 892 140.578"; - rotation = "0 0 1 54"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "708 252 95.1562"; - rotation = "0 0 1 66.0002"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "420 676 178.266"; - rotation = "0 0 -1 29"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "956 868 153.906"; - rotation = "0 0 1 67.9998"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "908 524 173"; - rotation = "0 0 1 205"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "868 156 94.3594"; - rotation = "0 0 1 117"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "460 516 183.859"; - rotation = "0 0 1 230"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "604 916 149.047"; - rotation = "0 0 -1 119"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "1012 804 150.625"; - rotation = "0 0 -1 37.0002"; - scale = "1 1 1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "980 756 116.422"; - rotation = "0 0 1 28"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "788 668 117.719"; - rotation = "0 0 1 17"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "1012 348 117.969"; - rotation = "0 0 1 217"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "964 700 155.375"; - rotation = "0 0 -1 61.0005"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "756 252 86.9531"; - rotation = "0 0 -1 77.0004"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "1148 380 70.6719"; - rotation = "0 0 1 22"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "428 644 178.656"; - rotation = "0 0 1 161"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "1180 644 160.187"; - rotation = "0 0 1 215"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "908 300 68.1719"; - rotation = "0 0 -1 58.0005"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "924 524 173.031"; - rotation = "0 0 1 69.0002"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "692 364 123.922"; - rotation = "0 0 -1 53.9998"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "1156 796 167.719"; - rotation = "0 0 -1 92.0004"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "524 788 196.734"; - rotation = "0 0 1 141"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg16.dts"; - }; - }; - new SimGroup(Addition12DSPlant17) { - - powerCount = "0"; - - new TSStatic() { - position = "596 604 155.219"; - rotation = "-0.252214 0.0568745 0.965999 52.557"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "676 780 168.969"; - rotation = "0.0644755 0.0918072 -0.993687 79.3563"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "1180 428 100.875"; - rotation = "-0.13555 -0.0513793 0.989437 205.735"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "796 884 150.734"; - rotation = "0.214537 0.335293 -0.917362 31.4878"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "1052 516 172.5"; - rotation = "0.0326082 -0.0612456 0.99759 96.1377"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "700 444 95.7187"; - rotation = "0.0236739 -0.00272442 0.999716 130.013"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "444 364 181.766"; - rotation = "0.182467 -0.00253999 -0.983209 95.9659"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "748 388 124.922"; - rotation = "0.145242 0.0220224 0.989151 227.537"; - scale = "1 1 1"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "684 508 115.016"; - rotation = "0.107873 -0.0904691 0.99004 144.336"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "1012 812 150.656"; - rotation = "-0.436177 -0.113977 -0.892614 22.3487"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "764 268 90.5625"; - rotation = "-0.151402 -0.00972159 0.988424 127.531"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "972 220 99.687"; - rotation = "-0.0666638 0.167378 0.983636 83.9389"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "948 908 112.328"; - rotation = "-0.0115508 -0.143244 0.98962 84.5949"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "1164 772 170.828"; - rotation = "-0.0696701 0.0635217 0.995546 107.245"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "1140 788 162.828"; - rotation = "-0.138555 0.0419806 0.989465 124.501"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "668 484 117.547"; - rotation = "-0.112626 -0.107037 0.987855 147.379"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "1068 468 173.547"; - rotation = "-0.0739407 0.066415 0.995049 182.985"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "572 548 163.734"; - rotation = "0.0235022 -0.0760124 0.99683 188.971"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "932 748 132.016"; - rotation = "0.0157534 0.0466812 -0.998786 97.0689"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "556 636 146.938"; - rotation = "0.00172912 -0.183868 0.982949 61.8651"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "700 380 127.609"; - rotation = "-0.575477 -0.32338 0.751166 26.4206"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "388 844 163.953"; - rotation = "0.0485287 0.0029749 0.998817 109.064"; - scale = "1 1 1"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "812 748 130.172"; - rotation = "-0.121092 0.110974 -0.986418 41.5167"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "932 628 129.078"; - rotation = "0.0144005 -0.0381498 0.999168 167.011"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "964 708 155.375"; - rotation = "-0.0136492 0.313518 -0.949484 37.7824"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "580 604 156.922"; - rotation = "-0.450827 -0.23556 -0.860969 37.971"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "668 484 117.547"; - rotation = "-0.121311 -0.101946 0.987366 140.466"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "764 492 156.484"; - rotation = "0.117335 -0.0381243 0.99236 54.3563"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "588 924 147.562"; - rotation = "0.204729 0.174863 -0.963073 58.8262"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "436 724 168.313"; - rotation = "0.0454692 0.134065 0.989929 209.711"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "908 756 125.5"; - rotation = "0.0625492 -0.146797 0.987187 145.422"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "980 820 135.922"; - rotation = "0.127602 -0.10248 0.986517 223.463"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "748 268 88.3906"; - rotation = "-0.0133015 -0.0530759 0.998502 115.078"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "428 644 178.656"; - rotation = "-0.100363 0.105261 0.989367 146.341"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "1044 468 164.875"; - rotation = "0.0348411 0.150912 -0.987933 116.624"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "1180 572 127.766"; - rotation = "-0.0265204 -0.163439 -0.986197 116.714"; - scale = "1 1 1"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "980 812 135.953"; - rotation = "0.0360907 0.0983098 0.994501 179.006"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "756 228 77.6875"; - rotation = "-0.0980146 0.223292 -0.969811 77.7097"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "1124 772 160.703"; - rotation = "-0.0907992 -0.261222 0.960999 65.0491"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "628 884 140.391"; - rotation = "-0.894358 -0.309023 0.323463 12.3235"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "692 140 113.016"; - rotation = "0.0792873 -0.0294701 0.996416 157.08"; - scale = "1 1 1"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "916 220 72.7969"; - rotation = "0.00019495 0.0903265 0.995912 109.222"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "804 700 108.672"; - rotation = "0.583341 0.0169456 0.81205 28.1309"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "1044 252 125.531"; - rotation = "0.00811237 -0.0415602 0.999103 139.034"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "556 900 159.969"; - rotation = "0.137374 -0.210933 0.967799 61.6371"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "908 228 72.875"; - rotation = "-0.0695661 0.115309 -0.990891 115.474"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg17.dts"; - }; - }; - new SimGroup(Addition13DSPlant18) { - - powerCount = "0"; - - new TSStatic() { - position = "972 156 95.4218"; - rotation = "0 0 -1 74.0004"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "1116 868 181.031"; - rotation = "0 0 1 58.9998"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "428 372 177.891"; - rotation = "0 0 1 79"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "676 388 126.625"; - rotation = "0 0 -1 58.0005"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "828 764 134.531"; - rotation = "0 0 -1 82"; - scale = "1 1 1"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "924 508 173.453"; - rotation = "0 0 -1 14.9998"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "1100 812 157.953"; - rotation = "0 0 1 1.9999"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "404 388 158.766"; - rotation = "0 0 1 205"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "556 884 168.078"; - rotation = "0 0 1 99.0002"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "484 484 178.281"; - rotation = "0 0 -1 81.0002"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "1116 676 142.453"; - rotation = "0 0 1 221"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "676 836 154.063"; - rotation = "0 0 -1 107"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "452 492 179"; - rotation = "0 0 -1 90.0002"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "1068 860 172.672"; - rotation = "0 0 -1 104"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "684 268 90.8593"; - rotation = "0 0 1 160"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "788 308 109.531"; - rotation = "0 0 1 39"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "1012 804 150.625"; - rotation = "0 0 -1 115"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "980 204 104.016"; - rotation = "0 0 1 44"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "924 244 77.6875"; - rotation = "0 0 1 122"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "1020 652 182.672"; - rotation = "0 0 1 18"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "620 204 143.344"; - rotation = "0 0 1 12"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "924 516 173.063"; - rotation = "0 0 1 214"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "492 308 158.859"; - rotation = "0 0 1 143"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "1084 652 152.109"; - rotation = "0 0 1 28"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "620 212 144.453"; - rotation = "0 0 1 156"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "1108 524 155.203"; - rotation = "0 0 1 28"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "844 452 125.641"; - rotation = "0 0 1 136"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "532 428 180.125"; - rotation = "0 0 -1 10.9999"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "684 388 127.75"; - rotation = "0 0 1 109"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "692 276 90.8124"; - rotation = "0 0 1 20"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "1068 820 175.313"; - rotation = "0 0 1 66.0002"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "860 156 94.125"; - rotation = "0 0 -1 107"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "540 428 178.094"; - rotation = "0 0 -1 100"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "940 708 139.703"; - rotation = "0 0 1 60.0001"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "924 252 78.1406"; - rotation = "0 0 1 165"; - scale = "1 1 1"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "772 260 90.8437"; - rotation = "0 0 -1 50.9998"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "692 156 112.984"; - rotation = "0 0 1 148"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "1100 860 183.859"; - rotation = "0 0 1 49"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "1108 628 148.562"; - rotation = "0 0 1 94.9998"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "972 812 136.266"; - rotation = "0 0 1 229"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "972 220 99.687"; - rotation = "0 0 1 222"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "1036 756 151.047"; - rotation = "0 0 1 29"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "596 772 152.672"; - rotation = "0 0 1 235"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "836 452 126.141"; - rotation = "0 0 1 64"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "436 732 167.469"; - rotation = "0 0 1 7.99996"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "988 284 116.016"; - rotation = "0 0 1 57.9999"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "500 756 195.719"; - rotation = "0 0 1 172"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "644 492 118.75"; - rotation = "0 0 1 20"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg18.dts"; - }; - }; - new SimGroup(Addition14DSPlant19) { - - powerCount = "0"; - - new TSStatic() { - position = "756 212 76.8125"; - rotation = "0 0 1 208"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "676 764 169.812"; - rotation = "0 0 -1 110"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "1108 748 157.578"; - rotation = "0 0 1 140"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "572 564 167.922"; - rotation = "0 0 -1 97"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "828 452 126.687"; - rotation = "0 0 1 185"; - scale = "1 1 1"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "460 900 128.109"; - rotation = "0 0 1 51"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "892 876 171.438"; - rotation = "0 0 -1 44"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "1180 860 197.953"; - rotation = "0 0 1 236"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "1100 524 154.406"; - rotation = "0 0 1 236"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "604 164 171.953"; - rotation = "0 0 -1 93.0002"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "780 308 112.078"; - rotation = "0 0 -1 76"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "812 276 91.4532"; - rotation = "0 0 1 49"; - scale = "1 1 1"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "740 892 162.078"; - rotation = "0 0 1 90.0002"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "1028 484 164"; - rotation = "0 0 -1 95.0004"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "452 604 159.688"; - rotation = "0 0 1 153"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "676 876 157.391"; - rotation = "0 0 -1 5.99979"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "572 804 158.656"; - rotation = "0 0 1 204"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "804 692 111.109"; - rotation = "0 0 1 239"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "556 540 157.937"; - rotation = "0 0 -1 112"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "1124 868 180.422"; - rotation = "0 0 -1 38.9999"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "748 276 89.7344"; - rotation = "0 0 1 198"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "844 236 116.266"; - rotation = "0 0 1 169"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "668 532 112.703"; - rotation = "0 0 1 87.0002"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "1124 772 160.703"; - rotation = "0 0 -1 46.0002"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "572 716 204.594"; - rotation = "0 0 -1 32.9998"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "820 460 127.109"; - rotation = "0 0 1 150"; - scale = "1 1 1"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "980 220 100.625"; - rotation = "0 0 1 24"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "772 708 109.203"; - rotation = "0 0 -1 53.9998"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "388 812 156.672"; - rotation = "0 0 -1 23.9998"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "588 932 148.109"; - rotation = "0 0 -1 4.00015"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "956 588 160.734"; - rotation = "0 0 1 152"; - scale = "1.4 1.4 1.4"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "908 436 151.469"; - rotation = "0 0 1 101"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "1004 316 118.219"; - rotation = "0 0 -1 26"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "540 420 178.047"; - rotation = "0 0 -1 32"; - scale = "1.3 1.3 1.3"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "564 212 171.297"; - rotation = "0 0 -1 65.0004"; - scale = "1 1 1"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "596 700 209.375"; - rotation = "0 0 1 1.9999"; - scale = "1.5 1.5 1.5"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "580 932 147"; - rotation = "0 0 1 235"; - scale = "1.2 1.2 1.2"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "572 804 158.656"; - rotation = "0 0 1 128"; - scale = "1 1 1"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "812 900 150.344"; - rotation = "0 0 1 119"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "828 428 120.375"; - rotation = "0 0 1 162"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "604 852 130.406"; - rotation = "0 0 1 224"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "1172 860 197.391"; - rotation = "0 0 1 150"; - scale = "0.8 0.8 0.8"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "668 516 115.172"; - rotation = "0 0 1 67"; - scale = "1.1 1.1 1.1"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "428 380 178.078"; - rotation = "0 0 -1 72.0002"; - scale = "0.9 0.9 0.9"; - shapeName = "dorg19.dts"; - }; - }; - }; - new SimGroup(environment) { - - powerCount = "0"; - - new AudioEmitter(Outside1) { - position = "266.262 824.24 137.226"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - fileName = "fx/environment/lavamellow1.wav"; - useProfileDescription = "0"; - outsideAmbient = "1"; - volume = "0.4"; - isLooping = "1"; - is3D = "0"; - minDistance = "20"; - maxDistance = "1280"; - coneInsideAngle = "360"; - coneOutsideAngle = "360"; - coneOutsideVolume = "1"; - coneVector = "0 0 1"; - loopCount = "-1"; - minLoopGap = "0"; - maxLoopGap = "0"; - type = "EffectAudioType"; - - locked = "1"; - }; - new AudioEmitter(Outside2) { - position = "266.262 824.24 137.226"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - fileName = "fx/environment/gravel3.wav"; - useProfileDescription = "0"; - outsideAmbient = "1"; - volume = "0.1"; - isLooping = "1"; - is3D = "0"; - minDistance = "20"; - maxDistance = "1280"; - coneInsideAngle = "360"; - coneOutsideAngle = "360"; - coneOutsideVolume = "1"; - coneVector = "0 0 1"; - loopCount = "-1"; - minLoopGap = "4000"; - maxLoopGap = "15000"; - type = "EffectAudioType"; - - locked = "1"; - }; - }; - new SimGroup(FlightPath) { - - powerCount = "0"; - - new Camera(1) { - position = "269.562 -741.61 246.951"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - - team = "1"; - }; - new Camera(2) { - position = "269.562 -641.61 246.951"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - - team = "1"; - }; - new Camera(3) { - position = "269.562 -541.61 246.951"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - - team = "1"; - }; - new Camera(4) { - position = "269.562 -441.61 246.951"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - - team = "1"; - }; - new Camera(5) { - position = "269.562 341.61 246.951"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - - team = "1"; - }; - new Camera(6) { - position = "269.562 -341.61 246.951"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - - team = "1"; - }; - new Camera(7) { - position = "269.562 -241.61 246.951"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - - team = "1"; - }; - new Camera(8) { - position = "269.562 -141.61 246.951"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - - team = "1"; - }; - }; - new Camera(introFlyerSP) { - position = "269.562 -841.61 246.951"; - rotation = "0.00124964 0.000196249 -0.999999 17.8502"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - - team = "1"; - }; - new Camera(OutPostWP) { - position = "-463.403 -369.998 111.882"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - - team = "1"; - locked = "1"; - }; -}; -//--- OBJECT WRITE END --- - -//exec("scripts/HotZone.cs"); +// HotZone (Mission 1) +// MissionTypes = DM +// DisplayName = Hotzone + +//--- MISSION BRIEFING BEGIN --- +//Not working. +//--- MISSION BRIEFING END --- + +// BriefingWAV = T2BOL_1 +// Bitmap = trn_5draconis + +//--- MISSION STRING BEGIN --- +//OBJECTIVES: +//Bleck +//--- MISSION STRING END --- + +// PlanetName = Xeron, 3960 CE +//--- MISSION BLURB BEGIN --- +//You are aboard the Draakan Dropship USS Cerebus heading to drop off soldiers at the hotzone. You are having a quick training session before you land. +//--- MISSION BLURB END --- + +//--- OBJECT WRITE BEGIN --- +new SimGroup(MissionGroup) { + + cdTrack = "6"; + powerCount = "0"; + musicTrack = "desert"; + + new MissionArea(MissionArea) { + area = "-1024 -1024 2048 2048"; + flightCeiling = "4000"; + flightCeilingRange = "20"; + + locked = "true"; + }; + new SimGroup(Teams) { + + powerCount = "0"; + + new SimGroup(Team1) { + + powerCount = "0"; + }; + new SimGroup(team0) { + + powerCount = "0"; + }; + new Sun(Sun) { + position = "0 0 0"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + direction = "0.57735 0.57735 -0.57735"; + color = "1.000000 1.000000 1.000000 1.000000"; + ambient = "0.500000 0.500000 0.500000 1.000000"; + texture[0] = "special/sunFlare"; + texture[1] = "special/sunFlare02"; + texture[2] = "special/LensFlare/flare01"; + texture[3] = "special/LensFlare/flare02"; + texture[4] = "special/LensFlare/flare03"; + lensFlareScale = "0.7"; + lensFlareIntensity = "1"; + frontFlareSize = "300"; + backFlareSize = "450"; + flareColor = "1.000000 1.000000 1.000000 1.000000"; + + locked = "true"; + }; + new TerrainBlock(Terrain) { + rotation = "1 0 0 0"; + scale = "1 1 1"; + detailTexture = "details/lavadet1"; + terrainFile = "Training.ter"; + squareSize = "8"; + emptySquares = "217661 217676 86852 152390 87108 152646 218429 218444 232883 233139 364467 299189 364981 299702 234423"; + + position = "-1024 -1024 0"; + }; + new Sky(Sky) { + position = "692 -352 0"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + cloudHeightPer[0] = "0.349971"; + cloudHeightPer[1] = "0.25"; + cloudHeightPer[2] = "0.199973"; + cloudSpeed1 = "0.0001"; + cloudSpeed2 = "0.0002"; + cloudSpeed3 = "0.0003"; + visibleDistance = "550"; + useSkyTextures = "1"; + renderBottomTexture = "0"; + SkySolidColor = "0.300000 0.100000 0.000000 0.800000"; + fogDistance = "250"; + fogColor = "0.300000 0.100000 0.000000 0.800000"; + fogVolume1 = "100 0 85"; + fogVolume2 = "600 85 270"; + fogVolume3 = "0 0 0"; + materialList = "sky_lava_starrynight.dml"; + windVelocity = "1 0 0"; + windEffectPrecipitation = "0"; + fogVolumeColor1 = "128.000000 128.000000 128.000000 0.000000"; + fogVolumeColor2 = "128.000000 128.000000 128.000000 0.000000"; + fogVolumeColor3 = "128.000000 128.000000 128.000000 0.000000"; + high_visibleDistance = "-1"; + high_fogDistance = "-1"; + high_fogVolume1 = "-1 5.98911e+07 1.03256e-38"; + high_fogVolume2 = "-1 4.39735e+21 1.1119e-16"; + high_fogVolume3 = "-1 6.71258e+22 1.21749e+22"; + + locked = "true"; + }; + new NavigationGraph(NavGraph) { + conjoinAngleDev = "50"; + cullDensity = "0.3"; + customArea = "0 0 0 0"; + + coverage = "0"; + position = "0 0 0 1"; + conjoinBowlDev = "20"; + rotation = "0 0 0 0"; + locked = "true"; + scale = "1 1 1"; + GraphFile = "Training.nav"; + }; + new SimGroup(team2) { + + powerCount = "0"; + + new SimGroup(base0) { + + powerCount = "0"; + + new InteriorInstance(CriollosBase) { + position = "-463.118 -366.83 17.0706"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "dbase2.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "1"; + }; + new InteriorInstance() { + position = "-481.857 -249.119 101.34"; + rotation = "0 0 1 179.909"; + scale = "1 1 1"; + interiorFile = "dmisc1.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "1"; + }; + new InteriorInstance() { + position = "-256.927 -389.808 83.3756"; + rotation = "-0 0 -1 52.3217"; + scale = "1 1 1"; + interiorFile = "dmisc1.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "1"; + }; + }; + }; + }; + new SimGroup(RandomOrganics) { + + powerCount = "0"; + + new SimGroup(Addition1DSPlant16) { + + powerCount = "0"; + + new TSStatic() { + position = "-348 -196 106.781"; + rotation = "0 0 1 167"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-636 -532 150.656"; + rotation = "0 0 1 230"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-428 -260 111.188"; + rotation = "0 0 1 114"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-412 -164 111.656"; + rotation = "0 0 -1 119"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-364 -164 103.953"; + rotation = "0 0 1 120"; + scale = "1 1 1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-292 -188 128.547"; + rotation = "0 0 1 184"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-492 -548 122.672"; + rotation = "0 0 -1 75.0002"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-276 -468 111.969"; + rotation = "0 0 -1 58.0005"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-500 -556 123.344"; + rotation = "0 0 1 61"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-604 -292 115.953"; + rotation = "0 0 1 52"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-636 -188 157.312"; + rotation = "0 0 1 103"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-316 -260 122.5"; + rotation = "0 0 1 58.9998"; + scale = "1 1 1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-572 -284 131.266"; + rotation = "0 0 -1 55.0003"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-636 -492 158.203"; + rotation = "0 0 1 3.99996"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-636 -540 152.703"; + rotation = "0 0 1 219"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-444 -540 129.828"; + rotation = "0 0 -1 19.0001"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-588 -556 106.531"; + rotation = "0 0 -1 92.0004"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-292 -188 128.547"; + rotation = "0 0 1 202"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-620 -252 148.969"; + rotation = "0 0 1 38"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-276 -180 125.922"; + rotation = "0 0 1 43"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-660 -236 138.141"; + rotation = "0 0 1 224"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-556 -196 130.344"; + rotation = "0 0 -1 78.0002"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-564 -228 136.031"; + rotation = "0 0 1 228"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-356 -204 105.172"; + rotation = "0 0 1 19"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-444 -476 96.5469"; + rotation = "0 0 1 206"; + scale = "1 1 1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-380 -188 101.297"; + rotation = "0 0 1 48"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-276 -420 95.9688"; + rotation = "0 0 1 15"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-292 -540 126.203"; + rotation = "0 0 -1 112"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-428 -260 111.188"; + rotation = "0 0 -1 13.0002"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-580 -556 104.781"; + rotation = "0 0 1 147"; + scale = "1 1 1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-508 -548 122.984"; + rotation = "0 0 1 60.0001"; + scale = "1 1 1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-276 -188 124.547"; + rotation = "0 0 1 76.9998"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-284 -484 110.828"; + rotation = "0 0 -1 35"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-412 -172 113.031"; + rotation = "0 0 -1 16.9999"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-412 -172 113.031"; + rotation = "0 0 -1 50.9998"; + scale = "1 1 1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-436 -244 112.297"; + rotation = "0 0 1 78.0002"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-644 -228 141.891"; + rotation = "0 0 1 97.9998"; + scale = "1 1 1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-524 -164 147.094"; + rotation = "0 0 1 142"; + scale = "1 1 1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-292 -492 109.156"; + rotation = "0 0 1 53"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-620 -228 151.547"; + rotation = "0 0 -1 92.0004"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg16.dts"; + }; + }; + new SimGroup(Addition2DSPlant17) { + + powerCount = "0"; + + new TSStatic() { + position = "-500 -548 123.25"; + rotation = "-0.0619038 0.012427 0.998005 146.064"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "-564 -236 137.688"; + rotation = "0.101053 0.144122 0.984387 70.8497"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "-444 -548 127.344"; + rotation = "-0.830265 -0.530269 0.17168 17.3446"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "-492 -524 123.797"; + rotation = "0.477358 -0.532224 -0.69919 26.9199"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "-636 -500 157.062"; + rotation = "-0.749737 0.399268 -0.527712 16.9644"; + scale = "1 1 1"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "-412 -164 111.656"; + rotation = "0.0543937 0.0547673 -0.997016 88.1707"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "-316 -412 79.5"; + rotation = "0.00755817 -0.103259 0.994626 63.2758"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "-444 -196 126.422"; + rotation = "0.175219 -0.324668 -0.929456 39.597"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg17.dts"; + }; + }; + new SimGroup(Addition3DSPlant17) { + + powerCount = "0"; + + new TSStatic() { + position = "12 -412 104.844"; + rotation = "-0.0503551 -0.018623 0.998558 143.05"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "-20 -412 106.25"; + rotation = "0.0761431 -0.110215 -0.990987 88.5186"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "-12 -468 142.812"; + rotation = "0.137513 0.111945 0.984154 97.9076"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "-84 -452 145.703"; + rotation = "0.0935228 0.120898 0.98825 234.447"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "-68 -492 131.578"; + rotation = "-0.0355517 -0.0468571 0.998269 78.0976"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "-12 -412 106.219"; + rotation = "0.0821308 -0.000199039 0.996622 84.1933"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "-4 -412 105.5"; + rotation = "0.0670501 -0.0130461 0.997664 88.134"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "-68 -492 131.578"; + rotation = "-0.495608 -0.154473 0.854699 8.18628"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "-68 -476 133.109"; + rotation = "-0.00379916 0.163641 -0.986513 80.767"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "-76 -484 132.672"; + rotation = "0.108004 0.0352753 0.993524 194.904"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg17.dts"; + }; + }; + new SimGroup(Addition4DSPlant19) { + + powerCount = "0"; + + new TSStatic() { + position = "172 -332 146.234"; + rotation = "0 0 1 16"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "172 -348 148.938"; + rotation = "0 0 -1 73.0006"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "172 -348 148.938"; + rotation = "0 0 1 69.0002"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "140 -452 147.734"; + rotation = "0 0 1 111"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "-4 -412 105.5"; + rotation = "0 0 1 70.9998"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "212 -332 153.156"; + rotation = "0 0 1 104"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "84 -308 164.703"; + rotation = "0 0 1 3.99996"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "204 -380 156.266"; + rotation = "0 0 1 17"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "196 -372 157.594"; + rotation = "0 0 -1 11.9998"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "-12 -476 143.562"; + rotation = "0 0 -1 37.0002"; + scale = "1 1 1"; + shapeName = "dorg19.dts"; + }; + }; + new SimGroup(Addition5DSPlant19) { + + powerCount = "0"; + + new TSStatic() { + position = "-364 28 166"; + rotation = "0 0 -1 60.0001"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "-420 -100 94.5312"; + rotation = "0 0 1 113"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "-292 -172 129.5"; + rotation = "0 0 1 138"; + scale = "1 1 1"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "-204 196 132.141"; + rotation = "0 0 -1 50.9998"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "-364 -172 103.875"; + rotation = "0 0 1 39"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg19.dts"; + }; + }; + new SimGroup(Addition6DSPlant16) { + + powerCount = "0"; + + new TSStatic() { + position = "-524 -212 146.031"; + rotation = "0 0 1 38"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "-500 -76 105.25"; + rotation = "0 0 1 126"; + scale = "1 1 1"; + shapeName = "dorg16.dts"; + }; + }; + new SimGroup(Addition11DSPlant16) { + + powerCount = "0"; + + new TSStatic() { + position = "892 476 173.172"; + rotation = "0 0 1 209"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "964 356 99.141"; + rotation = "0 0 -1 97"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "948 812 136.375"; + rotation = "0 0 -1 94"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "964 156 94.0313"; + rotation = "0 0 1 97"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "1148 572 136.016"; + rotation = "0 0 1 118"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "812 420 116.266"; + rotation = "0 0 1 141"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "548 900 161.422"; + rotation = "0 0 -1 50.9998"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "756 612 151.969"; + rotation = "0 0 1 233"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "1140 788 162.828"; + rotation = "0 0 -1 73.0006"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "1028 484 164"; + rotation = "0 0 1 234"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "1044 484 161.5"; + rotation = "0 0 -1 2.9997"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "812 268 89.9687"; + rotation = "0 0 1 238"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "956 812 136.484"; + rotation = "0 0 1 35"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "476 364 194.453"; + rotation = "0 0 1 177"; + scale = "1 1 1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "604 916 149.047"; + rotation = "0 0 -1 4.00015"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "812 748 130.172"; + rotation = "0 0 1 24"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "732 212 76.3593"; + rotation = "0 0 1 51"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "1100 508 149.781"; + rotation = "0 0 -1 29.9998"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "676 764 169.812"; + rotation = "0 0 -1 80.0004"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "1092 876 185.672"; + rotation = "0 0 1 217"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "428 548 211.094"; + rotation = "0 0 1 121"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "932 524 173.125"; + rotation = "0 0 -1 71.0004"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "996 180 97.219"; + rotation = "0 0 1 44"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "636 892 140.578"; + rotation = "0 0 1 54"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "708 252 95.1562"; + rotation = "0 0 1 66.0002"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "420 676 178.266"; + rotation = "0 0 -1 29"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "956 868 153.906"; + rotation = "0 0 1 67.9998"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "908 524 173"; + rotation = "0 0 1 205"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "868 156 94.3594"; + rotation = "0 0 1 117"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "460 516 183.859"; + rotation = "0 0 1 230"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "604 916 149.047"; + rotation = "0 0 -1 119"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "1012 804 150.625"; + rotation = "0 0 -1 37.0002"; + scale = "1 1 1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "980 756 116.422"; + rotation = "0 0 1 28"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "788 668 117.719"; + rotation = "0 0 1 17"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "1012 348 117.969"; + rotation = "0 0 1 217"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "964 700 155.375"; + rotation = "0 0 -1 61.0005"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "756 252 86.9531"; + rotation = "0 0 -1 77.0004"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "1148 380 70.6719"; + rotation = "0 0 1 22"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "428 644 178.656"; + rotation = "0 0 1 161"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "1180 644 160.187"; + rotation = "0 0 1 215"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "908 300 68.1719"; + rotation = "0 0 -1 58.0005"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "924 524 173.031"; + rotation = "0 0 1 69.0002"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "692 364 123.922"; + rotation = "0 0 -1 53.9998"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "1156 796 167.719"; + rotation = "0 0 -1 92.0004"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "524 788 196.734"; + rotation = "0 0 1 141"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg16.dts"; + }; + }; + new SimGroup(Addition12DSPlant17) { + + powerCount = "0"; + + new TSStatic() { + position = "596 604 155.219"; + rotation = "-0.252214 0.0568745 0.965999 52.557"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "676 780 168.969"; + rotation = "0.0644755 0.0918072 -0.993687 79.3563"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "1180 428 100.875"; + rotation = "-0.13555 -0.0513793 0.989437 205.735"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "796 884 150.734"; + rotation = "0.214537 0.335293 -0.917362 31.4878"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "1052 516 172.5"; + rotation = "0.0326082 -0.0612456 0.99759 96.1377"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "700 444 95.7187"; + rotation = "0.0236739 -0.00272442 0.999716 130.013"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "444 364 181.766"; + rotation = "0.182467 -0.00253999 -0.983209 95.9659"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "748 388 124.922"; + rotation = "0.145242 0.0220224 0.989151 227.537"; + scale = "1 1 1"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "684 508 115.016"; + rotation = "0.107873 -0.0904691 0.99004 144.336"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "1012 812 150.656"; + rotation = "-0.436177 -0.113977 -0.892614 22.3487"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "764 268 90.5625"; + rotation = "-0.151402 -0.00972159 0.988424 127.531"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "972 220 99.687"; + rotation = "-0.0666638 0.167378 0.983636 83.9389"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "948 908 112.328"; + rotation = "-0.0115508 -0.143244 0.98962 84.5949"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "1164 772 170.828"; + rotation = "-0.0696701 0.0635217 0.995546 107.245"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "1140 788 162.828"; + rotation = "-0.138555 0.0419806 0.989465 124.501"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "668 484 117.547"; + rotation = "-0.112626 -0.107037 0.987855 147.379"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "1068 468 173.547"; + rotation = "-0.0739407 0.066415 0.995049 182.985"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "572 548 163.734"; + rotation = "0.0235022 -0.0760124 0.99683 188.971"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "932 748 132.016"; + rotation = "0.0157534 0.0466812 -0.998786 97.0689"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "556 636 146.938"; + rotation = "0.00172912 -0.183868 0.982949 61.8651"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "700 380 127.609"; + rotation = "-0.575477 -0.32338 0.751166 26.4206"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "388 844 163.953"; + rotation = "0.0485287 0.0029749 0.998817 109.064"; + scale = "1 1 1"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "812 748 130.172"; + rotation = "-0.121092 0.110974 -0.986418 41.5167"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "932 628 129.078"; + rotation = "0.0144005 -0.0381498 0.999168 167.011"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "964 708 155.375"; + rotation = "-0.0136492 0.313518 -0.949484 37.7824"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "580 604 156.922"; + rotation = "-0.450827 -0.23556 -0.860969 37.971"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "668 484 117.547"; + rotation = "-0.121311 -0.101946 0.987366 140.466"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "764 492 156.484"; + rotation = "0.117335 -0.0381243 0.99236 54.3563"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "588 924 147.562"; + rotation = "0.204729 0.174863 -0.963073 58.8262"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "436 724 168.313"; + rotation = "0.0454692 0.134065 0.989929 209.711"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "908 756 125.5"; + rotation = "0.0625492 -0.146797 0.987187 145.422"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "980 820 135.922"; + rotation = "0.127602 -0.10248 0.986517 223.463"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "748 268 88.3906"; + rotation = "-0.0133015 -0.0530759 0.998502 115.078"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "428 644 178.656"; + rotation = "-0.100363 0.105261 0.989367 146.341"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "1044 468 164.875"; + rotation = "0.0348411 0.150912 -0.987933 116.624"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "1180 572 127.766"; + rotation = "-0.0265204 -0.163439 -0.986197 116.714"; + scale = "1 1 1"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "980 812 135.953"; + rotation = "0.0360907 0.0983098 0.994501 179.006"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "756 228 77.6875"; + rotation = "-0.0980146 0.223292 -0.969811 77.7097"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "1124 772 160.703"; + rotation = "-0.0907992 -0.261222 0.960999 65.0491"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "628 884 140.391"; + rotation = "-0.894358 -0.309023 0.323463 12.3235"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "692 140 113.016"; + rotation = "0.0792873 -0.0294701 0.996416 157.08"; + scale = "1 1 1"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "916 220 72.7969"; + rotation = "0.00019495 0.0903265 0.995912 109.222"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "804 700 108.672"; + rotation = "0.583341 0.0169456 0.81205 28.1309"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "1044 252 125.531"; + rotation = "0.00811237 -0.0415602 0.999103 139.034"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "556 900 159.969"; + rotation = "0.137374 -0.210933 0.967799 61.6371"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "908 228 72.875"; + rotation = "-0.0695661 0.115309 -0.990891 115.474"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg17.dts"; + }; + }; + new SimGroup(Addition13DSPlant18) { + + powerCount = "0"; + + new TSStatic() { + position = "972 156 95.4218"; + rotation = "0 0 -1 74.0004"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "1116 868 181.031"; + rotation = "0 0 1 58.9998"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "428 372 177.891"; + rotation = "0 0 1 79"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "676 388 126.625"; + rotation = "0 0 -1 58.0005"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "828 764 134.531"; + rotation = "0 0 -1 82"; + scale = "1 1 1"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "924 508 173.453"; + rotation = "0 0 -1 14.9998"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "1100 812 157.953"; + rotation = "0 0 1 1.9999"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "404 388 158.766"; + rotation = "0 0 1 205"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "556 884 168.078"; + rotation = "0 0 1 99.0002"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "484 484 178.281"; + rotation = "0 0 -1 81.0002"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "1116 676 142.453"; + rotation = "0 0 1 221"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "676 836 154.063"; + rotation = "0 0 -1 107"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "452 492 179"; + rotation = "0 0 -1 90.0002"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "1068 860 172.672"; + rotation = "0 0 -1 104"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "684 268 90.8593"; + rotation = "0 0 1 160"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "788 308 109.531"; + rotation = "0 0 1 39"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "1012 804 150.625"; + rotation = "0 0 -1 115"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "980 204 104.016"; + rotation = "0 0 1 44"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "924 244 77.6875"; + rotation = "0 0 1 122"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "1020 652 182.672"; + rotation = "0 0 1 18"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "620 204 143.344"; + rotation = "0 0 1 12"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "924 516 173.063"; + rotation = "0 0 1 214"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "492 308 158.859"; + rotation = "0 0 1 143"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "1084 652 152.109"; + rotation = "0 0 1 28"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "620 212 144.453"; + rotation = "0 0 1 156"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "1108 524 155.203"; + rotation = "0 0 1 28"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "844 452 125.641"; + rotation = "0 0 1 136"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "532 428 180.125"; + rotation = "0 0 -1 10.9999"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "684 388 127.75"; + rotation = "0 0 1 109"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "692 276 90.8124"; + rotation = "0 0 1 20"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "1068 820 175.313"; + rotation = "0 0 1 66.0002"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "860 156 94.125"; + rotation = "0 0 -1 107"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "540 428 178.094"; + rotation = "0 0 -1 100"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "940 708 139.703"; + rotation = "0 0 1 60.0001"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "924 252 78.1406"; + rotation = "0 0 1 165"; + scale = "1 1 1"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "772 260 90.8437"; + rotation = "0 0 -1 50.9998"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "692 156 112.984"; + rotation = "0 0 1 148"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "1100 860 183.859"; + rotation = "0 0 1 49"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "1108 628 148.562"; + rotation = "0 0 1 94.9998"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "972 812 136.266"; + rotation = "0 0 1 229"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "972 220 99.687"; + rotation = "0 0 1 222"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "1036 756 151.047"; + rotation = "0 0 1 29"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "596 772 152.672"; + rotation = "0 0 1 235"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "836 452 126.141"; + rotation = "0 0 1 64"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "436 732 167.469"; + rotation = "0 0 1 7.99996"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "988 284 116.016"; + rotation = "0 0 1 57.9999"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "500 756 195.719"; + rotation = "0 0 1 172"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "644 492 118.75"; + rotation = "0 0 1 20"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg18.dts"; + }; + }; + new SimGroup(Addition14DSPlant19) { + + powerCount = "0"; + + new TSStatic() { + position = "756 212 76.8125"; + rotation = "0 0 1 208"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "676 764 169.812"; + rotation = "0 0 -1 110"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "1108 748 157.578"; + rotation = "0 0 1 140"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "572 564 167.922"; + rotation = "0 0 -1 97"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "828 452 126.687"; + rotation = "0 0 1 185"; + scale = "1 1 1"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "460 900 128.109"; + rotation = "0 0 1 51"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "892 876 171.438"; + rotation = "0 0 -1 44"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "1180 860 197.953"; + rotation = "0 0 1 236"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "1100 524 154.406"; + rotation = "0 0 1 236"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "604 164 171.953"; + rotation = "0 0 -1 93.0002"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "780 308 112.078"; + rotation = "0 0 -1 76"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "812 276 91.4532"; + rotation = "0 0 1 49"; + scale = "1 1 1"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "740 892 162.078"; + rotation = "0 0 1 90.0002"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "1028 484 164"; + rotation = "0 0 -1 95.0004"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "452 604 159.688"; + rotation = "0 0 1 153"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "676 876 157.391"; + rotation = "0 0 -1 5.99979"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "572 804 158.656"; + rotation = "0 0 1 204"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "804 692 111.109"; + rotation = "0 0 1 239"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "556 540 157.937"; + rotation = "0 0 -1 112"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "1124 868 180.422"; + rotation = "0 0 -1 38.9999"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "748 276 89.7344"; + rotation = "0 0 1 198"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "844 236 116.266"; + rotation = "0 0 1 169"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "668 532 112.703"; + rotation = "0 0 1 87.0002"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "1124 772 160.703"; + rotation = "0 0 -1 46.0002"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "572 716 204.594"; + rotation = "0 0 -1 32.9998"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "820 460 127.109"; + rotation = "0 0 1 150"; + scale = "1 1 1"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "980 220 100.625"; + rotation = "0 0 1 24"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "772 708 109.203"; + rotation = "0 0 -1 53.9998"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "388 812 156.672"; + rotation = "0 0 -1 23.9998"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "588 932 148.109"; + rotation = "0 0 -1 4.00015"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "956 588 160.734"; + rotation = "0 0 1 152"; + scale = "1.4 1.4 1.4"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "908 436 151.469"; + rotation = "0 0 1 101"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "1004 316 118.219"; + rotation = "0 0 -1 26"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "540 420 178.047"; + rotation = "0 0 -1 32"; + scale = "1.3 1.3 1.3"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "564 212 171.297"; + rotation = "0 0 -1 65.0004"; + scale = "1 1 1"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "596 700 209.375"; + rotation = "0 0 1 1.9999"; + scale = "1.5 1.5 1.5"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "580 932 147"; + rotation = "0 0 1 235"; + scale = "1.2 1.2 1.2"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "572 804 158.656"; + rotation = "0 0 1 128"; + scale = "1 1 1"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "812 900 150.344"; + rotation = "0 0 1 119"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "828 428 120.375"; + rotation = "0 0 1 162"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "604 852 130.406"; + rotation = "0 0 1 224"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "1172 860 197.391"; + rotation = "0 0 1 150"; + scale = "0.8 0.8 0.8"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "668 516 115.172"; + rotation = "0 0 1 67"; + scale = "1.1 1.1 1.1"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "428 380 178.078"; + rotation = "0 0 -1 72.0002"; + scale = "0.9 0.9 0.9"; + shapeName = "dorg19.dts"; + }; + }; + }; + new SimGroup(environment) { + + powerCount = "0"; + + new AudioEmitter(Outside1) { + position = "266.262 824.24 137.226"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + fileName = "fx/environment/lavamellow1.wav"; + useProfileDescription = "0"; + outsideAmbient = "1"; + volume = "0.4"; + isLooping = "1"; + is3D = "0"; + minDistance = "20"; + maxDistance = "1280"; + coneInsideAngle = "360"; + coneOutsideAngle = "360"; + coneOutsideVolume = "1"; + coneVector = "0 0 1"; + loopCount = "-1"; + minLoopGap = "0"; + maxLoopGap = "0"; + type = "EffectAudioType"; + + locked = "1"; + }; + new AudioEmitter(Outside2) { + position = "266.262 824.24 137.226"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + fileName = "fx/environment/gravel3.wav"; + useProfileDescription = "0"; + outsideAmbient = "1"; + volume = "0.1"; + isLooping = "1"; + is3D = "0"; + minDistance = "20"; + maxDistance = "1280"; + coneInsideAngle = "360"; + coneOutsideAngle = "360"; + coneOutsideVolume = "1"; + coneVector = "0 0 1"; + loopCount = "-1"; + minLoopGap = "4000"; + maxLoopGap = "15000"; + type = "EffectAudioType"; + + locked = "1"; + }; + }; + new SimGroup(FlightPath) { + + powerCount = "0"; + + new Camera(1) { + position = "269.562 -741.61 246.951"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + team = "1"; + }; + new Camera(2) { + position = "269.562 -641.61 246.951"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + team = "1"; + }; + new Camera(3) { + position = "269.562 -541.61 246.951"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + team = "1"; + }; + new Camera(4) { + position = "269.562 -441.61 246.951"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + team = "1"; + }; + new Camera(5) { + position = "269.562 341.61 246.951"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + team = "1"; + }; + new Camera(6) { + position = "269.562 -341.61 246.951"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + team = "1"; + }; + new Camera(7) { + position = "269.562 -241.61 246.951"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + team = "1"; + }; + new Camera(8) { + position = "269.562 -141.61 246.951"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + team = "1"; + }; + }; + new Camera(introFlyerSP) { + position = "269.562 -841.61 246.951"; + rotation = "0.00124964 0.000196249 -0.999999 17.8502"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + team = "1"; + }; + new Camera(OutPostWP) { + position = "-463.403 -369.998 111.882"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + team = "1"; + locked = "1"; + }; +}; +//--- OBJECT WRITE END --- + +//exec("scripts/HotZone.cs"); diff --git a/missions/KatabaticSV.mis b/missions/KatabaticSV.mis index 8e2553e..82baba7 100644 --- a/missions/KatabaticSV.mis +++ b/missions/KatabaticSV.mis @@ -1,885 +1,885 @@ -// DisplayName = Katabatic -// MissionTypes = SV - -//--- MISSION QUOTE BEGIN --- -// Infinity is the sum of all numbers. -// -- Dark Dragon DX -//--- MISSION QUOTE END --- - -//--- MISSION STRING BEGIN --- -// How long will YOU survive? -//--- MISSION STRING END --- - -//--- OBJECT WRITE BEGIN --- -new SimGroup(MissionGroup) { - - powerCount = "0"; - musicTrack = "ice"; - CTF_scoreLimit = "8"; - cdTrack = "5"; - - new MissionArea(MissionArea) { - area = "-896 -696 1504 1392"; - flightCeiling = "300"; - flightCeilingRange = "20"; - - locked = "true"; - }; - new Sky(Sky) { - position = "0 0 0"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - cloudHeightPer[0] = "0.349971"; - cloudHeightPer[1] = "0.25"; - cloudHeightPer[2] = "0.199973"; - cloudSpeed1 = "0.0001"; - cloudSpeed2 = "0.0002"; - cloudSpeed3 = "0.0003"; - visibleDistance = "500"; - useSkyTextures = "1"; - renderBottomTexture = "0"; - SkySolidColor = "0.365000 0.390000 0.420000 0.000000"; - fogDistance = "400"; - fogColor = "0.650000 0.650000 0.700000 1.000000"; - fogVolume1 = "450 0 100"; - fogVolume2 = "400 100 250"; - fogVolume3 = "0 0 0"; - materialList = "sky_ice_blue.dml"; - windVelocity = "1 0 0"; - windEffectPrecipitation = "0"; - fogVolumeColor1 = "128.000000 128.000000 128.000000 -0.000000"; - fogVolumeColor2 = "128.000000 128.000000 128.000000 0.000000"; - fogVolumeColor3 = "128.000000 128.000000 128.000000 0.000000"; - high_visibleDistance = "-1"; - high_fogDistance = "-1"; - high_fogVolume1 = "-1 -7.46981 -8.15131e+06"; - high_fogVolume2 = "-1 -1.30796e-32 -2.39155e+36"; - high_fogVolume3 = "-1 -1.87939e-07 8041.65"; - - cloudSpeed0 = "0.000000 0.000000"; - locked = "true"; - }; - new Sun() { - position = "0 0 0"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - direction = "0.57735 0.57735 -0.57735"; - color = "0.700000 0.700000 0.700000 1.000000"; - ambient = "0.400000 0.400000 0.400000 1.000000"; - texture[0] = "special/sunFlare"; - texture[1] = "special/sunFlare02"; - texture[2] = "special/LensFlare/flare01"; - texture[3] = "special/LensFlare/flare02"; - texture[4] = "special/LensFlare/flare03"; - lensFlareScale = "0.7"; - lensFlareIntensity = "1"; - frontFlareSize = "300"; - backFlareSize = "450"; - flareColor = "1.000000 1.000000 1.000000 1.000000"; - - locked = "true"; - }; - new Precipitation(Precipitation) { - position = "0 0 0"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Snow"; - lockCount = "0"; - homingCount = "0"; - percentage = "1"; - color1 = "1.000000 1.000000 1.000000 1.000000"; - color2 = "-1.000000 0.000000 0.000000 1.000000"; - color3 = "-1.000000 0.000000 0.000000 1.000000"; - offsetSpeed = "0.25"; - minVelocity = "0.25"; - maxVelocity = "1.5"; - maxNumDrops = "2000"; - maxRadius = "125"; - - locked = "true"; - }; - new TerrainBlock(Terrain) { - rotation = "1 0 0 0"; - scale = "1 1 1"; - detailTexture = "details/snowdet2"; - terrainFile = "Katabatic.ter"; - squareSize = "8"; - - locked = "true"; - position = "-1024 -1024 0"; - }; - new NavigationGraph(NavGraph) { - conjoinAngleDev = "75"; - cullDensity = "0.1"; - customArea = "0 0 0 0"; - - coverage = "0"; - scale = "1 1 1"; - locked = "true"; - position = "0 0 0 1"; - conjoinBowlDev = "20"; - GraphFile = "KatabaticSV.nav"; - rotation = "0 0 0 0"; - }; - new SimGroup(ObserverDropPoints) { - - powerCount = "0"; - - new Camera(Camera01) { - position = "-155.439 207.989 143.178"; - rotation = "0.0488457 -0.239805 0.969592 157.656"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - - locked = "1"; - team = "1"; - }; - new Camera(Camera02) { - position = "-135.432 113.485 88.9461"; - rotation = "0.616067 -0.0338559 0.786966 7.98918"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - - locked = "1"; - team = "1"; - }; - }; - new SimGroup(Teams) { - - powerCount = "0"; - - new SimGroup(Team1) { - - powerCount = "0"; - - new SimGroup(spawnspheres) { - - powerCount = "0"; - - new SpawnSphere() { - position = "-133.456 141.629 83.7518"; - rotation = "0 0 1 44.6907"; - scale = "1 1 1"; - dataBlock = "SpawnSphereMarker"; - lockCount = "0"; - homingCount = "0"; - radius = "50"; - sphereWeight = "100"; - indoorWeight = "100"; - outdoorWeight = "100"; - - locked = "1"; - }; - }; - new SimGroup(base0) { - - new InteriorInstance() { - position = "-133.456 141.629 83.7518"; - rotation = "0 0 1 44.6907"; - scale = "1 1 1"; - interiorFile = "splat7.dif"; - showTerrainInside = "0"; - - locked = "1"; - }; - new StaticShape(TeamGeneratorLarge1) { - position = "-132.109 145.682 69.7085"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - nameTag = "Power"; - dataBlock = "GeneratorLarge"; - lockCount = "0"; - homingCount = "0"; - - Target = "75"; - locked = "1"; - }; - new Item() { - position = "-133.456 141.629 83.7716"; - rotation = "0 0 1 44.6907"; - scale = "1 1 1"; - dataBlock = "RepairPack"; - lockCount = "0"; - homingCount = "0"; - collideable = "1"; - static = "0"; - rotate = "0"; - - Target = "-1"; - locked = "1"; - }; - new StaticShape(TeamStationInventory1) { - position = "-143.098 131.817 83.786"; - rotation = "0 0 1 225.172"; - scale = "1 1 1"; - nameTag = "Main"; - dataBlock = "StationInventory"; - lockCount = "0"; - homingCount = "0"; - - Target = "33"; - locked = "1"; - Trigger = "10063"; - }; - new StaticShape(TeamStationInventory2) { - position = "-123.723 151.291 83.7518"; - rotation = "0 0 1 42.9718"; - scale = "1 1 1"; - nameTag = "Main"; - dataBlock = "StationInventory"; - lockCount = "0"; - homingCount = "0"; - - Target = "34"; - locked = "1"; - Trigger = "10239"; - }; - new WayPoint() { - position = "-133.456 141.629 83.762"; - rotation = "0 0 1 44.6907"; - scale = "1 1 1"; - dataBlock = "WayPointMarker"; - lockCount = "0"; - homingCount = "0"; - name = "HeadQuarters"; - team = "1"; - - locked = "1"; - }; - }; - new SimGroup(AIObjectives) { - - new AIObjective(AIORepairObject) { - position = "-131.844 143.743 71.1518"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Repair the GeneratorLarge"; - targetObject = "TeamGeneratorLarge1"; - targetClientId = "-1"; - targetObjectId = "8436"; - location = "-131.844 143.743 71.1518"; - weightLevel1 = "3200"; - weightLevel2 = "1600"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "0"; - defense = "1"; - equipment = "RepairPack"; - buyEquipmentSet = "MediumRepairSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - }; - new AIObjective(AIOAttackObject) { - position = "-131.844 143.743 71.1518"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Attack the GeneratorLarge"; - targetObject = "TeamGeneratorLarge1"; - targetClientId = "-1"; - targetObjectId = "8436"; - location = "-131.844 143.743 71.1518"; - weightLevel1 = "3100"; - weightLevel2 = "1600"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "1"; - defense = "0"; - desiredEquipment = "ShieldPack"; - buyEquipmentSet = "HeavyAmmoSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - }; - new AIObjective(AIODefendLocation) { - position = "-131.844 143.743 71.1518"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Defend the GeneratorLarge"; - targetObject = "TeamGeneratorLarge1"; - targetClientId = "-1"; - targetObjectId = "8436"; - location = "-131.844 143.743 71.1518"; - weightLevel1 = "3100"; - weightLevel2 = "1500"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "0"; - defense = "1"; - desiredEquipment = "ShieldPack Plasma PlasmaAmmo"; - buyEquipmentSet = "HeavyShieldSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - }; - new AIObjective(AIORepairObject) { - position = "-143.098 131.817 85.3518"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Repair the StationInventory"; - targetObject = "TeamStationInventory1"; - targetClientId = "-1"; - targetObjectId = "10062"; - location = "-143.098 131.817 85.3518"; - weightLevel1 = "2900"; - weightLevel2 = "1400"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "0"; - defense = "1"; - equipment = "RepairPack"; - buyEquipmentSet = "MediumRepairSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - }; - new AIObjective(AIOAttackObject) { - position = "-143.098 131.817 85.3518"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Attack the StationInventory"; - targetObject = "TeamStationInventory1"; - targetClientId = "-1"; - targetObjectId = "10062"; - location = "-143.098 131.817 85.3518"; - weightLevel1 = "2900"; - weightLevel2 = "1400"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "1"; - defense = "0"; - desiredEquipment = "ShieldPack"; - buyEquipmentSet = "HeavyAmmoSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - }; - new AIObjective(AIORepairObject) { - position = "-123.723 151.291 85.3176"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Repair the StationInventory"; - targetObject = "TeamStationInventory2"; - targetClientId = "-1"; - targetObjectId = "10238"; - location = "-123.723 151.291 85.3176"; - weightLevel1 = "2900"; - weightLevel2 = "1400"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "0"; - defense = "1"; - equipment = "RepairPack"; - buyEquipmentSet = "MediumRepairSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - }; - new AIObjective(AIOAttackObject) { - position = "-123.723 151.291 85.3176"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Attack the StationInventory"; - targetObject = "TeamStationInventory2"; - targetClientId = "-1"; - targetObjectId = "10238"; - location = "-123.723 151.291 85.3176"; - weightLevel1 = "2900"; - weightLevel2 = "1400"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "1"; - defense = "0"; - desiredEquipment = "ShieldPack"; - buyEquipmentSet = "HeavyAmmoSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - }; - }; - }; - new SimGroup(Team2) { - - powerCount = "0"; - - new SimGroup(spawnspheres) { - - powerCount = "0"; - - new SpawnSphere() { - position = "338.722 -170.868 83.0065"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "SpawnSphereMarker"; - lockCount = "0"; - homingCount = "0"; - radius = "70"; - sphereWeight = "100"; - indoorWeight = "100"; - outdoorWeight = "100"; - - locked = "1"; - }; - new SpawnSphere() { - position = "-245.736 -43.4338 142.744"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "SpawnSphereMarker"; - lockCount = "0"; - homingCount = "0"; - radius = "50"; - sphereWeight = "100"; - indoorWeight = "100"; - outdoorWeight = "100"; - - locked = "1"; - }; - new SpawnSphere() { - position = "-574.01 362.613 76.6507"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "SpawnSphereMarker"; - lockCount = "0"; - homingCount = "0"; - radius = "100"; - sphereWeight = "100"; - indoorWeight = "100"; - outdoorWeight = "100"; - - locked = "1"; - }; - new SpawnSphere() { - position = "60.2399 434.126 77.2077"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "SpawnSphereMarker"; - lockCount = "0"; - homingCount = "0"; - radius = "100"; - sphereWeight = "100"; - indoorWeight = "100"; - outdoorWeight = "100"; - - locked = "1"; - }; - }; - new SimGroup(AIObjectives) { - - new AIObjective(AIORepairObject) { - position = "-131.844 143.743 71.1518"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Repair the GeneratorLarge"; - targetObject = "TeamGeneratorLarge1"; - targetClientId = "-1"; - targetObjectId = "8436"; - location = "-131.844 143.743 71.1518"; - weightLevel1 = "3200"; - weightLevel2 = "1600"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "0"; - defense = "1"; - equipment = "RepairPack"; - buyEquipmentSet = "MediumRepairSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - }; - new AIObjective(AIOAttackObject) { - position = "-131.844 143.743 71.1518"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Attack the GeneratorLarge"; - targetObject = "TeamGeneratorLarge1"; - targetClientId = "-1"; - targetObjectId = "8436"; - location = "-131.844 143.743 71.1518"; - weightLevel1 = "3100"; - weightLevel2 = "1600"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "1"; - defense = "0"; - desiredEquipment = "ShieldPack"; - buyEquipmentSet = "HeavyAmmoSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - }; - new AIObjective(AIODefendLocation) { - position = "-131.844 143.743 71.1518"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Defend the GeneratorLarge"; - targetObject = "TeamGeneratorLarge1"; - targetClientId = "-1"; - targetObjectId = "8436"; - location = "-131.844 143.743 71.1518"; - weightLevel1 = "3100"; - weightLevel2 = "1500"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "0"; - defense = "1"; - desiredEquipment = "ShieldPack Plasma PlasmaAmmo"; - buyEquipmentSet = "HeavyShieldSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - }; - new AIObjective(AIORepairObject) { - position = "-143.098 131.817 85.3518"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Repair the StationInventory"; - targetObject = "TeamStationInventory1"; - targetClientId = "-1"; - targetObjectId = "10062"; - location = "-143.098 131.817 85.3518"; - weightLevel1 = "2900"; - weightLevel2 = "1400"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "0"; - defense = "1"; - equipment = "RepairPack"; - buyEquipmentSet = "MediumRepairSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - }; - new AIObjective(AIOAttackObject) { - position = "-143.098 131.817 85.3518"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Attack the StationInventory"; - targetObject = "TeamStationInventory1"; - targetClientId = "-1"; - targetObjectId = "10062"; - location = "-143.098 131.817 85.3518"; - weightLevel1 = "2900"; - weightLevel2 = "1400"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "1"; - defense = "0"; - desiredEquipment = "ShieldPack"; - buyEquipmentSet = "HeavyAmmoSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - }; - new AIObjective(AIORepairObject) { - position = "-123.723 151.291 85.3176"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Repair the StationInventory"; - targetObject = "TeamStationInventory2"; - targetClientId = "-1"; - targetObjectId = "10238"; - location = "-123.723 151.291 85.3176"; - weightLevel1 = "2900"; - weightLevel2 = "1400"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "0"; - defense = "1"; - equipment = "RepairPack"; - buyEquipmentSet = "MediumRepairSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - }; - new AIObjective(AIOAttackObject) { - position = "-123.723 151.291 85.3176"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Attack the StationInventory"; - targetObject = "TeamStationInventory2"; - targetClientId = "-1"; - targetObjectId = "10238"; - location = "-123.723 151.291 85.3176"; - weightLevel1 = "2900"; - weightLevel2 = "1400"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "1"; - defense = "0"; - desiredEquipment = "ShieldPack"; - buyEquipmentSet = "HeavyAmmoSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - }; - }; - }; - new SimGroup(team0) { - - powerCount = "0"; - - new SimGroup(AIObjectives) { - }; - }; - }; - new SimGroup(Landmarks) { - - powerCount = "0"; - - new InteriorInstance(SmallRock) { - position = "4.29272 -678.22 87.0344"; - rotation = "0 0 1 40.68"; - scale = "1 1 1"; - interiorFile = "sspir4.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "604.674 288.347 95.0202"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "sspir3.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "-694.001 688.419 81.4125"; - rotation = "0 0 1 68.7549"; - scale = "1 1 1"; - interiorFile = "sspir4.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "-882.758 293.23 98.8326"; - rotation = "0 0 -1 25.2101"; - scale = "1 1 1"; - interiorFile = "sspir2.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "-891.714 -286.207 88.3106"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "sspir2.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "-221.53 190.742 77.4905"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "srock8.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "-209.718 191.939 80.2187"; - rotation = "-0.819622 -0.568812 -0.0683577 80.983"; - scale = "1 1 1"; - interiorFile = "srock8.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "-177.352 224.065 77.315"; - rotation = "-0.844132 -0.0752246 -0.530831 52.3752"; - scale = "1 1 1"; - interiorFile = "srock8.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "-179.65 235.545 77.0884"; - rotation = "0.960354 0.139691 0.24126 110.99"; - scale = "1 1 1"; - interiorFile = "srock8.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "-106.21 57.7174 78.575"; - rotation = "0.632488 0.637505 -0.439938 88.8149"; - scale = "1 1 1"; - interiorFile = "srock8.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "-107.599 41.1366 80.8043"; - rotation = "1 0 0 135.218"; - scale = "1 1 1"; - interiorFile = "srock8.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "-40.5405 106.833 78.0061"; - rotation = "-0.785982 0.317479 0.530508 101.895"; - scale = "1 1 1"; - interiorFile = "srock8.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "-53.613 125.786 84.5896"; - rotation = "-0.729593 -0.471499 -0.495362 81.0287"; - scale = "1 1 1"; - interiorFile = "srock8.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "-50.1881 105.939 76.4521"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "srock7.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "-58.092 116.907 76.9334"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "srock6.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "-93.3823 63.4909 76.8637"; - rotation = "1 0 0 205.874"; - scale = "1 1 1"; - interiorFile = "srock6.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "-191.544 230.281 76.4113"; - rotation = "0 1 0 17.7616"; - scale = "1 1 1"; - interiorFile = "srock7.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "-216.399 199.251 77.8031"; - rotation = "-0.00419048 -0.594692 -0.803943 94.5913"; - scale = "1 1 1"; - interiorFile = "srock6.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance(SmallRock) { - position = "-33.1756 122.498 78.0202"; - rotation = "-0.335772 0.927883 -0.162146 125.688"; - scale = "1 1 1"; - interiorFile = "srock8.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - }; - new AudioEmitter() { - position = "289.762 209.214 173.677"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - fileName = "fx/environment/moaningwind1.wav"; - useProfileDescription = "0"; - outsideAmbient = "1"; - volume = "1"; - isLooping = "1"; - is3D = "0"; - minDistance = "20"; - maxDistance = "1280"; - coneInsideAngle = "360"; - coneOutsideAngle = "360"; - coneOutsideVolume = "1"; - coneVector = "0 0 1"; - loopCount = "-1"; - minLoopGap = "0"; - maxLoopGap = "0"; - type = "EffectAudioType"; - - locked = "true"; - }; -}; -//--- OBJECT WRITE END --- +// DisplayName = Katabatic +// MissionTypes = SV + +//--- MISSION QUOTE BEGIN --- +// Infinity is the sum of all numbers. +// -- Dark Dragon DX +//--- MISSION QUOTE END --- + +//--- MISSION STRING BEGIN --- +// How long will YOU survive? +//--- MISSION STRING END --- + +//--- OBJECT WRITE BEGIN --- +new SimGroup(MissionGroup) { + + powerCount = "0"; + musicTrack = "ice"; + CTF_scoreLimit = "8"; + cdTrack = "5"; + + new MissionArea(MissionArea) { + area = "-896 -696 1504 1392"; + flightCeiling = "300"; + flightCeilingRange = "20"; + + locked = "true"; + }; + new Sky(Sky) { + position = "0 0 0"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + cloudHeightPer[0] = "0.349971"; + cloudHeightPer[1] = "0.25"; + cloudHeightPer[2] = "0.199973"; + cloudSpeed1 = "0.0001"; + cloudSpeed2 = "0.0002"; + cloudSpeed3 = "0.0003"; + visibleDistance = "500"; + useSkyTextures = "1"; + renderBottomTexture = "0"; + SkySolidColor = "0.365000 0.390000 0.420000 0.000000"; + fogDistance = "400"; + fogColor = "0.650000 0.650000 0.700000 1.000000"; + fogVolume1 = "450 0 100"; + fogVolume2 = "400 100 250"; + fogVolume3 = "0 0 0"; + materialList = "sky_ice_blue.dml"; + windVelocity = "1 0 0"; + windEffectPrecipitation = "0"; + fogVolumeColor1 = "128.000000 128.000000 128.000000 -0.000000"; + fogVolumeColor2 = "128.000000 128.000000 128.000000 0.000000"; + fogVolumeColor3 = "128.000000 128.000000 128.000000 0.000000"; + high_visibleDistance = "-1"; + high_fogDistance = "-1"; + high_fogVolume1 = "-1 -7.46981 -8.15131e+06"; + high_fogVolume2 = "-1 -1.30796e-32 -2.39155e+36"; + high_fogVolume3 = "-1 -1.87939e-07 8041.65"; + + cloudSpeed0 = "0.000000 0.000000"; + locked = "true"; + }; + new Sun() { + position = "0 0 0"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + direction = "0.57735 0.57735 -0.57735"; + color = "0.700000 0.700000 0.700000 1.000000"; + ambient = "0.400000 0.400000 0.400000 1.000000"; + texture[0] = "special/sunFlare"; + texture[1] = "special/sunFlare02"; + texture[2] = "special/LensFlare/flare01"; + texture[3] = "special/LensFlare/flare02"; + texture[4] = "special/LensFlare/flare03"; + lensFlareScale = "0.7"; + lensFlareIntensity = "1"; + frontFlareSize = "300"; + backFlareSize = "450"; + flareColor = "1.000000 1.000000 1.000000 1.000000"; + + locked = "true"; + }; + new Precipitation(Precipitation) { + position = "0 0 0"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Snow"; + lockCount = "0"; + homingCount = "0"; + percentage = "1"; + color1 = "1.000000 1.000000 1.000000 1.000000"; + color2 = "-1.000000 0.000000 0.000000 1.000000"; + color3 = "-1.000000 0.000000 0.000000 1.000000"; + offsetSpeed = "0.25"; + minVelocity = "0.25"; + maxVelocity = "1.5"; + maxNumDrops = "2000"; + maxRadius = "125"; + + locked = "true"; + }; + new TerrainBlock(Terrain) { + rotation = "1 0 0 0"; + scale = "1 1 1"; + detailTexture = "details/snowdet2"; + terrainFile = "Katabatic.ter"; + squareSize = "8"; + + locked = "true"; + position = "-1024 -1024 0"; + }; + new NavigationGraph(NavGraph) { + conjoinAngleDev = "75"; + cullDensity = "0.1"; + customArea = "0 0 0 0"; + + coverage = "0"; + scale = "1 1 1"; + locked = "true"; + position = "0 0 0 1"; + conjoinBowlDev = "20"; + GraphFile = "KatabaticSV.nav"; + rotation = "0 0 0 0"; + }; + new SimGroup(ObserverDropPoints) { + + powerCount = "0"; + + new Camera(Camera01) { + position = "-155.439 207.989 143.178"; + rotation = "0.0488457 -0.239805 0.969592 157.656"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + locked = "1"; + team = "1"; + }; + new Camera(Camera02) { + position = "-135.432 113.485 88.9461"; + rotation = "0.616067 -0.0338559 0.786966 7.98918"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + locked = "1"; + team = "1"; + }; + }; + new SimGroup(Teams) { + + powerCount = "0"; + + new SimGroup(Team1) { + + powerCount = "0"; + + new SimGroup(spawnspheres) { + + powerCount = "0"; + + new SpawnSphere() { + position = "-133.456 141.629 83.7518"; + rotation = "0 0 1 44.6907"; + scale = "1 1 1"; + dataBlock = "SpawnSphereMarker"; + lockCount = "0"; + homingCount = "0"; + radius = "50"; + sphereWeight = "100"; + indoorWeight = "100"; + outdoorWeight = "100"; + + locked = "1"; + }; + }; + new SimGroup(base0) { + + new InteriorInstance() { + position = "-133.456 141.629 83.7518"; + rotation = "0 0 1 44.6907"; + scale = "1 1 1"; + interiorFile = "splat7.dif"; + showTerrainInside = "0"; + + locked = "1"; + }; + new StaticShape(TeamGeneratorLarge1) { + position = "-132.109 145.682 69.7085"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + nameTag = "Power"; + dataBlock = "GeneratorLarge"; + lockCount = "0"; + homingCount = "0"; + + Target = "75"; + locked = "1"; + }; + new Item() { + position = "-133.456 141.629 83.7716"; + rotation = "0 0 1 44.6907"; + scale = "1 1 1"; + dataBlock = "RepairPack"; + lockCount = "0"; + homingCount = "0"; + collideable = "1"; + static = "0"; + rotate = "0"; + + Target = "-1"; + locked = "1"; + }; + new StaticShape(TeamStationInventory1) { + position = "-143.098 131.817 83.786"; + rotation = "0 0 1 225.172"; + scale = "1 1 1"; + nameTag = "Main"; + dataBlock = "StationInventory"; + lockCount = "0"; + homingCount = "0"; + + Target = "33"; + locked = "1"; + Trigger = "10063"; + }; + new StaticShape(TeamStationInventory2) { + position = "-123.723 151.291 83.7518"; + rotation = "0 0 1 42.9718"; + scale = "1 1 1"; + nameTag = "Main"; + dataBlock = "StationInventory"; + lockCount = "0"; + homingCount = "0"; + + Target = "34"; + locked = "1"; + Trigger = "10239"; + }; + new WayPoint() { + position = "-133.456 141.629 83.762"; + rotation = "0 0 1 44.6907"; + scale = "1 1 1"; + dataBlock = "WayPointMarker"; + lockCount = "0"; + homingCount = "0"; + name = "HeadQuarters"; + team = "1"; + + locked = "1"; + }; + }; + new SimGroup(AIObjectives) { + + new AIObjective(AIORepairObject) { + position = "-131.844 143.743 71.1518"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Repair the GeneratorLarge"; + targetObject = "TeamGeneratorLarge1"; + targetClientId = "-1"; + targetObjectId = "8436"; + location = "-131.844 143.743 71.1518"; + weightLevel1 = "3200"; + weightLevel2 = "1600"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "0"; + defense = "1"; + equipment = "RepairPack"; + buyEquipmentSet = "MediumRepairSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + }; + new AIObjective(AIOAttackObject) { + position = "-131.844 143.743 71.1518"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Attack the GeneratorLarge"; + targetObject = "TeamGeneratorLarge1"; + targetClientId = "-1"; + targetObjectId = "8436"; + location = "-131.844 143.743 71.1518"; + weightLevel1 = "3100"; + weightLevel2 = "1600"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "1"; + defense = "0"; + desiredEquipment = "ShieldPack"; + buyEquipmentSet = "HeavyAmmoSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + }; + new AIObjective(AIODefendLocation) { + position = "-131.844 143.743 71.1518"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Defend the GeneratorLarge"; + targetObject = "TeamGeneratorLarge1"; + targetClientId = "-1"; + targetObjectId = "8436"; + location = "-131.844 143.743 71.1518"; + weightLevel1 = "3100"; + weightLevel2 = "1500"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "0"; + defense = "1"; + desiredEquipment = "ShieldPack Plasma PlasmaAmmo"; + buyEquipmentSet = "HeavyShieldSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + }; + new AIObjective(AIORepairObject) { + position = "-143.098 131.817 85.3518"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Repair the StationInventory"; + targetObject = "TeamStationInventory1"; + targetClientId = "-1"; + targetObjectId = "10062"; + location = "-143.098 131.817 85.3518"; + weightLevel1 = "2900"; + weightLevel2 = "1400"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "0"; + defense = "1"; + equipment = "RepairPack"; + buyEquipmentSet = "MediumRepairSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + }; + new AIObjective(AIOAttackObject) { + position = "-143.098 131.817 85.3518"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Attack the StationInventory"; + targetObject = "TeamStationInventory1"; + targetClientId = "-1"; + targetObjectId = "10062"; + location = "-143.098 131.817 85.3518"; + weightLevel1 = "2900"; + weightLevel2 = "1400"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "1"; + defense = "0"; + desiredEquipment = "ShieldPack"; + buyEquipmentSet = "HeavyAmmoSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + }; + new AIObjective(AIORepairObject) { + position = "-123.723 151.291 85.3176"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Repair the StationInventory"; + targetObject = "TeamStationInventory2"; + targetClientId = "-1"; + targetObjectId = "10238"; + location = "-123.723 151.291 85.3176"; + weightLevel1 = "2900"; + weightLevel2 = "1400"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "0"; + defense = "1"; + equipment = "RepairPack"; + buyEquipmentSet = "MediumRepairSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + }; + new AIObjective(AIOAttackObject) { + position = "-123.723 151.291 85.3176"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Attack the StationInventory"; + targetObject = "TeamStationInventory2"; + targetClientId = "-1"; + targetObjectId = "10238"; + location = "-123.723 151.291 85.3176"; + weightLevel1 = "2900"; + weightLevel2 = "1400"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "1"; + defense = "0"; + desiredEquipment = "ShieldPack"; + buyEquipmentSet = "HeavyAmmoSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + }; + }; + }; + new SimGroup(Team2) { + + powerCount = "0"; + + new SimGroup(spawnspheres) { + + powerCount = "0"; + + new SpawnSphere() { + position = "338.722 -170.868 83.0065"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "SpawnSphereMarker"; + lockCount = "0"; + homingCount = "0"; + radius = "70"; + sphereWeight = "100"; + indoorWeight = "100"; + outdoorWeight = "100"; + + locked = "1"; + }; + new SpawnSphere() { + position = "-245.736 -43.4338 142.744"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "SpawnSphereMarker"; + lockCount = "0"; + homingCount = "0"; + radius = "50"; + sphereWeight = "100"; + indoorWeight = "100"; + outdoorWeight = "100"; + + locked = "1"; + }; + new SpawnSphere() { + position = "-574.01 362.613 76.6507"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "SpawnSphereMarker"; + lockCount = "0"; + homingCount = "0"; + radius = "100"; + sphereWeight = "100"; + indoorWeight = "100"; + outdoorWeight = "100"; + + locked = "1"; + }; + new SpawnSphere() { + position = "60.2399 434.126 77.2077"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "SpawnSphereMarker"; + lockCount = "0"; + homingCount = "0"; + radius = "100"; + sphereWeight = "100"; + indoorWeight = "100"; + outdoorWeight = "100"; + + locked = "1"; + }; + }; + new SimGroup(AIObjectives) { + + new AIObjective(AIORepairObject) { + position = "-131.844 143.743 71.1518"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Repair the GeneratorLarge"; + targetObject = "TeamGeneratorLarge1"; + targetClientId = "-1"; + targetObjectId = "8436"; + location = "-131.844 143.743 71.1518"; + weightLevel1 = "3200"; + weightLevel2 = "1600"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "0"; + defense = "1"; + equipment = "RepairPack"; + buyEquipmentSet = "MediumRepairSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + }; + new AIObjective(AIOAttackObject) { + position = "-131.844 143.743 71.1518"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Attack the GeneratorLarge"; + targetObject = "TeamGeneratorLarge1"; + targetClientId = "-1"; + targetObjectId = "8436"; + location = "-131.844 143.743 71.1518"; + weightLevel1 = "3100"; + weightLevel2 = "1600"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "1"; + defense = "0"; + desiredEquipment = "ShieldPack"; + buyEquipmentSet = "HeavyAmmoSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + }; + new AIObjective(AIODefendLocation) { + position = "-131.844 143.743 71.1518"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Defend the GeneratorLarge"; + targetObject = "TeamGeneratorLarge1"; + targetClientId = "-1"; + targetObjectId = "8436"; + location = "-131.844 143.743 71.1518"; + weightLevel1 = "3100"; + weightLevel2 = "1500"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "0"; + defense = "1"; + desiredEquipment = "ShieldPack Plasma PlasmaAmmo"; + buyEquipmentSet = "HeavyShieldSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + }; + new AIObjective(AIORepairObject) { + position = "-143.098 131.817 85.3518"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Repair the StationInventory"; + targetObject = "TeamStationInventory1"; + targetClientId = "-1"; + targetObjectId = "10062"; + location = "-143.098 131.817 85.3518"; + weightLevel1 = "2900"; + weightLevel2 = "1400"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "0"; + defense = "1"; + equipment = "RepairPack"; + buyEquipmentSet = "MediumRepairSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + }; + new AIObjective(AIOAttackObject) { + position = "-143.098 131.817 85.3518"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Attack the StationInventory"; + targetObject = "TeamStationInventory1"; + targetClientId = "-1"; + targetObjectId = "10062"; + location = "-143.098 131.817 85.3518"; + weightLevel1 = "2900"; + weightLevel2 = "1400"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "1"; + defense = "0"; + desiredEquipment = "ShieldPack"; + buyEquipmentSet = "HeavyAmmoSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + }; + new AIObjective(AIORepairObject) { + position = "-123.723 151.291 85.3176"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Repair the StationInventory"; + targetObject = "TeamStationInventory2"; + targetClientId = "-1"; + targetObjectId = "10238"; + location = "-123.723 151.291 85.3176"; + weightLevel1 = "2900"; + weightLevel2 = "1400"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "0"; + defense = "1"; + equipment = "RepairPack"; + buyEquipmentSet = "MediumRepairSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + }; + new AIObjective(AIOAttackObject) { + position = "-123.723 151.291 85.3176"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Attack the StationInventory"; + targetObject = "TeamStationInventory2"; + targetClientId = "-1"; + targetObjectId = "10238"; + location = "-123.723 151.291 85.3176"; + weightLevel1 = "2900"; + weightLevel2 = "1400"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "1"; + defense = "0"; + desiredEquipment = "ShieldPack"; + buyEquipmentSet = "HeavyAmmoSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + }; + }; + }; + new SimGroup(team0) { + + powerCount = "0"; + + new SimGroup(AIObjectives) { + }; + }; + }; + new SimGroup(Landmarks) { + + powerCount = "0"; + + new InteriorInstance(SmallRock) { + position = "4.29272 -678.22 87.0344"; + rotation = "0 0 1 40.68"; + scale = "1 1 1"; + interiorFile = "sspir4.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "604.674 288.347 95.0202"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "sspir3.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "-694.001 688.419 81.4125"; + rotation = "0 0 1 68.7549"; + scale = "1 1 1"; + interiorFile = "sspir4.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "-882.758 293.23 98.8326"; + rotation = "0 0 -1 25.2101"; + scale = "1 1 1"; + interiorFile = "sspir2.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "-891.714 -286.207 88.3106"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "sspir2.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "-221.53 190.742 77.4905"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "srock8.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "-209.718 191.939 80.2187"; + rotation = "-0.819622 -0.568812 -0.0683577 80.983"; + scale = "1 1 1"; + interiorFile = "srock8.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "-177.352 224.065 77.315"; + rotation = "-0.844132 -0.0752246 -0.530831 52.3752"; + scale = "1 1 1"; + interiorFile = "srock8.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "-179.65 235.545 77.0884"; + rotation = "0.960354 0.139691 0.24126 110.99"; + scale = "1 1 1"; + interiorFile = "srock8.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "-106.21 57.7174 78.575"; + rotation = "0.632488 0.637505 -0.439938 88.8149"; + scale = "1 1 1"; + interiorFile = "srock8.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "-107.599 41.1366 80.8043"; + rotation = "1 0 0 135.218"; + scale = "1 1 1"; + interiorFile = "srock8.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "-40.5405 106.833 78.0061"; + rotation = "-0.785982 0.317479 0.530508 101.895"; + scale = "1 1 1"; + interiorFile = "srock8.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "-53.613 125.786 84.5896"; + rotation = "-0.729593 -0.471499 -0.495362 81.0287"; + scale = "1 1 1"; + interiorFile = "srock8.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "-50.1881 105.939 76.4521"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "srock7.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "-58.092 116.907 76.9334"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "srock6.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "-93.3823 63.4909 76.8637"; + rotation = "1 0 0 205.874"; + scale = "1 1 1"; + interiorFile = "srock6.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "-191.544 230.281 76.4113"; + rotation = "0 1 0 17.7616"; + scale = "1 1 1"; + interiorFile = "srock7.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "-216.399 199.251 77.8031"; + rotation = "-0.00419048 -0.594692 -0.803943 94.5913"; + scale = "1 1 1"; + interiorFile = "srock6.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance(SmallRock) { + position = "-33.1756 122.498 78.0202"; + rotation = "-0.335772 0.927883 -0.162146 125.688"; + scale = "1 1 1"; + interiorFile = "srock8.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + }; + new AudioEmitter() { + position = "289.762 209.214 173.677"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + fileName = "fx/environment/moaningwind1.wav"; + useProfileDescription = "0"; + outsideAmbient = "1"; + volume = "1"; + isLooping = "1"; + is3D = "0"; + minDistance = "20"; + maxDistance = "1280"; + coneInsideAngle = "360"; + coneOutsideAngle = "360"; + coneOutsideVolume = "1"; + coneVector = "0 0 1"; + loopCount = "-1"; + minLoopGap = "0"; + maxLoopGap = "0"; + type = "EffectAudioType"; + + locked = "true"; + }; +}; +//--- OBJECT WRITE END --- diff --git a/missions/Mission1.mis b/missions/Mission1.mis index 1cc7269..36681d6 100644 --- a/missions/Mission1.mis +++ b/missions/Mission1.mis @@ -1,2754 +1,2754 @@ -// MissionTypes = SinglePlayer -// DisplayName = Recruit - -//--- MISSION BRIEFING BEGIN --- -//Dear Recruit Iguana, -//This is a notification of activation. You are to report to the launch bay at 3:00 sharp. You will be deployed to the Southern hemisphere of Xeron; your objecive is to take back an HQ of ours. -// -//Letter No. 626938. -//Department: Alpha Viper -// -//Sincerely,Alpha Viper deployment -//--- MISSION BRIEFING END --- - -// PlanetName = Xeron, 3960 CE -// Bitmap = trn_5draconis - -//--- MISSION STRING BEGIN --- -//OBJECTIVES: -//Bleck -//--- MISSION STRING END --- - -//--- MISSION BLURB BEGIN --- -//In 3941, the BioDerm Hordes crushed the Starwolf tribe at the star system of Ymir. Six years later, the tribal alliance called the Pact begins a crucial offensive. You are of the Pact, a Starwolf newblood. Remember Ymir. Avenge your people. -//--- MISSION BLURB END --- - - -//scriptlet -//we have to jump through a lot of hoops to get those dead bodies in training1 -function deadArmor::onAdd(%this, %obj) -{ - %skin = (%obj.trainingSkin == 1 ? 'swolf' : 'beagle'); - //echo("skin = " SPC %skin); - createTarget(%obj, 'Dead Body', %skin, "", 'deadArmor', 0); -} - -function deadArmor::onRemove(%this, %obj) -{ - //echo("singleplayerGame -- deadArmor::onRemove"); - freeTarget(%obj.getTarget()); -} - - -//--- OBJECT WRITE BEGIN --- -new SimGroup(MissionGroup) { - powerCount = "0"; - - new MissionArea(MissionArea) { - area = "-448 -1408 2304 2208"; - flightCeiling = "2000"; - flightCeilingRange = "50"; - }; - new Sky(Sky) { - position = "0 0 0"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - cloudHeightPer[0] = "0.349971"; - cloudHeightPer[1] = "0.25"; - cloudHeightPer[2] = "0.199973"; - cloudSpeed1 = "0.0001"; - cloudSpeed2 = "0.0002"; - cloudSpeed3 = "0.0003"; - visibleDistance = "400"; - useSkyTextures = "1"; - SkySolidColor = "0.390000 0.390000 0.390000 1.000000"; - fogDistance = "100"; - fogColor = "0.500000 0.500000 0.500000 1.000000"; - fogVolume1 = "0 0 0"; - fogVolume2 = "0 0 0"; - fogVolume3 = "0 0 0"; - materialList = "Lush_l4.dml"; - windVelocity = "0 0 0"; - windEffectPrecipitation = "0"; - cloudSpeed0 = "0.000000 0.000000"; - }; - new Sun() { - direction = "0.57735 0.57735 -0.57735"; - color = "0.600000 0.600000 0.600000 1.000000"; - ambient = "0.600000 0.600000 0.600000 1.000000"; - scale = "1 1 1"; - position = "0 0 0"; - rotation = "1 0 0 0"; - }; - new TerrainBlock(Terrain) { - rotation = "1 0 0 0"; - scale = "1 1 1"; - detailTexture = "details/lushdet1"; - terrainFile = "Training1.ter"; - squareSize = "8"; - position = "-1024 -1024 0"; - }; - new NavigationGraph(NavGraph) { - conjoinAngleDev = "50"; - cullDensity = "0.1"; - customArea = "0 0 0 0"; - conjoinBowlDev = "20"; - scale = "1 1 1"; - GraphFile = "Training1.nav"; - position = "0 0 0 1"; - coverage = "0"; - rotation = "0 0 0 0"; - }; - new Camera(hoverBikeDP) { - position = "629.407 -58.6929 124.08"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - new SimGroup(Teams) { - - new SimGroup(Team2) { - - new SimGroup(DropPoints) { - - new Camera(enemy0) { - position = "472.802 349.922 204.888"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - SkillLevel = "0"; - }; - new Camera(enemy1) { - position = "551.142 790.21 107.5"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - SkillLevel = "0"; - }; - new Camera(enemy2) { - position = "738.109 5.1693 152.475"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - SkillLevel = "0"; - }; - new Camera(enemy3) { - position = "988.221 -326.252 86.2044"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - SkillLevel = "0"; - }; - new Camera(enemy4) { - position = "917.043 -476.293 102.216"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - SkillLevel = "0"; - }; - new Camera(enemy5) { - position = "977.56 -584.56 107.011"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - SkillLevel = "0"; - }; - new Camera(enemy6) { - position = "980.365 -777.838 97.7195"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - SkillLevel = "0"; - }; - new Camera(enemy7) { - position = "472.356 345.155 200.883"; - rotation = "0 0 -1 75.6304"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - SkillLevel = "0"; - }; - new Camera(enemy8) { - position = "564.903 791.638 107.929"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - new Camera(enemy9) { - position = "589.296 806.741 111.858"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - new Camera(enemy10) { - position = "575.32 -29.8525 138.276"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - new Camera(enemy11) { - position = "827.178 406.124 195.466"; - rotation = "0 0 1 183.919"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - new Camera(enemy12) { - position = "-721.719 296.493 83.3617"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - new Camera(enemy13) { - position = "882.259 49.6576 147.146"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - }; - }; - new SimGroup(Team1) { - providesPower = "1"; - - new SimGroup(DropPoints) { - - new Camera() { - position = "1301.77 -832.202 88.3109"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - new Camera() { - position = "1255.36 -826.299 79.1645"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - new Camera(DP) { - position = "-262.22 528.825 148.641"; - rotation = "0 0 1 174.696"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - new SimGroup(Respawns) { - - new Camera() { - position = "-311.987 532.198 155.274"; - rotation = "0 0 1 150.115"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - new Camera() { - position = "-293.826 391.612 75.1421"; - rotation = "0 0 1 96.2569"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - new Camera() { - position = "483.448 364.206 225.265"; - rotation = "0 0 1 178.763"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - new Camera() { - position = "635.748 -42.3523 127.123"; - rotation = "0 0 1 183.346"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - }; - }; - new StaticShape(Team1SensorLargePulse1) { - position = "476.731 363.919 232.695"; - rotation = "0 0 1 94.538"; - scale = "1 1 1"; - dataBlock = "SensorLargePulse"; - lockCount = "0"; - homingCount = "0"; - }; - new InteriorInstance(Tower) { - position = "478.373 363.933 210.21"; - rotation = "0 0 -1 90.137"; - scale = "1 1 1"; - interiorFile = "btowr2.dif"; - showTerrainInside = "0"; - AudioProfile = "Universal_Base_1"; - threshold2 = "60"; - threshold1 = "330"; - AudioEnvironment = SmallRoom; - }; - }; - new SimGroup(team0) { - }; - }; - new SimGroup(RandomRocks) { - - new SimGroup(Addition2brock6) { - - new InteriorInstance() { - position = "-211.225 415.883 78.0187"; - rotation = "0.0859163 -0.728135 0.680028 92.551"; - scale = "0.5 0.5 0.5"; - interiorFile = "brock6.dif"; - showTerrainInside = "0"; - }; - new InteriorInstance() { - position = "-247.225 413.883 69.4588"; - rotation = "0.0903608 -0.723175 0.684728 92.9544"; - scale = "1.5 1.5 1.5"; - interiorFile = "brock6.dif"; - showTerrainInside = "0"; - }; - new InteriorInstance() { - position = "-249.142 384.741 73.6875"; - rotation = "0.999508 0.0207068 0.0235741 82.6183"; - scale = "1.5 1.5 1.5"; - interiorFile = "brock6.dif"; - showTerrainInside = "0"; - }; - }; - new SimGroup(Addition3brock6) { - - new InteriorInstance() { - position = "-361.859 580.372 133.844"; - rotation = "0.0749949 -0.739978 0.668437 91.5936"; - scale = "0.5 0.5 0.5"; - interiorFile = "brock6.dif"; - showTerrainInside = "0"; - }; - new InteriorInstance() { - position = "-327.859 553.372 138.108"; - rotation = "0 0 1 3.17638"; - scale = "0.5 0.5 0.5"; - interiorFile = "brock6.dif"; - showTerrainInside = "0"; - }; - new InteriorInstance() { - position = "-338.859 543.372 141.73"; - rotation = "0 0 1 6.1087"; - scale = "0.5 0.5 0.5"; - interiorFile = "brock6.dif"; - showTerrainInside = "0"; - }; - }; - new SimGroup(Addition4brock6) { - - new InteriorInstance() { - position = "614.302 -90.5742 134.156"; - rotation = "0.999363 0.00750352 -0.0349017 194.321"; - scale = "0.5 0.5 0.5"; - interiorFile = "brock6.dif"; - showTerrainInside = "0"; - }; - new InteriorInstance() { - position = "623.302 -78.5742 127.591"; - rotation = "0.985035 0.145617 0.0922095 182.429"; - scale = "0.5 0.5 0.5"; - interiorFile = "brock6.dif"; - showTerrainInside = "0"; - }; - new InteriorInstance() { - position = "621.302 -52.5742 122.494"; - rotation = "0.496802 0.867682 0.0177913 176.44"; - scale = "0.5 0.5 0.5"; - interiorFile = "brock6.dif"; - showTerrainInside = "0"; - }; - }; - new SimGroup(Addition5brock6) { - - new InteriorInstance() { - position = "854.237 -299.5 51.5671"; - rotation = "0.990727 0.0989551 0.0930998 181.927"; - scale = "1.5 1.5 1.5"; - interiorFile = "brock6.dif"; - showTerrainInside = "0"; - }; - new InteriorInstance() { - position = "844.237 -312.5 50.7056"; - rotation = "0 0 1 5.44537"; - scale = "0.5 0.5 0.5"; - interiorFile = "brock6.dif"; - showTerrainInside = "0"; - }; - new InteriorInstance() { - position = "855.237 -281.5 51.8106"; - rotation = "0 0 1 1.30923"; - scale = "1.5 1.5 1.5"; - interiorFile = "brock6.dif"; - showTerrainInside = "0"; - }; - }; - }; - new SimGroup(Goodies) { - - new Item() { - position = "474.634 364.471 216.897"; - rotation = "0 0 1 94.538"; - scale = "1 1 1"; - dataBlock = "SniperRifle"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - }; - new Item() { - position = "-289.395 388.467 76.2374"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "RepairPatch"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - }; - new Item() { - position = "479.087 360.808 224.938"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "RepairPatch"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - }; - new Item() { - position = "475.639 368.891 224.967"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "RepairPatch"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - }; - new Item() { - position = "475.428 360.075 205.496"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "EnergyPack"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - }; - new Item() { - position = "-284.144 392.475 76.8"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "RepairPatch"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - }; - new Item() { - position = "-289.826 398.197 76.5"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "RepairPatch"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - }; - new Item() { - position = "473.838 358.562 224.84"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "ChaingunAmmo"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - }; - new Item() { - position = "480.085 363.933 224.88"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "ChaingunAmmo"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - }; - new Item() { - position = "474.75 368.018 205.334"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "DiscAmmo"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - }; - new Item() { - position = "478.415 368.123 205.334"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "DiscAmmo"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - }; - new Item() { - position = "-307.816 375.393 71.9373"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "ChaingunAmmo"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - }; - new Item() { - position = "-310.012 376.784 72.4285"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "DiscAmmo"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - }; - new Item() { - position = "-298.878 367.65 72.8"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "ChaingunAmmo"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - }; - }; - new SimGroup(RandomOrganics) { - - new SimGroup(Addition1BEPlant1) { - - new TSStatic() { - position = "12 44 103.084"; - rotation = "0.187078 -0.299834 -0.935469 91.8214"; - scale = "0.9 0.9 0.9"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "12 28 112.272"; - rotation = "0.673747 -0.00405274 0.738951 46.2144"; - scale = "0.7 0.7 0.7"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "-12 -60 115.006"; - rotation = "0.222631 0.00381878 0.974895 201.461"; - scale = "1.4 1.4 1.4"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "-44 -12 158.381"; - rotation = "0.296084 -0.0550443 0.953575 213.468"; - scale = "1 1 1"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "44 20 116.163"; - rotation = "0.0927419 0.0384151 -0.994949 45.2054"; - scale = "2 2 2"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "12 -12 110.944"; - rotation = "-0.125633 -0.322398 0.93823 94.648"; - scale = "0.5 0.5 0.5"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "52 4 115.459"; - rotation = "-0.325118 -0.266284 0.907409 15.4122"; - scale = "0.5 0.5 0.5"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "28 -36 103.991"; - rotation = "-0.104028 -0.1201 0.987296 217.551"; - scale = "0.7 0.7 0.7"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "-60 -12 164.709"; - rotation = "0.0580189 -0.15164 0.986732 104.741"; - scale = "1 1 1"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "-28 -60 120.725"; - rotation = "0.0577292 -0.221813 0.973379 141.962"; - scale = "0.5 0.5 0.5"; - shapeName = "borg1.dts"; - }; - }; - new SimGroup(Addition2BEPlant1) { - - new TSStatic() { - position = "-212 388 75.4125"; - rotation = "-0.206499 0.0467321 0.97733 186.842"; - scale = "0.5 0.5 0.5"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "-212 444 88.4125"; - rotation = "-0.574363 0.322049 0.75259 32.8274"; - scale = "0.7 0.7 0.7"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "-252 388 73.9906"; - rotation = "0.148682 -0.256464 -0.95505 66.3921"; - scale = "0.8 0.8 0.8"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "-276 356 78.7875"; - rotation = "-0.140865 0.079089 0.986865 160.257"; - scale = "0.5 0.5 0.5"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "-252 436 77.725"; - rotation = "0.166724 -0.218018 0.961598 224.408"; - scale = "0.5 0.5 0.5"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "-292 372 74.2094"; - rotation = "-0.207835 0.156096 0.965629 73.9162"; - scale = "1 1 1"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "-228 436 80.4438"; - rotation = "-0.287258 0.463175 -0.838422 54.8233"; - scale = "1.5 1.5 1.5"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "-196 356 91.7093"; - rotation = "0.201291 0.712453 0.67223 42.085"; - scale = "1.8 1.8 1.8"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "-212 420 79.5531"; - rotation = "-0.61971 0.490923 0.612335 36.7589"; - scale = "0.6 0.6 0.6"; - shapeName = "borg1.dts"; - }; - }; - new SimGroup(Addition3BELgTree16) { - - new TSStatic() { - position = "-316 268 55.3594"; - rotation = "0 0 1 97.9998"; - scale = "1.1 1.1 1.1"; - shapeName = "borg16.dts"; - }; - new TSStatic() { - position = "-276 236 66.9844"; - rotation = "0 0 1 183"; - scale = "0.9 0.9 0.9"; - shapeName = "borg16.dts"; - }; - new TSStatic() { - position = "-28 316 81.6407"; - rotation = "0 0 -1 38"; - scale = "1 1 1"; - shapeName = "borg16.dts"; - }; - new TSStatic() { - position = "-412 364 69.0468"; - rotation = "0 0 1 79.9998"; - scale = "1.2 1.2 1.2"; - shapeName = "borg16.dts"; - }; - new TSStatic() { - position = "-148 244 78.6875"; - rotation = "0 0 1 116"; - scale = "1.3 1.3 1.3"; - shapeName = "borg16.dts"; - }; - new TSStatic() { - position = "-68 300 89.1407"; - rotation = "0 0 1 192"; - scale = "1.3 1.3 1.3"; - shapeName = "borg16.dts"; - }; - new TSStatic() { - position = "-236 540 147.953"; - rotation = "0 0 1 37"; - scale = "1.2 1.2 1.2"; - shapeName = "borg16.dts"; - }; - new TSStatic() { - position = "-92 292 91.3282"; - rotation = "0 0 1 67"; - scale = "1.3 1.3 1.3"; - shapeName = "borg16.dts"; - }; - new TSStatic() { - position = "-52 300 86.4375"; - rotation = "0 0 1 12"; - scale = "1.3 1.3 1.3"; - shapeName = "borg16.dts"; - }; - new TSStatic() { - position = "-76 260 95.8438"; - rotation = "0 0 1 9.00004"; - scale = "1.1 1.1 1.1"; - shapeName = "borg16.dts"; - }; - new TSStatic() { - position = "-276 364 74.8594"; - rotation = "0 0 1 231"; - scale = "1.5 1.5 1.5"; - shapeName = "borg16.dts"; - }; - new TSStatic() { - position = "-420 236 87.4531"; - rotation = "0 0 1 81.0002"; - scale = "1.2 1.2 1.2"; - shapeName = "borg16.dts"; - }; - new TSStatic() { - position = "-140 580 123.656"; - rotation = "0 0 -1 88"; - scale = "1 1 1"; - shapeName = "borg16.dts"; - }; - new TSStatic() { - position = "-292 572 141.844"; - rotation = "0 0 1 46"; - scale = "0.8 0.8 0.8"; - shapeName = "borg16.dts"; - }; - new TSStatic() { - position = "-140 540 112.297"; - rotation = "0 0 1 123"; - scale = "1.5 1.5 1.5"; - shapeName = "borg16.dts"; - }; - }; - new SimGroup(Addition1BESmTree17) { - - new TSStatic() { - position = "140 -228 165.828"; - rotation = "0.285418 0.403782 0.869193 24.074"; - scale = "1.2 1.2 1.2"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "-268 -100 140.031"; - rotation = "-0.0727138 0.0455015 0.996314 146.118"; - scale = "1.5 1.5 1.5"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "292 -172 96.375"; - rotation = "-0.437468 0.474769 -0.763686 29.8352"; - scale = "1.4 1.4 1.4"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "84 84 105.656"; - rotation = "-0.154012 -0.0638678 0.986003 239.303"; - scale = "1 1 1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "-172 28 185.844"; - rotation = "0.13083 -0.102316 -0.986111 65.7286"; - scale = "0.9 0.9 0.9"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "-308 60 92.1562"; - rotation = "-0.6199 0.346496 0.704035 21.1836"; - scale = "1.5 1.5 1.5"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "-76 -4 162.375"; - rotation = "0.0636308 -0.172424 -0.982965 109.928"; - scale = "0.9 0.9 0.9"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "-356 12 77.4531"; - rotation = "-0.160854 0.0557614 0.985402 186.898"; - scale = "1.4 1.4 1.4"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "-124 228 82.5781"; - rotation = "0.00475492 0.193705 -0.981048 83.0869"; - scale = "1.3 1.3 1.3"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "364 -284 77.0157"; - rotation = "0.0643768 0.238911 -0.968905 59.5481"; - scale = "1 1 1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "-340 20 82.375"; - rotation = "-0.0214268 0.428443 0.903315 30.8605"; - scale = "1.1 1.1 1.1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "300 -116 111.453"; - rotation = "0.265667 0.740693 -0.617086 19.3317"; - scale = "1.1 1.1 1.1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "324 -108 114.109"; - rotation = "0.0390719 0.0270788 0.998869 134.046"; - scale = "1.4 1.4 1.4"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "-388 -388 100.922"; - rotation = "0.278494 0.331909 0.901264 24.3416"; - scale = "1.1 1.1 1.1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "348 -412 76.1093"; - rotation = "-0.0417168 0.0484254 0.997955 222.92"; - scale = "0.8 0.8 0.8"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "300 84 104.672"; - rotation = "-0.184826 -0.0124876 -0.982692 74.9641"; - scale = "1.5 1.5 1.5"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "-372 -548 99.172"; - rotation = "0.0555475 0.0330002 0.997911 229.908"; - scale = "1.1 1.1 1.1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "-196 -508 110.563"; - rotation = "-0.142972 0.0412338 0.988867 214.634"; - scale = "1.5 1.5 1.5"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "340 236 165.906"; - rotation = "-0.0987353 0.15622 0.982775 86.9933"; - scale = "1.3 1.3 1.3"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "380 -308 77.75"; - rotation = "0.157783 -0.115876 0.980651 69.0414"; - scale = "1 1 1"; - shapeName = "borg17.dts"; - }; - }; - new SimGroup(Addition2BELgTree18) { - - new TSStatic() { - position = "-308 364 65.6094"; - rotation = "0 0 -1 69.0002"; - scale = "1.3 1.3 1.3"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "-260 340 82.5312"; - rotation = "0 0 1 195"; - scale = "1.3 1.3 1.3"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "236 -60 105.828"; - rotation = "0 0 1 176"; - scale = "0.9 0.9 0.9"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "76 100 104.641"; - rotation = "0 0 -1 92.0004"; - scale = "1.5 1.5 1.5"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "260 -60 103.438"; - rotation = "0 0 -1 94"; - scale = "0.9 0.9 0.9"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "-244 276 65.7344"; - rotation = "0 0 1 6.00005"; - scale = "1.4 1.4 1.4"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "-36 -188 64.8282"; - rotation = "0 0 -1 120"; - scale = "1 1 1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "188 380 84"; - rotation = "0 0 1 35"; - scale = "1 1 1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "-364 300 58.6406"; - rotation = "0 0 1 215"; - scale = "1.3 1.3 1.3"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "-76 -300 120.156"; - rotation = "0 0 1 75.0002"; - scale = "1 1 1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "84 28 111.031"; - rotation = "0 0 1 47"; - scale = "1.4 1.4 1.4"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "-276 244 65"; - rotation = "0 0 1 130"; - scale = "1.5 1.5 1.5"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "300 -244 97.797"; - rotation = "0 0 1 152"; - scale = "1.2 1.2 1.2"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "364 36 124.031"; - rotation = "0 0 1 218"; - scale = "1 1 1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "-340 156 87.4531"; - rotation = "0 0 1 104"; - scale = "1.3 1.3 1.3"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "92 276 67.375"; - rotation = "0 0 1 39"; - scale = "0.8 0.8 0.8"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "-4 228 101.828"; - rotation = "0 0 -1 87.0002"; - scale = "0.8 0.8 0.8"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "92 340 71.3125"; - rotation = "0 0 1 76.9998"; - scale = "1.2 1.2 1.2"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "-300 276 58.1875"; - rotation = "0 0 1 57.9999"; - scale = "1 1 1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "-188 452 92.2656"; - rotation = "0 0 -1 81.0002"; - scale = "1.4 1.4 1.4"; - shapeName = "borg18.dts"; - }; - }; - new SimGroup(Addition1BESmTree17) { - - new TSStatic() { - position = "500 -316 96.6875"; - rotation = "0.0189433 -0.0920088 0.995578 210.869"; - scale = "1.4 1.4 1.4"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "820 -412 60.8594"; - rotation = "0.151268 0.0290211 0.988067 97.6825"; - scale = "1.2 1.2 1.2"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "876 -276 51.7187"; - rotation = "-0.0767067 0.461516 -0.883809 20.3196"; - scale = "0.9 0.9 0.9"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "652 244 85.625"; - rotation = "0.307312 -0.398951 0.863943 32.1955"; - scale = "1.3 1.3 1.3"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "708 -276 72.7656"; - rotation = "0.265436 -0.176198 0.947891 59.6082"; - scale = "1.5 1.5 1.5"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "836 -308 47.8438"; - rotation = "0.0204826 -0.0196076 0.999598 140.015"; - scale = "1.4 1.4 1.4"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "604 4 141.703"; - rotation = "-0.107106 -0.00849662 0.994211 233.731"; - scale = "1.2 1.2 1.2"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "1172 -12 145.812"; - rotation = "-0.169217 0.00416148 0.98557 91.8325"; - scale = "0.8 0.8 0.8"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "1020 -204 127.797"; - rotation = "-0.0211118 0.743291 0.668635 20.8112"; - scale = "0.8 0.8 0.8"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "1108 44 107.75"; - rotation = "-0.0451934 0.160773 0.985956 44.5658"; - scale = "1 1 1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "644 -348 115.234"; - rotation = "0.737692 0.0137925 -0.674997 20.6192"; - scale = "1.2 1.2 1.2"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "844 140 163.828"; - rotation = "-0.155668 -0.0493325 0.986577 83.7687"; - scale = "1.1 1.1 1.1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "1092 76 116.188"; - rotation = "-0.140404 -0.0943009 -0.985593 74.8008"; - scale = "1.2 1.2 1.2"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "940 -180 84.4688"; - rotation = "-0.0699772 0.0254908 0.997223 103.155"; - scale = "1 1 1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "596 76 133.891"; - rotation = "-0.145307 -0.0467364 0.988282 129.523"; - scale = "0.8 0.8 0.8"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "1036 188 136.187"; - rotation = "0.0143986 -0.126977 0.991801 89.4714"; - scale = "1.3 1.3 1.3"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "708 -60 140.547"; - rotation = "-0.214297 -0.107879 0.970793 63.5095"; - scale = "0.9 0.9 0.9"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "980 -316 79.7969"; - rotation = "-0.524424 0.50887 -0.682665 23.2662"; - scale = "1.2 1.2 1.2"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "532 52 118.094"; - rotation = "0.236918 0.0674468 -0.969186 70.6835"; - scale = "1.1 1.1 1.1"; - shapeName = "borg17.dts"; - }; - }; - new SimGroup(Addition2BELgTree18) { - - new TSStatic() { - position = "428 188 135.5"; - rotation = "0 0 1 49"; - scale = "1.5 1.5 1.5"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "844 -212 55.6563"; - rotation = "0 0 -1 82"; - scale = "0.9 0.9 0.9"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "588 292 116.109"; - rotation = "0 0 1 144"; - scale = "1.2 1.2 1.2"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "964 12 184.766"; - rotation = "0 0 1 134"; - scale = "1.5 1.5 1.5"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "844 -244 54.0469"; - rotation = "0 0 -1 16.9999"; - scale = "1.4 1.4 1.4"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "700 244 81.3907"; - rotation = "0 0 1 9.99989"; - scale = "0.9 0.9 0.9"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1060 -220 118.953"; - rotation = "0 0 1 228"; - scale = "1 1 1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1204 316 61.4843"; - rotation = "0 0 1 177"; - scale = "0.9 0.9 0.9"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1132 284 74.4219"; - rotation = "0 0 -1 23.9998"; - scale = "1.1 1.1 1.1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "556 -12 129.312"; - rotation = "0 0 -1 111"; - scale = "1.3 1.3 1.3"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "412 -44 68.4531"; - rotation = "0 0 1 7.00001"; - scale = "0.9 0.9 0.9"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "860 292 155.844"; - rotation = "0 0 -1 10.9999"; - scale = "1.3 1.3 1.3"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1036 -180 124.484"; - rotation = "0 0 1 88.9998"; - scale = "0.9 0.9 0.9"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "588 -52 129.75"; - rotation = "0 0 -1 67.0005"; - scale = "1.1 1.1 1.1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "468 -372 66.0937"; - rotation = "0 0 1 128"; - scale = "1.1 1.1 1.1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "860 116 166.922"; - rotation = "0 0 1 11"; - scale = "1.5 1.5 1.5"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "716 252 82.9531"; - rotation = "0 0 1 11"; - scale = "1.4 1.4 1.4"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1180 -444 145.719"; - rotation = "0 0 1 4.99997"; - scale = "1.5 1.5 1.5"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "876 -380 52.9063"; - rotation = "0 0 1 46"; - scale = "0.9 0.9 0.9"; - shapeName = "borg18.dts"; - }; - }; - new SimGroup(Addition3BEPlant5) { - - new TSStatic() { - position = "588 156 102.809"; - rotation = "-0.193563 0.0259592 0.980744 181.962"; - scale = "1 1 1"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "492 140 100.575"; - rotation = "0.146029 0.137793 0.979637 117.055"; - scale = "1.5 1.5 1.5"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "588 140 108.325"; - rotation = "-0.318993 0.168786 0.932606 227.962"; - scale = "1 1 1"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "548 220 119.778"; - rotation = "-0.542672 -0.517663 -0.661462 28.3949"; - scale = "1 1 1"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "548 196 107.903"; - rotation = "-0.575099 -0.240159 0.782039 51.104"; - scale = "1.3 1.3 1.3"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "492 196 112.762"; - rotation = "0.253778 -0.1873 0.948955 203.761"; - scale = "1 1 1"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "604 156 105.887"; - rotation = "-0.0326261 0.0389834 0.998707 225.946"; - scale = "1.5 1.5 1.5"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "564 236 114.544"; - rotation = "0.208184 -0.0821455 0.974634 115.338"; - scale = "1.4 1.4 1.4"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "492 148 99.2617"; - rotation = "-0.0149542 -0.224199 -0.974429 58.2532"; - scale = "1.1 1.1 1.1"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "572 44 129.95"; - rotation = "-0.0753689 0.145225 0.986524 67.7173"; - scale = "1.3 1.3 1.3"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "628 188 107.028"; - rotation = "-0.124681 -0.107766 -0.986327 72.7519"; - scale = "1.3 1.3 1.3"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "580 108 129.606"; - rotation = "-0.160092 0.296592 0.94149 163.037"; - scale = "1.2 1.2 1.2"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "572 188 105.919"; - rotation = "-0.0916734 -0.212707 0.972806 188.756"; - scale = "1 1 1"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "636 236 95.4966"; - rotation = "0.296211 -0.0940407 0.950482 86.9005"; - scale = "1.1 1.1 1.1"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "652 132 111.966"; - rotation = "0.114039 0.329162 0.937362 63.2603"; - scale = "1.2 1.2 1.2"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "596 108 134.653"; - rotation = "-0.131211 0.224869 0.965514 229.455"; - scale = "1.5 1.5 1.5"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "660 60 143.575"; - rotation = "-0.0366527 -0.205783 0.977911 82.2664"; - scale = "1.2 1.2 1.2"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "676 92 133.559"; - rotation = "-0.143912 0.101845 0.984336 208.565"; - scale = "1.2 1.2 1.2"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "484 124 107.887"; - rotation = "0.0688712 0.267605 0.961064 116.062"; - scale = "1.4 1.4 1.4"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "548 188 102.95"; - rotation = "-0.141141 -0.288261 0.947093 135.236"; - scale = "1.2 1.2 1.2"; - shapeName = "borg5.dts"; - }; - }; - new SimGroup(Addition4BEPlant1) { - - new TSStatic() { - position = "196 124 106.788"; - rotation = "-0.0194762 0.0360942 0.999159 185.995"; - scale = "0.8 0.8 0.8"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "324 132 137.709"; - rotation = "-0.824061 0.269725 0.498169 40.8144"; - scale = "1.5 1.5 1.5"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "404 148 129.272"; - rotation = "-0.453514 0.0103151 -0.89119 57.3823"; - scale = "1.3 1.3 1.3"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "148 164 106.272"; - rotation = "0.346131 0.139353 0.927779 82.2303"; - scale = "1.3 1.3 1.3"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "388 52 119.178"; - rotation = "0.299604 0.0496035 0.952773 96.7594"; - scale = "0.8 0.8 0.8"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "452 220 146.162"; - rotation = "-0.155184 -0.275246 0.948766 94.0103"; - scale = "1.5 1.5 1.5"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "164 324 104.084"; - rotation = "-0.256999 0.966412 0 31.3768"; - scale = "1.4 1.4 1.4"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "380 100 118.959"; - rotation = "0.252843 -0.0682316 0.965098 206.091"; - scale = "0.7 0.7 0.7"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "252 140 124.506"; - rotation = "-0.290357 -0.0857175 0.953072 149.43"; - scale = "0.7 0.7 0.7"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "172 364 93.2094"; - rotation = "0.0544781 0.166186 0.984588 180.985"; - scale = "1 1 1"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "156 180 97.1313"; - rotation = "0.735189 0.316481 0.599448 35.9322"; - scale = "1.5 1.5 1.5"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "452 212 143.413"; - rotation = "-0.292077 -0.0147327 -0.956281 70.3941"; - scale = "2 2 2"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "476 324 193.725"; - rotation = "-0.46624 -0.0634 0.882384 21.4771"; - scale = "1.5 1.5 1.5"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "428 164 133.319"; - rotation = "-0.0128469 -0.219879 0.975443 155.595"; - scale = "0.6 0.6 0.6"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "388 252 165.584"; - rotation = "0.0979139 -0.392969 0.914324 89.1213"; - scale = "0.7 0.7 0.7"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "388 164 134.662"; - rotation = "0.136418 -0.0673901 0.988357 100.66"; - scale = "0.6 0.6 0.6"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "436 148 121.663"; - rotation = "-0.487287 0.0647607 -0.870837 83.7945"; - scale = "1.7 1.7 1.7"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "236 340 114.647"; - rotation = "-0.0104936 0.224169 0.974494 182.924"; - scale = "1.1 1.1 1.1"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "324 164 150.147"; - rotation = "-0.547013 0.782764 -0.296745 23.293"; - scale = "1 1 1"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "268 116 123.741"; - rotation = "-0.479476 0.578886 -0.65954 35.7259"; - scale = "1.2 1.2 1.2"; - shapeName = "borg1.dts"; - }; - }; - new SimGroup(Addition5BEPlant1) { - - new TSStatic() { - position = "1364 -852 77.2562"; - rotation = "-0.768939 0.365446 -0.524579 33.6006"; - scale = "0.9 0.9 0.9"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1196 -836 64.3031"; - rotation = "0.210641 0.146051 -0.966592 61.7001"; - scale = "0.9 0.9 0.9"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1244 -780 86.6625"; - rotation = "-0.115374 -0.141325 0.983217 175.084"; - scale = "1.3 1.3 1.3"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1308 -876 75.1782"; - rotation = "0.228708 -0.120099 0.966058 183.864"; - scale = "0.9 0.9 0.9"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1132 -892 65.725"; - rotation = "-0.12685 0.170462 0.977165 141.825"; - scale = "0.9 0.9 0.9"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1244 -924 102.069"; - rotation = "-0.110985 0.0519229 0.992465 144.254"; - scale = "2 2 2"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1180 -868 69.0688"; - rotation = "0.0109543 0.159993 0.987057 149.382"; - scale = "1.8 1.8 1.8"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1204 -644 98.9593"; - rotation = "0.110772 -0.25673 0.960114 237.022"; - scale = "1.3 1.3 1.3"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1396 -940 87.4594"; - rotation = "-0.266377 0.35014 0.898023 69.6625"; - scale = "0.5 0.5 0.5"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1292 -620 110.038"; - rotation = "-0.054907 0.139267 0.988732 202.747"; - scale = "1.7 1.7 1.7"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1060 -644 119.631"; - rotation = "-0.492076 0.214682 -0.843666 61.1638"; - scale = "0.6 0.6 0.6"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1316 -708 100.069"; - rotation = "-0.195611 0.0941593 0.976151 203.444"; - scale = "2 2 2"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1172 -788 55.9126"; - rotation = "0.0333406 0.00956025 0.999398 122.029"; - scale = "1.6 1.6 1.6"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1076 -700 95.6469"; - rotation = "-0.0505172 -0.443439 -0.89488 14.5118"; - scale = "0.9 0.9 0.9"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1260 -828 77.9125"; - rotation = "0.0225397 0.0724205 0.997119 129.128"; - scale = "1.2 1.2 1.2"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1076 -860 65.7719"; - rotation = "0.133628 -0.137519 0.981444 105.039"; - scale = "1.7 1.7 1.7"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1316 -836 87.85"; - rotation = "-0.09518 -0.0525785 0.994071 108.324"; - scale = "0.6 0.6 0.6"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1132 -908 71.2563"; - rotation = "0.00708622 0.347095 0.937803 103.601"; - scale = "0.8 0.8 0.8"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1156 -916 80.3344"; - rotation = "-0.0730995 0.138384 0.987677 220.536"; - scale = "1.2 1.2 1.2"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1060 -564 127.616"; - rotation = "0.0985932 0.092788 0.990793 200.811"; - scale = "1.1 1.1 1.1"; - shapeName = "borg1.dts"; - }; - }; - new SimGroup(Addition6BELgTree18) { - - new TSStatic() { - position = "1340 -876 63.3125"; - rotation = "0 0 1 232"; - scale = "1.1 1.1 1.1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1348 -524 77.4063"; - rotation = "0 0 1 201"; - scale = "1.5 1.5 1.5"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1244 -972 92.5"; - rotation = "0 0 1 195"; - scale = "1.5 1.5 1.5"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1004 -932 71.3281"; - rotation = "0 0 1 121"; - scale = "0.8 0.8 0.8"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1044 -852 70.5938"; - rotation = "0 0 -1 96.0002"; - scale = "1 1 1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1172 -804 54.0625"; - rotation = "0 0 1 138"; - scale = "1.2 1.2 1.2"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1164 -852 60.6406"; - rotation = "0 0 1 153"; - scale = "1.1 1.1 1.1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1060 -716 94.75"; - rotation = "0 0 -1 73.0006"; - scale = "0.9 0.9 0.9"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1260 -612 106.578"; - rotation = "0 0 -1 82"; - scale = "1.1 1.1 1.1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1036 -836 72.0157"; - rotation = "0 0 -1 113"; - scale = "1.2 1.2 1.2"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1268 -948 95.7499"; - rotation = "0 0 1 113"; - scale = "1.5 1.5 1.5"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1244 -932 98.625"; - rotation = "0 0 1 9.99989"; - scale = "1.1 1.1 1.1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1252 -716 85.6875"; - rotation = "0 0 1 33"; - scale = "1.1 1.1 1.1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1316 -524 79.6719"; - rotation = "0 0 1 207"; - scale = "0.9 0.9 0.9"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1324 -644 109.062"; - rotation = "0 0 1 113"; - scale = "0.8 0.8 0.8"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1132 -452 157.297"; - rotation = "0 0 1 180"; - scale = "1.1 1.1 1.1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "980 -924 78.2031"; - rotation = "1 0 0 0"; - scale = "1.3 1.3 1.3"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1004 -716 103.766"; - rotation = "0 0 1 72.0002"; - scale = "0.8 0.8 0.8"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1020 -740 98.406"; - rotation = "0 0 1 127"; - scale = "1.4 1.4 1.4"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1204 -724 66.0312"; - rotation = "0 0 1 149"; - scale = "1.2 1.2 1.2"; - shapeName = "borg18.dts"; - }; - }; - new SimGroup(Addition1BESmTree17) { - - new TSStatic() { - position = "516 -852 114.203"; - rotation = "0.0226453 0.0115586 0.999677 203.992"; - scale = "1.4 1.4 1.4"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "412 -636 137.328"; - rotation = "-0.054195 -0.05415 0.997061 181.994"; - scale = "1.1 1.1 1.1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "516 -852 114.203"; - rotation = "-0.0128273 -0.0480088 -0.998765 60.0615"; - scale = "1.1 1.1 1.1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "444 -756 96.0001"; - rotation = "-0.0616775 -0.117932 0.991104 215.7"; - scale = "1.1 1.1 1.1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "340 -772 79.5938"; - rotation = "-0.214777 0.964319 0.154792 6.45366"; - scale = "1.5 1.5 1.5"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "604 -844 157.766"; - rotation = "-0.0445501 -0.0465846 0.99792 184.99"; - scale = "1.4 1.4 1.4"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "628 -644 187.891"; - rotation = "0.19108 -0.0345838 -0.980965 98.0915"; - scale = "0.8 0.8 0.8"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "372 -764 83.5781"; - rotation = "0.126305 0.0603915 -0.990151 87.5658"; - scale = "1.5 1.5 1.5"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "588 -844 156.516"; - rotation = "-0.124319 -0.119349 0.985038 104.836"; - scale = "1.3 1.3 1.3"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "412 -900 119.953"; - rotation = "-0.0628523 -0.0476702 0.996884 210.907"; - scale = "1.1 1.1 1.1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "428 -540 160.078"; - rotation = "-0.106477 0.0229367 0.994051 223.763"; - scale = "1.5 1.5 1.5"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "468 -652 141.938"; - rotation = "0.209904 -0.0580286 -0.975998 73.3289"; - scale = "1.5 1.5 1.5"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "404 -892 119.344"; - rotation = "0.0258563 0.208098 -0.977766 83.2771"; - scale = "1.3 1.3 1.3"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "476 -500 153.453"; - rotation = "0.770847 -0.137338 -0.62204 20.7593"; - scale = "1.1 1.1 1.1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "284 -532 90.2187"; - rotation = "-0.835172 0.10902 0.539075 20.2546"; - scale = "1.3 1.3 1.3"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "300 -860 106.953"; - rotation = "0.0300008 0.141884 0.989429 78.5967"; - scale = "1.5 1.5 1.5"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "468 -724 105.984"; - rotation = "-0.231502 0.313655 -0.920884 48.4362"; - scale = "1.1 1.1 1.1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "436 -780 93.1406"; - rotation = "-0.0166021 0.0320587 0.999348 205.983"; - scale = "0.9 0.9 0.9"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "276 -876 111.875"; - rotation = "0.10672 0.12651 0.986208 236.335"; - scale = "1.5 1.5 1.5"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "380 -740 84.4219"; - rotation = "-0.126943 0.171214 0.977022 55.0849"; - scale = "0.8 0.8 0.8"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "460 -564 163.094"; - rotation = "-0.00537145 0.279877 -0.960021 67.1369"; - scale = "1.2 1.2 1.2"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "468 -868 119.641"; - rotation = "-0.275798 -0.0223686 -0.960955 45.6079"; - scale = "1.2 1.2 1.2"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "580 -812 159.172"; - rotation = "0.11136 -0.181869 0.976997 71.2576"; - scale = "0.9 0.9 0.9"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "292 -644 101.859"; - rotation = "-0.154484 -0.000180158 0.987995 176.048"; - scale = "0.9 0.9 0.9"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "340 -876 123.937"; - rotation = "0.00543177 0.0324584 0.999458 184.997"; - scale = "1.3 1.3 1.3"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "356 -644 117.328"; - rotation = "-0.0709721 -0.0117515 0.997409 157.058"; - scale = "0.9 0.9 0.9"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "444 -540 160.797"; - rotation = "0.0687445 0.0224915 0.997381 82.149"; - scale = "1.2 1.2 1.2"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "516 -852 114.203"; - rotation = "0.0261136 -0.00134998 0.999658 144.011"; - scale = "1.3 1.3 1.3"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "580 -796 159.547"; - rotation = "0.0555007 0.0996695 0.993472 234.693"; - scale = "1.2 1.2 1.2"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "452 -532 160.047"; - rotation = "0.0187232 0.0595054 0.998052 143.067"; - scale = "1.4 1.4 1.4"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "452 -572 159.516"; - rotation = "-0.107753 -0.142268 0.983946 143.555"; - scale = "1 1 1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "572 -772 157.203"; - rotation = "0.085667 0.0576616 0.994654 176.021"; - scale = "0.8 0.8 0.8"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "348 -788 81.5782"; - rotation = "-0.119645 0.050421 0.991536 217.701"; - scale = "0.8 0.8 0.8"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "380 -740 84.4219"; - rotation = "-0.152944 0.359364 0.920579 29.2333"; - scale = "1 1 1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "268 -564 82.4531"; - rotation = "-0.0958363 0.325672 -0.940613 33.9076"; - scale = "0.9 0.9 0.9"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "460 -540 162.266"; - rotation = "-0.131657 0.0740015 0.988529 198.786"; - scale = "0.8 0.8 0.8"; - shapeName = "borg17.dts"; - }; - }; - new SimGroup(Addition2BELgTree18) { - - new TSStatic() { - position = "332 -932 118.766"; - rotation = "0 0 -1 53.9998"; - scale = "1.5 1.5 1.5"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "188 -604 87.5781"; - rotation = "0 0 1 159"; - scale = "1.1 1.1 1.1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "12 -844 121.125"; - rotation = "0 0 1 233"; - scale = "1.2 1.2 1.2"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "-36 -468 135.203"; - rotation = "0 0 1 76"; - scale = "0.8 0.8 0.8"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "108 -892 102.594"; - rotation = "0 0 1 53"; - scale = "0.8 0.8 0.8"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "476 -652 142.578"; - rotation = "0 0 1 208"; - scale = "1.5 1.5 1.5"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "444 -524 160.156"; - rotation = "0 0 1 17"; - scale = "1.1 1.1 1.1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "-28 -468 136"; - rotation = "0 0 1 121"; - scale = "0.9 0.9 0.9"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "228 -452 115.188"; - rotation = "0 0 1 36"; - scale = "1 1 1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "164 -564 91.9688"; - rotation = "0 0 -1 44.9999"; - scale = "1.3 1.3 1.3"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "76 -412 131.828"; - rotation = "0 0 -1 1.00014"; - scale = "0.8 0.8 0.8"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "260 -892 118.438"; - rotation = "0 0 1 150"; - scale = "1.1 1.1 1.1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "452 -556 162.062"; - rotation = "0 0 1 20"; - scale = "0.9 0.9 0.9"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "156 -604 84.5781"; - rotation = "0 0 1 93.0002"; - scale = "1.5 1.5 1.5"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "340 -780 79.5"; - rotation = "0 0 -1 10.9999"; - scale = "1.5 1.5 1.5"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "284 -676 104.078"; - rotation = "0 0 1 109"; - scale = "1.5 1.5 1.5"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "212 -748 102.672"; - rotation = "0 0 1 180"; - scale = "1.2 1.2 1.2"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "44 -708 86.1249"; - rotation = "0 0 1 177"; - scale = "0.8 0.8 0.8"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "324 -436 77.3281"; - rotation = "0 0 -1 35"; - scale = "1.1 1.1 1.1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "228 -532 103.313"; - rotation = "0 0 1 174"; - scale = "1 1 1"; - shapeName = "borg18.dts"; - }; - }; - new TSStatic() { - position = "590.041 -542.501 248.284"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - shapeName = "borg18.dts"; - }; - new SimGroup(Addition3BELgTree18) { - - new TSStatic() { - position = "612 676 187.797"; - rotation = "0 0 1 236"; - scale = "1 1 1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "596 684 188.609"; - rotation = "0 0 1 222"; - scale = "1.4 1.4 1.4"; - shapeName = "borg18.dts"; - }; - }; - new SimGroup(Addition4BELgTree18) { - - new TSStatic() { - position = "484 548 68.625"; - rotation = "0 0 1 75.0002"; - scale = "1.3 1.3 1.3"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "532 524 84.0782"; - rotation = "0 0 1 161"; - scale = "0.8 0.8 0.8"; - shapeName = "borg18.dts"; - }; - }; - new SimGroup(Addition5BELgTree18) { - - new TSStatic() { - position = "268 668 97.359"; - rotation = "0 0 1 60.0001"; - scale = "0.8 0.8 0.8"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "60 588 135.438"; - rotation = "0 0 1 218"; - scale = "1.2 1.2 1.2"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "44 780 52.0312"; - rotation = "0 0 1 168"; - scale = "1.3 1.3 1.3"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "316 604 115.359"; - rotation = "0 0 1 1.9999"; - scale = "1.1 1.1 1.1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "124 820 54.7031"; - rotation = "0 0 1 21"; - scale = "1.1 1.1 1.1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "84 556 133.891"; - rotation = "0 0 -1 38"; - scale = "0.9 0.9 0.9"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "76 572 133.078"; - rotation = "0 0 -1 34.0002"; - scale = "0.8 0.8 0.8"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "236 588 125.078"; - rotation = "0 0 1 57"; - scale = "0.8 0.8 0.8"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "332 668 98.781"; - rotation = "0 0 1 130"; - scale = "0.9 0.9 0.9"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "332 740 90.7656"; - rotation = "0 0 1 85.9998"; - scale = "1.5 1.5 1.5"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "276 812 99.359"; - rotation = "0 0 1 42"; - scale = "1 1 1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "300 692 100.281"; - rotation = "0 0 1 32"; - scale = "1.2 1.2 1.2"; - shapeName = "borg18.dts"; - }; - }; - new SimGroup(Addition6BESmTree17) { - - new TSStatic() { - position = "316 764 90.3593"; - rotation = "-0.269346 0.0747762 0.960136 9.37201"; - scale = "1.4 1.4 1.4"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "284 796 100.625"; - rotation = "-0.109174 -0.268087 0.957189 30.2388"; - scale = "1 1 1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "92 788 52.4374"; - rotation = "-0.00226441 0.0373222 0.999301 211.979"; - scale = "0.8 0.8 0.8"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "236 596 124.828"; - rotation = "0.0374212 -0.125582 -0.991377 48.3697"; - scale = "0.9 0.9 0.9"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "92 604 130.219"; - rotation = "0.130424 -0.533966 0.835386 29.7251"; - scale = "1.2 1.2 1.2"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "236 580 125.891"; - rotation = "0.988853 -0.0859407 0.121593 8.21026"; - scale = "1.1 1.1 1.1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "204 844 64"; - rotation = "0.075034 -0.0658218 0.995006 117.256"; - scale = "1.4 1.4 1.4"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "324 724 93.625"; - rotation = "0.177271 -0.147427 0.973057 84.5554"; - scale = "0.9 0.9 0.9"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "68 692 85.2812"; - rotation = "0.197225 0.181032 0.963499 72.0145"; - scale = "0.8 0.8 0.8"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "324 588 114.719"; - rotation = "-0.0913719 -0.0166197 0.995678 143.149"; - scale = "1.5 1.5 1.5"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "124 812 54.3437"; - rotation = "-0.139173 -0.0205308 0.990055 195.843"; - scale = "1 1 1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "332 772 93.0156"; - rotation = "-0.630648 0.457846 -0.626626 22.1727"; - scale = "0.8 0.8 0.8"; - shapeName = "borg17.dts"; - }; - }; - new SimGroup(Addition7BESmTree17) { - - new TSStatic() { - position = "724 500 100.312"; - rotation = "-0.474947 0.55988 -0.67894 10.2955"; - scale = "0.8 0.8 0.8"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "692 644 172.547"; - rotation = "-0.120142 -0.104658 0.987225 130.562"; - scale = "0.8 0.8 0.8"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "788 604 183.453"; - rotation = "-0.381454 0.132918 0.914782 46.594"; - scale = "0.8 0.8 0.8"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "748 620 177.734"; - rotation = "-0.133731 0.0451644 0.989988 126.465"; - scale = "1 1 1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "700 636 170.906"; - rotation = "-0.28187 -0.0991843 0.954312 63.3697"; - scale = "1.4 1.4 1.4"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "796 676 167.984"; - rotation = "-0.114769 0.0364394 0.992724 166.101"; - scale = "1.5 1.5 1.5"; - shapeName = "borg17.dts"; - }; - }; - new SimGroup(Addition8BESmTree17) { - - new TSStatic() { - position = "612 492 82.4219"; - rotation = "0.15131 -0.0330094 0.987935 175.06"; - scale = "1.4 1.4 1.4"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "652 428 79.7656"; - rotation = "0.122244 -0.16474 -0.978732 87.229"; - scale = "0.8 0.8 0.8"; - shapeName = "borg17.dts"; - }; - }; - }; - new SimGroup(NotSoRandomOrganics) { - - new InteriorInstance() { - position = "-234.377 399.56 72.0484"; - rotation = "1 0 0 139.229"; - scale = "1.18518 1.63312 1"; - interiorFile = "brock7.dif"; - showTerrainInside = "0"; - }; - new InteriorInstance() { - position = "-359.655 570.11 126.837"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "brock8.dif"; - showTerrainInside = "0"; - }; - new InteriorInstance() { - position = "-361.343 564.269 130.504"; - rotation = "1 0 0 50.4203"; - scale = "1 1 1"; - interiorFile = "brock8.dif"; - showTerrainInside = "0"; - }; - new InteriorInstance() { - position = "-351.76 562.309 125.975"; - rotation = "0.769297 0.578037 -0.272129 62.9301"; - scale = "1 1 1"; - interiorFile = "brock8.dif"; - showTerrainInside = "0"; - }; - new StaticShape(SWDeadMed) { - position = "-332.993 471.436 122.37"; - rotation = "-0.294439 -0.309888 0.904033 47.0646"; - scale = "1 1 0.99"; - dataBlock = "MediumMaleHuman_Dead"; - lockCount = "0"; - homingCount = "0"; - trainingSkin = 1; - }; - new StaticShape(MedDeadBody) { - position = "477.477 360.201 204.267"; - rotation = "0 0 1 82.5059"; - scale = "1 1 1"; - dataBlock = "MediumMaleHuman_Dead"; - lockCount = "0"; - homingCount = "0"; - }; - new StaticShape(SWDeadLt) { - position = "-205.392 473.86 97.7869"; - rotation = "-0.94867 0.262068 0.177046 24.3075"; - scale = "1 1 1"; - dataBlock = "LightMaleHuman_Dead"; - lockCount = "0"; - homingCount = "0"; - trainingSkin = 1; - }; - new StaticShape(LightDeadBody) { - position = "474.167 360.154 215.68"; - rotation = "0 0 1 94.538"; - scale = "1 1 1"; - dataBlock = "LightMaleHuman_Dead"; - lockCount = "0"; - homingCount = "0"; - }; - new InteriorInstance() { - position = "-32.6219 242.339 102.947"; - rotation = "0 0 -1 115.92"; - scale = "1 1 1"; - interiorFile = "bspir1.dif"; - showTerrainInside = "0"; - }; - new InteriorInstance() { - position = "93.7696 300.472 66.6777"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "bspir5.dif"; - showTerrainInside = "0"; - }; - new InteriorInstance() { - position = "363.768 249.524 170.509"; - rotation = "0 0 1 218.479"; - scale = "1 1 1"; - interiorFile = "bspir4.dif"; - showTerrainInside = "0"; - }; - new InteriorInstance() { - position = "976.562 -614.672 90.2773"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "bspir3.dif"; - showTerrainInside = "0"; - }; - new StaticShape(HeavyDeadBody) { - position = "476.153 360.368 232.658"; - rotation = "0 0 1 94.538"; - scale = "1 1 1"; - dataBlock = "HeavyMaleHuman_Dead"; - lockCount = "0"; - homingCount = "0"; - }; - new WheeledVehicle(MPB) { - position = "1273.71 -818.372 79.5295"; - rotation = "0.12202 0.0215281 -0.992294 60.694"; - scale = "1 1 1"; - dataBlock = "mobileBaseVehicle"; - lockCount = "0"; - homingCount = "0"; - disableMove = "0"; - respawn = "0"; - selfPower = "1"; - mountable = "1"; - }; - }; - new SimGroup(Water) { - - new WaterBlock() { - position = "-16 -80 71.5051"; - rotation = "1 0 0 0"; - scale = "128 128 6.3387"; - liquidType = "StagnantWater"; - density = "1"; - viscosity = "6"; - waveMagnitude = "1"; - surfaceTexture = "LiquidTiles/GreenWater"; - surfaceOpacity = "0.7"; - envMapTexture = "lush/skies/lushcloud3"; - envMapIntensity = "0.9"; - removeWetEdges = "1"; - AudioEnvironment = Underwater; - }; - new WaterBlock() { - position = "-8 48 95.5"; - rotation = "1 0 0 0"; - scale = "64 64 3.71365"; - liquidType = "StagnantWater"; - density = "1"; - viscosity = "6"; - waveMagnitude = "0.2"; - surfaceTexture = "LiquidTiles/AlgaeWater"; - surfaceOpacity = "0.7"; - envMapTexture = "lush/skies/lushcloud3"; - envMapIntensity = "0.9"; - removeWetEdges = "1"; - AudioEnvironment = Underwater; - }; - new WaterBlock() { - position = "-272 376 72"; - rotation = "1 0 0 0"; - scale = "64 64 1"; - liquidType = "StagnantWater"; - density = "1"; - viscosity = "6"; - waveMagnitude = "0.1"; - surfaceTexture = "LiquidTiles/AlgaeWater"; - surfaceOpacity = "0.7"; - envMapTexture = "lush/skies/lushcloud3"; - envMapIntensity = "0.9"; - removeWetEdges = "1"; - AudioEnvironment = Underwater; - }; - }; - new SimGroup(Sounds) { - - new AudioEmitter(Frog1) { - position = "-222.356 401.06 75.6289"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - fileName = "fx/environment/frog1.wav"; - useProfileDescription = "0"; - outsideAmbient = "1"; - volume = "1"; - isLooping = "1"; - is3D = "1"; - minDistance = "20"; - maxDistance = "150"; - coneInsideAngle = "360"; - coneOutsideAngle = "360"; - coneOutsideVolume = "1"; - coneVector = "0 0 1"; - loopCount = "-1"; - minLoopGap = "0"; - maxLoopGap = "0"; - type = "EffectAudioType"; - }; - new AudioEmitter(Cricket1) { - position = "-59.9835 298.318 95.3758"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - fileName = "fx/environment/crickets.wav"; - useProfileDescription = "0"; - outsideAmbient = "1"; - volume = "1"; - isLooping = "1"; - is3D = "1"; - minDistance = "20"; - maxDistance = "150"; - coneInsideAngle = "360"; - coneOutsideAngle = "360"; - coneOutsideVolume = "1"; - coneVector = "0 0 1"; - loopCount = "-1"; - minLoopGap = "0"; - maxLoopGap = "0"; - type = "EffectAudioType"; - }; - new AudioEmitter(Frog2) { - position = "534.092 163.88 102.215"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - fileName = "fx/environment/frog2.wav"; - useProfileDescription = "0"; - outsideAmbient = "1"; - volume = "1"; - isLooping = "1"; - is3D = "1"; - minDistance = "20"; - maxDistance = "150"; - coneInsideAngle = "360"; - coneOutsideAngle = "360"; - coneOutsideVolume = "1"; - coneVector = "0 0 1"; - loopCount = "-1"; - minLoopGap = "0"; - maxLoopGap = "0"; - type = "EffectAudioType"; - }; - new AudioEmitter(Cricket1) { - position = "377.544 386.028 124.305"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - fileName = "fx/environment/crickets.wav"; - useProfileDescription = "0"; - outsideAmbient = "1"; - volume = "1"; - isLooping = "1"; - is3D = "1"; - minDistance = "20"; - maxDistance = "150"; - coneInsideAngle = "360"; - coneOutsideAngle = "360"; - coneOutsideVolume = "1"; - coneVector = "0 0 1"; - loopCount = "-1"; - minLoopGap = "0"; - maxLoopGap = "0"; - type = "EffectAudioType"; - }; - new AudioEmitter(Cricket1) { - position = "818.623 -238.858 63.6823"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - fileName = "fx/environment/crickets.wav"; - useProfileDescription = "0"; - outsideAmbient = "1"; - volume = "1"; - isLooping = "1"; - is3D = "1"; - minDistance = "20"; - maxDistance = "150"; - coneInsideAngle = "360"; - coneOutsideAngle = "360"; - coneOutsideVolume = "1"; - coneVector = "0 0 1"; - loopCount = "-1"; - minLoopGap = "0"; - maxLoopGap = "0"; - type = "EffectAudioType"; - }; - new AudioEmitter(Cricket1) { - position = "1211.31 -579.262 126.456"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - fileName = "fx/environment/crickets.wav"; - useProfileDescription = "0"; - outsideAmbient = "1"; - volume = "1"; - isLooping = "1"; - is3D = "1"; - minDistance = "20"; - maxDistance = "150"; - coneInsideAngle = "360"; - coneOutsideAngle = "360"; - coneOutsideVolume = "1"; - coneVector = "0 0 1"; - loopCount = "-1"; - minLoopGap = "0"; - maxLoopGap = "0"; - type = "EffectAudioType"; - }; - new AudioEmitter(Cricket1) { - position = "1058.83 -419.898 124.77"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - fileName = "fx/environment/crickets.wav"; - useProfileDescription = "0"; - outsideAmbient = "1"; - volume = "1"; - isLooping = "1"; - is3D = "1"; - minDistance = "20"; - maxDistance = "150"; - coneInsideAngle = "360"; - coneOutsideAngle = "360"; - coneOutsideVolume = "1"; - coneVector = "0 0 1"; - loopCount = "-1"; - minLoopGap = "0"; - maxLoopGap = "0"; - type = "EffectAudioType"; - }; - new AudioEmitter(bird) { - position = "-260.284 339.991 112.661"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - fileName = "fx/environment/bird_echo5.wav"; - useProfileDescription = "0"; - outsideAmbient = "1"; - volume = "1"; - isLooping = "1"; - is3D = "1"; - minDistance = "2"; - maxDistance = "150"; - coneInsideAngle = "360"; - coneOutsideAngle = "360"; - coneOutsideVolume = "1"; - coneVector = "0 0 1"; - loopCount = "-1"; - minLoopGap = "0"; - maxLoopGap = "0"; - type = "EffectAudioType"; - }; - }; - new Camera(introFlyerDP) { - position = "400 -1000 200"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - new SimGroup(FlightPath) { - - new Camera(1) { - position = "400 -800 200"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - new Camera(2) { - position = "400 -650 200"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - new Camera(3) { - position = "400 -350 200"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - new Camera(4) { - position = "400 -245 200"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - new Camera(5) { - position = "400 45 200"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - }; - new Camera(MissileGuySpot) { - position = "250.052 -348.706 132.918"; - rotation = "0 0 -1 43.1546"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - new Camera(MissileCamera) { - position = "246.608 -349.915 134.29"; - rotation = "0 0 1 39.6094"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; -}; -//--- OBJECT WRITE END --- - -exec("scripts/training1.cs"); +// MissionTypes = SinglePlayer +// DisplayName = Recruit + +//--- MISSION BRIEFING BEGIN --- +//Dear Recruit Iguana, +//This is a notification of activation. You are to report to the launch bay at 3:00 sharp. You will be deployed to the Southern hemisphere of Xeron; your objecive is to take back an HQ of ours. +// +//Letter No. 626938. +//Department: Alpha Viper +// +//Sincerely,Alpha Viper deployment +//--- MISSION BRIEFING END --- + +// PlanetName = Xeron, 3960 CE +// Bitmap = trn_5draconis + +//--- MISSION STRING BEGIN --- +//OBJECTIVES: +//Bleck +//--- MISSION STRING END --- + +//--- MISSION BLURB BEGIN --- +//In 3941, the BioDerm Hordes crushed the Starwolf tribe at the star system of Ymir. Six years later, the tribal alliance called the Pact begins a crucial offensive. You are of the Pact, a Starwolf newblood. Remember Ymir. Avenge your people. +//--- MISSION BLURB END --- + + +//scriptlet +//we have to jump through a lot of hoops to get those dead bodies in training1 +function deadArmor::onAdd(%this, %obj) +{ + %skin = (%obj.trainingSkin == 1 ? 'swolf' : 'beagle'); + //echo("skin = " SPC %skin); + createTarget(%obj, 'Dead Body', %skin, "", 'deadArmor', 0); +} + +function deadArmor::onRemove(%this, %obj) +{ + //echo("singleplayerGame -- deadArmor::onRemove"); + freeTarget(%obj.getTarget()); +} + + +//--- OBJECT WRITE BEGIN --- +new SimGroup(MissionGroup) { + powerCount = "0"; + + new MissionArea(MissionArea) { + area = "-448 -1408 2304 2208"; + flightCeiling = "2000"; + flightCeilingRange = "50"; + }; + new Sky(Sky) { + position = "0 0 0"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + cloudHeightPer[0] = "0.349971"; + cloudHeightPer[1] = "0.25"; + cloudHeightPer[2] = "0.199973"; + cloudSpeed1 = "0.0001"; + cloudSpeed2 = "0.0002"; + cloudSpeed3 = "0.0003"; + visibleDistance = "400"; + useSkyTextures = "1"; + SkySolidColor = "0.390000 0.390000 0.390000 1.000000"; + fogDistance = "100"; + fogColor = "0.500000 0.500000 0.500000 1.000000"; + fogVolume1 = "0 0 0"; + fogVolume2 = "0 0 0"; + fogVolume3 = "0 0 0"; + materialList = "Lush_l4.dml"; + windVelocity = "0 0 0"; + windEffectPrecipitation = "0"; + cloudSpeed0 = "0.000000 0.000000"; + }; + new Sun() { + direction = "0.57735 0.57735 -0.57735"; + color = "0.600000 0.600000 0.600000 1.000000"; + ambient = "0.600000 0.600000 0.600000 1.000000"; + scale = "1 1 1"; + position = "0 0 0"; + rotation = "1 0 0 0"; + }; + new TerrainBlock(Terrain) { + rotation = "1 0 0 0"; + scale = "1 1 1"; + detailTexture = "details/lushdet1"; + terrainFile = "Training1.ter"; + squareSize = "8"; + position = "-1024 -1024 0"; + }; + new NavigationGraph(NavGraph) { + conjoinAngleDev = "50"; + cullDensity = "0.1"; + customArea = "0 0 0 0"; + conjoinBowlDev = "20"; + scale = "1 1 1"; + GraphFile = "Training1.nav"; + position = "0 0 0 1"; + coverage = "0"; + rotation = "0 0 0 0"; + }; + new Camera(hoverBikeDP) { + position = "629.407 -58.6929 124.08"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + new SimGroup(Teams) { + + new SimGroup(Team2) { + + new SimGroup(DropPoints) { + + new Camera(enemy0) { + position = "472.802 349.922 204.888"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + SkillLevel = "0"; + }; + new Camera(enemy1) { + position = "551.142 790.21 107.5"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + SkillLevel = "0"; + }; + new Camera(enemy2) { + position = "738.109 5.1693 152.475"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + SkillLevel = "0"; + }; + new Camera(enemy3) { + position = "988.221 -326.252 86.2044"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + SkillLevel = "0"; + }; + new Camera(enemy4) { + position = "917.043 -476.293 102.216"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + SkillLevel = "0"; + }; + new Camera(enemy5) { + position = "977.56 -584.56 107.011"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + SkillLevel = "0"; + }; + new Camera(enemy6) { + position = "980.365 -777.838 97.7195"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + SkillLevel = "0"; + }; + new Camera(enemy7) { + position = "472.356 345.155 200.883"; + rotation = "0 0 -1 75.6304"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + SkillLevel = "0"; + }; + new Camera(enemy8) { + position = "564.903 791.638 107.929"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + new Camera(enemy9) { + position = "589.296 806.741 111.858"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + new Camera(enemy10) { + position = "575.32 -29.8525 138.276"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + new Camera(enemy11) { + position = "827.178 406.124 195.466"; + rotation = "0 0 1 183.919"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + new Camera(enemy12) { + position = "-721.719 296.493 83.3617"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + new Camera(enemy13) { + position = "882.259 49.6576 147.146"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + }; + }; + new SimGroup(Team1) { + providesPower = "1"; + + new SimGroup(DropPoints) { + + new Camera() { + position = "1301.77 -832.202 88.3109"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + new Camera() { + position = "1255.36 -826.299 79.1645"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + new Camera(DP) { + position = "-262.22 528.825 148.641"; + rotation = "0 0 1 174.696"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + new SimGroup(Respawns) { + + new Camera() { + position = "-311.987 532.198 155.274"; + rotation = "0 0 1 150.115"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + new Camera() { + position = "-293.826 391.612 75.1421"; + rotation = "0 0 1 96.2569"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + new Camera() { + position = "483.448 364.206 225.265"; + rotation = "0 0 1 178.763"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + new Camera() { + position = "635.748 -42.3523 127.123"; + rotation = "0 0 1 183.346"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + }; + }; + new StaticShape(Team1SensorLargePulse1) { + position = "476.731 363.919 232.695"; + rotation = "0 0 1 94.538"; + scale = "1 1 1"; + dataBlock = "SensorLargePulse"; + lockCount = "0"; + homingCount = "0"; + }; + new InteriorInstance(Tower) { + position = "478.373 363.933 210.21"; + rotation = "0 0 -1 90.137"; + scale = "1 1 1"; + interiorFile = "btowr2.dif"; + showTerrainInside = "0"; + AudioProfile = "Universal_Base_1"; + threshold2 = "60"; + threshold1 = "330"; + AudioEnvironment = SmallRoom; + }; + }; + new SimGroup(team0) { + }; + }; + new SimGroup(RandomRocks) { + + new SimGroup(Addition2brock6) { + + new InteriorInstance() { + position = "-211.225 415.883 78.0187"; + rotation = "0.0859163 -0.728135 0.680028 92.551"; + scale = "0.5 0.5 0.5"; + interiorFile = "brock6.dif"; + showTerrainInside = "0"; + }; + new InteriorInstance() { + position = "-247.225 413.883 69.4588"; + rotation = "0.0903608 -0.723175 0.684728 92.9544"; + scale = "1.5 1.5 1.5"; + interiorFile = "brock6.dif"; + showTerrainInside = "0"; + }; + new InteriorInstance() { + position = "-249.142 384.741 73.6875"; + rotation = "0.999508 0.0207068 0.0235741 82.6183"; + scale = "1.5 1.5 1.5"; + interiorFile = "brock6.dif"; + showTerrainInside = "0"; + }; + }; + new SimGroup(Addition3brock6) { + + new InteriorInstance() { + position = "-361.859 580.372 133.844"; + rotation = "0.0749949 -0.739978 0.668437 91.5936"; + scale = "0.5 0.5 0.5"; + interiorFile = "brock6.dif"; + showTerrainInside = "0"; + }; + new InteriorInstance() { + position = "-327.859 553.372 138.108"; + rotation = "0 0 1 3.17638"; + scale = "0.5 0.5 0.5"; + interiorFile = "brock6.dif"; + showTerrainInside = "0"; + }; + new InteriorInstance() { + position = "-338.859 543.372 141.73"; + rotation = "0 0 1 6.1087"; + scale = "0.5 0.5 0.5"; + interiorFile = "brock6.dif"; + showTerrainInside = "0"; + }; + }; + new SimGroup(Addition4brock6) { + + new InteriorInstance() { + position = "614.302 -90.5742 134.156"; + rotation = "0.999363 0.00750352 -0.0349017 194.321"; + scale = "0.5 0.5 0.5"; + interiorFile = "brock6.dif"; + showTerrainInside = "0"; + }; + new InteriorInstance() { + position = "623.302 -78.5742 127.591"; + rotation = "0.985035 0.145617 0.0922095 182.429"; + scale = "0.5 0.5 0.5"; + interiorFile = "brock6.dif"; + showTerrainInside = "0"; + }; + new InteriorInstance() { + position = "621.302 -52.5742 122.494"; + rotation = "0.496802 0.867682 0.0177913 176.44"; + scale = "0.5 0.5 0.5"; + interiorFile = "brock6.dif"; + showTerrainInside = "0"; + }; + }; + new SimGroup(Addition5brock6) { + + new InteriorInstance() { + position = "854.237 -299.5 51.5671"; + rotation = "0.990727 0.0989551 0.0930998 181.927"; + scale = "1.5 1.5 1.5"; + interiorFile = "brock6.dif"; + showTerrainInside = "0"; + }; + new InteriorInstance() { + position = "844.237 -312.5 50.7056"; + rotation = "0 0 1 5.44537"; + scale = "0.5 0.5 0.5"; + interiorFile = "brock6.dif"; + showTerrainInside = "0"; + }; + new InteriorInstance() { + position = "855.237 -281.5 51.8106"; + rotation = "0 0 1 1.30923"; + scale = "1.5 1.5 1.5"; + interiorFile = "brock6.dif"; + showTerrainInside = "0"; + }; + }; + }; + new SimGroup(Goodies) { + + new Item() { + position = "474.634 364.471 216.897"; + rotation = "0 0 1 94.538"; + scale = "1 1 1"; + dataBlock = "SniperRifle"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + }; + new Item() { + position = "-289.395 388.467 76.2374"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "RepairPatch"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + }; + new Item() { + position = "479.087 360.808 224.938"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "RepairPatch"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + }; + new Item() { + position = "475.639 368.891 224.967"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "RepairPatch"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + }; + new Item() { + position = "475.428 360.075 205.496"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "EnergyPack"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + }; + new Item() { + position = "-284.144 392.475 76.8"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "RepairPatch"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + }; + new Item() { + position = "-289.826 398.197 76.5"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "RepairPatch"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + }; + new Item() { + position = "473.838 358.562 224.84"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "ChaingunAmmo"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + }; + new Item() { + position = "480.085 363.933 224.88"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "ChaingunAmmo"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + }; + new Item() { + position = "474.75 368.018 205.334"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "DiscAmmo"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + }; + new Item() { + position = "478.415 368.123 205.334"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "DiscAmmo"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + }; + new Item() { + position = "-307.816 375.393 71.9373"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "ChaingunAmmo"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + }; + new Item() { + position = "-310.012 376.784 72.4285"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "DiscAmmo"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + }; + new Item() { + position = "-298.878 367.65 72.8"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "ChaingunAmmo"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + }; + }; + new SimGroup(RandomOrganics) { + + new SimGroup(Addition1BEPlant1) { + + new TSStatic() { + position = "12 44 103.084"; + rotation = "0.187078 -0.299834 -0.935469 91.8214"; + scale = "0.9 0.9 0.9"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "12 28 112.272"; + rotation = "0.673747 -0.00405274 0.738951 46.2144"; + scale = "0.7 0.7 0.7"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "-12 -60 115.006"; + rotation = "0.222631 0.00381878 0.974895 201.461"; + scale = "1.4 1.4 1.4"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "-44 -12 158.381"; + rotation = "0.296084 -0.0550443 0.953575 213.468"; + scale = "1 1 1"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "44 20 116.163"; + rotation = "0.0927419 0.0384151 -0.994949 45.2054"; + scale = "2 2 2"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "12 -12 110.944"; + rotation = "-0.125633 -0.322398 0.93823 94.648"; + scale = "0.5 0.5 0.5"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "52 4 115.459"; + rotation = "-0.325118 -0.266284 0.907409 15.4122"; + scale = "0.5 0.5 0.5"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "28 -36 103.991"; + rotation = "-0.104028 -0.1201 0.987296 217.551"; + scale = "0.7 0.7 0.7"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "-60 -12 164.709"; + rotation = "0.0580189 -0.15164 0.986732 104.741"; + scale = "1 1 1"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "-28 -60 120.725"; + rotation = "0.0577292 -0.221813 0.973379 141.962"; + scale = "0.5 0.5 0.5"; + shapeName = "borg1.dts"; + }; + }; + new SimGroup(Addition2BEPlant1) { + + new TSStatic() { + position = "-212 388 75.4125"; + rotation = "-0.206499 0.0467321 0.97733 186.842"; + scale = "0.5 0.5 0.5"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "-212 444 88.4125"; + rotation = "-0.574363 0.322049 0.75259 32.8274"; + scale = "0.7 0.7 0.7"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "-252 388 73.9906"; + rotation = "0.148682 -0.256464 -0.95505 66.3921"; + scale = "0.8 0.8 0.8"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "-276 356 78.7875"; + rotation = "-0.140865 0.079089 0.986865 160.257"; + scale = "0.5 0.5 0.5"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "-252 436 77.725"; + rotation = "0.166724 -0.218018 0.961598 224.408"; + scale = "0.5 0.5 0.5"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "-292 372 74.2094"; + rotation = "-0.207835 0.156096 0.965629 73.9162"; + scale = "1 1 1"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "-228 436 80.4438"; + rotation = "-0.287258 0.463175 -0.838422 54.8233"; + scale = "1.5 1.5 1.5"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "-196 356 91.7093"; + rotation = "0.201291 0.712453 0.67223 42.085"; + scale = "1.8 1.8 1.8"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "-212 420 79.5531"; + rotation = "-0.61971 0.490923 0.612335 36.7589"; + scale = "0.6 0.6 0.6"; + shapeName = "borg1.dts"; + }; + }; + new SimGroup(Addition3BELgTree16) { + + new TSStatic() { + position = "-316 268 55.3594"; + rotation = "0 0 1 97.9998"; + scale = "1.1 1.1 1.1"; + shapeName = "borg16.dts"; + }; + new TSStatic() { + position = "-276 236 66.9844"; + rotation = "0 0 1 183"; + scale = "0.9 0.9 0.9"; + shapeName = "borg16.dts"; + }; + new TSStatic() { + position = "-28 316 81.6407"; + rotation = "0 0 -1 38"; + scale = "1 1 1"; + shapeName = "borg16.dts"; + }; + new TSStatic() { + position = "-412 364 69.0468"; + rotation = "0 0 1 79.9998"; + scale = "1.2 1.2 1.2"; + shapeName = "borg16.dts"; + }; + new TSStatic() { + position = "-148 244 78.6875"; + rotation = "0 0 1 116"; + scale = "1.3 1.3 1.3"; + shapeName = "borg16.dts"; + }; + new TSStatic() { + position = "-68 300 89.1407"; + rotation = "0 0 1 192"; + scale = "1.3 1.3 1.3"; + shapeName = "borg16.dts"; + }; + new TSStatic() { + position = "-236 540 147.953"; + rotation = "0 0 1 37"; + scale = "1.2 1.2 1.2"; + shapeName = "borg16.dts"; + }; + new TSStatic() { + position = "-92 292 91.3282"; + rotation = "0 0 1 67"; + scale = "1.3 1.3 1.3"; + shapeName = "borg16.dts"; + }; + new TSStatic() { + position = "-52 300 86.4375"; + rotation = "0 0 1 12"; + scale = "1.3 1.3 1.3"; + shapeName = "borg16.dts"; + }; + new TSStatic() { + position = "-76 260 95.8438"; + rotation = "0 0 1 9.00004"; + scale = "1.1 1.1 1.1"; + shapeName = "borg16.dts"; + }; + new TSStatic() { + position = "-276 364 74.8594"; + rotation = "0 0 1 231"; + scale = "1.5 1.5 1.5"; + shapeName = "borg16.dts"; + }; + new TSStatic() { + position = "-420 236 87.4531"; + rotation = "0 0 1 81.0002"; + scale = "1.2 1.2 1.2"; + shapeName = "borg16.dts"; + }; + new TSStatic() { + position = "-140 580 123.656"; + rotation = "0 0 -1 88"; + scale = "1 1 1"; + shapeName = "borg16.dts"; + }; + new TSStatic() { + position = "-292 572 141.844"; + rotation = "0 0 1 46"; + scale = "0.8 0.8 0.8"; + shapeName = "borg16.dts"; + }; + new TSStatic() { + position = "-140 540 112.297"; + rotation = "0 0 1 123"; + scale = "1.5 1.5 1.5"; + shapeName = "borg16.dts"; + }; + }; + new SimGroup(Addition1BESmTree17) { + + new TSStatic() { + position = "140 -228 165.828"; + rotation = "0.285418 0.403782 0.869193 24.074"; + scale = "1.2 1.2 1.2"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "-268 -100 140.031"; + rotation = "-0.0727138 0.0455015 0.996314 146.118"; + scale = "1.5 1.5 1.5"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "292 -172 96.375"; + rotation = "-0.437468 0.474769 -0.763686 29.8352"; + scale = "1.4 1.4 1.4"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "84 84 105.656"; + rotation = "-0.154012 -0.0638678 0.986003 239.303"; + scale = "1 1 1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "-172 28 185.844"; + rotation = "0.13083 -0.102316 -0.986111 65.7286"; + scale = "0.9 0.9 0.9"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "-308 60 92.1562"; + rotation = "-0.6199 0.346496 0.704035 21.1836"; + scale = "1.5 1.5 1.5"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "-76 -4 162.375"; + rotation = "0.0636308 -0.172424 -0.982965 109.928"; + scale = "0.9 0.9 0.9"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "-356 12 77.4531"; + rotation = "-0.160854 0.0557614 0.985402 186.898"; + scale = "1.4 1.4 1.4"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "-124 228 82.5781"; + rotation = "0.00475492 0.193705 -0.981048 83.0869"; + scale = "1.3 1.3 1.3"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "364 -284 77.0157"; + rotation = "0.0643768 0.238911 -0.968905 59.5481"; + scale = "1 1 1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "-340 20 82.375"; + rotation = "-0.0214268 0.428443 0.903315 30.8605"; + scale = "1.1 1.1 1.1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "300 -116 111.453"; + rotation = "0.265667 0.740693 -0.617086 19.3317"; + scale = "1.1 1.1 1.1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "324 -108 114.109"; + rotation = "0.0390719 0.0270788 0.998869 134.046"; + scale = "1.4 1.4 1.4"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "-388 -388 100.922"; + rotation = "0.278494 0.331909 0.901264 24.3416"; + scale = "1.1 1.1 1.1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "348 -412 76.1093"; + rotation = "-0.0417168 0.0484254 0.997955 222.92"; + scale = "0.8 0.8 0.8"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "300 84 104.672"; + rotation = "-0.184826 -0.0124876 -0.982692 74.9641"; + scale = "1.5 1.5 1.5"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "-372 -548 99.172"; + rotation = "0.0555475 0.0330002 0.997911 229.908"; + scale = "1.1 1.1 1.1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "-196 -508 110.563"; + rotation = "-0.142972 0.0412338 0.988867 214.634"; + scale = "1.5 1.5 1.5"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "340 236 165.906"; + rotation = "-0.0987353 0.15622 0.982775 86.9933"; + scale = "1.3 1.3 1.3"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "380 -308 77.75"; + rotation = "0.157783 -0.115876 0.980651 69.0414"; + scale = "1 1 1"; + shapeName = "borg17.dts"; + }; + }; + new SimGroup(Addition2BELgTree18) { + + new TSStatic() { + position = "-308 364 65.6094"; + rotation = "0 0 -1 69.0002"; + scale = "1.3 1.3 1.3"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "-260 340 82.5312"; + rotation = "0 0 1 195"; + scale = "1.3 1.3 1.3"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "236 -60 105.828"; + rotation = "0 0 1 176"; + scale = "0.9 0.9 0.9"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "76 100 104.641"; + rotation = "0 0 -1 92.0004"; + scale = "1.5 1.5 1.5"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "260 -60 103.438"; + rotation = "0 0 -1 94"; + scale = "0.9 0.9 0.9"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "-244 276 65.7344"; + rotation = "0 0 1 6.00005"; + scale = "1.4 1.4 1.4"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "-36 -188 64.8282"; + rotation = "0 0 -1 120"; + scale = "1 1 1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "188 380 84"; + rotation = "0 0 1 35"; + scale = "1 1 1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "-364 300 58.6406"; + rotation = "0 0 1 215"; + scale = "1.3 1.3 1.3"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "-76 -300 120.156"; + rotation = "0 0 1 75.0002"; + scale = "1 1 1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "84 28 111.031"; + rotation = "0 0 1 47"; + scale = "1.4 1.4 1.4"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "-276 244 65"; + rotation = "0 0 1 130"; + scale = "1.5 1.5 1.5"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "300 -244 97.797"; + rotation = "0 0 1 152"; + scale = "1.2 1.2 1.2"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "364 36 124.031"; + rotation = "0 0 1 218"; + scale = "1 1 1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "-340 156 87.4531"; + rotation = "0 0 1 104"; + scale = "1.3 1.3 1.3"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "92 276 67.375"; + rotation = "0 0 1 39"; + scale = "0.8 0.8 0.8"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "-4 228 101.828"; + rotation = "0 0 -1 87.0002"; + scale = "0.8 0.8 0.8"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "92 340 71.3125"; + rotation = "0 0 1 76.9998"; + scale = "1.2 1.2 1.2"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "-300 276 58.1875"; + rotation = "0 0 1 57.9999"; + scale = "1 1 1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "-188 452 92.2656"; + rotation = "0 0 -1 81.0002"; + scale = "1.4 1.4 1.4"; + shapeName = "borg18.dts"; + }; + }; + new SimGroup(Addition1BESmTree17) { + + new TSStatic() { + position = "500 -316 96.6875"; + rotation = "0.0189433 -0.0920088 0.995578 210.869"; + scale = "1.4 1.4 1.4"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "820 -412 60.8594"; + rotation = "0.151268 0.0290211 0.988067 97.6825"; + scale = "1.2 1.2 1.2"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "876 -276 51.7187"; + rotation = "-0.0767067 0.461516 -0.883809 20.3196"; + scale = "0.9 0.9 0.9"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "652 244 85.625"; + rotation = "0.307312 -0.398951 0.863943 32.1955"; + scale = "1.3 1.3 1.3"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "708 -276 72.7656"; + rotation = "0.265436 -0.176198 0.947891 59.6082"; + scale = "1.5 1.5 1.5"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "836 -308 47.8438"; + rotation = "0.0204826 -0.0196076 0.999598 140.015"; + scale = "1.4 1.4 1.4"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "604 4 141.703"; + rotation = "-0.107106 -0.00849662 0.994211 233.731"; + scale = "1.2 1.2 1.2"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "1172 -12 145.812"; + rotation = "-0.169217 0.00416148 0.98557 91.8325"; + scale = "0.8 0.8 0.8"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "1020 -204 127.797"; + rotation = "-0.0211118 0.743291 0.668635 20.8112"; + scale = "0.8 0.8 0.8"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "1108 44 107.75"; + rotation = "-0.0451934 0.160773 0.985956 44.5658"; + scale = "1 1 1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "644 -348 115.234"; + rotation = "0.737692 0.0137925 -0.674997 20.6192"; + scale = "1.2 1.2 1.2"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "844 140 163.828"; + rotation = "-0.155668 -0.0493325 0.986577 83.7687"; + scale = "1.1 1.1 1.1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "1092 76 116.188"; + rotation = "-0.140404 -0.0943009 -0.985593 74.8008"; + scale = "1.2 1.2 1.2"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "940 -180 84.4688"; + rotation = "-0.0699772 0.0254908 0.997223 103.155"; + scale = "1 1 1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "596 76 133.891"; + rotation = "-0.145307 -0.0467364 0.988282 129.523"; + scale = "0.8 0.8 0.8"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "1036 188 136.187"; + rotation = "0.0143986 -0.126977 0.991801 89.4714"; + scale = "1.3 1.3 1.3"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "708 -60 140.547"; + rotation = "-0.214297 -0.107879 0.970793 63.5095"; + scale = "0.9 0.9 0.9"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "980 -316 79.7969"; + rotation = "-0.524424 0.50887 -0.682665 23.2662"; + scale = "1.2 1.2 1.2"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "532 52 118.094"; + rotation = "0.236918 0.0674468 -0.969186 70.6835"; + scale = "1.1 1.1 1.1"; + shapeName = "borg17.dts"; + }; + }; + new SimGroup(Addition2BELgTree18) { + + new TSStatic() { + position = "428 188 135.5"; + rotation = "0 0 1 49"; + scale = "1.5 1.5 1.5"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "844 -212 55.6563"; + rotation = "0 0 -1 82"; + scale = "0.9 0.9 0.9"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "588 292 116.109"; + rotation = "0 0 1 144"; + scale = "1.2 1.2 1.2"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "964 12 184.766"; + rotation = "0 0 1 134"; + scale = "1.5 1.5 1.5"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "844 -244 54.0469"; + rotation = "0 0 -1 16.9999"; + scale = "1.4 1.4 1.4"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "700 244 81.3907"; + rotation = "0 0 1 9.99989"; + scale = "0.9 0.9 0.9"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1060 -220 118.953"; + rotation = "0 0 1 228"; + scale = "1 1 1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1204 316 61.4843"; + rotation = "0 0 1 177"; + scale = "0.9 0.9 0.9"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1132 284 74.4219"; + rotation = "0 0 -1 23.9998"; + scale = "1.1 1.1 1.1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "556 -12 129.312"; + rotation = "0 0 -1 111"; + scale = "1.3 1.3 1.3"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "412 -44 68.4531"; + rotation = "0 0 1 7.00001"; + scale = "0.9 0.9 0.9"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "860 292 155.844"; + rotation = "0 0 -1 10.9999"; + scale = "1.3 1.3 1.3"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1036 -180 124.484"; + rotation = "0 0 1 88.9998"; + scale = "0.9 0.9 0.9"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "588 -52 129.75"; + rotation = "0 0 -1 67.0005"; + scale = "1.1 1.1 1.1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "468 -372 66.0937"; + rotation = "0 0 1 128"; + scale = "1.1 1.1 1.1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "860 116 166.922"; + rotation = "0 0 1 11"; + scale = "1.5 1.5 1.5"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "716 252 82.9531"; + rotation = "0 0 1 11"; + scale = "1.4 1.4 1.4"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1180 -444 145.719"; + rotation = "0 0 1 4.99997"; + scale = "1.5 1.5 1.5"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "876 -380 52.9063"; + rotation = "0 0 1 46"; + scale = "0.9 0.9 0.9"; + shapeName = "borg18.dts"; + }; + }; + new SimGroup(Addition3BEPlant5) { + + new TSStatic() { + position = "588 156 102.809"; + rotation = "-0.193563 0.0259592 0.980744 181.962"; + scale = "1 1 1"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "492 140 100.575"; + rotation = "0.146029 0.137793 0.979637 117.055"; + scale = "1.5 1.5 1.5"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "588 140 108.325"; + rotation = "-0.318993 0.168786 0.932606 227.962"; + scale = "1 1 1"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "548 220 119.778"; + rotation = "-0.542672 -0.517663 -0.661462 28.3949"; + scale = "1 1 1"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "548 196 107.903"; + rotation = "-0.575099 -0.240159 0.782039 51.104"; + scale = "1.3 1.3 1.3"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "492 196 112.762"; + rotation = "0.253778 -0.1873 0.948955 203.761"; + scale = "1 1 1"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "604 156 105.887"; + rotation = "-0.0326261 0.0389834 0.998707 225.946"; + scale = "1.5 1.5 1.5"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "564 236 114.544"; + rotation = "0.208184 -0.0821455 0.974634 115.338"; + scale = "1.4 1.4 1.4"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "492 148 99.2617"; + rotation = "-0.0149542 -0.224199 -0.974429 58.2532"; + scale = "1.1 1.1 1.1"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "572 44 129.95"; + rotation = "-0.0753689 0.145225 0.986524 67.7173"; + scale = "1.3 1.3 1.3"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "628 188 107.028"; + rotation = "-0.124681 -0.107766 -0.986327 72.7519"; + scale = "1.3 1.3 1.3"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "580 108 129.606"; + rotation = "-0.160092 0.296592 0.94149 163.037"; + scale = "1.2 1.2 1.2"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "572 188 105.919"; + rotation = "-0.0916734 -0.212707 0.972806 188.756"; + scale = "1 1 1"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "636 236 95.4966"; + rotation = "0.296211 -0.0940407 0.950482 86.9005"; + scale = "1.1 1.1 1.1"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "652 132 111.966"; + rotation = "0.114039 0.329162 0.937362 63.2603"; + scale = "1.2 1.2 1.2"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "596 108 134.653"; + rotation = "-0.131211 0.224869 0.965514 229.455"; + scale = "1.5 1.5 1.5"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "660 60 143.575"; + rotation = "-0.0366527 -0.205783 0.977911 82.2664"; + scale = "1.2 1.2 1.2"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "676 92 133.559"; + rotation = "-0.143912 0.101845 0.984336 208.565"; + scale = "1.2 1.2 1.2"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "484 124 107.887"; + rotation = "0.0688712 0.267605 0.961064 116.062"; + scale = "1.4 1.4 1.4"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "548 188 102.95"; + rotation = "-0.141141 -0.288261 0.947093 135.236"; + scale = "1.2 1.2 1.2"; + shapeName = "borg5.dts"; + }; + }; + new SimGroup(Addition4BEPlant1) { + + new TSStatic() { + position = "196 124 106.788"; + rotation = "-0.0194762 0.0360942 0.999159 185.995"; + scale = "0.8 0.8 0.8"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "324 132 137.709"; + rotation = "-0.824061 0.269725 0.498169 40.8144"; + scale = "1.5 1.5 1.5"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "404 148 129.272"; + rotation = "-0.453514 0.0103151 -0.89119 57.3823"; + scale = "1.3 1.3 1.3"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "148 164 106.272"; + rotation = "0.346131 0.139353 0.927779 82.2303"; + scale = "1.3 1.3 1.3"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "388 52 119.178"; + rotation = "0.299604 0.0496035 0.952773 96.7594"; + scale = "0.8 0.8 0.8"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "452 220 146.162"; + rotation = "-0.155184 -0.275246 0.948766 94.0103"; + scale = "1.5 1.5 1.5"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "164 324 104.084"; + rotation = "-0.256999 0.966412 0 31.3768"; + scale = "1.4 1.4 1.4"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "380 100 118.959"; + rotation = "0.252843 -0.0682316 0.965098 206.091"; + scale = "0.7 0.7 0.7"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "252 140 124.506"; + rotation = "-0.290357 -0.0857175 0.953072 149.43"; + scale = "0.7 0.7 0.7"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "172 364 93.2094"; + rotation = "0.0544781 0.166186 0.984588 180.985"; + scale = "1 1 1"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "156 180 97.1313"; + rotation = "0.735189 0.316481 0.599448 35.9322"; + scale = "1.5 1.5 1.5"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "452 212 143.413"; + rotation = "-0.292077 -0.0147327 -0.956281 70.3941"; + scale = "2 2 2"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "476 324 193.725"; + rotation = "-0.46624 -0.0634 0.882384 21.4771"; + scale = "1.5 1.5 1.5"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "428 164 133.319"; + rotation = "-0.0128469 -0.219879 0.975443 155.595"; + scale = "0.6 0.6 0.6"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "388 252 165.584"; + rotation = "0.0979139 -0.392969 0.914324 89.1213"; + scale = "0.7 0.7 0.7"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "388 164 134.662"; + rotation = "0.136418 -0.0673901 0.988357 100.66"; + scale = "0.6 0.6 0.6"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "436 148 121.663"; + rotation = "-0.487287 0.0647607 -0.870837 83.7945"; + scale = "1.7 1.7 1.7"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "236 340 114.647"; + rotation = "-0.0104936 0.224169 0.974494 182.924"; + scale = "1.1 1.1 1.1"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "324 164 150.147"; + rotation = "-0.547013 0.782764 -0.296745 23.293"; + scale = "1 1 1"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "268 116 123.741"; + rotation = "-0.479476 0.578886 -0.65954 35.7259"; + scale = "1.2 1.2 1.2"; + shapeName = "borg1.dts"; + }; + }; + new SimGroup(Addition5BEPlant1) { + + new TSStatic() { + position = "1364 -852 77.2562"; + rotation = "-0.768939 0.365446 -0.524579 33.6006"; + scale = "0.9 0.9 0.9"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1196 -836 64.3031"; + rotation = "0.210641 0.146051 -0.966592 61.7001"; + scale = "0.9 0.9 0.9"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1244 -780 86.6625"; + rotation = "-0.115374 -0.141325 0.983217 175.084"; + scale = "1.3 1.3 1.3"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1308 -876 75.1782"; + rotation = "0.228708 -0.120099 0.966058 183.864"; + scale = "0.9 0.9 0.9"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1132 -892 65.725"; + rotation = "-0.12685 0.170462 0.977165 141.825"; + scale = "0.9 0.9 0.9"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1244 -924 102.069"; + rotation = "-0.110985 0.0519229 0.992465 144.254"; + scale = "2 2 2"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1180 -868 69.0688"; + rotation = "0.0109543 0.159993 0.987057 149.382"; + scale = "1.8 1.8 1.8"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1204 -644 98.9593"; + rotation = "0.110772 -0.25673 0.960114 237.022"; + scale = "1.3 1.3 1.3"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1396 -940 87.4594"; + rotation = "-0.266377 0.35014 0.898023 69.6625"; + scale = "0.5 0.5 0.5"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1292 -620 110.038"; + rotation = "-0.054907 0.139267 0.988732 202.747"; + scale = "1.7 1.7 1.7"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1060 -644 119.631"; + rotation = "-0.492076 0.214682 -0.843666 61.1638"; + scale = "0.6 0.6 0.6"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1316 -708 100.069"; + rotation = "-0.195611 0.0941593 0.976151 203.444"; + scale = "2 2 2"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1172 -788 55.9126"; + rotation = "0.0333406 0.00956025 0.999398 122.029"; + scale = "1.6 1.6 1.6"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1076 -700 95.6469"; + rotation = "-0.0505172 -0.443439 -0.89488 14.5118"; + scale = "0.9 0.9 0.9"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1260 -828 77.9125"; + rotation = "0.0225397 0.0724205 0.997119 129.128"; + scale = "1.2 1.2 1.2"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1076 -860 65.7719"; + rotation = "0.133628 -0.137519 0.981444 105.039"; + scale = "1.7 1.7 1.7"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1316 -836 87.85"; + rotation = "-0.09518 -0.0525785 0.994071 108.324"; + scale = "0.6 0.6 0.6"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1132 -908 71.2563"; + rotation = "0.00708622 0.347095 0.937803 103.601"; + scale = "0.8 0.8 0.8"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1156 -916 80.3344"; + rotation = "-0.0730995 0.138384 0.987677 220.536"; + scale = "1.2 1.2 1.2"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1060 -564 127.616"; + rotation = "0.0985932 0.092788 0.990793 200.811"; + scale = "1.1 1.1 1.1"; + shapeName = "borg1.dts"; + }; + }; + new SimGroup(Addition6BELgTree18) { + + new TSStatic() { + position = "1340 -876 63.3125"; + rotation = "0 0 1 232"; + scale = "1.1 1.1 1.1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1348 -524 77.4063"; + rotation = "0 0 1 201"; + scale = "1.5 1.5 1.5"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1244 -972 92.5"; + rotation = "0 0 1 195"; + scale = "1.5 1.5 1.5"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1004 -932 71.3281"; + rotation = "0 0 1 121"; + scale = "0.8 0.8 0.8"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1044 -852 70.5938"; + rotation = "0 0 -1 96.0002"; + scale = "1 1 1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1172 -804 54.0625"; + rotation = "0 0 1 138"; + scale = "1.2 1.2 1.2"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1164 -852 60.6406"; + rotation = "0 0 1 153"; + scale = "1.1 1.1 1.1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1060 -716 94.75"; + rotation = "0 0 -1 73.0006"; + scale = "0.9 0.9 0.9"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1260 -612 106.578"; + rotation = "0 0 -1 82"; + scale = "1.1 1.1 1.1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1036 -836 72.0157"; + rotation = "0 0 -1 113"; + scale = "1.2 1.2 1.2"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1268 -948 95.7499"; + rotation = "0 0 1 113"; + scale = "1.5 1.5 1.5"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1244 -932 98.625"; + rotation = "0 0 1 9.99989"; + scale = "1.1 1.1 1.1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1252 -716 85.6875"; + rotation = "0 0 1 33"; + scale = "1.1 1.1 1.1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1316 -524 79.6719"; + rotation = "0 0 1 207"; + scale = "0.9 0.9 0.9"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1324 -644 109.062"; + rotation = "0 0 1 113"; + scale = "0.8 0.8 0.8"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1132 -452 157.297"; + rotation = "0 0 1 180"; + scale = "1.1 1.1 1.1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "980 -924 78.2031"; + rotation = "1 0 0 0"; + scale = "1.3 1.3 1.3"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1004 -716 103.766"; + rotation = "0 0 1 72.0002"; + scale = "0.8 0.8 0.8"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1020 -740 98.406"; + rotation = "0 0 1 127"; + scale = "1.4 1.4 1.4"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1204 -724 66.0312"; + rotation = "0 0 1 149"; + scale = "1.2 1.2 1.2"; + shapeName = "borg18.dts"; + }; + }; + new SimGroup(Addition1BESmTree17) { + + new TSStatic() { + position = "516 -852 114.203"; + rotation = "0.0226453 0.0115586 0.999677 203.992"; + scale = "1.4 1.4 1.4"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "412 -636 137.328"; + rotation = "-0.054195 -0.05415 0.997061 181.994"; + scale = "1.1 1.1 1.1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "516 -852 114.203"; + rotation = "-0.0128273 -0.0480088 -0.998765 60.0615"; + scale = "1.1 1.1 1.1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "444 -756 96.0001"; + rotation = "-0.0616775 -0.117932 0.991104 215.7"; + scale = "1.1 1.1 1.1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "340 -772 79.5938"; + rotation = "-0.214777 0.964319 0.154792 6.45366"; + scale = "1.5 1.5 1.5"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "604 -844 157.766"; + rotation = "-0.0445501 -0.0465846 0.99792 184.99"; + scale = "1.4 1.4 1.4"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "628 -644 187.891"; + rotation = "0.19108 -0.0345838 -0.980965 98.0915"; + scale = "0.8 0.8 0.8"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "372 -764 83.5781"; + rotation = "0.126305 0.0603915 -0.990151 87.5658"; + scale = "1.5 1.5 1.5"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "588 -844 156.516"; + rotation = "-0.124319 -0.119349 0.985038 104.836"; + scale = "1.3 1.3 1.3"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "412 -900 119.953"; + rotation = "-0.0628523 -0.0476702 0.996884 210.907"; + scale = "1.1 1.1 1.1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "428 -540 160.078"; + rotation = "-0.106477 0.0229367 0.994051 223.763"; + scale = "1.5 1.5 1.5"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "468 -652 141.938"; + rotation = "0.209904 -0.0580286 -0.975998 73.3289"; + scale = "1.5 1.5 1.5"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "404 -892 119.344"; + rotation = "0.0258563 0.208098 -0.977766 83.2771"; + scale = "1.3 1.3 1.3"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "476 -500 153.453"; + rotation = "0.770847 -0.137338 -0.62204 20.7593"; + scale = "1.1 1.1 1.1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "284 -532 90.2187"; + rotation = "-0.835172 0.10902 0.539075 20.2546"; + scale = "1.3 1.3 1.3"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "300 -860 106.953"; + rotation = "0.0300008 0.141884 0.989429 78.5967"; + scale = "1.5 1.5 1.5"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "468 -724 105.984"; + rotation = "-0.231502 0.313655 -0.920884 48.4362"; + scale = "1.1 1.1 1.1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "436 -780 93.1406"; + rotation = "-0.0166021 0.0320587 0.999348 205.983"; + scale = "0.9 0.9 0.9"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "276 -876 111.875"; + rotation = "0.10672 0.12651 0.986208 236.335"; + scale = "1.5 1.5 1.5"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "380 -740 84.4219"; + rotation = "-0.126943 0.171214 0.977022 55.0849"; + scale = "0.8 0.8 0.8"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "460 -564 163.094"; + rotation = "-0.00537145 0.279877 -0.960021 67.1369"; + scale = "1.2 1.2 1.2"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "468 -868 119.641"; + rotation = "-0.275798 -0.0223686 -0.960955 45.6079"; + scale = "1.2 1.2 1.2"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "580 -812 159.172"; + rotation = "0.11136 -0.181869 0.976997 71.2576"; + scale = "0.9 0.9 0.9"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "292 -644 101.859"; + rotation = "-0.154484 -0.000180158 0.987995 176.048"; + scale = "0.9 0.9 0.9"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "340 -876 123.937"; + rotation = "0.00543177 0.0324584 0.999458 184.997"; + scale = "1.3 1.3 1.3"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "356 -644 117.328"; + rotation = "-0.0709721 -0.0117515 0.997409 157.058"; + scale = "0.9 0.9 0.9"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "444 -540 160.797"; + rotation = "0.0687445 0.0224915 0.997381 82.149"; + scale = "1.2 1.2 1.2"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "516 -852 114.203"; + rotation = "0.0261136 -0.00134998 0.999658 144.011"; + scale = "1.3 1.3 1.3"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "580 -796 159.547"; + rotation = "0.0555007 0.0996695 0.993472 234.693"; + scale = "1.2 1.2 1.2"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "452 -532 160.047"; + rotation = "0.0187232 0.0595054 0.998052 143.067"; + scale = "1.4 1.4 1.4"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "452 -572 159.516"; + rotation = "-0.107753 -0.142268 0.983946 143.555"; + scale = "1 1 1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "572 -772 157.203"; + rotation = "0.085667 0.0576616 0.994654 176.021"; + scale = "0.8 0.8 0.8"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "348 -788 81.5782"; + rotation = "-0.119645 0.050421 0.991536 217.701"; + scale = "0.8 0.8 0.8"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "380 -740 84.4219"; + rotation = "-0.152944 0.359364 0.920579 29.2333"; + scale = "1 1 1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "268 -564 82.4531"; + rotation = "-0.0958363 0.325672 -0.940613 33.9076"; + scale = "0.9 0.9 0.9"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "460 -540 162.266"; + rotation = "-0.131657 0.0740015 0.988529 198.786"; + scale = "0.8 0.8 0.8"; + shapeName = "borg17.dts"; + }; + }; + new SimGroup(Addition2BELgTree18) { + + new TSStatic() { + position = "332 -932 118.766"; + rotation = "0 0 -1 53.9998"; + scale = "1.5 1.5 1.5"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "188 -604 87.5781"; + rotation = "0 0 1 159"; + scale = "1.1 1.1 1.1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "12 -844 121.125"; + rotation = "0 0 1 233"; + scale = "1.2 1.2 1.2"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "-36 -468 135.203"; + rotation = "0 0 1 76"; + scale = "0.8 0.8 0.8"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "108 -892 102.594"; + rotation = "0 0 1 53"; + scale = "0.8 0.8 0.8"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "476 -652 142.578"; + rotation = "0 0 1 208"; + scale = "1.5 1.5 1.5"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "444 -524 160.156"; + rotation = "0 0 1 17"; + scale = "1.1 1.1 1.1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "-28 -468 136"; + rotation = "0 0 1 121"; + scale = "0.9 0.9 0.9"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "228 -452 115.188"; + rotation = "0 0 1 36"; + scale = "1 1 1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "164 -564 91.9688"; + rotation = "0 0 -1 44.9999"; + scale = "1.3 1.3 1.3"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "76 -412 131.828"; + rotation = "0 0 -1 1.00014"; + scale = "0.8 0.8 0.8"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "260 -892 118.438"; + rotation = "0 0 1 150"; + scale = "1.1 1.1 1.1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "452 -556 162.062"; + rotation = "0 0 1 20"; + scale = "0.9 0.9 0.9"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "156 -604 84.5781"; + rotation = "0 0 1 93.0002"; + scale = "1.5 1.5 1.5"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "340 -780 79.5"; + rotation = "0 0 -1 10.9999"; + scale = "1.5 1.5 1.5"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "284 -676 104.078"; + rotation = "0 0 1 109"; + scale = "1.5 1.5 1.5"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "212 -748 102.672"; + rotation = "0 0 1 180"; + scale = "1.2 1.2 1.2"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "44 -708 86.1249"; + rotation = "0 0 1 177"; + scale = "0.8 0.8 0.8"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "324 -436 77.3281"; + rotation = "0 0 -1 35"; + scale = "1.1 1.1 1.1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "228 -532 103.313"; + rotation = "0 0 1 174"; + scale = "1 1 1"; + shapeName = "borg18.dts"; + }; + }; + new TSStatic() { + position = "590.041 -542.501 248.284"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + shapeName = "borg18.dts"; + }; + new SimGroup(Addition3BELgTree18) { + + new TSStatic() { + position = "612 676 187.797"; + rotation = "0 0 1 236"; + scale = "1 1 1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "596 684 188.609"; + rotation = "0 0 1 222"; + scale = "1.4 1.4 1.4"; + shapeName = "borg18.dts"; + }; + }; + new SimGroup(Addition4BELgTree18) { + + new TSStatic() { + position = "484 548 68.625"; + rotation = "0 0 1 75.0002"; + scale = "1.3 1.3 1.3"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "532 524 84.0782"; + rotation = "0 0 1 161"; + scale = "0.8 0.8 0.8"; + shapeName = "borg18.dts"; + }; + }; + new SimGroup(Addition5BELgTree18) { + + new TSStatic() { + position = "268 668 97.359"; + rotation = "0 0 1 60.0001"; + scale = "0.8 0.8 0.8"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "60 588 135.438"; + rotation = "0 0 1 218"; + scale = "1.2 1.2 1.2"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "44 780 52.0312"; + rotation = "0 0 1 168"; + scale = "1.3 1.3 1.3"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "316 604 115.359"; + rotation = "0 0 1 1.9999"; + scale = "1.1 1.1 1.1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "124 820 54.7031"; + rotation = "0 0 1 21"; + scale = "1.1 1.1 1.1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "84 556 133.891"; + rotation = "0 0 -1 38"; + scale = "0.9 0.9 0.9"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "76 572 133.078"; + rotation = "0 0 -1 34.0002"; + scale = "0.8 0.8 0.8"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "236 588 125.078"; + rotation = "0 0 1 57"; + scale = "0.8 0.8 0.8"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "332 668 98.781"; + rotation = "0 0 1 130"; + scale = "0.9 0.9 0.9"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "332 740 90.7656"; + rotation = "0 0 1 85.9998"; + scale = "1.5 1.5 1.5"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "276 812 99.359"; + rotation = "0 0 1 42"; + scale = "1 1 1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "300 692 100.281"; + rotation = "0 0 1 32"; + scale = "1.2 1.2 1.2"; + shapeName = "borg18.dts"; + }; + }; + new SimGroup(Addition6BESmTree17) { + + new TSStatic() { + position = "316 764 90.3593"; + rotation = "-0.269346 0.0747762 0.960136 9.37201"; + scale = "1.4 1.4 1.4"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "284 796 100.625"; + rotation = "-0.109174 -0.268087 0.957189 30.2388"; + scale = "1 1 1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "92 788 52.4374"; + rotation = "-0.00226441 0.0373222 0.999301 211.979"; + scale = "0.8 0.8 0.8"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "236 596 124.828"; + rotation = "0.0374212 -0.125582 -0.991377 48.3697"; + scale = "0.9 0.9 0.9"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "92 604 130.219"; + rotation = "0.130424 -0.533966 0.835386 29.7251"; + scale = "1.2 1.2 1.2"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "236 580 125.891"; + rotation = "0.988853 -0.0859407 0.121593 8.21026"; + scale = "1.1 1.1 1.1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "204 844 64"; + rotation = "0.075034 -0.0658218 0.995006 117.256"; + scale = "1.4 1.4 1.4"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "324 724 93.625"; + rotation = "0.177271 -0.147427 0.973057 84.5554"; + scale = "0.9 0.9 0.9"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "68 692 85.2812"; + rotation = "0.197225 0.181032 0.963499 72.0145"; + scale = "0.8 0.8 0.8"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "324 588 114.719"; + rotation = "-0.0913719 -0.0166197 0.995678 143.149"; + scale = "1.5 1.5 1.5"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "124 812 54.3437"; + rotation = "-0.139173 -0.0205308 0.990055 195.843"; + scale = "1 1 1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "332 772 93.0156"; + rotation = "-0.630648 0.457846 -0.626626 22.1727"; + scale = "0.8 0.8 0.8"; + shapeName = "borg17.dts"; + }; + }; + new SimGroup(Addition7BESmTree17) { + + new TSStatic() { + position = "724 500 100.312"; + rotation = "-0.474947 0.55988 -0.67894 10.2955"; + scale = "0.8 0.8 0.8"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "692 644 172.547"; + rotation = "-0.120142 -0.104658 0.987225 130.562"; + scale = "0.8 0.8 0.8"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "788 604 183.453"; + rotation = "-0.381454 0.132918 0.914782 46.594"; + scale = "0.8 0.8 0.8"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "748 620 177.734"; + rotation = "-0.133731 0.0451644 0.989988 126.465"; + scale = "1 1 1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "700 636 170.906"; + rotation = "-0.28187 -0.0991843 0.954312 63.3697"; + scale = "1.4 1.4 1.4"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "796 676 167.984"; + rotation = "-0.114769 0.0364394 0.992724 166.101"; + scale = "1.5 1.5 1.5"; + shapeName = "borg17.dts"; + }; + }; + new SimGroup(Addition8BESmTree17) { + + new TSStatic() { + position = "612 492 82.4219"; + rotation = "0.15131 -0.0330094 0.987935 175.06"; + scale = "1.4 1.4 1.4"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "652 428 79.7656"; + rotation = "0.122244 -0.16474 -0.978732 87.229"; + scale = "0.8 0.8 0.8"; + shapeName = "borg17.dts"; + }; + }; + }; + new SimGroup(NotSoRandomOrganics) { + + new InteriorInstance() { + position = "-234.377 399.56 72.0484"; + rotation = "1 0 0 139.229"; + scale = "1.18518 1.63312 1"; + interiorFile = "brock7.dif"; + showTerrainInside = "0"; + }; + new InteriorInstance() { + position = "-359.655 570.11 126.837"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "brock8.dif"; + showTerrainInside = "0"; + }; + new InteriorInstance() { + position = "-361.343 564.269 130.504"; + rotation = "1 0 0 50.4203"; + scale = "1 1 1"; + interiorFile = "brock8.dif"; + showTerrainInside = "0"; + }; + new InteriorInstance() { + position = "-351.76 562.309 125.975"; + rotation = "0.769297 0.578037 -0.272129 62.9301"; + scale = "1 1 1"; + interiorFile = "brock8.dif"; + showTerrainInside = "0"; + }; + new StaticShape(SWDeadMed) { + position = "-332.993 471.436 122.37"; + rotation = "-0.294439 -0.309888 0.904033 47.0646"; + scale = "1 1 0.99"; + dataBlock = "MediumMaleHuman_Dead"; + lockCount = "0"; + homingCount = "0"; + trainingSkin = 1; + }; + new StaticShape(MedDeadBody) { + position = "477.477 360.201 204.267"; + rotation = "0 0 1 82.5059"; + scale = "1 1 1"; + dataBlock = "MediumMaleHuman_Dead"; + lockCount = "0"; + homingCount = "0"; + }; + new StaticShape(SWDeadLt) { + position = "-205.392 473.86 97.7869"; + rotation = "-0.94867 0.262068 0.177046 24.3075"; + scale = "1 1 1"; + dataBlock = "LightMaleHuman_Dead"; + lockCount = "0"; + homingCount = "0"; + trainingSkin = 1; + }; + new StaticShape(LightDeadBody) { + position = "474.167 360.154 215.68"; + rotation = "0 0 1 94.538"; + scale = "1 1 1"; + dataBlock = "LightMaleHuman_Dead"; + lockCount = "0"; + homingCount = "0"; + }; + new InteriorInstance() { + position = "-32.6219 242.339 102.947"; + rotation = "0 0 -1 115.92"; + scale = "1 1 1"; + interiorFile = "bspir1.dif"; + showTerrainInside = "0"; + }; + new InteriorInstance() { + position = "93.7696 300.472 66.6777"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "bspir5.dif"; + showTerrainInside = "0"; + }; + new InteriorInstance() { + position = "363.768 249.524 170.509"; + rotation = "0 0 1 218.479"; + scale = "1 1 1"; + interiorFile = "bspir4.dif"; + showTerrainInside = "0"; + }; + new InteriorInstance() { + position = "976.562 -614.672 90.2773"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "bspir3.dif"; + showTerrainInside = "0"; + }; + new StaticShape(HeavyDeadBody) { + position = "476.153 360.368 232.658"; + rotation = "0 0 1 94.538"; + scale = "1 1 1"; + dataBlock = "HeavyMaleHuman_Dead"; + lockCount = "0"; + homingCount = "0"; + }; + new WheeledVehicle(MPB) { + position = "1273.71 -818.372 79.5295"; + rotation = "0.12202 0.0215281 -0.992294 60.694"; + scale = "1 1 1"; + dataBlock = "mobileBaseVehicle"; + lockCount = "0"; + homingCount = "0"; + disableMove = "0"; + respawn = "0"; + selfPower = "1"; + mountable = "1"; + }; + }; + new SimGroup(Water) { + + new WaterBlock() { + position = "-16 -80 71.5051"; + rotation = "1 0 0 0"; + scale = "128 128 6.3387"; + liquidType = "StagnantWater"; + density = "1"; + viscosity = "6"; + waveMagnitude = "1"; + surfaceTexture = "LiquidTiles/GreenWater"; + surfaceOpacity = "0.7"; + envMapTexture = "lush/skies/lushcloud3"; + envMapIntensity = "0.9"; + removeWetEdges = "1"; + AudioEnvironment = Underwater; + }; + new WaterBlock() { + position = "-8 48 95.5"; + rotation = "1 0 0 0"; + scale = "64 64 3.71365"; + liquidType = "StagnantWater"; + density = "1"; + viscosity = "6"; + waveMagnitude = "0.2"; + surfaceTexture = "LiquidTiles/AlgaeWater"; + surfaceOpacity = "0.7"; + envMapTexture = "lush/skies/lushcloud3"; + envMapIntensity = "0.9"; + removeWetEdges = "1"; + AudioEnvironment = Underwater; + }; + new WaterBlock() { + position = "-272 376 72"; + rotation = "1 0 0 0"; + scale = "64 64 1"; + liquidType = "StagnantWater"; + density = "1"; + viscosity = "6"; + waveMagnitude = "0.1"; + surfaceTexture = "LiquidTiles/AlgaeWater"; + surfaceOpacity = "0.7"; + envMapTexture = "lush/skies/lushcloud3"; + envMapIntensity = "0.9"; + removeWetEdges = "1"; + AudioEnvironment = Underwater; + }; + }; + new SimGroup(Sounds) { + + new AudioEmitter(Frog1) { + position = "-222.356 401.06 75.6289"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + fileName = "fx/environment/frog1.wav"; + useProfileDescription = "0"; + outsideAmbient = "1"; + volume = "1"; + isLooping = "1"; + is3D = "1"; + minDistance = "20"; + maxDistance = "150"; + coneInsideAngle = "360"; + coneOutsideAngle = "360"; + coneOutsideVolume = "1"; + coneVector = "0 0 1"; + loopCount = "-1"; + minLoopGap = "0"; + maxLoopGap = "0"; + type = "EffectAudioType"; + }; + new AudioEmitter(Cricket1) { + position = "-59.9835 298.318 95.3758"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + fileName = "fx/environment/crickets.wav"; + useProfileDescription = "0"; + outsideAmbient = "1"; + volume = "1"; + isLooping = "1"; + is3D = "1"; + minDistance = "20"; + maxDistance = "150"; + coneInsideAngle = "360"; + coneOutsideAngle = "360"; + coneOutsideVolume = "1"; + coneVector = "0 0 1"; + loopCount = "-1"; + minLoopGap = "0"; + maxLoopGap = "0"; + type = "EffectAudioType"; + }; + new AudioEmitter(Frog2) { + position = "534.092 163.88 102.215"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + fileName = "fx/environment/frog2.wav"; + useProfileDescription = "0"; + outsideAmbient = "1"; + volume = "1"; + isLooping = "1"; + is3D = "1"; + minDistance = "20"; + maxDistance = "150"; + coneInsideAngle = "360"; + coneOutsideAngle = "360"; + coneOutsideVolume = "1"; + coneVector = "0 0 1"; + loopCount = "-1"; + minLoopGap = "0"; + maxLoopGap = "0"; + type = "EffectAudioType"; + }; + new AudioEmitter(Cricket1) { + position = "377.544 386.028 124.305"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + fileName = "fx/environment/crickets.wav"; + useProfileDescription = "0"; + outsideAmbient = "1"; + volume = "1"; + isLooping = "1"; + is3D = "1"; + minDistance = "20"; + maxDistance = "150"; + coneInsideAngle = "360"; + coneOutsideAngle = "360"; + coneOutsideVolume = "1"; + coneVector = "0 0 1"; + loopCount = "-1"; + minLoopGap = "0"; + maxLoopGap = "0"; + type = "EffectAudioType"; + }; + new AudioEmitter(Cricket1) { + position = "818.623 -238.858 63.6823"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + fileName = "fx/environment/crickets.wav"; + useProfileDescription = "0"; + outsideAmbient = "1"; + volume = "1"; + isLooping = "1"; + is3D = "1"; + minDistance = "20"; + maxDistance = "150"; + coneInsideAngle = "360"; + coneOutsideAngle = "360"; + coneOutsideVolume = "1"; + coneVector = "0 0 1"; + loopCount = "-1"; + minLoopGap = "0"; + maxLoopGap = "0"; + type = "EffectAudioType"; + }; + new AudioEmitter(Cricket1) { + position = "1211.31 -579.262 126.456"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + fileName = "fx/environment/crickets.wav"; + useProfileDescription = "0"; + outsideAmbient = "1"; + volume = "1"; + isLooping = "1"; + is3D = "1"; + minDistance = "20"; + maxDistance = "150"; + coneInsideAngle = "360"; + coneOutsideAngle = "360"; + coneOutsideVolume = "1"; + coneVector = "0 0 1"; + loopCount = "-1"; + minLoopGap = "0"; + maxLoopGap = "0"; + type = "EffectAudioType"; + }; + new AudioEmitter(Cricket1) { + position = "1058.83 -419.898 124.77"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + fileName = "fx/environment/crickets.wav"; + useProfileDescription = "0"; + outsideAmbient = "1"; + volume = "1"; + isLooping = "1"; + is3D = "1"; + minDistance = "20"; + maxDistance = "150"; + coneInsideAngle = "360"; + coneOutsideAngle = "360"; + coneOutsideVolume = "1"; + coneVector = "0 0 1"; + loopCount = "-1"; + minLoopGap = "0"; + maxLoopGap = "0"; + type = "EffectAudioType"; + }; + new AudioEmitter(bird) { + position = "-260.284 339.991 112.661"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + fileName = "fx/environment/bird_echo5.wav"; + useProfileDescription = "0"; + outsideAmbient = "1"; + volume = "1"; + isLooping = "1"; + is3D = "1"; + minDistance = "2"; + maxDistance = "150"; + coneInsideAngle = "360"; + coneOutsideAngle = "360"; + coneOutsideVolume = "1"; + coneVector = "0 0 1"; + loopCount = "-1"; + minLoopGap = "0"; + maxLoopGap = "0"; + type = "EffectAudioType"; + }; + }; + new Camera(introFlyerDP) { + position = "400 -1000 200"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + new SimGroup(FlightPath) { + + new Camera(1) { + position = "400 -800 200"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + new Camera(2) { + position = "400 -650 200"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + new Camera(3) { + position = "400 -350 200"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + new Camera(4) { + position = "400 -245 200"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + new Camera(5) { + position = "400 45 200"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + }; + new Camera(MissileGuySpot) { + position = "250.052 -348.706 132.918"; + rotation = "0 0 -1 43.1546"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + new Camera(MissileCamera) { + position = "246.608 -349.915 134.29"; + rotation = "0 0 1 39.6094"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; +}; +//--- OBJECT WRITE END --- + +exec("scripts/training1.cs"); diff --git a/missions/Mission2.mis b/missions/Mission2.mis index 9a9da55..ce796ae 100644 --- a/missions/Mission2.mis +++ b/missions/Mission2.mis @@ -1,2754 +1,2754 @@ -// MissionTypes = SinglePlayer -// DisplayName = Major - -//--- MISSION BRIEFING BEGIN --- -//Dear Recruit Iguana, -//This is a notification of activation. You are to report to the launch bay at 3:00 sharp. You will be deployed to the Southern hemisphere of Xeron; your objecive is to take back an HQ of ours. -// -//Letter No. 626938. -//Department: Alpha Viper -// -//Sincerely,Alpha Viper deployment -//--- MISSION BRIEFING END --- - -// PlanetName = Xeron, 3960 CE -// Bitmap = trn_5draconis - -//--- MISSION STRING BEGIN --- -//OBJECTIVES: -//Bleck -//--- MISSION STRING END --- - -//--- MISSION BLURB BEGIN --- -//In 3941, the BioDerm Hordes crushed the Starwolf tribe at the star system of Ymir. Six years later, the tribal alliance called the Pact begins a crucial offensive. You are of the Pact, a Starwolf newblood. Remember Ymir. Avenge your people. -//--- MISSION BLURB END --- - - -//scriptlet -//we have to jump through a lot of hoops to get those dead bodies in training1 -function deadArmor::onAdd(%this, %obj) -{ - %skin = (%obj.trainingSkin == 1 ? 'swolf' : 'beagle'); - //echo("skin = " SPC %skin); - createTarget(%obj, 'Dead Body', %skin, "", 'deadArmor', 0); -} - -function deadArmor::onRemove(%this, %obj) -{ - //echo("singleplayerGame -- deadArmor::onRemove"); - freeTarget(%obj.getTarget()); -} - - -//--- OBJECT WRITE BEGIN --- -new SimGroup(MissionGroup) { - powerCount = "0"; - - new MissionArea(MissionArea) { - area = "-448 -1408 2304 2208"; - flightCeiling = "2000"; - flightCeilingRange = "50"; - }; - new Sky(Sky) { - position = "0 0 0"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - cloudHeightPer[0] = "0.349971"; - cloudHeightPer[1] = "0.25"; - cloudHeightPer[2] = "0.199973"; - cloudSpeed1 = "0.0001"; - cloudSpeed2 = "0.0002"; - cloudSpeed3 = "0.0003"; - visibleDistance = "400"; - useSkyTextures = "1"; - SkySolidColor = "0.390000 0.390000 0.390000 1.000000"; - fogDistance = "100"; - fogColor = "0.500000 0.500000 0.500000 1.000000"; - fogVolume1 = "0 0 0"; - fogVolume2 = "0 0 0"; - fogVolume3 = "0 0 0"; - materialList = "Lush_l4.dml"; - windVelocity = "0 0 0"; - windEffectPrecipitation = "0"; - cloudSpeed0 = "0.000000 0.000000"; - }; - new Sun() { - direction = "0.57735 0.57735 -0.57735"; - color = "0.600000 0.600000 0.600000 1.000000"; - ambient = "0.600000 0.600000 0.600000 1.000000"; - scale = "1 1 1"; - position = "0 0 0"; - rotation = "1 0 0 0"; - }; - new TerrainBlock(Terrain) { - rotation = "1 0 0 0"; - scale = "1 1 1"; - detailTexture = "details/lushdet1"; - terrainFile = "Training1.ter"; - squareSize = "8"; - position = "-1024 -1024 0"; - }; - new NavigationGraph(NavGraph) { - conjoinAngleDev = "50"; - cullDensity = "0.1"; - customArea = "0 0 0 0"; - conjoinBowlDev = "20"; - scale = "1 1 1"; - GraphFile = "Training1.nav"; - position = "0 0 0 1"; - coverage = "0"; - rotation = "0 0 0 0"; - }; - new Camera(hoverBikeDP) { - position = "629.407 -58.6929 124.08"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - new SimGroup(Teams) { - - new SimGroup(Team2) { - - new SimGroup(DropPoints) { - - new Camera(enemy0) { - position = "472.802 349.922 204.888"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - SkillLevel = "0"; - }; - new Camera(enemy1) { - position = "551.142 790.21 107.5"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - SkillLevel = "0"; - }; - new Camera(enemy2) { - position = "738.109 5.1693 152.475"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - SkillLevel = "0"; - }; - new Camera(enemy3) { - position = "988.221 -326.252 86.2044"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - SkillLevel = "0"; - }; - new Camera(enemy4) { - position = "917.043 -476.293 102.216"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - SkillLevel = "0"; - }; - new Camera(enemy5) { - position = "977.56 -584.56 107.011"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - SkillLevel = "0"; - }; - new Camera(enemy6) { - position = "980.365 -777.838 97.7195"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - SkillLevel = "0"; - }; - new Camera(enemy7) { - position = "472.356 345.155 200.883"; - rotation = "0 0 -1 75.6304"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - SkillLevel = "0"; - }; - new Camera(enemy8) { - position = "564.903 791.638 107.929"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - new Camera(enemy9) { - position = "589.296 806.741 111.858"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - new Camera(enemy10) { - position = "575.32 -29.8525 138.276"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - new Camera(enemy11) { - position = "827.178 406.124 195.466"; - rotation = "0 0 1 183.919"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - new Camera(enemy12) { - position = "-721.719 296.493 83.3617"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - new Camera(enemy13) { - position = "882.259 49.6576 147.146"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - }; - }; - new SimGroup(Team1) { - providesPower = "1"; - - new SimGroup(DropPoints) { - - new Camera() { - position = "1301.77 -832.202 88.3109"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - new Camera() { - position = "1255.36 -826.299 79.1645"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - new Camera(DP) { - position = "-262.22 528.825 148.641"; - rotation = "0 0 1 174.696"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - new SimGroup(Respawns) { - - new Camera() { - position = "-311.987 532.198 155.274"; - rotation = "0 0 1 150.115"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - new Camera() { - position = "-293.826 391.612 75.1421"; - rotation = "0 0 1 96.2569"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - new Camera() { - position = "483.448 364.206 225.265"; - rotation = "0 0 1 178.763"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - new Camera() { - position = "635.748 -42.3523 127.123"; - rotation = "0 0 1 183.346"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - }; - }; - new StaticShape(Team1SensorLargePulse1) { - position = "476.731 363.919 232.695"; - rotation = "0 0 1 94.538"; - scale = "1 1 1"; - dataBlock = "SensorLargePulse"; - lockCount = "0"; - homingCount = "0"; - }; - new InteriorInstance(Tower) { - position = "478.373 363.933 210.21"; - rotation = "0 0 -1 90.137"; - scale = "1 1 1"; - interiorFile = "btowr2.dif"; - showTerrainInside = "0"; - AudioProfile = "Universal_Base_1"; - threshold2 = "60"; - threshold1 = "330"; - AudioEnvironment = SmallRoom; - }; - }; - new SimGroup(team0) { - }; - }; - new SimGroup(RandomRocks) { - - new SimGroup(Addition2brock6) { - - new InteriorInstance() { - position = "-211.225 415.883 78.0187"; - rotation = "0.0859163 -0.728135 0.680028 92.551"; - scale = "0.5 0.5 0.5"; - interiorFile = "brock6.dif"; - showTerrainInside = "0"; - }; - new InteriorInstance() { - position = "-247.225 413.883 69.4588"; - rotation = "0.0903608 -0.723175 0.684728 92.9544"; - scale = "1.5 1.5 1.5"; - interiorFile = "brock6.dif"; - showTerrainInside = "0"; - }; - new InteriorInstance() { - position = "-249.142 384.741 73.6875"; - rotation = "0.999508 0.0207068 0.0235741 82.6183"; - scale = "1.5 1.5 1.5"; - interiorFile = "brock6.dif"; - showTerrainInside = "0"; - }; - }; - new SimGroup(Addition3brock6) { - - new InteriorInstance() { - position = "-361.859 580.372 133.844"; - rotation = "0.0749949 -0.739978 0.668437 91.5936"; - scale = "0.5 0.5 0.5"; - interiorFile = "brock6.dif"; - showTerrainInside = "0"; - }; - new InteriorInstance() { - position = "-327.859 553.372 138.108"; - rotation = "0 0 1 3.17638"; - scale = "0.5 0.5 0.5"; - interiorFile = "brock6.dif"; - showTerrainInside = "0"; - }; - new InteriorInstance() { - position = "-338.859 543.372 141.73"; - rotation = "0 0 1 6.1087"; - scale = "0.5 0.5 0.5"; - interiorFile = "brock6.dif"; - showTerrainInside = "0"; - }; - }; - new SimGroup(Addition4brock6) { - - new InteriorInstance() { - position = "614.302 -90.5742 134.156"; - rotation = "0.999363 0.00750352 -0.0349017 194.321"; - scale = "0.5 0.5 0.5"; - interiorFile = "brock6.dif"; - showTerrainInside = "0"; - }; - new InteriorInstance() { - position = "623.302 -78.5742 127.591"; - rotation = "0.985035 0.145617 0.0922095 182.429"; - scale = "0.5 0.5 0.5"; - interiorFile = "brock6.dif"; - showTerrainInside = "0"; - }; - new InteriorInstance() { - position = "621.302 -52.5742 122.494"; - rotation = "0.496802 0.867682 0.0177913 176.44"; - scale = "0.5 0.5 0.5"; - interiorFile = "brock6.dif"; - showTerrainInside = "0"; - }; - }; - new SimGroup(Addition5brock6) { - - new InteriorInstance() { - position = "854.237 -299.5 51.5671"; - rotation = "0.990727 0.0989551 0.0930998 181.927"; - scale = "1.5 1.5 1.5"; - interiorFile = "brock6.dif"; - showTerrainInside = "0"; - }; - new InteriorInstance() { - position = "844.237 -312.5 50.7056"; - rotation = "0 0 1 5.44537"; - scale = "0.5 0.5 0.5"; - interiorFile = "brock6.dif"; - showTerrainInside = "0"; - }; - new InteriorInstance() { - position = "855.237 -281.5 51.8106"; - rotation = "0 0 1 1.30923"; - scale = "1.5 1.5 1.5"; - interiorFile = "brock6.dif"; - showTerrainInside = "0"; - }; - }; - }; - new SimGroup(Goodies) { - - new Item() { - position = "474.634 364.471 216.897"; - rotation = "0 0 1 94.538"; - scale = "1 1 1"; - dataBlock = "SniperRifle"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - }; - new Item() { - position = "-289.395 388.467 76.2374"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "RepairPatch"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - }; - new Item() { - position = "479.087 360.808 224.938"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "RepairPatch"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - }; - new Item() { - position = "475.639 368.891 224.967"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "RepairPatch"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - }; - new Item() { - position = "475.428 360.075 205.496"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "EnergyPack"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - }; - new Item() { - position = "-284.144 392.475 76.8"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "RepairPatch"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - }; - new Item() { - position = "-289.826 398.197 76.5"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "RepairPatch"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - }; - new Item() { - position = "473.838 358.562 224.84"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "ChaingunAmmo"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - }; - new Item() { - position = "480.085 363.933 224.88"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "ChaingunAmmo"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - }; - new Item() { - position = "474.75 368.018 205.334"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "DiscAmmo"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - }; - new Item() { - position = "478.415 368.123 205.334"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "DiscAmmo"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - }; - new Item() { - position = "-307.816 375.393 71.9373"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "ChaingunAmmo"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - }; - new Item() { - position = "-310.012 376.784 72.4285"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "DiscAmmo"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - }; - new Item() { - position = "-298.878 367.65 72.8"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "ChaingunAmmo"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - }; - }; - new SimGroup(RandomOrganics) { - - new SimGroup(Addition1BEPlant1) { - - new TSStatic() { - position = "12 44 103.084"; - rotation = "0.187078 -0.299834 -0.935469 91.8214"; - scale = "0.9 0.9 0.9"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "12 28 112.272"; - rotation = "0.673747 -0.00405274 0.738951 46.2144"; - scale = "0.7 0.7 0.7"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "-12 -60 115.006"; - rotation = "0.222631 0.00381878 0.974895 201.461"; - scale = "1.4 1.4 1.4"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "-44 -12 158.381"; - rotation = "0.296084 -0.0550443 0.953575 213.468"; - scale = "1 1 1"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "44 20 116.163"; - rotation = "0.0927419 0.0384151 -0.994949 45.2054"; - scale = "2 2 2"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "12 -12 110.944"; - rotation = "-0.125633 -0.322398 0.93823 94.648"; - scale = "0.5 0.5 0.5"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "52 4 115.459"; - rotation = "-0.325118 -0.266284 0.907409 15.4122"; - scale = "0.5 0.5 0.5"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "28 -36 103.991"; - rotation = "-0.104028 -0.1201 0.987296 217.551"; - scale = "0.7 0.7 0.7"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "-60 -12 164.709"; - rotation = "0.0580189 -0.15164 0.986732 104.741"; - scale = "1 1 1"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "-28 -60 120.725"; - rotation = "0.0577292 -0.221813 0.973379 141.962"; - scale = "0.5 0.5 0.5"; - shapeName = "borg1.dts"; - }; - }; - new SimGroup(Addition2BEPlant1) { - - new TSStatic() { - position = "-212 388 75.4125"; - rotation = "-0.206499 0.0467321 0.97733 186.842"; - scale = "0.5 0.5 0.5"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "-212 444 88.4125"; - rotation = "-0.574363 0.322049 0.75259 32.8274"; - scale = "0.7 0.7 0.7"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "-252 388 73.9906"; - rotation = "0.148682 -0.256464 -0.95505 66.3921"; - scale = "0.8 0.8 0.8"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "-276 356 78.7875"; - rotation = "-0.140865 0.079089 0.986865 160.257"; - scale = "0.5 0.5 0.5"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "-252 436 77.725"; - rotation = "0.166724 -0.218018 0.961598 224.408"; - scale = "0.5 0.5 0.5"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "-292 372 74.2094"; - rotation = "-0.207835 0.156096 0.965629 73.9162"; - scale = "1 1 1"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "-228 436 80.4438"; - rotation = "-0.287258 0.463175 -0.838422 54.8233"; - scale = "1.5 1.5 1.5"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "-196 356 91.7093"; - rotation = "0.201291 0.712453 0.67223 42.085"; - scale = "1.8 1.8 1.8"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "-212 420 79.5531"; - rotation = "-0.61971 0.490923 0.612335 36.7589"; - scale = "0.6 0.6 0.6"; - shapeName = "borg1.dts"; - }; - }; - new SimGroup(Addition3BELgTree16) { - - new TSStatic() { - position = "-316 268 55.3594"; - rotation = "0 0 1 97.9998"; - scale = "1.1 1.1 1.1"; - shapeName = "borg16.dts"; - }; - new TSStatic() { - position = "-276 236 66.9844"; - rotation = "0 0 1 183"; - scale = "0.9 0.9 0.9"; - shapeName = "borg16.dts"; - }; - new TSStatic() { - position = "-28 316 81.6407"; - rotation = "0 0 -1 38"; - scale = "1 1 1"; - shapeName = "borg16.dts"; - }; - new TSStatic() { - position = "-412 364 69.0468"; - rotation = "0 0 1 79.9998"; - scale = "1.2 1.2 1.2"; - shapeName = "borg16.dts"; - }; - new TSStatic() { - position = "-148 244 78.6875"; - rotation = "0 0 1 116"; - scale = "1.3 1.3 1.3"; - shapeName = "borg16.dts"; - }; - new TSStatic() { - position = "-68 300 89.1407"; - rotation = "0 0 1 192"; - scale = "1.3 1.3 1.3"; - shapeName = "borg16.dts"; - }; - new TSStatic() { - position = "-236 540 147.953"; - rotation = "0 0 1 37"; - scale = "1.2 1.2 1.2"; - shapeName = "borg16.dts"; - }; - new TSStatic() { - position = "-92 292 91.3282"; - rotation = "0 0 1 67"; - scale = "1.3 1.3 1.3"; - shapeName = "borg16.dts"; - }; - new TSStatic() { - position = "-52 300 86.4375"; - rotation = "0 0 1 12"; - scale = "1.3 1.3 1.3"; - shapeName = "borg16.dts"; - }; - new TSStatic() { - position = "-76 260 95.8438"; - rotation = "0 0 1 9.00004"; - scale = "1.1 1.1 1.1"; - shapeName = "borg16.dts"; - }; - new TSStatic() { - position = "-276 364 74.8594"; - rotation = "0 0 1 231"; - scale = "1.5 1.5 1.5"; - shapeName = "borg16.dts"; - }; - new TSStatic() { - position = "-420 236 87.4531"; - rotation = "0 0 1 81.0002"; - scale = "1.2 1.2 1.2"; - shapeName = "borg16.dts"; - }; - new TSStatic() { - position = "-140 580 123.656"; - rotation = "0 0 -1 88"; - scale = "1 1 1"; - shapeName = "borg16.dts"; - }; - new TSStatic() { - position = "-292 572 141.844"; - rotation = "0 0 1 46"; - scale = "0.8 0.8 0.8"; - shapeName = "borg16.dts"; - }; - new TSStatic() { - position = "-140 540 112.297"; - rotation = "0 0 1 123"; - scale = "1.5 1.5 1.5"; - shapeName = "borg16.dts"; - }; - }; - new SimGroup(Addition1BESmTree17) { - - new TSStatic() { - position = "140 -228 165.828"; - rotation = "0.285418 0.403782 0.869193 24.074"; - scale = "1.2 1.2 1.2"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "-268 -100 140.031"; - rotation = "-0.0727138 0.0455015 0.996314 146.118"; - scale = "1.5 1.5 1.5"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "292 -172 96.375"; - rotation = "-0.437468 0.474769 -0.763686 29.8352"; - scale = "1.4 1.4 1.4"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "84 84 105.656"; - rotation = "-0.154012 -0.0638678 0.986003 239.303"; - scale = "1 1 1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "-172 28 185.844"; - rotation = "0.13083 -0.102316 -0.986111 65.7286"; - scale = "0.9 0.9 0.9"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "-308 60 92.1562"; - rotation = "-0.6199 0.346496 0.704035 21.1836"; - scale = "1.5 1.5 1.5"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "-76 -4 162.375"; - rotation = "0.0636308 -0.172424 -0.982965 109.928"; - scale = "0.9 0.9 0.9"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "-356 12 77.4531"; - rotation = "-0.160854 0.0557614 0.985402 186.898"; - scale = "1.4 1.4 1.4"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "-124 228 82.5781"; - rotation = "0.00475492 0.193705 -0.981048 83.0869"; - scale = "1.3 1.3 1.3"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "364 -284 77.0157"; - rotation = "0.0643768 0.238911 -0.968905 59.5481"; - scale = "1 1 1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "-340 20 82.375"; - rotation = "-0.0214268 0.428443 0.903315 30.8605"; - scale = "1.1 1.1 1.1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "300 -116 111.453"; - rotation = "0.265667 0.740693 -0.617086 19.3317"; - scale = "1.1 1.1 1.1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "324 -108 114.109"; - rotation = "0.0390719 0.0270788 0.998869 134.046"; - scale = "1.4 1.4 1.4"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "-388 -388 100.922"; - rotation = "0.278494 0.331909 0.901264 24.3416"; - scale = "1.1 1.1 1.1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "348 -412 76.1093"; - rotation = "-0.0417168 0.0484254 0.997955 222.92"; - scale = "0.8 0.8 0.8"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "300 84 104.672"; - rotation = "-0.184826 -0.0124876 -0.982692 74.9641"; - scale = "1.5 1.5 1.5"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "-372 -548 99.172"; - rotation = "0.0555475 0.0330002 0.997911 229.908"; - scale = "1.1 1.1 1.1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "-196 -508 110.563"; - rotation = "-0.142972 0.0412338 0.988867 214.634"; - scale = "1.5 1.5 1.5"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "340 236 165.906"; - rotation = "-0.0987353 0.15622 0.982775 86.9933"; - scale = "1.3 1.3 1.3"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "380 -308 77.75"; - rotation = "0.157783 -0.115876 0.980651 69.0414"; - scale = "1 1 1"; - shapeName = "borg17.dts"; - }; - }; - new SimGroup(Addition2BELgTree18) { - - new TSStatic() { - position = "-308 364 65.6094"; - rotation = "0 0 -1 69.0002"; - scale = "1.3 1.3 1.3"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "-260 340 82.5312"; - rotation = "0 0 1 195"; - scale = "1.3 1.3 1.3"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "236 -60 105.828"; - rotation = "0 0 1 176"; - scale = "0.9 0.9 0.9"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "76 100 104.641"; - rotation = "0 0 -1 92.0004"; - scale = "1.5 1.5 1.5"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "260 -60 103.438"; - rotation = "0 0 -1 94"; - scale = "0.9 0.9 0.9"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "-244 276 65.7344"; - rotation = "0 0 1 6.00005"; - scale = "1.4 1.4 1.4"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "-36 -188 64.8282"; - rotation = "0 0 -1 120"; - scale = "1 1 1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "188 380 84"; - rotation = "0 0 1 35"; - scale = "1 1 1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "-364 300 58.6406"; - rotation = "0 0 1 215"; - scale = "1.3 1.3 1.3"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "-76 -300 120.156"; - rotation = "0 0 1 75.0002"; - scale = "1 1 1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "84 28 111.031"; - rotation = "0 0 1 47"; - scale = "1.4 1.4 1.4"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "-276 244 65"; - rotation = "0 0 1 130"; - scale = "1.5 1.5 1.5"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "300 -244 97.797"; - rotation = "0 0 1 152"; - scale = "1.2 1.2 1.2"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "364 36 124.031"; - rotation = "0 0 1 218"; - scale = "1 1 1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "-340 156 87.4531"; - rotation = "0 0 1 104"; - scale = "1.3 1.3 1.3"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "92 276 67.375"; - rotation = "0 0 1 39"; - scale = "0.8 0.8 0.8"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "-4 228 101.828"; - rotation = "0 0 -1 87.0002"; - scale = "0.8 0.8 0.8"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "92 340 71.3125"; - rotation = "0 0 1 76.9998"; - scale = "1.2 1.2 1.2"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "-300 276 58.1875"; - rotation = "0 0 1 57.9999"; - scale = "1 1 1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "-188 452 92.2656"; - rotation = "0 0 -1 81.0002"; - scale = "1.4 1.4 1.4"; - shapeName = "borg18.dts"; - }; - }; - new SimGroup(Addition1BESmTree17) { - - new TSStatic() { - position = "500 -316 96.6875"; - rotation = "0.0189433 -0.0920088 0.995578 210.869"; - scale = "1.4 1.4 1.4"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "820 -412 60.8594"; - rotation = "0.151268 0.0290211 0.988067 97.6825"; - scale = "1.2 1.2 1.2"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "876 -276 51.7187"; - rotation = "-0.0767067 0.461516 -0.883809 20.3196"; - scale = "0.9 0.9 0.9"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "652 244 85.625"; - rotation = "0.307312 -0.398951 0.863943 32.1955"; - scale = "1.3 1.3 1.3"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "708 -276 72.7656"; - rotation = "0.265436 -0.176198 0.947891 59.6082"; - scale = "1.5 1.5 1.5"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "836 -308 47.8438"; - rotation = "0.0204826 -0.0196076 0.999598 140.015"; - scale = "1.4 1.4 1.4"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "604 4 141.703"; - rotation = "-0.107106 -0.00849662 0.994211 233.731"; - scale = "1.2 1.2 1.2"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "1172 -12 145.812"; - rotation = "-0.169217 0.00416148 0.98557 91.8325"; - scale = "0.8 0.8 0.8"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "1020 -204 127.797"; - rotation = "-0.0211118 0.743291 0.668635 20.8112"; - scale = "0.8 0.8 0.8"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "1108 44 107.75"; - rotation = "-0.0451934 0.160773 0.985956 44.5658"; - scale = "1 1 1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "644 -348 115.234"; - rotation = "0.737692 0.0137925 -0.674997 20.6192"; - scale = "1.2 1.2 1.2"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "844 140 163.828"; - rotation = "-0.155668 -0.0493325 0.986577 83.7687"; - scale = "1.1 1.1 1.1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "1092 76 116.188"; - rotation = "-0.140404 -0.0943009 -0.985593 74.8008"; - scale = "1.2 1.2 1.2"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "940 -180 84.4688"; - rotation = "-0.0699772 0.0254908 0.997223 103.155"; - scale = "1 1 1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "596 76 133.891"; - rotation = "-0.145307 -0.0467364 0.988282 129.523"; - scale = "0.8 0.8 0.8"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "1036 188 136.187"; - rotation = "0.0143986 -0.126977 0.991801 89.4714"; - scale = "1.3 1.3 1.3"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "708 -60 140.547"; - rotation = "-0.214297 -0.107879 0.970793 63.5095"; - scale = "0.9 0.9 0.9"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "980 -316 79.7969"; - rotation = "-0.524424 0.50887 -0.682665 23.2662"; - scale = "1.2 1.2 1.2"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "532 52 118.094"; - rotation = "0.236918 0.0674468 -0.969186 70.6835"; - scale = "1.1 1.1 1.1"; - shapeName = "borg17.dts"; - }; - }; - new SimGroup(Addition2BELgTree18) { - - new TSStatic() { - position = "428 188 135.5"; - rotation = "0 0 1 49"; - scale = "1.5 1.5 1.5"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "844 -212 55.6563"; - rotation = "0 0 -1 82"; - scale = "0.9 0.9 0.9"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "588 292 116.109"; - rotation = "0 0 1 144"; - scale = "1.2 1.2 1.2"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "964 12 184.766"; - rotation = "0 0 1 134"; - scale = "1.5 1.5 1.5"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "844 -244 54.0469"; - rotation = "0 0 -1 16.9999"; - scale = "1.4 1.4 1.4"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "700 244 81.3907"; - rotation = "0 0 1 9.99989"; - scale = "0.9 0.9 0.9"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1060 -220 118.953"; - rotation = "0 0 1 228"; - scale = "1 1 1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1204 316 61.4843"; - rotation = "0 0 1 177"; - scale = "0.9 0.9 0.9"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1132 284 74.4219"; - rotation = "0 0 -1 23.9998"; - scale = "1.1 1.1 1.1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "556 -12 129.312"; - rotation = "0 0 -1 111"; - scale = "1.3 1.3 1.3"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "412 -44 68.4531"; - rotation = "0 0 1 7.00001"; - scale = "0.9 0.9 0.9"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "860 292 155.844"; - rotation = "0 0 -1 10.9999"; - scale = "1.3 1.3 1.3"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1036 -180 124.484"; - rotation = "0 0 1 88.9998"; - scale = "0.9 0.9 0.9"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "588 -52 129.75"; - rotation = "0 0 -1 67.0005"; - scale = "1.1 1.1 1.1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "468 -372 66.0937"; - rotation = "0 0 1 128"; - scale = "1.1 1.1 1.1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "860 116 166.922"; - rotation = "0 0 1 11"; - scale = "1.5 1.5 1.5"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "716 252 82.9531"; - rotation = "0 0 1 11"; - scale = "1.4 1.4 1.4"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1180 -444 145.719"; - rotation = "0 0 1 4.99997"; - scale = "1.5 1.5 1.5"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "876 -380 52.9063"; - rotation = "0 0 1 46"; - scale = "0.9 0.9 0.9"; - shapeName = "borg18.dts"; - }; - }; - new SimGroup(Addition3BEPlant5) { - - new TSStatic() { - position = "588 156 102.809"; - rotation = "-0.193563 0.0259592 0.980744 181.962"; - scale = "1 1 1"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "492 140 100.575"; - rotation = "0.146029 0.137793 0.979637 117.055"; - scale = "1.5 1.5 1.5"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "588 140 108.325"; - rotation = "-0.318993 0.168786 0.932606 227.962"; - scale = "1 1 1"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "548 220 119.778"; - rotation = "-0.542672 -0.517663 -0.661462 28.3949"; - scale = "1 1 1"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "548 196 107.903"; - rotation = "-0.575099 -0.240159 0.782039 51.104"; - scale = "1.3 1.3 1.3"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "492 196 112.762"; - rotation = "0.253778 -0.1873 0.948955 203.761"; - scale = "1 1 1"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "604 156 105.887"; - rotation = "-0.0326261 0.0389834 0.998707 225.946"; - scale = "1.5 1.5 1.5"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "564 236 114.544"; - rotation = "0.208184 -0.0821455 0.974634 115.338"; - scale = "1.4 1.4 1.4"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "492 148 99.2617"; - rotation = "-0.0149542 -0.224199 -0.974429 58.2532"; - scale = "1.1 1.1 1.1"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "572 44 129.95"; - rotation = "-0.0753689 0.145225 0.986524 67.7173"; - scale = "1.3 1.3 1.3"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "628 188 107.028"; - rotation = "-0.124681 -0.107766 -0.986327 72.7519"; - scale = "1.3 1.3 1.3"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "580 108 129.606"; - rotation = "-0.160092 0.296592 0.94149 163.037"; - scale = "1.2 1.2 1.2"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "572 188 105.919"; - rotation = "-0.0916734 -0.212707 0.972806 188.756"; - scale = "1 1 1"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "636 236 95.4966"; - rotation = "0.296211 -0.0940407 0.950482 86.9005"; - scale = "1.1 1.1 1.1"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "652 132 111.966"; - rotation = "0.114039 0.329162 0.937362 63.2603"; - scale = "1.2 1.2 1.2"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "596 108 134.653"; - rotation = "-0.131211 0.224869 0.965514 229.455"; - scale = "1.5 1.5 1.5"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "660 60 143.575"; - rotation = "-0.0366527 -0.205783 0.977911 82.2664"; - scale = "1.2 1.2 1.2"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "676 92 133.559"; - rotation = "-0.143912 0.101845 0.984336 208.565"; - scale = "1.2 1.2 1.2"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "484 124 107.887"; - rotation = "0.0688712 0.267605 0.961064 116.062"; - scale = "1.4 1.4 1.4"; - shapeName = "borg5.dts"; - }; - new TSStatic() { - position = "548 188 102.95"; - rotation = "-0.141141 -0.288261 0.947093 135.236"; - scale = "1.2 1.2 1.2"; - shapeName = "borg5.dts"; - }; - }; - new SimGroup(Addition4BEPlant1) { - - new TSStatic() { - position = "196 124 106.788"; - rotation = "-0.0194762 0.0360942 0.999159 185.995"; - scale = "0.8 0.8 0.8"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "324 132 137.709"; - rotation = "-0.824061 0.269725 0.498169 40.8144"; - scale = "1.5 1.5 1.5"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "404 148 129.272"; - rotation = "-0.453514 0.0103151 -0.89119 57.3823"; - scale = "1.3 1.3 1.3"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "148 164 106.272"; - rotation = "0.346131 0.139353 0.927779 82.2303"; - scale = "1.3 1.3 1.3"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "388 52 119.178"; - rotation = "0.299604 0.0496035 0.952773 96.7594"; - scale = "0.8 0.8 0.8"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "452 220 146.162"; - rotation = "-0.155184 -0.275246 0.948766 94.0103"; - scale = "1.5 1.5 1.5"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "164 324 104.084"; - rotation = "-0.256999 0.966412 0 31.3768"; - scale = "1.4 1.4 1.4"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "380 100 118.959"; - rotation = "0.252843 -0.0682316 0.965098 206.091"; - scale = "0.7 0.7 0.7"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "252 140 124.506"; - rotation = "-0.290357 -0.0857175 0.953072 149.43"; - scale = "0.7 0.7 0.7"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "172 364 93.2094"; - rotation = "0.0544781 0.166186 0.984588 180.985"; - scale = "1 1 1"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "156 180 97.1313"; - rotation = "0.735189 0.316481 0.599448 35.9322"; - scale = "1.5 1.5 1.5"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "452 212 143.413"; - rotation = "-0.292077 -0.0147327 -0.956281 70.3941"; - scale = "2 2 2"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "476 324 193.725"; - rotation = "-0.46624 -0.0634 0.882384 21.4771"; - scale = "1.5 1.5 1.5"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "428 164 133.319"; - rotation = "-0.0128469 -0.219879 0.975443 155.595"; - scale = "0.6 0.6 0.6"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "388 252 165.584"; - rotation = "0.0979139 -0.392969 0.914324 89.1213"; - scale = "0.7 0.7 0.7"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "388 164 134.662"; - rotation = "0.136418 -0.0673901 0.988357 100.66"; - scale = "0.6 0.6 0.6"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "436 148 121.663"; - rotation = "-0.487287 0.0647607 -0.870837 83.7945"; - scale = "1.7 1.7 1.7"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "236 340 114.647"; - rotation = "-0.0104936 0.224169 0.974494 182.924"; - scale = "1.1 1.1 1.1"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "324 164 150.147"; - rotation = "-0.547013 0.782764 -0.296745 23.293"; - scale = "1 1 1"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "268 116 123.741"; - rotation = "-0.479476 0.578886 -0.65954 35.7259"; - scale = "1.2 1.2 1.2"; - shapeName = "borg1.dts"; - }; - }; - new SimGroup(Addition5BEPlant1) { - - new TSStatic() { - position = "1364 -852 77.2562"; - rotation = "-0.768939 0.365446 -0.524579 33.6006"; - scale = "0.9 0.9 0.9"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1196 -836 64.3031"; - rotation = "0.210641 0.146051 -0.966592 61.7001"; - scale = "0.9 0.9 0.9"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1244 -780 86.6625"; - rotation = "-0.115374 -0.141325 0.983217 175.084"; - scale = "1.3 1.3 1.3"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1308 -876 75.1782"; - rotation = "0.228708 -0.120099 0.966058 183.864"; - scale = "0.9 0.9 0.9"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1132 -892 65.725"; - rotation = "-0.12685 0.170462 0.977165 141.825"; - scale = "0.9 0.9 0.9"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1244 -924 102.069"; - rotation = "-0.110985 0.0519229 0.992465 144.254"; - scale = "2 2 2"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1180 -868 69.0688"; - rotation = "0.0109543 0.159993 0.987057 149.382"; - scale = "1.8 1.8 1.8"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1204 -644 98.9593"; - rotation = "0.110772 -0.25673 0.960114 237.022"; - scale = "1.3 1.3 1.3"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1396 -940 87.4594"; - rotation = "-0.266377 0.35014 0.898023 69.6625"; - scale = "0.5 0.5 0.5"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1292 -620 110.038"; - rotation = "-0.054907 0.139267 0.988732 202.747"; - scale = "1.7 1.7 1.7"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1060 -644 119.631"; - rotation = "-0.492076 0.214682 -0.843666 61.1638"; - scale = "0.6 0.6 0.6"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1316 -708 100.069"; - rotation = "-0.195611 0.0941593 0.976151 203.444"; - scale = "2 2 2"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1172 -788 55.9126"; - rotation = "0.0333406 0.00956025 0.999398 122.029"; - scale = "1.6 1.6 1.6"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1076 -700 95.6469"; - rotation = "-0.0505172 -0.443439 -0.89488 14.5118"; - scale = "0.9 0.9 0.9"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1260 -828 77.9125"; - rotation = "0.0225397 0.0724205 0.997119 129.128"; - scale = "1.2 1.2 1.2"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1076 -860 65.7719"; - rotation = "0.133628 -0.137519 0.981444 105.039"; - scale = "1.7 1.7 1.7"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1316 -836 87.85"; - rotation = "-0.09518 -0.0525785 0.994071 108.324"; - scale = "0.6 0.6 0.6"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1132 -908 71.2563"; - rotation = "0.00708622 0.347095 0.937803 103.601"; - scale = "0.8 0.8 0.8"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1156 -916 80.3344"; - rotation = "-0.0730995 0.138384 0.987677 220.536"; - scale = "1.2 1.2 1.2"; - shapeName = "borg1.dts"; - }; - new TSStatic() { - position = "1060 -564 127.616"; - rotation = "0.0985932 0.092788 0.990793 200.811"; - scale = "1.1 1.1 1.1"; - shapeName = "borg1.dts"; - }; - }; - new SimGroup(Addition6BELgTree18) { - - new TSStatic() { - position = "1340 -876 63.3125"; - rotation = "0 0 1 232"; - scale = "1.1 1.1 1.1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1348 -524 77.4063"; - rotation = "0 0 1 201"; - scale = "1.5 1.5 1.5"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1244 -972 92.5"; - rotation = "0 0 1 195"; - scale = "1.5 1.5 1.5"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1004 -932 71.3281"; - rotation = "0 0 1 121"; - scale = "0.8 0.8 0.8"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1044 -852 70.5938"; - rotation = "0 0 -1 96.0002"; - scale = "1 1 1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1172 -804 54.0625"; - rotation = "0 0 1 138"; - scale = "1.2 1.2 1.2"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1164 -852 60.6406"; - rotation = "0 0 1 153"; - scale = "1.1 1.1 1.1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1060 -716 94.75"; - rotation = "0 0 -1 73.0006"; - scale = "0.9 0.9 0.9"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1260 -612 106.578"; - rotation = "0 0 -1 82"; - scale = "1.1 1.1 1.1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1036 -836 72.0157"; - rotation = "0 0 -1 113"; - scale = "1.2 1.2 1.2"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1268 -948 95.7499"; - rotation = "0 0 1 113"; - scale = "1.5 1.5 1.5"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1244 -932 98.625"; - rotation = "0 0 1 9.99989"; - scale = "1.1 1.1 1.1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1252 -716 85.6875"; - rotation = "0 0 1 33"; - scale = "1.1 1.1 1.1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1316 -524 79.6719"; - rotation = "0 0 1 207"; - scale = "0.9 0.9 0.9"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1324 -644 109.062"; - rotation = "0 0 1 113"; - scale = "0.8 0.8 0.8"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1132 -452 157.297"; - rotation = "0 0 1 180"; - scale = "1.1 1.1 1.1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "980 -924 78.2031"; - rotation = "1 0 0 0"; - scale = "1.3 1.3 1.3"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1004 -716 103.766"; - rotation = "0 0 1 72.0002"; - scale = "0.8 0.8 0.8"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1020 -740 98.406"; - rotation = "0 0 1 127"; - scale = "1.4 1.4 1.4"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "1204 -724 66.0312"; - rotation = "0 0 1 149"; - scale = "1.2 1.2 1.2"; - shapeName = "borg18.dts"; - }; - }; - new SimGroup(Addition1BESmTree17) { - - new TSStatic() { - position = "516 -852 114.203"; - rotation = "0.0226453 0.0115586 0.999677 203.992"; - scale = "1.4 1.4 1.4"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "412 -636 137.328"; - rotation = "-0.054195 -0.05415 0.997061 181.994"; - scale = "1.1 1.1 1.1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "516 -852 114.203"; - rotation = "-0.0128273 -0.0480088 -0.998765 60.0615"; - scale = "1.1 1.1 1.1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "444 -756 96.0001"; - rotation = "-0.0616775 -0.117932 0.991104 215.7"; - scale = "1.1 1.1 1.1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "340 -772 79.5938"; - rotation = "-0.214777 0.964319 0.154792 6.45366"; - scale = "1.5 1.5 1.5"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "604 -844 157.766"; - rotation = "-0.0445501 -0.0465846 0.99792 184.99"; - scale = "1.4 1.4 1.4"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "628 -644 187.891"; - rotation = "0.19108 -0.0345838 -0.980965 98.0915"; - scale = "0.8 0.8 0.8"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "372 -764 83.5781"; - rotation = "0.126305 0.0603915 -0.990151 87.5658"; - scale = "1.5 1.5 1.5"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "588 -844 156.516"; - rotation = "-0.124319 -0.119349 0.985038 104.836"; - scale = "1.3 1.3 1.3"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "412 -900 119.953"; - rotation = "-0.0628523 -0.0476702 0.996884 210.907"; - scale = "1.1 1.1 1.1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "428 -540 160.078"; - rotation = "-0.106477 0.0229367 0.994051 223.763"; - scale = "1.5 1.5 1.5"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "468 -652 141.938"; - rotation = "0.209904 -0.0580286 -0.975998 73.3289"; - scale = "1.5 1.5 1.5"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "404 -892 119.344"; - rotation = "0.0258563 0.208098 -0.977766 83.2771"; - scale = "1.3 1.3 1.3"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "476 -500 153.453"; - rotation = "0.770847 -0.137338 -0.62204 20.7593"; - scale = "1.1 1.1 1.1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "284 -532 90.2187"; - rotation = "-0.835172 0.10902 0.539075 20.2546"; - scale = "1.3 1.3 1.3"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "300 -860 106.953"; - rotation = "0.0300008 0.141884 0.989429 78.5967"; - scale = "1.5 1.5 1.5"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "468 -724 105.984"; - rotation = "-0.231502 0.313655 -0.920884 48.4362"; - scale = "1.1 1.1 1.1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "436 -780 93.1406"; - rotation = "-0.0166021 0.0320587 0.999348 205.983"; - scale = "0.9 0.9 0.9"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "276 -876 111.875"; - rotation = "0.10672 0.12651 0.986208 236.335"; - scale = "1.5 1.5 1.5"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "380 -740 84.4219"; - rotation = "-0.126943 0.171214 0.977022 55.0849"; - scale = "0.8 0.8 0.8"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "460 -564 163.094"; - rotation = "-0.00537145 0.279877 -0.960021 67.1369"; - scale = "1.2 1.2 1.2"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "468 -868 119.641"; - rotation = "-0.275798 -0.0223686 -0.960955 45.6079"; - scale = "1.2 1.2 1.2"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "580 -812 159.172"; - rotation = "0.11136 -0.181869 0.976997 71.2576"; - scale = "0.9 0.9 0.9"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "292 -644 101.859"; - rotation = "-0.154484 -0.000180158 0.987995 176.048"; - scale = "0.9 0.9 0.9"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "340 -876 123.937"; - rotation = "0.00543177 0.0324584 0.999458 184.997"; - scale = "1.3 1.3 1.3"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "356 -644 117.328"; - rotation = "-0.0709721 -0.0117515 0.997409 157.058"; - scale = "0.9 0.9 0.9"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "444 -540 160.797"; - rotation = "0.0687445 0.0224915 0.997381 82.149"; - scale = "1.2 1.2 1.2"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "516 -852 114.203"; - rotation = "0.0261136 -0.00134998 0.999658 144.011"; - scale = "1.3 1.3 1.3"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "580 -796 159.547"; - rotation = "0.0555007 0.0996695 0.993472 234.693"; - scale = "1.2 1.2 1.2"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "452 -532 160.047"; - rotation = "0.0187232 0.0595054 0.998052 143.067"; - scale = "1.4 1.4 1.4"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "452 -572 159.516"; - rotation = "-0.107753 -0.142268 0.983946 143.555"; - scale = "1 1 1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "572 -772 157.203"; - rotation = "0.085667 0.0576616 0.994654 176.021"; - scale = "0.8 0.8 0.8"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "348 -788 81.5782"; - rotation = "-0.119645 0.050421 0.991536 217.701"; - scale = "0.8 0.8 0.8"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "380 -740 84.4219"; - rotation = "-0.152944 0.359364 0.920579 29.2333"; - scale = "1 1 1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "268 -564 82.4531"; - rotation = "-0.0958363 0.325672 -0.940613 33.9076"; - scale = "0.9 0.9 0.9"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "460 -540 162.266"; - rotation = "-0.131657 0.0740015 0.988529 198.786"; - scale = "0.8 0.8 0.8"; - shapeName = "borg17.dts"; - }; - }; - new SimGroup(Addition2BELgTree18) { - - new TSStatic() { - position = "332 -932 118.766"; - rotation = "0 0 -1 53.9998"; - scale = "1.5 1.5 1.5"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "188 -604 87.5781"; - rotation = "0 0 1 159"; - scale = "1.1 1.1 1.1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "12 -844 121.125"; - rotation = "0 0 1 233"; - scale = "1.2 1.2 1.2"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "-36 -468 135.203"; - rotation = "0 0 1 76"; - scale = "0.8 0.8 0.8"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "108 -892 102.594"; - rotation = "0 0 1 53"; - scale = "0.8 0.8 0.8"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "476 -652 142.578"; - rotation = "0 0 1 208"; - scale = "1.5 1.5 1.5"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "444 -524 160.156"; - rotation = "0 0 1 17"; - scale = "1.1 1.1 1.1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "-28 -468 136"; - rotation = "0 0 1 121"; - scale = "0.9 0.9 0.9"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "228 -452 115.188"; - rotation = "0 0 1 36"; - scale = "1 1 1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "164 -564 91.9688"; - rotation = "0 0 -1 44.9999"; - scale = "1.3 1.3 1.3"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "76 -412 131.828"; - rotation = "0 0 -1 1.00014"; - scale = "0.8 0.8 0.8"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "260 -892 118.438"; - rotation = "0 0 1 150"; - scale = "1.1 1.1 1.1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "452 -556 162.062"; - rotation = "0 0 1 20"; - scale = "0.9 0.9 0.9"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "156 -604 84.5781"; - rotation = "0 0 1 93.0002"; - scale = "1.5 1.5 1.5"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "340 -780 79.5"; - rotation = "0 0 -1 10.9999"; - scale = "1.5 1.5 1.5"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "284 -676 104.078"; - rotation = "0 0 1 109"; - scale = "1.5 1.5 1.5"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "212 -748 102.672"; - rotation = "0 0 1 180"; - scale = "1.2 1.2 1.2"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "44 -708 86.1249"; - rotation = "0 0 1 177"; - scale = "0.8 0.8 0.8"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "324 -436 77.3281"; - rotation = "0 0 -1 35"; - scale = "1.1 1.1 1.1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "228 -532 103.313"; - rotation = "0 0 1 174"; - scale = "1 1 1"; - shapeName = "borg18.dts"; - }; - }; - new TSStatic() { - position = "590.041 -542.501 248.284"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - shapeName = "borg18.dts"; - }; - new SimGroup(Addition3BELgTree18) { - - new TSStatic() { - position = "612 676 187.797"; - rotation = "0 0 1 236"; - scale = "1 1 1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "596 684 188.609"; - rotation = "0 0 1 222"; - scale = "1.4 1.4 1.4"; - shapeName = "borg18.dts"; - }; - }; - new SimGroup(Addition4BELgTree18) { - - new TSStatic() { - position = "484 548 68.625"; - rotation = "0 0 1 75.0002"; - scale = "1.3 1.3 1.3"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "532 524 84.0782"; - rotation = "0 0 1 161"; - scale = "0.8 0.8 0.8"; - shapeName = "borg18.dts"; - }; - }; - new SimGroup(Addition5BELgTree18) { - - new TSStatic() { - position = "268 668 97.359"; - rotation = "0 0 1 60.0001"; - scale = "0.8 0.8 0.8"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "60 588 135.438"; - rotation = "0 0 1 218"; - scale = "1.2 1.2 1.2"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "44 780 52.0312"; - rotation = "0 0 1 168"; - scale = "1.3 1.3 1.3"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "316 604 115.359"; - rotation = "0 0 1 1.9999"; - scale = "1.1 1.1 1.1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "124 820 54.7031"; - rotation = "0 0 1 21"; - scale = "1.1 1.1 1.1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "84 556 133.891"; - rotation = "0 0 -1 38"; - scale = "0.9 0.9 0.9"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "76 572 133.078"; - rotation = "0 0 -1 34.0002"; - scale = "0.8 0.8 0.8"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "236 588 125.078"; - rotation = "0 0 1 57"; - scale = "0.8 0.8 0.8"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "332 668 98.781"; - rotation = "0 0 1 130"; - scale = "0.9 0.9 0.9"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "332 740 90.7656"; - rotation = "0 0 1 85.9998"; - scale = "1.5 1.5 1.5"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "276 812 99.359"; - rotation = "0 0 1 42"; - scale = "1 1 1"; - shapeName = "borg18.dts"; - }; - new TSStatic() { - position = "300 692 100.281"; - rotation = "0 0 1 32"; - scale = "1.2 1.2 1.2"; - shapeName = "borg18.dts"; - }; - }; - new SimGroup(Addition6BESmTree17) { - - new TSStatic() { - position = "316 764 90.3593"; - rotation = "-0.269346 0.0747762 0.960136 9.37201"; - scale = "1.4 1.4 1.4"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "284 796 100.625"; - rotation = "-0.109174 -0.268087 0.957189 30.2388"; - scale = "1 1 1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "92 788 52.4374"; - rotation = "-0.00226441 0.0373222 0.999301 211.979"; - scale = "0.8 0.8 0.8"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "236 596 124.828"; - rotation = "0.0374212 -0.125582 -0.991377 48.3697"; - scale = "0.9 0.9 0.9"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "92 604 130.219"; - rotation = "0.130424 -0.533966 0.835386 29.7251"; - scale = "1.2 1.2 1.2"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "236 580 125.891"; - rotation = "0.988853 -0.0859407 0.121593 8.21026"; - scale = "1.1 1.1 1.1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "204 844 64"; - rotation = "0.075034 -0.0658218 0.995006 117.256"; - scale = "1.4 1.4 1.4"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "324 724 93.625"; - rotation = "0.177271 -0.147427 0.973057 84.5554"; - scale = "0.9 0.9 0.9"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "68 692 85.2812"; - rotation = "0.197225 0.181032 0.963499 72.0145"; - scale = "0.8 0.8 0.8"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "324 588 114.719"; - rotation = "-0.0913719 -0.0166197 0.995678 143.149"; - scale = "1.5 1.5 1.5"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "124 812 54.3437"; - rotation = "-0.139173 -0.0205308 0.990055 195.843"; - scale = "1 1 1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "332 772 93.0156"; - rotation = "-0.630648 0.457846 -0.626626 22.1727"; - scale = "0.8 0.8 0.8"; - shapeName = "borg17.dts"; - }; - }; - new SimGroup(Addition7BESmTree17) { - - new TSStatic() { - position = "724 500 100.312"; - rotation = "-0.474947 0.55988 -0.67894 10.2955"; - scale = "0.8 0.8 0.8"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "692 644 172.547"; - rotation = "-0.120142 -0.104658 0.987225 130.562"; - scale = "0.8 0.8 0.8"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "788 604 183.453"; - rotation = "-0.381454 0.132918 0.914782 46.594"; - scale = "0.8 0.8 0.8"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "748 620 177.734"; - rotation = "-0.133731 0.0451644 0.989988 126.465"; - scale = "1 1 1"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "700 636 170.906"; - rotation = "-0.28187 -0.0991843 0.954312 63.3697"; - scale = "1.4 1.4 1.4"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "796 676 167.984"; - rotation = "-0.114769 0.0364394 0.992724 166.101"; - scale = "1.5 1.5 1.5"; - shapeName = "borg17.dts"; - }; - }; - new SimGroup(Addition8BESmTree17) { - - new TSStatic() { - position = "612 492 82.4219"; - rotation = "0.15131 -0.0330094 0.987935 175.06"; - scale = "1.4 1.4 1.4"; - shapeName = "borg17.dts"; - }; - new TSStatic() { - position = "652 428 79.7656"; - rotation = "0.122244 -0.16474 -0.978732 87.229"; - scale = "0.8 0.8 0.8"; - shapeName = "borg17.dts"; - }; - }; - }; - new SimGroup(NotSoRandomOrganics) { - - new InteriorInstance() { - position = "-234.377 399.56 72.0484"; - rotation = "1 0 0 139.229"; - scale = "1.18518 1.63312 1"; - interiorFile = "brock7.dif"; - showTerrainInside = "0"; - }; - new InteriorInstance() { - position = "-359.655 570.11 126.837"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "brock8.dif"; - showTerrainInside = "0"; - }; - new InteriorInstance() { - position = "-361.343 564.269 130.504"; - rotation = "1 0 0 50.4203"; - scale = "1 1 1"; - interiorFile = "brock8.dif"; - showTerrainInside = "0"; - }; - new InteriorInstance() { - position = "-351.76 562.309 125.975"; - rotation = "0.769297 0.578037 -0.272129 62.9301"; - scale = "1 1 1"; - interiorFile = "brock8.dif"; - showTerrainInside = "0"; - }; - new StaticShape(SWDeadMed) { - position = "-332.993 471.436 122.37"; - rotation = "-0.294439 -0.309888 0.904033 47.0646"; - scale = "1 1 0.99"; - dataBlock = "MediumMaleHuman_Dead"; - lockCount = "0"; - homingCount = "0"; - trainingSkin = 1; - }; - new StaticShape(MedDeadBody) { - position = "477.477 360.201 204.267"; - rotation = "0 0 1 82.5059"; - scale = "1 1 1"; - dataBlock = "MediumMaleHuman_Dead"; - lockCount = "0"; - homingCount = "0"; - }; - new StaticShape(SWDeadLt) { - position = "-205.392 473.86 97.7869"; - rotation = "-0.94867 0.262068 0.177046 24.3075"; - scale = "1 1 1"; - dataBlock = "LightMaleHuman_Dead"; - lockCount = "0"; - homingCount = "0"; - trainingSkin = 1; - }; - new StaticShape(LightDeadBody) { - position = "474.167 360.154 215.68"; - rotation = "0 0 1 94.538"; - scale = "1 1 1"; - dataBlock = "LightMaleHuman_Dead"; - lockCount = "0"; - homingCount = "0"; - }; - new InteriorInstance() { - position = "-32.6219 242.339 102.947"; - rotation = "0 0 -1 115.92"; - scale = "1 1 1"; - interiorFile = "bspir1.dif"; - showTerrainInside = "0"; - }; - new InteriorInstance() { - position = "93.7696 300.472 66.6777"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "bspir5.dif"; - showTerrainInside = "0"; - }; - new InteriorInstance() { - position = "363.768 249.524 170.509"; - rotation = "0 0 1 218.479"; - scale = "1 1 1"; - interiorFile = "bspir4.dif"; - showTerrainInside = "0"; - }; - new InteriorInstance() { - position = "976.562 -614.672 90.2773"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "bspir3.dif"; - showTerrainInside = "0"; - }; - new StaticShape(HeavyDeadBody) { - position = "476.153 360.368 232.658"; - rotation = "0 0 1 94.538"; - scale = "1 1 1"; - dataBlock = "HeavyMaleHuman_Dead"; - lockCount = "0"; - homingCount = "0"; - }; - new WheeledVehicle(MPB) { - position = "1273.71 -818.372 79.5295"; - rotation = "0.12202 0.0215281 -0.992294 60.694"; - scale = "1 1 1"; - dataBlock = "mobileBaseVehicle"; - lockCount = "0"; - homingCount = "0"; - disableMove = "0"; - respawn = "0"; - selfPower = "1"; - mountable = "1"; - }; - }; - new SimGroup(Water) { - - new WaterBlock() { - position = "-16 -80 71.5051"; - rotation = "1 0 0 0"; - scale = "128 128 6.3387"; - liquidType = "StagnantWater"; - density = "1"; - viscosity = "6"; - waveMagnitude = "1"; - surfaceTexture = "LiquidTiles/GreenWater"; - surfaceOpacity = "0.7"; - envMapTexture = "lush/skies/lushcloud3"; - envMapIntensity = "0.9"; - removeWetEdges = "1"; - AudioEnvironment = Underwater; - }; - new WaterBlock() { - position = "-8 48 95.5"; - rotation = "1 0 0 0"; - scale = "64 64 3.71365"; - liquidType = "StagnantWater"; - density = "1"; - viscosity = "6"; - waveMagnitude = "0.2"; - surfaceTexture = "LiquidTiles/AlgaeWater"; - surfaceOpacity = "0.7"; - envMapTexture = "lush/skies/lushcloud3"; - envMapIntensity = "0.9"; - removeWetEdges = "1"; - AudioEnvironment = Underwater; - }; - new WaterBlock() { - position = "-272 376 72"; - rotation = "1 0 0 0"; - scale = "64 64 1"; - liquidType = "StagnantWater"; - density = "1"; - viscosity = "6"; - waveMagnitude = "0.1"; - surfaceTexture = "LiquidTiles/AlgaeWater"; - surfaceOpacity = "0.7"; - envMapTexture = "lush/skies/lushcloud3"; - envMapIntensity = "0.9"; - removeWetEdges = "1"; - AudioEnvironment = Underwater; - }; - }; - new SimGroup(Sounds) { - - new AudioEmitter(Frog1) { - position = "-222.356 401.06 75.6289"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - fileName = "fx/environment/frog1.wav"; - useProfileDescription = "0"; - outsideAmbient = "1"; - volume = "1"; - isLooping = "1"; - is3D = "1"; - minDistance = "20"; - maxDistance = "150"; - coneInsideAngle = "360"; - coneOutsideAngle = "360"; - coneOutsideVolume = "1"; - coneVector = "0 0 1"; - loopCount = "-1"; - minLoopGap = "0"; - maxLoopGap = "0"; - type = "EffectAudioType"; - }; - new AudioEmitter(Cricket1) { - position = "-59.9835 298.318 95.3758"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - fileName = "fx/environment/crickets.wav"; - useProfileDescription = "0"; - outsideAmbient = "1"; - volume = "1"; - isLooping = "1"; - is3D = "1"; - minDistance = "20"; - maxDistance = "150"; - coneInsideAngle = "360"; - coneOutsideAngle = "360"; - coneOutsideVolume = "1"; - coneVector = "0 0 1"; - loopCount = "-1"; - minLoopGap = "0"; - maxLoopGap = "0"; - type = "EffectAudioType"; - }; - new AudioEmitter(Frog2) { - position = "534.092 163.88 102.215"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - fileName = "fx/environment/frog2.wav"; - useProfileDescription = "0"; - outsideAmbient = "1"; - volume = "1"; - isLooping = "1"; - is3D = "1"; - minDistance = "20"; - maxDistance = "150"; - coneInsideAngle = "360"; - coneOutsideAngle = "360"; - coneOutsideVolume = "1"; - coneVector = "0 0 1"; - loopCount = "-1"; - minLoopGap = "0"; - maxLoopGap = "0"; - type = "EffectAudioType"; - }; - new AudioEmitter(Cricket1) { - position = "377.544 386.028 124.305"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - fileName = "fx/environment/crickets.wav"; - useProfileDescription = "0"; - outsideAmbient = "1"; - volume = "1"; - isLooping = "1"; - is3D = "1"; - minDistance = "20"; - maxDistance = "150"; - coneInsideAngle = "360"; - coneOutsideAngle = "360"; - coneOutsideVolume = "1"; - coneVector = "0 0 1"; - loopCount = "-1"; - minLoopGap = "0"; - maxLoopGap = "0"; - type = "EffectAudioType"; - }; - new AudioEmitter(Cricket1) { - position = "818.623 -238.858 63.6823"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - fileName = "fx/environment/crickets.wav"; - useProfileDescription = "0"; - outsideAmbient = "1"; - volume = "1"; - isLooping = "1"; - is3D = "1"; - minDistance = "20"; - maxDistance = "150"; - coneInsideAngle = "360"; - coneOutsideAngle = "360"; - coneOutsideVolume = "1"; - coneVector = "0 0 1"; - loopCount = "-1"; - minLoopGap = "0"; - maxLoopGap = "0"; - type = "EffectAudioType"; - }; - new AudioEmitter(Cricket1) { - position = "1211.31 -579.262 126.456"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - fileName = "fx/environment/crickets.wav"; - useProfileDescription = "0"; - outsideAmbient = "1"; - volume = "1"; - isLooping = "1"; - is3D = "1"; - minDistance = "20"; - maxDistance = "150"; - coneInsideAngle = "360"; - coneOutsideAngle = "360"; - coneOutsideVolume = "1"; - coneVector = "0 0 1"; - loopCount = "-1"; - minLoopGap = "0"; - maxLoopGap = "0"; - type = "EffectAudioType"; - }; - new AudioEmitter(Cricket1) { - position = "1058.83 -419.898 124.77"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - fileName = "fx/environment/crickets.wav"; - useProfileDescription = "0"; - outsideAmbient = "1"; - volume = "1"; - isLooping = "1"; - is3D = "1"; - minDistance = "20"; - maxDistance = "150"; - coneInsideAngle = "360"; - coneOutsideAngle = "360"; - coneOutsideVolume = "1"; - coneVector = "0 0 1"; - loopCount = "-1"; - minLoopGap = "0"; - maxLoopGap = "0"; - type = "EffectAudioType"; - }; - new AudioEmitter(bird) { - position = "-260.284 339.991 112.661"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - fileName = "fx/environment/bird_echo5.wav"; - useProfileDescription = "0"; - outsideAmbient = "1"; - volume = "1"; - isLooping = "1"; - is3D = "1"; - minDistance = "2"; - maxDistance = "150"; - coneInsideAngle = "360"; - coneOutsideAngle = "360"; - coneOutsideVolume = "1"; - coneVector = "0 0 1"; - loopCount = "-1"; - minLoopGap = "0"; - maxLoopGap = "0"; - type = "EffectAudioType"; - }; - }; - new Camera(introFlyerDP) { - position = "400 -1000 200"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - new SimGroup(FlightPath) { - - new Camera(1) { - position = "400 -800 200"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - new Camera(2) { - position = "400 -650 200"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - new Camera(3) { - position = "400 -350 200"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - new Camera(4) { - position = "400 -245 200"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - new Camera(5) { - position = "400 45 200"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - }; - new Camera(MissileGuySpot) { - position = "250.052 -348.706 132.918"; - rotation = "0 0 -1 43.1546"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; - new Camera(MissileCamera) { - position = "246.608 -349.915 134.29"; - rotation = "0 0 1 39.6094"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - }; -}; -//--- OBJECT WRITE END --- - -exec("scripts/training1.cs"); +// MissionTypes = SinglePlayer +// DisplayName = Major + +//--- MISSION BRIEFING BEGIN --- +//Dear Recruit Iguana, +//This is a notification of activation. You are to report to the launch bay at 3:00 sharp. You will be deployed to the Southern hemisphere of Xeron; your objecive is to take back an HQ of ours. +// +//Letter No. 626938. +//Department: Alpha Viper +// +//Sincerely,Alpha Viper deployment +//--- MISSION BRIEFING END --- + +// PlanetName = Xeron, 3960 CE +// Bitmap = trn_5draconis + +//--- MISSION STRING BEGIN --- +//OBJECTIVES: +//Bleck +//--- MISSION STRING END --- + +//--- MISSION BLURB BEGIN --- +//In 3941, the BioDerm Hordes crushed the Starwolf tribe at the star system of Ymir. Six years later, the tribal alliance called the Pact begins a crucial offensive. You are of the Pact, a Starwolf newblood. Remember Ymir. Avenge your people. +//--- MISSION BLURB END --- + + +//scriptlet +//we have to jump through a lot of hoops to get those dead bodies in training1 +function deadArmor::onAdd(%this, %obj) +{ + %skin = (%obj.trainingSkin == 1 ? 'swolf' : 'beagle'); + //echo("skin = " SPC %skin); + createTarget(%obj, 'Dead Body', %skin, "", 'deadArmor', 0); +} + +function deadArmor::onRemove(%this, %obj) +{ + //echo("singleplayerGame -- deadArmor::onRemove"); + freeTarget(%obj.getTarget()); +} + + +//--- OBJECT WRITE BEGIN --- +new SimGroup(MissionGroup) { + powerCount = "0"; + + new MissionArea(MissionArea) { + area = "-448 -1408 2304 2208"; + flightCeiling = "2000"; + flightCeilingRange = "50"; + }; + new Sky(Sky) { + position = "0 0 0"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + cloudHeightPer[0] = "0.349971"; + cloudHeightPer[1] = "0.25"; + cloudHeightPer[2] = "0.199973"; + cloudSpeed1 = "0.0001"; + cloudSpeed2 = "0.0002"; + cloudSpeed3 = "0.0003"; + visibleDistance = "400"; + useSkyTextures = "1"; + SkySolidColor = "0.390000 0.390000 0.390000 1.000000"; + fogDistance = "100"; + fogColor = "0.500000 0.500000 0.500000 1.000000"; + fogVolume1 = "0 0 0"; + fogVolume2 = "0 0 0"; + fogVolume3 = "0 0 0"; + materialList = "Lush_l4.dml"; + windVelocity = "0 0 0"; + windEffectPrecipitation = "0"; + cloudSpeed0 = "0.000000 0.000000"; + }; + new Sun() { + direction = "0.57735 0.57735 -0.57735"; + color = "0.600000 0.600000 0.600000 1.000000"; + ambient = "0.600000 0.600000 0.600000 1.000000"; + scale = "1 1 1"; + position = "0 0 0"; + rotation = "1 0 0 0"; + }; + new TerrainBlock(Terrain) { + rotation = "1 0 0 0"; + scale = "1 1 1"; + detailTexture = "details/lushdet1"; + terrainFile = "Training1.ter"; + squareSize = "8"; + position = "-1024 -1024 0"; + }; + new NavigationGraph(NavGraph) { + conjoinAngleDev = "50"; + cullDensity = "0.1"; + customArea = "0 0 0 0"; + conjoinBowlDev = "20"; + scale = "1 1 1"; + GraphFile = "Training1.nav"; + position = "0 0 0 1"; + coverage = "0"; + rotation = "0 0 0 0"; + }; + new Camera(hoverBikeDP) { + position = "629.407 -58.6929 124.08"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + new SimGroup(Teams) { + + new SimGroup(Team2) { + + new SimGroup(DropPoints) { + + new Camera(enemy0) { + position = "472.802 349.922 204.888"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + SkillLevel = "0"; + }; + new Camera(enemy1) { + position = "551.142 790.21 107.5"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + SkillLevel = "0"; + }; + new Camera(enemy2) { + position = "738.109 5.1693 152.475"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + SkillLevel = "0"; + }; + new Camera(enemy3) { + position = "988.221 -326.252 86.2044"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + SkillLevel = "0"; + }; + new Camera(enemy4) { + position = "917.043 -476.293 102.216"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + SkillLevel = "0"; + }; + new Camera(enemy5) { + position = "977.56 -584.56 107.011"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + SkillLevel = "0"; + }; + new Camera(enemy6) { + position = "980.365 -777.838 97.7195"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + SkillLevel = "0"; + }; + new Camera(enemy7) { + position = "472.356 345.155 200.883"; + rotation = "0 0 -1 75.6304"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + SkillLevel = "0"; + }; + new Camera(enemy8) { + position = "564.903 791.638 107.929"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + new Camera(enemy9) { + position = "589.296 806.741 111.858"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + new Camera(enemy10) { + position = "575.32 -29.8525 138.276"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + new Camera(enemy11) { + position = "827.178 406.124 195.466"; + rotation = "0 0 1 183.919"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + new Camera(enemy12) { + position = "-721.719 296.493 83.3617"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + new Camera(enemy13) { + position = "882.259 49.6576 147.146"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + }; + }; + new SimGroup(Team1) { + providesPower = "1"; + + new SimGroup(DropPoints) { + + new Camera() { + position = "1301.77 -832.202 88.3109"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + new Camera() { + position = "1255.36 -826.299 79.1645"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + new Camera(DP) { + position = "-262.22 528.825 148.641"; + rotation = "0 0 1 174.696"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + new SimGroup(Respawns) { + + new Camera() { + position = "-311.987 532.198 155.274"; + rotation = "0 0 1 150.115"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + new Camera() { + position = "-293.826 391.612 75.1421"; + rotation = "0 0 1 96.2569"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + new Camera() { + position = "483.448 364.206 225.265"; + rotation = "0 0 1 178.763"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + new Camera() { + position = "635.748 -42.3523 127.123"; + rotation = "0 0 1 183.346"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + }; + }; + new StaticShape(Team1SensorLargePulse1) { + position = "476.731 363.919 232.695"; + rotation = "0 0 1 94.538"; + scale = "1 1 1"; + dataBlock = "SensorLargePulse"; + lockCount = "0"; + homingCount = "0"; + }; + new InteriorInstance(Tower) { + position = "478.373 363.933 210.21"; + rotation = "0 0 -1 90.137"; + scale = "1 1 1"; + interiorFile = "btowr2.dif"; + showTerrainInside = "0"; + AudioProfile = "Universal_Base_1"; + threshold2 = "60"; + threshold1 = "330"; + AudioEnvironment = SmallRoom; + }; + }; + new SimGroup(team0) { + }; + }; + new SimGroup(RandomRocks) { + + new SimGroup(Addition2brock6) { + + new InteriorInstance() { + position = "-211.225 415.883 78.0187"; + rotation = "0.0859163 -0.728135 0.680028 92.551"; + scale = "0.5 0.5 0.5"; + interiorFile = "brock6.dif"; + showTerrainInside = "0"; + }; + new InteriorInstance() { + position = "-247.225 413.883 69.4588"; + rotation = "0.0903608 -0.723175 0.684728 92.9544"; + scale = "1.5 1.5 1.5"; + interiorFile = "brock6.dif"; + showTerrainInside = "0"; + }; + new InteriorInstance() { + position = "-249.142 384.741 73.6875"; + rotation = "0.999508 0.0207068 0.0235741 82.6183"; + scale = "1.5 1.5 1.5"; + interiorFile = "brock6.dif"; + showTerrainInside = "0"; + }; + }; + new SimGroup(Addition3brock6) { + + new InteriorInstance() { + position = "-361.859 580.372 133.844"; + rotation = "0.0749949 -0.739978 0.668437 91.5936"; + scale = "0.5 0.5 0.5"; + interiorFile = "brock6.dif"; + showTerrainInside = "0"; + }; + new InteriorInstance() { + position = "-327.859 553.372 138.108"; + rotation = "0 0 1 3.17638"; + scale = "0.5 0.5 0.5"; + interiorFile = "brock6.dif"; + showTerrainInside = "0"; + }; + new InteriorInstance() { + position = "-338.859 543.372 141.73"; + rotation = "0 0 1 6.1087"; + scale = "0.5 0.5 0.5"; + interiorFile = "brock6.dif"; + showTerrainInside = "0"; + }; + }; + new SimGroup(Addition4brock6) { + + new InteriorInstance() { + position = "614.302 -90.5742 134.156"; + rotation = "0.999363 0.00750352 -0.0349017 194.321"; + scale = "0.5 0.5 0.5"; + interiorFile = "brock6.dif"; + showTerrainInside = "0"; + }; + new InteriorInstance() { + position = "623.302 -78.5742 127.591"; + rotation = "0.985035 0.145617 0.0922095 182.429"; + scale = "0.5 0.5 0.5"; + interiorFile = "brock6.dif"; + showTerrainInside = "0"; + }; + new InteriorInstance() { + position = "621.302 -52.5742 122.494"; + rotation = "0.496802 0.867682 0.0177913 176.44"; + scale = "0.5 0.5 0.5"; + interiorFile = "brock6.dif"; + showTerrainInside = "0"; + }; + }; + new SimGroup(Addition5brock6) { + + new InteriorInstance() { + position = "854.237 -299.5 51.5671"; + rotation = "0.990727 0.0989551 0.0930998 181.927"; + scale = "1.5 1.5 1.5"; + interiorFile = "brock6.dif"; + showTerrainInside = "0"; + }; + new InteriorInstance() { + position = "844.237 -312.5 50.7056"; + rotation = "0 0 1 5.44537"; + scale = "0.5 0.5 0.5"; + interiorFile = "brock6.dif"; + showTerrainInside = "0"; + }; + new InteriorInstance() { + position = "855.237 -281.5 51.8106"; + rotation = "0 0 1 1.30923"; + scale = "1.5 1.5 1.5"; + interiorFile = "brock6.dif"; + showTerrainInside = "0"; + }; + }; + }; + new SimGroup(Goodies) { + + new Item() { + position = "474.634 364.471 216.897"; + rotation = "0 0 1 94.538"; + scale = "1 1 1"; + dataBlock = "SniperRifle"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + }; + new Item() { + position = "-289.395 388.467 76.2374"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "RepairPatch"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + }; + new Item() { + position = "479.087 360.808 224.938"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "RepairPatch"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + }; + new Item() { + position = "475.639 368.891 224.967"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "RepairPatch"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + }; + new Item() { + position = "475.428 360.075 205.496"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "EnergyPack"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + }; + new Item() { + position = "-284.144 392.475 76.8"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "RepairPatch"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + }; + new Item() { + position = "-289.826 398.197 76.5"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "RepairPatch"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + }; + new Item() { + position = "473.838 358.562 224.84"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "ChaingunAmmo"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + }; + new Item() { + position = "480.085 363.933 224.88"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "ChaingunAmmo"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + }; + new Item() { + position = "474.75 368.018 205.334"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "DiscAmmo"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + }; + new Item() { + position = "478.415 368.123 205.334"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "DiscAmmo"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + }; + new Item() { + position = "-307.816 375.393 71.9373"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "ChaingunAmmo"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + }; + new Item() { + position = "-310.012 376.784 72.4285"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "DiscAmmo"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + }; + new Item() { + position = "-298.878 367.65 72.8"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "ChaingunAmmo"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + }; + }; + new SimGroup(RandomOrganics) { + + new SimGroup(Addition1BEPlant1) { + + new TSStatic() { + position = "12 44 103.084"; + rotation = "0.187078 -0.299834 -0.935469 91.8214"; + scale = "0.9 0.9 0.9"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "12 28 112.272"; + rotation = "0.673747 -0.00405274 0.738951 46.2144"; + scale = "0.7 0.7 0.7"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "-12 -60 115.006"; + rotation = "0.222631 0.00381878 0.974895 201.461"; + scale = "1.4 1.4 1.4"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "-44 -12 158.381"; + rotation = "0.296084 -0.0550443 0.953575 213.468"; + scale = "1 1 1"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "44 20 116.163"; + rotation = "0.0927419 0.0384151 -0.994949 45.2054"; + scale = "2 2 2"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "12 -12 110.944"; + rotation = "-0.125633 -0.322398 0.93823 94.648"; + scale = "0.5 0.5 0.5"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "52 4 115.459"; + rotation = "-0.325118 -0.266284 0.907409 15.4122"; + scale = "0.5 0.5 0.5"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "28 -36 103.991"; + rotation = "-0.104028 -0.1201 0.987296 217.551"; + scale = "0.7 0.7 0.7"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "-60 -12 164.709"; + rotation = "0.0580189 -0.15164 0.986732 104.741"; + scale = "1 1 1"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "-28 -60 120.725"; + rotation = "0.0577292 -0.221813 0.973379 141.962"; + scale = "0.5 0.5 0.5"; + shapeName = "borg1.dts"; + }; + }; + new SimGroup(Addition2BEPlant1) { + + new TSStatic() { + position = "-212 388 75.4125"; + rotation = "-0.206499 0.0467321 0.97733 186.842"; + scale = "0.5 0.5 0.5"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "-212 444 88.4125"; + rotation = "-0.574363 0.322049 0.75259 32.8274"; + scale = "0.7 0.7 0.7"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "-252 388 73.9906"; + rotation = "0.148682 -0.256464 -0.95505 66.3921"; + scale = "0.8 0.8 0.8"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "-276 356 78.7875"; + rotation = "-0.140865 0.079089 0.986865 160.257"; + scale = "0.5 0.5 0.5"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "-252 436 77.725"; + rotation = "0.166724 -0.218018 0.961598 224.408"; + scale = "0.5 0.5 0.5"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "-292 372 74.2094"; + rotation = "-0.207835 0.156096 0.965629 73.9162"; + scale = "1 1 1"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "-228 436 80.4438"; + rotation = "-0.287258 0.463175 -0.838422 54.8233"; + scale = "1.5 1.5 1.5"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "-196 356 91.7093"; + rotation = "0.201291 0.712453 0.67223 42.085"; + scale = "1.8 1.8 1.8"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "-212 420 79.5531"; + rotation = "-0.61971 0.490923 0.612335 36.7589"; + scale = "0.6 0.6 0.6"; + shapeName = "borg1.dts"; + }; + }; + new SimGroup(Addition3BELgTree16) { + + new TSStatic() { + position = "-316 268 55.3594"; + rotation = "0 0 1 97.9998"; + scale = "1.1 1.1 1.1"; + shapeName = "borg16.dts"; + }; + new TSStatic() { + position = "-276 236 66.9844"; + rotation = "0 0 1 183"; + scale = "0.9 0.9 0.9"; + shapeName = "borg16.dts"; + }; + new TSStatic() { + position = "-28 316 81.6407"; + rotation = "0 0 -1 38"; + scale = "1 1 1"; + shapeName = "borg16.dts"; + }; + new TSStatic() { + position = "-412 364 69.0468"; + rotation = "0 0 1 79.9998"; + scale = "1.2 1.2 1.2"; + shapeName = "borg16.dts"; + }; + new TSStatic() { + position = "-148 244 78.6875"; + rotation = "0 0 1 116"; + scale = "1.3 1.3 1.3"; + shapeName = "borg16.dts"; + }; + new TSStatic() { + position = "-68 300 89.1407"; + rotation = "0 0 1 192"; + scale = "1.3 1.3 1.3"; + shapeName = "borg16.dts"; + }; + new TSStatic() { + position = "-236 540 147.953"; + rotation = "0 0 1 37"; + scale = "1.2 1.2 1.2"; + shapeName = "borg16.dts"; + }; + new TSStatic() { + position = "-92 292 91.3282"; + rotation = "0 0 1 67"; + scale = "1.3 1.3 1.3"; + shapeName = "borg16.dts"; + }; + new TSStatic() { + position = "-52 300 86.4375"; + rotation = "0 0 1 12"; + scale = "1.3 1.3 1.3"; + shapeName = "borg16.dts"; + }; + new TSStatic() { + position = "-76 260 95.8438"; + rotation = "0 0 1 9.00004"; + scale = "1.1 1.1 1.1"; + shapeName = "borg16.dts"; + }; + new TSStatic() { + position = "-276 364 74.8594"; + rotation = "0 0 1 231"; + scale = "1.5 1.5 1.5"; + shapeName = "borg16.dts"; + }; + new TSStatic() { + position = "-420 236 87.4531"; + rotation = "0 0 1 81.0002"; + scale = "1.2 1.2 1.2"; + shapeName = "borg16.dts"; + }; + new TSStatic() { + position = "-140 580 123.656"; + rotation = "0 0 -1 88"; + scale = "1 1 1"; + shapeName = "borg16.dts"; + }; + new TSStatic() { + position = "-292 572 141.844"; + rotation = "0 0 1 46"; + scale = "0.8 0.8 0.8"; + shapeName = "borg16.dts"; + }; + new TSStatic() { + position = "-140 540 112.297"; + rotation = "0 0 1 123"; + scale = "1.5 1.5 1.5"; + shapeName = "borg16.dts"; + }; + }; + new SimGroup(Addition1BESmTree17) { + + new TSStatic() { + position = "140 -228 165.828"; + rotation = "0.285418 0.403782 0.869193 24.074"; + scale = "1.2 1.2 1.2"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "-268 -100 140.031"; + rotation = "-0.0727138 0.0455015 0.996314 146.118"; + scale = "1.5 1.5 1.5"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "292 -172 96.375"; + rotation = "-0.437468 0.474769 -0.763686 29.8352"; + scale = "1.4 1.4 1.4"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "84 84 105.656"; + rotation = "-0.154012 -0.0638678 0.986003 239.303"; + scale = "1 1 1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "-172 28 185.844"; + rotation = "0.13083 -0.102316 -0.986111 65.7286"; + scale = "0.9 0.9 0.9"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "-308 60 92.1562"; + rotation = "-0.6199 0.346496 0.704035 21.1836"; + scale = "1.5 1.5 1.5"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "-76 -4 162.375"; + rotation = "0.0636308 -0.172424 -0.982965 109.928"; + scale = "0.9 0.9 0.9"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "-356 12 77.4531"; + rotation = "-0.160854 0.0557614 0.985402 186.898"; + scale = "1.4 1.4 1.4"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "-124 228 82.5781"; + rotation = "0.00475492 0.193705 -0.981048 83.0869"; + scale = "1.3 1.3 1.3"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "364 -284 77.0157"; + rotation = "0.0643768 0.238911 -0.968905 59.5481"; + scale = "1 1 1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "-340 20 82.375"; + rotation = "-0.0214268 0.428443 0.903315 30.8605"; + scale = "1.1 1.1 1.1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "300 -116 111.453"; + rotation = "0.265667 0.740693 -0.617086 19.3317"; + scale = "1.1 1.1 1.1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "324 -108 114.109"; + rotation = "0.0390719 0.0270788 0.998869 134.046"; + scale = "1.4 1.4 1.4"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "-388 -388 100.922"; + rotation = "0.278494 0.331909 0.901264 24.3416"; + scale = "1.1 1.1 1.1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "348 -412 76.1093"; + rotation = "-0.0417168 0.0484254 0.997955 222.92"; + scale = "0.8 0.8 0.8"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "300 84 104.672"; + rotation = "-0.184826 -0.0124876 -0.982692 74.9641"; + scale = "1.5 1.5 1.5"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "-372 -548 99.172"; + rotation = "0.0555475 0.0330002 0.997911 229.908"; + scale = "1.1 1.1 1.1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "-196 -508 110.563"; + rotation = "-0.142972 0.0412338 0.988867 214.634"; + scale = "1.5 1.5 1.5"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "340 236 165.906"; + rotation = "-0.0987353 0.15622 0.982775 86.9933"; + scale = "1.3 1.3 1.3"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "380 -308 77.75"; + rotation = "0.157783 -0.115876 0.980651 69.0414"; + scale = "1 1 1"; + shapeName = "borg17.dts"; + }; + }; + new SimGroup(Addition2BELgTree18) { + + new TSStatic() { + position = "-308 364 65.6094"; + rotation = "0 0 -1 69.0002"; + scale = "1.3 1.3 1.3"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "-260 340 82.5312"; + rotation = "0 0 1 195"; + scale = "1.3 1.3 1.3"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "236 -60 105.828"; + rotation = "0 0 1 176"; + scale = "0.9 0.9 0.9"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "76 100 104.641"; + rotation = "0 0 -1 92.0004"; + scale = "1.5 1.5 1.5"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "260 -60 103.438"; + rotation = "0 0 -1 94"; + scale = "0.9 0.9 0.9"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "-244 276 65.7344"; + rotation = "0 0 1 6.00005"; + scale = "1.4 1.4 1.4"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "-36 -188 64.8282"; + rotation = "0 0 -1 120"; + scale = "1 1 1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "188 380 84"; + rotation = "0 0 1 35"; + scale = "1 1 1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "-364 300 58.6406"; + rotation = "0 0 1 215"; + scale = "1.3 1.3 1.3"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "-76 -300 120.156"; + rotation = "0 0 1 75.0002"; + scale = "1 1 1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "84 28 111.031"; + rotation = "0 0 1 47"; + scale = "1.4 1.4 1.4"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "-276 244 65"; + rotation = "0 0 1 130"; + scale = "1.5 1.5 1.5"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "300 -244 97.797"; + rotation = "0 0 1 152"; + scale = "1.2 1.2 1.2"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "364 36 124.031"; + rotation = "0 0 1 218"; + scale = "1 1 1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "-340 156 87.4531"; + rotation = "0 0 1 104"; + scale = "1.3 1.3 1.3"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "92 276 67.375"; + rotation = "0 0 1 39"; + scale = "0.8 0.8 0.8"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "-4 228 101.828"; + rotation = "0 0 -1 87.0002"; + scale = "0.8 0.8 0.8"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "92 340 71.3125"; + rotation = "0 0 1 76.9998"; + scale = "1.2 1.2 1.2"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "-300 276 58.1875"; + rotation = "0 0 1 57.9999"; + scale = "1 1 1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "-188 452 92.2656"; + rotation = "0 0 -1 81.0002"; + scale = "1.4 1.4 1.4"; + shapeName = "borg18.dts"; + }; + }; + new SimGroup(Addition1BESmTree17) { + + new TSStatic() { + position = "500 -316 96.6875"; + rotation = "0.0189433 -0.0920088 0.995578 210.869"; + scale = "1.4 1.4 1.4"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "820 -412 60.8594"; + rotation = "0.151268 0.0290211 0.988067 97.6825"; + scale = "1.2 1.2 1.2"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "876 -276 51.7187"; + rotation = "-0.0767067 0.461516 -0.883809 20.3196"; + scale = "0.9 0.9 0.9"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "652 244 85.625"; + rotation = "0.307312 -0.398951 0.863943 32.1955"; + scale = "1.3 1.3 1.3"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "708 -276 72.7656"; + rotation = "0.265436 -0.176198 0.947891 59.6082"; + scale = "1.5 1.5 1.5"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "836 -308 47.8438"; + rotation = "0.0204826 -0.0196076 0.999598 140.015"; + scale = "1.4 1.4 1.4"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "604 4 141.703"; + rotation = "-0.107106 -0.00849662 0.994211 233.731"; + scale = "1.2 1.2 1.2"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "1172 -12 145.812"; + rotation = "-0.169217 0.00416148 0.98557 91.8325"; + scale = "0.8 0.8 0.8"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "1020 -204 127.797"; + rotation = "-0.0211118 0.743291 0.668635 20.8112"; + scale = "0.8 0.8 0.8"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "1108 44 107.75"; + rotation = "-0.0451934 0.160773 0.985956 44.5658"; + scale = "1 1 1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "644 -348 115.234"; + rotation = "0.737692 0.0137925 -0.674997 20.6192"; + scale = "1.2 1.2 1.2"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "844 140 163.828"; + rotation = "-0.155668 -0.0493325 0.986577 83.7687"; + scale = "1.1 1.1 1.1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "1092 76 116.188"; + rotation = "-0.140404 -0.0943009 -0.985593 74.8008"; + scale = "1.2 1.2 1.2"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "940 -180 84.4688"; + rotation = "-0.0699772 0.0254908 0.997223 103.155"; + scale = "1 1 1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "596 76 133.891"; + rotation = "-0.145307 -0.0467364 0.988282 129.523"; + scale = "0.8 0.8 0.8"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "1036 188 136.187"; + rotation = "0.0143986 -0.126977 0.991801 89.4714"; + scale = "1.3 1.3 1.3"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "708 -60 140.547"; + rotation = "-0.214297 -0.107879 0.970793 63.5095"; + scale = "0.9 0.9 0.9"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "980 -316 79.7969"; + rotation = "-0.524424 0.50887 -0.682665 23.2662"; + scale = "1.2 1.2 1.2"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "532 52 118.094"; + rotation = "0.236918 0.0674468 -0.969186 70.6835"; + scale = "1.1 1.1 1.1"; + shapeName = "borg17.dts"; + }; + }; + new SimGroup(Addition2BELgTree18) { + + new TSStatic() { + position = "428 188 135.5"; + rotation = "0 0 1 49"; + scale = "1.5 1.5 1.5"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "844 -212 55.6563"; + rotation = "0 0 -1 82"; + scale = "0.9 0.9 0.9"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "588 292 116.109"; + rotation = "0 0 1 144"; + scale = "1.2 1.2 1.2"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "964 12 184.766"; + rotation = "0 0 1 134"; + scale = "1.5 1.5 1.5"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "844 -244 54.0469"; + rotation = "0 0 -1 16.9999"; + scale = "1.4 1.4 1.4"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "700 244 81.3907"; + rotation = "0 0 1 9.99989"; + scale = "0.9 0.9 0.9"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1060 -220 118.953"; + rotation = "0 0 1 228"; + scale = "1 1 1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1204 316 61.4843"; + rotation = "0 0 1 177"; + scale = "0.9 0.9 0.9"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1132 284 74.4219"; + rotation = "0 0 -1 23.9998"; + scale = "1.1 1.1 1.1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "556 -12 129.312"; + rotation = "0 0 -1 111"; + scale = "1.3 1.3 1.3"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "412 -44 68.4531"; + rotation = "0 0 1 7.00001"; + scale = "0.9 0.9 0.9"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "860 292 155.844"; + rotation = "0 0 -1 10.9999"; + scale = "1.3 1.3 1.3"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1036 -180 124.484"; + rotation = "0 0 1 88.9998"; + scale = "0.9 0.9 0.9"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "588 -52 129.75"; + rotation = "0 0 -1 67.0005"; + scale = "1.1 1.1 1.1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "468 -372 66.0937"; + rotation = "0 0 1 128"; + scale = "1.1 1.1 1.1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "860 116 166.922"; + rotation = "0 0 1 11"; + scale = "1.5 1.5 1.5"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "716 252 82.9531"; + rotation = "0 0 1 11"; + scale = "1.4 1.4 1.4"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1180 -444 145.719"; + rotation = "0 0 1 4.99997"; + scale = "1.5 1.5 1.5"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "876 -380 52.9063"; + rotation = "0 0 1 46"; + scale = "0.9 0.9 0.9"; + shapeName = "borg18.dts"; + }; + }; + new SimGroup(Addition3BEPlant5) { + + new TSStatic() { + position = "588 156 102.809"; + rotation = "-0.193563 0.0259592 0.980744 181.962"; + scale = "1 1 1"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "492 140 100.575"; + rotation = "0.146029 0.137793 0.979637 117.055"; + scale = "1.5 1.5 1.5"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "588 140 108.325"; + rotation = "-0.318993 0.168786 0.932606 227.962"; + scale = "1 1 1"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "548 220 119.778"; + rotation = "-0.542672 -0.517663 -0.661462 28.3949"; + scale = "1 1 1"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "548 196 107.903"; + rotation = "-0.575099 -0.240159 0.782039 51.104"; + scale = "1.3 1.3 1.3"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "492 196 112.762"; + rotation = "0.253778 -0.1873 0.948955 203.761"; + scale = "1 1 1"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "604 156 105.887"; + rotation = "-0.0326261 0.0389834 0.998707 225.946"; + scale = "1.5 1.5 1.5"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "564 236 114.544"; + rotation = "0.208184 -0.0821455 0.974634 115.338"; + scale = "1.4 1.4 1.4"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "492 148 99.2617"; + rotation = "-0.0149542 -0.224199 -0.974429 58.2532"; + scale = "1.1 1.1 1.1"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "572 44 129.95"; + rotation = "-0.0753689 0.145225 0.986524 67.7173"; + scale = "1.3 1.3 1.3"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "628 188 107.028"; + rotation = "-0.124681 -0.107766 -0.986327 72.7519"; + scale = "1.3 1.3 1.3"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "580 108 129.606"; + rotation = "-0.160092 0.296592 0.94149 163.037"; + scale = "1.2 1.2 1.2"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "572 188 105.919"; + rotation = "-0.0916734 -0.212707 0.972806 188.756"; + scale = "1 1 1"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "636 236 95.4966"; + rotation = "0.296211 -0.0940407 0.950482 86.9005"; + scale = "1.1 1.1 1.1"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "652 132 111.966"; + rotation = "0.114039 0.329162 0.937362 63.2603"; + scale = "1.2 1.2 1.2"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "596 108 134.653"; + rotation = "-0.131211 0.224869 0.965514 229.455"; + scale = "1.5 1.5 1.5"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "660 60 143.575"; + rotation = "-0.0366527 -0.205783 0.977911 82.2664"; + scale = "1.2 1.2 1.2"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "676 92 133.559"; + rotation = "-0.143912 0.101845 0.984336 208.565"; + scale = "1.2 1.2 1.2"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "484 124 107.887"; + rotation = "0.0688712 0.267605 0.961064 116.062"; + scale = "1.4 1.4 1.4"; + shapeName = "borg5.dts"; + }; + new TSStatic() { + position = "548 188 102.95"; + rotation = "-0.141141 -0.288261 0.947093 135.236"; + scale = "1.2 1.2 1.2"; + shapeName = "borg5.dts"; + }; + }; + new SimGroup(Addition4BEPlant1) { + + new TSStatic() { + position = "196 124 106.788"; + rotation = "-0.0194762 0.0360942 0.999159 185.995"; + scale = "0.8 0.8 0.8"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "324 132 137.709"; + rotation = "-0.824061 0.269725 0.498169 40.8144"; + scale = "1.5 1.5 1.5"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "404 148 129.272"; + rotation = "-0.453514 0.0103151 -0.89119 57.3823"; + scale = "1.3 1.3 1.3"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "148 164 106.272"; + rotation = "0.346131 0.139353 0.927779 82.2303"; + scale = "1.3 1.3 1.3"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "388 52 119.178"; + rotation = "0.299604 0.0496035 0.952773 96.7594"; + scale = "0.8 0.8 0.8"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "452 220 146.162"; + rotation = "-0.155184 -0.275246 0.948766 94.0103"; + scale = "1.5 1.5 1.5"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "164 324 104.084"; + rotation = "-0.256999 0.966412 0 31.3768"; + scale = "1.4 1.4 1.4"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "380 100 118.959"; + rotation = "0.252843 -0.0682316 0.965098 206.091"; + scale = "0.7 0.7 0.7"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "252 140 124.506"; + rotation = "-0.290357 -0.0857175 0.953072 149.43"; + scale = "0.7 0.7 0.7"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "172 364 93.2094"; + rotation = "0.0544781 0.166186 0.984588 180.985"; + scale = "1 1 1"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "156 180 97.1313"; + rotation = "0.735189 0.316481 0.599448 35.9322"; + scale = "1.5 1.5 1.5"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "452 212 143.413"; + rotation = "-0.292077 -0.0147327 -0.956281 70.3941"; + scale = "2 2 2"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "476 324 193.725"; + rotation = "-0.46624 -0.0634 0.882384 21.4771"; + scale = "1.5 1.5 1.5"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "428 164 133.319"; + rotation = "-0.0128469 -0.219879 0.975443 155.595"; + scale = "0.6 0.6 0.6"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "388 252 165.584"; + rotation = "0.0979139 -0.392969 0.914324 89.1213"; + scale = "0.7 0.7 0.7"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "388 164 134.662"; + rotation = "0.136418 -0.0673901 0.988357 100.66"; + scale = "0.6 0.6 0.6"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "436 148 121.663"; + rotation = "-0.487287 0.0647607 -0.870837 83.7945"; + scale = "1.7 1.7 1.7"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "236 340 114.647"; + rotation = "-0.0104936 0.224169 0.974494 182.924"; + scale = "1.1 1.1 1.1"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "324 164 150.147"; + rotation = "-0.547013 0.782764 -0.296745 23.293"; + scale = "1 1 1"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "268 116 123.741"; + rotation = "-0.479476 0.578886 -0.65954 35.7259"; + scale = "1.2 1.2 1.2"; + shapeName = "borg1.dts"; + }; + }; + new SimGroup(Addition5BEPlant1) { + + new TSStatic() { + position = "1364 -852 77.2562"; + rotation = "-0.768939 0.365446 -0.524579 33.6006"; + scale = "0.9 0.9 0.9"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1196 -836 64.3031"; + rotation = "0.210641 0.146051 -0.966592 61.7001"; + scale = "0.9 0.9 0.9"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1244 -780 86.6625"; + rotation = "-0.115374 -0.141325 0.983217 175.084"; + scale = "1.3 1.3 1.3"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1308 -876 75.1782"; + rotation = "0.228708 -0.120099 0.966058 183.864"; + scale = "0.9 0.9 0.9"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1132 -892 65.725"; + rotation = "-0.12685 0.170462 0.977165 141.825"; + scale = "0.9 0.9 0.9"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1244 -924 102.069"; + rotation = "-0.110985 0.0519229 0.992465 144.254"; + scale = "2 2 2"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1180 -868 69.0688"; + rotation = "0.0109543 0.159993 0.987057 149.382"; + scale = "1.8 1.8 1.8"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1204 -644 98.9593"; + rotation = "0.110772 -0.25673 0.960114 237.022"; + scale = "1.3 1.3 1.3"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1396 -940 87.4594"; + rotation = "-0.266377 0.35014 0.898023 69.6625"; + scale = "0.5 0.5 0.5"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1292 -620 110.038"; + rotation = "-0.054907 0.139267 0.988732 202.747"; + scale = "1.7 1.7 1.7"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1060 -644 119.631"; + rotation = "-0.492076 0.214682 -0.843666 61.1638"; + scale = "0.6 0.6 0.6"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1316 -708 100.069"; + rotation = "-0.195611 0.0941593 0.976151 203.444"; + scale = "2 2 2"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1172 -788 55.9126"; + rotation = "0.0333406 0.00956025 0.999398 122.029"; + scale = "1.6 1.6 1.6"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1076 -700 95.6469"; + rotation = "-0.0505172 -0.443439 -0.89488 14.5118"; + scale = "0.9 0.9 0.9"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1260 -828 77.9125"; + rotation = "0.0225397 0.0724205 0.997119 129.128"; + scale = "1.2 1.2 1.2"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1076 -860 65.7719"; + rotation = "0.133628 -0.137519 0.981444 105.039"; + scale = "1.7 1.7 1.7"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1316 -836 87.85"; + rotation = "-0.09518 -0.0525785 0.994071 108.324"; + scale = "0.6 0.6 0.6"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1132 -908 71.2563"; + rotation = "0.00708622 0.347095 0.937803 103.601"; + scale = "0.8 0.8 0.8"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1156 -916 80.3344"; + rotation = "-0.0730995 0.138384 0.987677 220.536"; + scale = "1.2 1.2 1.2"; + shapeName = "borg1.dts"; + }; + new TSStatic() { + position = "1060 -564 127.616"; + rotation = "0.0985932 0.092788 0.990793 200.811"; + scale = "1.1 1.1 1.1"; + shapeName = "borg1.dts"; + }; + }; + new SimGroup(Addition6BELgTree18) { + + new TSStatic() { + position = "1340 -876 63.3125"; + rotation = "0 0 1 232"; + scale = "1.1 1.1 1.1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1348 -524 77.4063"; + rotation = "0 0 1 201"; + scale = "1.5 1.5 1.5"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1244 -972 92.5"; + rotation = "0 0 1 195"; + scale = "1.5 1.5 1.5"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1004 -932 71.3281"; + rotation = "0 0 1 121"; + scale = "0.8 0.8 0.8"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1044 -852 70.5938"; + rotation = "0 0 -1 96.0002"; + scale = "1 1 1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1172 -804 54.0625"; + rotation = "0 0 1 138"; + scale = "1.2 1.2 1.2"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1164 -852 60.6406"; + rotation = "0 0 1 153"; + scale = "1.1 1.1 1.1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1060 -716 94.75"; + rotation = "0 0 -1 73.0006"; + scale = "0.9 0.9 0.9"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1260 -612 106.578"; + rotation = "0 0 -1 82"; + scale = "1.1 1.1 1.1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1036 -836 72.0157"; + rotation = "0 0 -1 113"; + scale = "1.2 1.2 1.2"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1268 -948 95.7499"; + rotation = "0 0 1 113"; + scale = "1.5 1.5 1.5"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1244 -932 98.625"; + rotation = "0 0 1 9.99989"; + scale = "1.1 1.1 1.1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1252 -716 85.6875"; + rotation = "0 0 1 33"; + scale = "1.1 1.1 1.1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1316 -524 79.6719"; + rotation = "0 0 1 207"; + scale = "0.9 0.9 0.9"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1324 -644 109.062"; + rotation = "0 0 1 113"; + scale = "0.8 0.8 0.8"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1132 -452 157.297"; + rotation = "0 0 1 180"; + scale = "1.1 1.1 1.1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "980 -924 78.2031"; + rotation = "1 0 0 0"; + scale = "1.3 1.3 1.3"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1004 -716 103.766"; + rotation = "0 0 1 72.0002"; + scale = "0.8 0.8 0.8"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1020 -740 98.406"; + rotation = "0 0 1 127"; + scale = "1.4 1.4 1.4"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "1204 -724 66.0312"; + rotation = "0 0 1 149"; + scale = "1.2 1.2 1.2"; + shapeName = "borg18.dts"; + }; + }; + new SimGroup(Addition1BESmTree17) { + + new TSStatic() { + position = "516 -852 114.203"; + rotation = "0.0226453 0.0115586 0.999677 203.992"; + scale = "1.4 1.4 1.4"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "412 -636 137.328"; + rotation = "-0.054195 -0.05415 0.997061 181.994"; + scale = "1.1 1.1 1.1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "516 -852 114.203"; + rotation = "-0.0128273 -0.0480088 -0.998765 60.0615"; + scale = "1.1 1.1 1.1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "444 -756 96.0001"; + rotation = "-0.0616775 -0.117932 0.991104 215.7"; + scale = "1.1 1.1 1.1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "340 -772 79.5938"; + rotation = "-0.214777 0.964319 0.154792 6.45366"; + scale = "1.5 1.5 1.5"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "604 -844 157.766"; + rotation = "-0.0445501 -0.0465846 0.99792 184.99"; + scale = "1.4 1.4 1.4"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "628 -644 187.891"; + rotation = "0.19108 -0.0345838 -0.980965 98.0915"; + scale = "0.8 0.8 0.8"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "372 -764 83.5781"; + rotation = "0.126305 0.0603915 -0.990151 87.5658"; + scale = "1.5 1.5 1.5"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "588 -844 156.516"; + rotation = "-0.124319 -0.119349 0.985038 104.836"; + scale = "1.3 1.3 1.3"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "412 -900 119.953"; + rotation = "-0.0628523 -0.0476702 0.996884 210.907"; + scale = "1.1 1.1 1.1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "428 -540 160.078"; + rotation = "-0.106477 0.0229367 0.994051 223.763"; + scale = "1.5 1.5 1.5"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "468 -652 141.938"; + rotation = "0.209904 -0.0580286 -0.975998 73.3289"; + scale = "1.5 1.5 1.5"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "404 -892 119.344"; + rotation = "0.0258563 0.208098 -0.977766 83.2771"; + scale = "1.3 1.3 1.3"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "476 -500 153.453"; + rotation = "0.770847 -0.137338 -0.62204 20.7593"; + scale = "1.1 1.1 1.1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "284 -532 90.2187"; + rotation = "-0.835172 0.10902 0.539075 20.2546"; + scale = "1.3 1.3 1.3"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "300 -860 106.953"; + rotation = "0.0300008 0.141884 0.989429 78.5967"; + scale = "1.5 1.5 1.5"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "468 -724 105.984"; + rotation = "-0.231502 0.313655 -0.920884 48.4362"; + scale = "1.1 1.1 1.1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "436 -780 93.1406"; + rotation = "-0.0166021 0.0320587 0.999348 205.983"; + scale = "0.9 0.9 0.9"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "276 -876 111.875"; + rotation = "0.10672 0.12651 0.986208 236.335"; + scale = "1.5 1.5 1.5"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "380 -740 84.4219"; + rotation = "-0.126943 0.171214 0.977022 55.0849"; + scale = "0.8 0.8 0.8"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "460 -564 163.094"; + rotation = "-0.00537145 0.279877 -0.960021 67.1369"; + scale = "1.2 1.2 1.2"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "468 -868 119.641"; + rotation = "-0.275798 -0.0223686 -0.960955 45.6079"; + scale = "1.2 1.2 1.2"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "580 -812 159.172"; + rotation = "0.11136 -0.181869 0.976997 71.2576"; + scale = "0.9 0.9 0.9"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "292 -644 101.859"; + rotation = "-0.154484 -0.000180158 0.987995 176.048"; + scale = "0.9 0.9 0.9"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "340 -876 123.937"; + rotation = "0.00543177 0.0324584 0.999458 184.997"; + scale = "1.3 1.3 1.3"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "356 -644 117.328"; + rotation = "-0.0709721 -0.0117515 0.997409 157.058"; + scale = "0.9 0.9 0.9"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "444 -540 160.797"; + rotation = "0.0687445 0.0224915 0.997381 82.149"; + scale = "1.2 1.2 1.2"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "516 -852 114.203"; + rotation = "0.0261136 -0.00134998 0.999658 144.011"; + scale = "1.3 1.3 1.3"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "580 -796 159.547"; + rotation = "0.0555007 0.0996695 0.993472 234.693"; + scale = "1.2 1.2 1.2"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "452 -532 160.047"; + rotation = "0.0187232 0.0595054 0.998052 143.067"; + scale = "1.4 1.4 1.4"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "452 -572 159.516"; + rotation = "-0.107753 -0.142268 0.983946 143.555"; + scale = "1 1 1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "572 -772 157.203"; + rotation = "0.085667 0.0576616 0.994654 176.021"; + scale = "0.8 0.8 0.8"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "348 -788 81.5782"; + rotation = "-0.119645 0.050421 0.991536 217.701"; + scale = "0.8 0.8 0.8"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "380 -740 84.4219"; + rotation = "-0.152944 0.359364 0.920579 29.2333"; + scale = "1 1 1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "268 -564 82.4531"; + rotation = "-0.0958363 0.325672 -0.940613 33.9076"; + scale = "0.9 0.9 0.9"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "460 -540 162.266"; + rotation = "-0.131657 0.0740015 0.988529 198.786"; + scale = "0.8 0.8 0.8"; + shapeName = "borg17.dts"; + }; + }; + new SimGroup(Addition2BELgTree18) { + + new TSStatic() { + position = "332 -932 118.766"; + rotation = "0 0 -1 53.9998"; + scale = "1.5 1.5 1.5"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "188 -604 87.5781"; + rotation = "0 0 1 159"; + scale = "1.1 1.1 1.1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "12 -844 121.125"; + rotation = "0 0 1 233"; + scale = "1.2 1.2 1.2"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "-36 -468 135.203"; + rotation = "0 0 1 76"; + scale = "0.8 0.8 0.8"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "108 -892 102.594"; + rotation = "0 0 1 53"; + scale = "0.8 0.8 0.8"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "476 -652 142.578"; + rotation = "0 0 1 208"; + scale = "1.5 1.5 1.5"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "444 -524 160.156"; + rotation = "0 0 1 17"; + scale = "1.1 1.1 1.1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "-28 -468 136"; + rotation = "0 0 1 121"; + scale = "0.9 0.9 0.9"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "228 -452 115.188"; + rotation = "0 0 1 36"; + scale = "1 1 1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "164 -564 91.9688"; + rotation = "0 0 -1 44.9999"; + scale = "1.3 1.3 1.3"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "76 -412 131.828"; + rotation = "0 0 -1 1.00014"; + scale = "0.8 0.8 0.8"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "260 -892 118.438"; + rotation = "0 0 1 150"; + scale = "1.1 1.1 1.1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "452 -556 162.062"; + rotation = "0 0 1 20"; + scale = "0.9 0.9 0.9"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "156 -604 84.5781"; + rotation = "0 0 1 93.0002"; + scale = "1.5 1.5 1.5"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "340 -780 79.5"; + rotation = "0 0 -1 10.9999"; + scale = "1.5 1.5 1.5"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "284 -676 104.078"; + rotation = "0 0 1 109"; + scale = "1.5 1.5 1.5"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "212 -748 102.672"; + rotation = "0 0 1 180"; + scale = "1.2 1.2 1.2"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "44 -708 86.1249"; + rotation = "0 0 1 177"; + scale = "0.8 0.8 0.8"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "324 -436 77.3281"; + rotation = "0 0 -1 35"; + scale = "1.1 1.1 1.1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "228 -532 103.313"; + rotation = "0 0 1 174"; + scale = "1 1 1"; + shapeName = "borg18.dts"; + }; + }; + new TSStatic() { + position = "590.041 -542.501 248.284"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + shapeName = "borg18.dts"; + }; + new SimGroup(Addition3BELgTree18) { + + new TSStatic() { + position = "612 676 187.797"; + rotation = "0 0 1 236"; + scale = "1 1 1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "596 684 188.609"; + rotation = "0 0 1 222"; + scale = "1.4 1.4 1.4"; + shapeName = "borg18.dts"; + }; + }; + new SimGroup(Addition4BELgTree18) { + + new TSStatic() { + position = "484 548 68.625"; + rotation = "0 0 1 75.0002"; + scale = "1.3 1.3 1.3"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "532 524 84.0782"; + rotation = "0 0 1 161"; + scale = "0.8 0.8 0.8"; + shapeName = "borg18.dts"; + }; + }; + new SimGroup(Addition5BELgTree18) { + + new TSStatic() { + position = "268 668 97.359"; + rotation = "0 0 1 60.0001"; + scale = "0.8 0.8 0.8"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "60 588 135.438"; + rotation = "0 0 1 218"; + scale = "1.2 1.2 1.2"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "44 780 52.0312"; + rotation = "0 0 1 168"; + scale = "1.3 1.3 1.3"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "316 604 115.359"; + rotation = "0 0 1 1.9999"; + scale = "1.1 1.1 1.1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "124 820 54.7031"; + rotation = "0 0 1 21"; + scale = "1.1 1.1 1.1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "84 556 133.891"; + rotation = "0 0 -1 38"; + scale = "0.9 0.9 0.9"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "76 572 133.078"; + rotation = "0 0 -1 34.0002"; + scale = "0.8 0.8 0.8"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "236 588 125.078"; + rotation = "0 0 1 57"; + scale = "0.8 0.8 0.8"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "332 668 98.781"; + rotation = "0 0 1 130"; + scale = "0.9 0.9 0.9"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "332 740 90.7656"; + rotation = "0 0 1 85.9998"; + scale = "1.5 1.5 1.5"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "276 812 99.359"; + rotation = "0 0 1 42"; + scale = "1 1 1"; + shapeName = "borg18.dts"; + }; + new TSStatic() { + position = "300 692 100.281"; + rotation = "0 0 1 32"; + scale = "1.2 1.2 1.2"; + shapeName = "borg18.dts"; + }; + }; + new SimGroup(Addition6BESmTree17) { + + new TSStatic() { + position = "316 764 90.3593"; + rotation = "-0.269346 0.0747762 0.960136 9.37201"; + scale = "1.4 1.4 1.4"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "284 796 100.625"; + rotation = "-0.109174 -0.268087 0.957189 30.2388"; + scale = "1 1 1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "92 788 52.4374"; + rotation = "-0.00226441 0.0373222 0.999301 211.979"; + scale = "0.8 0.8 0.8"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "236 596 124.828"; + rotation = "0.0374212 -0.125582 -0.991377 48.3697"; + scale = "0.9 0.9 0.9"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "92 604 130.219"; + rotation = "0.130424 -0.533966 0.835386 29.7251"; + scale = "1.2 1.2 1.2"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "236 580 125.891"; + rotation = "0.988853 -0.0859407 0.121593 8.21026"; + scale = "1.1 1.1 1.1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "204 844 64"; + rotation = "0.075034 -0.0658218 0.995006 117.256"; + scale = "1.4 1.4 1.4"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "324 724 93.625"; + rotation = "0.177271 -0.147427 0.973057 84.5554"; + scale = "0.9 0.9 0.9"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "68 692 85.2812"; + rotation = "0.197225 0.181032 0.963499 72.0145"; + scale = "0.8 0.8 0.8"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "324 588 114.719"; + rotation = "-0.0913719 -0.0166197 0.995678 143.149"; + scale = "1.5 1.5 1.5"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "124 812 54.3437"; + rotation = "-0.139173 -0.0205308 0.990055 195.843"; + scale = "1 1 1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "332 772 93.0156"; + rotation = "-0.630648 0.457846 -0.626626 22.1727"; + scale = "0.8 0.8 0.8"; + shapeName = "borg17.dts"; + }; + }; + new SimGroup(Addition7BESmTree17) { + + new TSStatic() { + position = "724 500 100.312"; + rotation = "-0.474947 0.55988 -0.67894 10.2955"; + scale = "0.8 0.8 0.8"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "692 644 172.547"; + rotation = "-0.120142 -0.104658 0.987225 130.562"; + scale = "0.8 0.8 0.8"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "788 604 183.453"; + rotation = "-0.381454 0.132918 0.914782 46.594"; + scale = "0.8 0.8 0.8"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "748 620 177.734"; + rotation = "-0.133731 0.0451644 0.989988 126.465"; + scale = "1 1 1"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "700 636 170.906"; + rotation = "-0.28187 -0.0991843 0.954312 63.3697"; + scale = "1.4 1.4 1.4"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "796 676 167.984"; + rotation = "-0.114769 0.0364394 0.992724 166.101"; + scale = "1.5 1.5 1.5"; + shapeName = "borg17.dts"; + }; + }; + new SimGroup(Addition8BESmTree17) { + + new TSStatic() { + position = "612 492 82.4219"; + rotation = "0.15131 -0.0330094 0.987935 175.06"; + scale = "1.4 1.4 1.4"; + shapeName = "borg17.dts"; + }; + new TSStatic() { + position = "652 428 79.7656"; + rotation = "0.122244 -0.16474 -0.978732 87.229"; + scale = "0.8 0.8 0.8"; + shapeName = "borg17.dts"; + }; + }; + }; + new SimGroup(NotSoRandomOrganics) { + + new InteriorInstance() { + position = "-234.377 399.56 72.0484"; + rotation = "1 0 0 139.229"; + scale = "1.18518 1.63312 1"; + interiorFile = "brock7.dif"; + showTerrainInside = "0"; + }; + new InteriorInstance() { + position = "-359.655 570.11 126.837"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "brock8.dif"; + showTerrainInside = "0"; + }; + new InteriorInstance() { + position = "-361.343 564.269 130.504"; + rotation = "1 0 0 50.4203"; + scale = "1 1 1"; + interiorFile = "brock8.dif"; + showTerrainInside = "0"; + }; + new InteriorInstance() { + position = "-351.76 562.309 125.975"; + rotation = "0.769297 0.578037 -0.272129 62.9301"; + scale = "1 1 1"; + interiorFile = "brock8.dif"; + showTerrainInside = "0"; + }; + new StaticShape(SWDeadMed) { + position = "-332.993 471.436 122.37"; + rotation = "-0.294439 -0.309888 0.904033 47.0646"; + scale = "1 1 0.99"; + dataBlock = "MediumMaleHuman_Dead"; + lockCount = "0"; + homingCount = "0"; + trainingSkin = 1; + }; + new StaticShape(MedDeadBody) { + position = "477.477 360.201 204.267"; + rotation = "0 0 1 82.5059"; + scale = "1 1 1"; + dataBlock = "MediumMaleHuman_Dead"; + lockCount = "0"; + homingCount = "0"; + }; + new StaticShape(SWDeadLt) { + position = "-205.392 473.86 97.7869"; + rotation = "-0.94867 0.262068 0.177046 24.3075"; + scale = "1 1 1"; + dataBlock = "LightMaleHuman_Dead"; + lockCount = "0"; + homingCount = "0"; + trainingSkin = 1; + }; + new StaticShape(LightDeadBody) { + position = "474.167 360.154 215.68"; + rotation = "0 0 1 94.538"; + scale = "1 1 1"; + dataBlock = "LightMaleHuman_Dead"; + lockCount = "0"; + homingCount = "0"; + }; + new InteriorInstance() { + position = "-32.6219 242.339 102.947"; + rotation = "0 0 -1 115.92"; + scale = "1 1 1"; + interiorFile = "bspir1.dif"; + showTerrainInside = "0"; + }; + new InteriorInstance() { + position = "93.7696 300.472 66.6777"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "bspir5.dif"; + showTerrainInside = "0"; + }; + new InteriorInstance() { + position = "363.768 249.524 170.509"; + rotation = "0 0 1 218.479"; + scale = "1 1 1"; + interiorFile = "bspir4.dif"; + showTerrainInside = "0"; + }; + new InteriorInstance() { + position = "976.562 -614.672 90.2773"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "bspir3.dif"; + showTerrainInside = "0"; + }; + new StaticShape(HeavyDeadBody) { + position = "476.153 360.368 232.658"; + rotation = "0 0 1 94.538"; + scale = "1 1 1"; + dataBlock = "HeavyMaleHuman_Dead"; + lockCount = "0"; + homingCount = "0"; + }; + new WheeledVehicle(MPB) { + position = "1273.71 -818.372 79.5295"; + rotation = "0.12202 0.0215281 -0.992294 60.694"; + scale = "1 1 1"; + dataBlock = "mobileBaseVehicle"; + lockCount = "0"; + homingCount = "0"; + disableMove = "0"; + respawn = "0"; + selfPower = "1"; + mountable = "1"; + }; + }; + new SimGroup(Water) { + + new WaterBlock() { + position = "-16 -80 71.5051"; + rotation = "1 0 0 0"; + scale = "128 128 6.3387"; + liquidType = "StagnantWater"; + density = "1"; + viscosity = "6"; + waveMagnitude = "1"; + surfaceTexture = "LiquidTiles/GreenWater"; + surfaceOpacity = "0.7"; + envMapTexture = "lush/skies/lushcloud3"; + envMapIntensity = "0.9"; + removeWetEdges = "1"; + AudioEnvironment = Underwater; + }; + new WaterBlock() { + position = "-8 48 95.5"; + rotation = "1 0 0 0"; + scale = "64 64 3.71365"; + liquidType = "StagnantWater"; + density = "1"; + viscosity = "6"; + waveMagnitude = "0.2"; + surfaceTexture = "LiquidTiles/AlgaeWater"; + surfaceOpacity = "0.7"; + envMapTexture = "lush/skies/lushcloud3"; + envMapIntensity = "0.9"; + removeWetEdges = "1"; + AudioEnvironment = Underwater; + }; + new WaterBlock() { + position = "-272 376 72"; + rotation = "1 0 0 0"; + scale = "64 64 1"; + liquidType = "StagnantWater"; + density = "1"; + viscosity = "6"; + waveMagnitude = "0.1"; + surfaceTexture = "LiquidTiles/AlgaeWater"; + surfaceOpacity = "0.7"; + envMapTexture = "lush/skies/lushcloud3"; + envMapIntensity = "0.9"; + removeWetEdges = "1"; + AudioEnvironment = Underwater; + }; + }; + new SimGroup(Sounds) { + + new AudioEmitter(Frog1) { + position = "-222.356 401.06 75.6289"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + fileName = "fx/environment/frog1.wav"; + useProfileDescription = "0"; + outsideAmbient = "1"; + volume = "1"; + isLooping = "1"; + is3D = "1"; + minDistance = "20"; + maxDistance = "150"; + coneInsideAngle = "360"; + coneOutsideAngle = "360"; + coneOutsideVolume = "1"; + coneVector = "0 0 1"; + loopCount = "-1"; + minLoopGap = "0"; + maxLoopGap = "0"; + type = "EffectAudioType"; + }; + new AudioEmitter(Cricket1) { + position = "-59.9835 298.318 95.3758"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + fileName = "fx/environment/crickets.wav"; + useProfileDescription = "0"; + outsideAmbient = "1"; + volume = "1"; + isLooping = "1"; + is3D = "1"; + minDistance = "20"; + maxDistance = "150"; + coneInsideAngle = "360"; + coneOutsideAngle = "360"; + coneOutsideVolume = "1"; + coneVector = "0 0 1"; + loopCount = "-1"; + minLoopGap = "0"; + maxLoopGap = "0"; + type = "EffectAudioType"; + }; + new AudioEmitter(Frog2) { + position = "534.092 163.88 102.215"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + fileName = "fx/environment/frog2.wav"; + useProfileDescription = "0"; + outsideAmbient = "1"; + volume = "1"; + isLooping = "1"; + is3D = "1"; + minDistance = "20"; + maxDistance = "150"; + coneInsideAngle = "360"; + coneOutsideAngle = "360"; + coneOutsideVolume = "1"; + coneVector = "0 0 1"; + loopCount = "-1"; + minLoopGap = "0"; + maxLoopGap = "0"; + type = "EffectAudioType"; + }; + new AudioEmitter(Cricket1) { + position = "377.544 386.028 124.305"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + fileName = "fx/environment/crickets.wav"; + useProfileDescription = "0"; + outsideAmbient = "1"; + volume = "1"; + isLooping = "1"; + is3D = "1"; + minDistance = "20"; + maxDistance = "150"; + coneInsideAngle = "360"; + coneOutsideAngle = "360"; + coneOutsideVolume = "1"; + coneVector = "0 0 1"; + loopCount = "-1"; + minLoopGap = "0"; + maxLoopGap = "0"; + type = "EffectAudioType"; + }; + new AudioEmitter(Cricket1) { + position = "818.623 -238.858 63.6823"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + fileName = "fx/environment/crickets.wav"; + useProfileDescription = "0"; + outsideAmbient = "1"; + volume = "1"; + isLooping = "1"; + is3D = "1"; + minDistance = "20"; + maxDistance = "150"; + coneInsideAngle = "360"; + coneOutsideAngle = "360"; + coneOutsideVolume = "1"; + coneVector = "0 0 1"; + loopCount = "-1"; + minLoopGap = "0"; + maxLoopGap = "0"; + type = "EffectAudioType"; + }; + new AudioEmitter(Cricket1) { + position = "1211.31 -579.262 126.456"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + fileName = "fx/environment/crickets.wav"; + useProfileDescription = "0"; + outsideAmbient = "1"; + volume = "1"; + isLooping = "1"; + is3D = "1"; + minDistance = "20"; + maxDistance = "150"; + coneInsideAngle = "360"; + coneOutsideAngle = "360"; + coneOutsideVolume = "1"; + coneVector = "0 0 1"; + loopCount = "-1"; + minLoopGap = "0"; + maxLoopGap = "0"; + type = "EffectAudioType"; + }; + new AudioEmitter(Cricket1) { + position = "1058.83 -419.898 124.77"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + fileName = "fx/environment/crickets.wav"; + useProfileDescription = "0"; + outsideAmbient = "1"; + volume = "1"; + isLooping = "1"; + is3D = "1"; + minDistance = "20"; + maxDistance = "150"; + coneInsideAngle = "360"; + coneOutsideAngle = "360"; + coneOutsideVolume = "1"; + coneVector = "0 0 1"; + loopCount = "-1"; + minLoopGap = "0"; + maxLoopGap = "0"; + type = "EffectAudioType"; + }; + new AudioEmitter(bird) { + position = "-260.284 339.991 112.661"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + fileName = "fx/environment/bird_echo5.wav"; + useProfileDescription = "0"; + outsideAmbient = "1"; + volume = "1"; + isLooping = "1"; + is3D = "1"; + minDistance = "2"; + maxDistance = "150"; + coneInsideAngle = "360"; + coneOutsideAngle = "360"; + coneOutsideVolume = "1"; + coneVector = "0 0 1"; + loopCount = "-1"; + minLoopGap = "0"; + maxLoopGap = "0"; + type = "EffectAudioType"; + }; + }; + new Camera(introFlyerDP) { + position = "400 -1000 200"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + new SimGroup(FlightPath) { + + new Camera(1) { + position = "400 -800 200"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + new Camera(2) { + position = "400 -650 200"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + new Camera(3) { + position = "400 -350 200"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + new Camera(4) { + position = "400 -245 200"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + new Camera(5) { + position = "400 45 200"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + }; + new Camera(MissileGuySpot) { + position = "250.052 -348.706 132.918"; + rotation = "0 0 -1 43.1546"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; + new Camera(MissileCamera) { + position = "246.608 -349.915 134.29"; + rotation = "0 0 1 39.6094"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + }; +}; +//--- OBJECT WRITE END --- + +exec("scripts/training1.cs"); diff --git a/missions/SlapDashSV.mis b/missions/SlapDashSV.mis index 9733880..f40da9e 100644 --- a/missions/SlapDashSV.mis +++ b/missions/SlapDashSV.mis @@ -1,1262 +1,1262 @@ -// DisplayName = Slapdash -// MissionTypes = SV - -//--- MISSION QUOTE BEGIN --- -// -// -- Dark Dragon DX -//--- MISSION QUOTE END --- - -//--- MISSION STRING BEGIN --- -// Stay in mission Boundries -// Don't run out of ammo -// Stay alive -//--- MISSION STRING END --- - -//--- OBJECT WRITE BEGIN --- -new SimGroup(MissionGroup) { - - powerCount = "0"; - cdTrack = "2"; - musicTrack = "lush"; - CTF_scoreLimit = "4"; - CTF_timeLimit = "25"; - - new MissionArea(MissionArea) { - area = "-848 -864 1264 1472"; - flightCeiling = "240"; - flightCeilingRange = "20"; - - locked = "true"; - }; - new Sun(Sun) { - position = "-1024 -1024 0"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - direction = "0.622506 0.622506 -0.474313"; - color = "0.800000 0.800000 0.800000 1.000000"; - ambient = "0.400000 0.400000 0.400000 1.000000"; - texture[0] = "special/sunFlare"; - texture[1] = "special/sunFlare02"; - texture[2] = "special/LensFlare/flare01"; - texture[3] = "special/LensFlare/flare02"; - texture[4] = "special/LensFlare/flare03"; - lensFlareScale = "0.7"; - lensFlareIntensity = "1"; - frontFlareSize = "300"; - backFlareSize = "450"; - flareColor = "1.000000 1.000000 1.000000 1.000000"; - - locked = "true"; - }; - new TerrainBlock(Terrain) { - rotation = "1 0 0 0"; - scale = "1 1 1"; - detailTexture = "details/lushdet2"; - terrainFile = "Slapdash.ter"; - squareSize = "8"; - emptySquares = "94579 99875"; - locked = "true"; - position = "-1024 -1024 0"; - visibleDistance = "1200"; - hazeDistance = "250"; - }; - new NavigationGraph(NavGraph) { - conjoinAngleDev = "70"; - cullDensity = "0.3"; - customArea = "0 0 0 0"; - - coverage = "0"; - GraphFile = "SlapdashSV.nav"; - scale = "1 1 1"; - XDimOverSize = "0"; - locked = "true"; - YDimOverSize = "0"; - position = "0 0 0 1"; - conjoinBowlDev = "20"; - rotation = "0 0 0 0"; - }; - new SimGroup(RandomOrganics) { - - powerCount = "0"; - - new SimGroup(Addition4BELgTree18) { - - powerCount = "0"; - - new TSStatic() { - position = "-19.85 -559.547 127.066"; - rotation = "0 0 1 79.8327"; - scale = "1.6 1.6 1.6"; - shapeName = "borg18.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "400.5 -277.5 128.938"; - rotation = "0 0 1 98"; - scale = "1.3 1.3 1.3"; - shapeName = "borg18.dts"; - - locked = "true"; - }; - }; - new TSStatic() { - position = "-33.151 -55.869 128.41"; - rotation = "0 0 -1 52.7121"; - scale = "1 1 1"; - shapeName = "borg19.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "-169.314 -61.619 128.085"; - rotation = "0 0 -1 34.3775"; - scale = "1 1 1"; - shapeName = "borg18.dts"; - - locked = "true"; - }; - new SimGroup(Addition1BEPlant1) { - - powerCount = "0"; - - new TSStatic() { - position = "-268 260 129.288"; - rotation = "0 0 1 82"; - scale = "0.6 0.6 0.6"; - shapeName = "borg1.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "140 -140 129.272"; - rotation = "-0.261677 0.145892 0.954065 108.572"; - scale = "1 1 1"; - shapeName = "borg1.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "-4 -20 129.772"; - rotation = "-0.133613 -0.0501878 0.989762 47.4328"; - scale = "1.7 1.7 1.7"; - shapeName = "borg1.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "-644 28 154.709"; - rotation = "0.143549 -0.119692 -0.982378 95.0154"; - scale = "1.4 1.4 1.4"; - shapeName = "borg1.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "-332 396 121.788"; - rotation = "0.108807 0.0797487 0.990859 34.2954"; - scale = "0.6 0.6 0.6"; - shapeName = "borg1.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "-155.685 59.4242 128.933"; - rotation = "-0.0783751 0.394846 0.915398 166.862"; - scale = "0.6 0.6 0.6"; - shapeName = "borg1.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "-308 412 133.881"; - rotation = "-0.243443 -0.261637 0.93396 17.1152"; - scale = "1.2 1.2 1.2"; - shapeName = "borg1.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "-500.097 -20.0703 153.531"; - rotation = "-0.162675 0.762419 0.626302 44.8742"; - scale = "1.1 1.1 1.1"; - shapeName = "borg1.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "-316 212 129.491"; - rotation = "-0.0303782 0.00824476 0.999505 181.999"; - scale = "2 2 2"; - shapeName = "borg1.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "-220 -276 126.459"; - rotation = "0.130888 0.298129 0.945509 132.415"; - scale = "1.6 1.6 1.6"; - shapeName = "borg1.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "-132 -100 129.288"; - rotation = "0 0 -1 82"; - scale = "0.5 0.5 0.5"; - shapeName = "borg1.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "-213.687 350.079 164.349"; - rotation = "-0.455246 0.4015 0.794701 55.0589"; - scale = "0.5 0.5 0.5"; - shapeName = "borg1.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "-220 -92 129.241"; - rotation = "-0.0056401 0.0148964 0.999873 162.002"; - scale = "1.6 1.6 1.6"; - shapeName = "borg1.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "-540 -220 102.225"; - rotation = "0.0385352 0.118458 0.992211 166.108"; - scale = "2 2 2"; - shapeName = "borg1.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "-36 -28 129.288"; - rotation = "0 0 -1 16.9999"; - scale = "0.7 0.7 0.7"; - shapeName = "borg1.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "-404 -196 166.491"; - rotation = "-0.00931408 -0.336025 -0.941807 113.194"; - scale = "0.7 0.7 0.7"; - shapeName = "borg1.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "148 28 112.459"; - rotation = "-0.257195 -0.216438 -0.94181 100.395"; - scale = "1.6 1.6 1.6"; - shapeName = "borg1.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "44 460 152.1"; - rotation = "0.785524 0.367614 -0.497808 27.7109"; - scale = "0.7 0.7 0.7"; - shapeName = "borg1.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "-27.9992 -132.002 129.15"; - rotation = "0.00904323 -0.00348301 -0.999953 79.0023"; - scale = "1.6 1.6 1.6"; - shapeName = "borg1.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "-300 300 129.288"; - rotation = "0 0 1 107"; - scale = "1 1 1"; - shapeName = "borg1.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "52 148 167.147"; - rotation = "0.320545 -0.0696586 -0.944669 114.99"; - scale = "2 2 2"; - shapeName = "borg1.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "-140 -92 129.288"; - rotation = "0 0 -1 41"; - scale = "2 2 2"; - shapeName = "borg1.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "-572 -12 129.678"; - rotation = "-0.15546 0.121266 0.980371 213.369"; - scale = "2 2 2"; - shapeName = "borg1.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "68 340 133.022"; - rotation = "0.185558 0.235852 0.953909 127.185"; - scale = "1.6 1.6 1.6"; - shapeName = "borg1.dts"; - - locked = "true"; - }; - }; - new TSStatic() { - position = "-740.673 129.85 139.443"; - rotation = "0 0 1 235.095"; - scale = "1 1 1"; - shapeName = "borg18.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "-538.483 -131.363 127.001"; - rotation = "0 0 -1 44.1178"; - scale = "1 1.07701 1"; - shapeName = "borg19.dts"; - - locked = "true"; - }; - new SimGroup(Addition1BESmTree17) { - - powerCount = "0"; - - new TSStatic() { - position = "-47.5 355.5 129.361"; - rotation = "0 0 1 35"; - scale = "0.7 0.7 0.7"; - shapeName = "borg17.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "-552.5 -791.5 128.607"; - rotation = "0 0 1 202"; - scale = "1.4 1.4 1.4"; - shapeName = "borg17.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "-382.5 -460.5 128.938"; - rotation = "0 0 1 187"; - scale = "1.2 1.2 1.2"; - shapeName = "borg17.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "234.5 -939.5 129.09"; - rotation = "0 0 1 110"; - scale = "1.4 1.4 1.4"; - shapeName = "borg17.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "-567.439 -379.794 129.179"; - rotation = "0 0 1 33.8327"; - scale = "1.1 1.1 1.1"; - shapeName = "borg17.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "160.5 -879.5 128.938"; - rotation = "0 0 -1 119"; - scale = "1.4 1.4 1.4"; - shapeName = "borg17.dts"; - - locked = "true"; - }; - }; - new TSStatic() { - position = "-353.375 -549.332 130.415"; - rotation = "0 0 1 67.0361"; - scale = "1 1.47973 0.940896"; - shapeName = "borg17.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "-514.178 494.43 128.51"; - rotation = "0 0 -1 34.9504"; - scale = "1 1 1"; - shapeName = "borg18.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "-482.358 465.83 128.431"; - rotation = "0 0 1 64.7442"; - scale = "1 1 1"; - shapeName = "borg17.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "178.9 -576.324 127.147"; - rotation = "0 0 1 40.107"; - scale = "1 1 1"; - shapeName = "borg19.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "116.51 -312.701 128.69"; - rotation = "0 0 1 138.083"; - scale = "1.29596 1.34204 1"; - shapeName = "borg19.dts"; - - locked = "true"; - }; - new SimGroup(Addition2BELgTree18) { - - powerCount = "0"; - - new TSStatic() { - position = "-563.5 563.5 128.232"; - rotation = "0 0 1 235"; - scale = "1.5 1.5 1.5"; - shapeName = "borg18.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "-404.5 -818.5 129.312"; - rotation = "0 0 1 233"; - scale = "1.5 1.5 1.5"; - shapeName = "borg18.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "157.5 501.5 128.992"; - rotation = "0 0 -1 17"; - scale = "1.6 1.6 1.6"; - shapeName = "borg18.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "-893.5 544.5 128.938"; - rotation = "0 0 -1 82"; - scale = "1.5 1.5 1.5"; - shapeName = "borg18.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "365.5 -320.5 128.938"; - rotation = "0 0 1 216"; - scale = "1.3 1.3 1.3"; - shapeName = "borg18.dts"; - - locked = "true"; - }; - }; - }; - new Sky(Sky) { - position = "-1024 -1024 0"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - cloudHeightPer[0] = "0.349971"; - cloudHeightPer[1] = "0.25"; - cloudHeightPer[2] = "0.199973"; - cloudSpeed1 = "0.0001"; - cloudSpeed2 = "0.0002"; - cloudSpeed3 = "0.0003"; - visibleDistance = "500"; - useSkyTextures = "1"; - renderBottomTexture = "0"; - SkySolidColor = "0.390000 0.390000 0.390000 0.000000"; - fogDistance = "280"; - fogColor = "0.500000 0.500000 0.500000 1.000000"; - fogVolume1 = "0 0 0"; - fogVolume2 = "100 100 120"; - fogVolume3 = "0 0 0"; - materialList = "Lush_l4.dml"; - windVelocity = "1 0 0"; - windEffectPrecipitation = "0"; - fogVolumeColor1 = "128.000000 128.000000 128.000000 -0.040112"; - fogVolumeColor2 = "128.000000 128.000000 128.000000 0.742938"; - fogVolumeColor3 = "128.000000 128.000000 128.000000 0.000000"; - high_visibleDistance = "-1"; - high_fogDistance = "-1"; - high_fogVolume1 = "-1 -nan -nan"; - high_fogVolume2 = "-1 -nan -nan"; - high_fogVolume3 = "-1 -nan -nan"; - - locked = "true"; - cloudSpeed0 = "0.000000 0.000000"; - }; - new SimGroup(Teams) { - - powerCount = "0"; - - new SimGroup(Team1) { - - powerCount = "0"; - - new SimGroup(spawnspheres) { - - powerCount = "0"; - - new SpawnSphere() { - position = "-74.927 -40.2688 128.938"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "SpawnSphereMarker"; - lockCount = "0"; - homingCount = "0"; - radius = "70"; - sphereWeight = "100"; - indoorWeight = "100"; - outdoorWeight = "100"; - - locked = "1"; - }; - }; - new SimGroup(base0) { - - new InteriorInstance() { - position = "-99.074 -115 126.206"; - rotation = "0 0 1 180"; - scale = "1 1 1"; - interiorFile = "bbunkd.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new WayPoint() { - position = "-99.066 -115.183 134.62"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - nameTag = "HeadQuarters"; - dataBlock = "WayPointMarker"; - lockCount = "0"; - homingCount = "0"; - name = "HeadQuarters"; - team = "0"; - - locked = "1"; - }; - new StaticShape(TeamSensorMediumPulse1) { - position = "-99.0642 -109.562 135.186"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - nameTag = "Main"; - dataBlock = "SensorMediumPulse"; - lockCount = "0"; - homingCount = "0"; - - Target = "35"; - locked = "1"; - }; - new StaticShape(TeamStationInventory1) { - position = "-99.0501 -116.179 127.213"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - nameTag = "Main"; - dataBlock = "StationInventory"; - lockCount = "0"; - homingCount = "0"; - - Target = "34"; - locked = "1"; - Trigger = "10775"; - }; - new Camera(Camera03) { - position = "-179.281 -16.8454 161.48"; - rotation = "0.0617406 -0.167472 0.983942 140.124"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - - locked = "1"; - team = "1"; - }; - }; - new StaticShape(TeamSolarPanel1) { - position = "-99.066 -115.183 134.62"; - rotation = "1 0 0 0"; - scale = "1.24627 1.50298 1.25212"; - nameTag = "Main"; - dataBlock = "SolarPanel"; - lockCount = "0"; - homingCount = "0"; - - Target = "33"; - locked = "1"; - }; - new Item() { - position = "-99.0633 -110.548 130.216"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "RepairPack"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "0"; - rotate = "0"; - - Target = "-1"; - locked = "1"; - }; - new SimGroup(AIObjectives) { - - new AIObjective(AIORepairObject) { - position = "-99.0642 -109.562 137.706"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Repair the SensorMediumPulse"; - targetObject = "TeamSensorMediumPulse1"; - targetClientId = "-1"; - targetObjectId = "10406"; - location = "-99.0642 -109.562 137.706"; - weightLevel1 = "3100"; - weightLevel2 = "1000"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "0"; - defense = "1"; - equipment = "RepairPack"; - buyEquipmentSet = "MediumRepairSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - }; - new AIObjective(AIOMortarObject) { - position = "-99.0642 -109.562 137.706"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Mortar the SensorMediumPulse"; - targetObject = "TeamSensorMediumPulse1"; - targetClientId = "-1"; - targetObjectId = "10406"; - location = "-99.0642 -109.562 137.706"; - weightLevel1 = "3400"; - weightLevel2 = "1000"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "1"; - defense = "0"; - equipment = "Mortar MortarAmmo"; - buyEquipmentSet = "HeavyAmmoSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - }; - new AIObjective(AIORepairObject) { - position = "-99.0501 -116.179 128.778"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Repair the StationInventory"; - targetObject = "TeamStationInventory1"; - targetClientId = "-1"; - targetObjectId = "10774"; - location = "-99.0501 -116.179 128.778"; - weightLevel1 = "2900"; - weightLevel2 = "1400"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "0"; - defense = "1"; - equipment = "RepairPack"; - buyEquipmentSet = "MediumRepairSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - }; - new AIObjective(AIOAttackObject) { - position = "-99.0501 -116.179 128.778"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Attack the StationInventory"; - targetObject = "TeamStationInventory1"; - targetClientId = "-1"; - targetObjectId = "10774"; - location = "-99.0501 -116.179 128.778"; - weightLevel1 = "2900"; - weightLevel2 = "1400"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "1"; - defense = "0"; - desiredEquipment = "ShieldPack"; - buyEquipmentSet = "HeavyAmmoSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - }; - new AIObjective(AIORepairObject) { - position = "-99.066 -114.701 135.741"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Repair the SolarPanel"; - targetObject = "TeamSolarPanel1"; - targetClientId = "-1"; - targetObjectId = "9237"; - location = "-99.066 -114.701 135.741"; - weightLevel1 = "3200"; - weightLevel2 = "1600"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "0"; - defense = "1"; - equipment = "RepairPack"; - buyEquipmentSet = "MediumRepairSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - }; - new AIObjective(AIOAttackObject) { - position = "-99.066 -114.701 135.741"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Attack the SolarPanel"; - targetObject = "TeamSolarPanel1"; - targetClientId = "-1"; - targetObjectId = "9237"; - location = "-99.066 -114.701 135.741"; - weightLevel1 = "3100"; - weightLevel2 = "1600"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "1"; - defense = "0"; - desiredEquipment = "ShieldPack"; - buyEquipmentSet = "HeavyAmmoSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - }; - new AIObjective(AIODefendLocation) { - position = "-99.066 -114.701 135.741"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Defend the SolarPanel"; - targetObject = "TeamSolarPanel1"; - targetClientId = "-1"; - targetObjectId = "9237"; - location = "-99.066 -114.701 135.741"; - weightLevel1 = "3100"; - weightLevel2 = "1500"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "0"; - defense = "1"; - desiredEquipment = "ShieldPack Plasma PlasmaAmmo"; - buyEquipmentSet = "HeavyShieldSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - }; - }; - }; - new SimGroup(Team2) { - - powerCount = "0"; - - new SimGroup(spawnspheres) { - - powerCount = "0"; - - new SpawnSphere() { - position = "-415.667 -497.317 128.938"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "SpawnSphereMarker"; - lockCount = "0"; - homingCount = "0"; - radius = "70"; - sphereWeight = "100"; - indoorWeight = "100"; - outdoorWeight = "100"; - - locked = "1"; - }; - new SpawnSphere() { - position = "-293.697 283.488 128.938"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "SpawnSphereMarker"; - lockCount = "0"; - homingCount = "0"; - radius = "50"; - sphereWeight = "100"; - indoorWeight = "100"; - outdoorWeight = "100"; - - locked = "1"; - }; - new SpawnSphere() { - position = "342.868 465.127 131.024"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "SpawnSphereMarker"; - lockCount = "0"; - homingCount = "0"; - radius = "70"; - sphereWeight = "100"; - indoorWeight = "100"; - outdoorWeight = "100"; - - locked = "1"; - }; - new SpawnSphere() { - position = "317.584 -508.799 128.269"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "SpawnSphereMarker"; - lockCount = "0"; - homingCount = "0"; - radius = "70"; - sphereWeight = "100"; - indoorWeight = "100"; - outdoorWeight = "100"; - - locked = "1"; - }; - }; - new SimGroup(AIObjectives) { - - new AIObjective(AIORepairObject) { - position = "-99.0642 -109.562 137.706"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Repair the SensorMediumPulse"; - targetObject = "TeamSensorMediumPulse1"; - targetClientId = "-1"; - targetObjectId = "10406"; - location = "-99.0642 -109.562 137.706"; - weightLevel1 = "3100"; - weightLevel2 = "1000"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "0"; - defense = "1"; - equipment = "RepairPack"; - buyEquipmentSet = "MediumRepairSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - }; - new AIObjective(AIOMortarObject) { - position = "-99.0642 -109.562 137.706"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Mortar the SensorMediumPulse"; - targetObject = "TeamSensorMediumPulse1"; - targetClientId = "-1"; - targetObjectId = "10406"; - location = "-99.0642 -109.562 137.706"; - weightLevel1 = "3400"; - weightLevel2 = "1000"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "1"; - defense = "0"; - equipment = "Mortar MortarAmmo"; - buyEquipmentSet = "HeavyAmmoSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - }; - new AIObjective(AIORepairObject) { - position = "-99.0501 -116.179 128.778"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Repair the StationInventory"; - targetObject = "TeamStationInventory1"; - targetClientId = "-1"; - targetObjectId = "10774"; - location = "-99.0501 -116.179 128.778"; - weightLevel1 = "2900"; - weightLevel2 = "1400"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "0"; - defense = "1"; - equipment = "RepairPack"; - buyEquipmentSet = "MediumRepairSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - }; - new AIObjective(AIOAttackObject) { - position = "-99.0501 -116.179 128.778"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Attack the StationInventory"; - targetObject = "TeamStationInventory1"; - targetClientId = "-1"; - targetObjectId = "10774"; - location = "-99.0501 -116.179 128.778"; - weightLevel1 = "2900"; - weightLevel2 = "1400"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "1"; - defense = "0"; - desiredEquipment = "ShieldPack"; - buyEquipmentSet = "HeavyAmmoSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - }; - new AIObjective(AIORepairObject) { - position = "-99.066 -114.701 135.741"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Repair the SolarPanel"; - targetObject = "TeamSolarPanel1"; - targetClientId = "-1"; - targetObjectId = "9237"; - location = "-99.066 -114.701 135.741"; - weightLevel1 = "3200"; - weightLevel2 = "1600"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "0"; - defense = "1"; - equipment = "RepairPack"; - buyEquipmentSet = "MediumRepairSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - }; - new AIObjective(AIOAttackObject) { - position = "-99.066 -114.701 135.741"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Attack the SolarPanel"; - targetObject = "TeamSolarPanel1"; - targetClientId = "-1"; - targetObjectId = "9237"; - location = "-99.066 -114.701 135.741"; - weightLevel1 = "3100"; - weightLevel2 = "1600"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "1"; - defense = "0"; - desiredEquipment = "ShieldPack"; - buyEquipmentSet = "HeavyAmmoSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - }; - new AIObjective(AIODefendLocation) { - position = "-99.066 -114.701 135.741"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "AIObjectiveMarker"; - lockCount = "0"; - homingCount = "0"; - description = "Defend the SolarPanel"; - targetObject = "TeamSolarPanel1"; - targetClientId = "-1"; - targetObjectId = "9237"; - location = "-99.066 -114.701 135.741"; - weightLevel1 = "3100"; - weightLevel2 = "1500"; - weightLevel3 = "0"; - weightLevel4 = "0"; - offense = "0"; - defense = "1"; - desiredEquipment = "ShieldPack Plasma PlasmaAmmo"; - buyEquipmentSet = "HeavyShieldSet"; - issuedByHuman = "0"; - issuedByClientId = "-1"; - forceClientId = "-1"; - locked = "0"; - }; - }; - }; - new SimGroup(team0) { - - powerCount = "0"; - - new SimGroup(AIObjectives) { - - powerCount = "0"; - }; - }; - }; - new SimGroup(ObserverDropPoints) { - - powerCount = "0"; - - new Camera(Camera01) { - position = "-54.7021 -73.726 158.935"; - rotation = "-0.0963814 -0.242121 0.965447 222.045"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - - locked = "1"; - team = "1"; - }; - new Camera(Camera02) { - position = "-98.6944 -131.848 137.766"; - rotation = "0.997549 0.0171719 -0.0678376 28.4771"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - - locked = "1"; - team = "1"; - }; - }; - new SimGroup(Miskellany) { - - powerCount = "0"; - - new InteriorInstance() { - position = "293.3 -393.442 128.618"; - rotation = "0 0 1 47.5555"; - scale = "1 1 1"; - interiorFile = "bbunk9.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - new InteriorInstance() { - position = "-741.056 50.94 127.615"; - rotation = "0 0 1 89.9544"; - scale = "1 1 1"; - interiorFile = "bbunkd.dif"; - showTerrainInside = "0"; - - locked = "true"; - }; - }; - new SimGroup(Ambiance) { - - powerCount = "0"; - - new AudioEmitter() { - position = "-87.88 -700.815 191.107"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - fileName = "fx/environment/bird_echo5.wav"; - useProfileDescription = "0"; - outsideAmbient = "1"; - volume = "1"; - isLooping = "1"; - is3D = "1"; - minDistance = "20"; - maxDistance = "1280"; - coneInsideAngle = "360"; - coneOutsideAngle = "360"; - coneOutsideVolume = "1"; - coneVector = "0 0 1"; - loopCount = "-1"; - minLoopGap = "10000"; - maxLoopGap = "40000"; - type = "EffectAudioType"; - - locked = "true"; - }; - new AudioEmitter() { - position = "-168.263 -2.47 139.564"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - fileName = "fx/environment/bird_echo1.wav"; - useProfileDescription = "0"; - outsideAmbient = "1"; - volume = "1"; - isLooping = "1"; - is3D = "1"; - minDistance = "20"; - maxDistance = "1280"; - coneInsideAngle = "360"; - coneOutsideAngle = "360"; - coneOutsideVolume = "1"; - coneVector = "0 0 1"; - loopCount = "-1"; - minLoopGap = "10000"; - maxLoopGap = "40000"; - type = "EffectAudioType"; - - locked = "true"; - }; - new AudioEmitter() { - position = "-573.301 606.13 141.004"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - fileName = "fx/environment/bird_echo3.wav"; - useProfileDescription = "0"; - outsideAmbient = "1"; - volume = "1"; - isLooping = "1"; - is3D = "1"; - minDistance = "20"; - maxDistance = "1280"; - coneInsideAngle = "360"; - coneOutsideAngle = "360"; - coneOutsideVolume = "1"; - coneVector = "0 0 1"; - loopCount = "-1"; - minLoopGap = "10000"; - maxLoopGap = "40000"; - type = "EffectAudioType"; - - locked = "true"; - }; - new AudioEmitter() { - position = "360.77 -363.742 158.176"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - fileName = "fx/environment/bird_echo2.wav"; - useProfileDescription = "0"; - outsideAmbient = "1"; - volume = "1"; - isLooping = "1"; - is3D = "1"; - minDistance = "20"; - maxDistance = "1280"; - coneInsideAngle = "360"; - coneOutsideAngle = "360"; - coneOutsideVolume = "1"; - coneVector = "0 0 1"; - loopCount = "-1"; - minLoopGap = "50000"; - maxLoopGap = "70000"; - type = "EffectAudioType"; - - locked = "true"; - }; - new AudioEmitter() { - position = "-212.09 -229.039 142.75"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - fileName = "fx/environment/bird_echo1.wav"; - useProfileDescription = "0"; - outsideAmbient = "1"; - volume = "1"; - isLooping = "1"; - is3D = "1"; - minDistance = "20"; - maxDistance = "1280"; - coneInsideAngle = "360"; - coneOutsideAngle = "360"; - coneOutsideVolume = "1"; - coneVector = "0 0 1"; - loopCount = "-1"; - minLoopGap = "20000"; - maxLoopGap = "60000"; - type = "EffectAudioType"; - - locked = "true"; - }; - new AudioEmitter() { - position = "-392.039 141.68 152.835"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - fileName = "fx/environment/bird_echo4.wav"; - useProfileDescription = "0"; - outsideAmbient = "1"; - volume = "1"; - isLooping = "1"; - is3D = "1"; - minDistance = "20"; - maxDistance = "1280"; - coneInsideAngle = "360"; - coneOutsideAngle = "360"; - coneOutsideVolume = "1"; - coneVector = "0 0 1"; - loopCount = "-1"; - minLoopGap = "10000"; - maxLoopGap = "30000"; - type = "EffectAudioType"; - - locked = "true"; - }; - new TSStatic() { - position = "405.613 599.739 128.641"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - shapeName = "statue_base.dts"; - - locked = "true"; - }; - new TSStatic() { - position = "405.92 599.28 131.892"; - rotation = "0 0 1 179.909"; - scale = "1 1 1"; - shapeName = "statue_hmale.dts"; - - locked = "true"; - }; - }; -}; -//--- OBJECT WRITE END --- +// DisplayName = Slapdash +// MissionTypes = SV + +//--- MISSION QUOTE BEGIN --- +// +// -- Dark Dragon DX +//--- MISSION QUOTE END --- + +//--- MISSION STRING BEGIN --- +// Stay in mission Boundries +// Don't run out of ammo +// Stay alive +//--- MISSION STRING END --- + +//--- OBJECT WRITE BEGIN --- +new SimGroup(MissionGroup) { + + powerCount = "0"; + cdTrack = "2"; + musicTrack = "lush"; + CTF_scoreLimit = "4"; + CTF_timeLimit = "25"; + + new MissionArea(MissionArea) { + area = "-848 -864 1264 1472"; + flightCeiling = "240"; + flightCeilingRange = "20"; + + locked = "true"; + }; + new Sun(Sun) { + position = "-1024 -1024 0"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + direction = "0.622506 0.622506 -0.474313"; + color = "0.800000 0.800000 0.800000 1.000000"; + ambient = "0.400000 0.400000 0.400000 1.000000"; + texture[0] = "special/sunFlare"; + texture[1] = "special/sunFlare02"; + texture[2] = "special/LensFlare/flare01"; + texture[3] = "special/LensFlare/flare02"; + texture[4] = "special/LensFlare/flare03"; + lensFlareScale = "0.7"; + lensFlareIntensity = "1"; + frontFlareSize = "300"; + backFlareSize = "450"; + flareColor = "1.000000 1.000000 1.000000 1.000000"; + + locked = "true"; + }; + new TerrainBlock(Terrain) { + rotation = "1 0 0 0"; + scale = "1 1 1"; + detailTexture = "details/lushdet2"; + terrainFile = "Slapdash.ter"; + squareSize = "8"; + emptySquares = "94579 99875"; + locked = "true"; + position = "-1024 -1024 0"; + visibleDistance = "1200"; + hazeDistance = "250"; + }; + new NavigationGraph(NavGraph) { + conjoinAngleDev = "70"; + cullDensity = "0.3"; + customArea = "0 0 0 0"; + + coverage = "0"; + GraphFile = "SlapdashSV.nav"; + scale = "1 1 1"; + XDimOverSize = "0"; + locked = "true"; + YDimOverSize = "0"; + position = "0 0 0 1"; + conjoinBowlDev = "20"; + rotation = "0 0 0 0"; + }; + new SimGroup(RandomOrganics) { + + powerCount = "0"; + + new SimGroup(Addition4BELgTree18) { + + powerCount = "0"; + + new TSStatic() { + position = "-19.85 -559.547 127.066"; + rotation = "0 0 1 79.8327"; + scale = "1.6 1.6 1.6"; + shapeName = "borg18.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "400.5 -277.5 128.938"; + rotation = "0 0 1 98"; + scale = "1.3 1.3 1.3"; + shapeName = "borg18.dts"; + + locked = "true"; + }; + }; + new TSStatic() { + position = "-33.151 -55.869 128.41"; + rotation = "0 0 -1 52.7121"; + scale = "1 1 1"; + shapeName = "borg19.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "-169.314 -61.619 128.085"; + rotation = "0 0 -1 34.3775"; + scale = "1 1 1"; + shapeName = "borg18.dts"; + + locked = "true"; + }; + new SimGroup(Addition1BEPlant1) { + + powerCount = "0"; + + new TSStatic() { + position = "-268 260 129.288"; + rotation = "0 0 1 82"; + scale = "0.6 0.6 0.6"; + shapeName = "borg1.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "140 -140 129.272"; + rotation = "-0.261677 0.145892 0.954065 108.572"; + scale = "1 1 1"; + shapeName = "borg1.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "-4 -20 129.772"; + rotation = "-0.133613 -0.0501878 0.989762 47.4328"; + scale = "1.7 1.7 1.7"; + shapeName = "borg1.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "-644 28 154.709"; + rotation = "0.143549 -0.119692 -0.982378 95.0154"; + scale = "1.4 1.4 1.4"; + shapeName = "borg1.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "-332 396 121.788"; + rotation = "0.108807 0.0797487 0.990859 34.2954"; + scale = "0.6 0.6 0.6"; + shapeName = "borg1.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "-155.685 59.4242 128.933"; + rotation = "-0.0783751 0.394846 0.915398 166.862"; + scale = "0.6 0.6 0.6"; + shapeName = "borg1.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "-308 412 133.881"; + rotation = "-0.243443 -0.261637 0.93396 17.1152"; + scale = "1.2 1.2 1.2"; + shapeName = "borg1.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "-500.097 -20.0703 153.531"; + rotation = "-0.162675 0.762419 0.626302 44.8742"; + scale = "1.1 1.1 1.1"; + shapeName = "borg1.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "-316 212 129.491"; + rotation = "-0.0303782 0.00824476 0.999505 181.999"; + scale = "2 2 2"; + shapeName = "borg1.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "-220 -276 126.459"; + rotation = "0.130888 0.298129 0.945509 132.415"; + scale = "1.6 1.6 1.6"; + shapeName = "borg1.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "-132 -100 129.288"; + rotation = "0 0 -1 82"; + scale = "0.5 0.5 0.5"; + shapeName = "borg1.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "-213.687 350.079 164.349"; + rotation = "-0.455246 0.4015 0.794701 55.0589"; + scale = "0.5 0.5 0.5"; + shapeName = "borg1.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "-220 -92 129.241"; + rotation = "-0.0056401 0.0148964 0.999873 162.002"; + scale = "1.6 1.6 1.6"; + shapeName = "borg1.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "-540 -220 102.225"; + rotation = "0.0385352 0.118458 0.992211 166.108"; + scale = "2 2 2"; + shapeName = "borg1.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "-36 -28 129.288"; + rotation = "0 0 -1 16.9999"; + scale = "0.7 0.7 0.7"; + shapeName = "borg1.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "-404 -196 166.491"; + rotation = "-0.00931408 -0.336025 -0.941807 113.194"; + scale = "0.7 0.7 0.7"; + shapeName = "borg1.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "148 28 112.459"; + rotation = "-0.257195 -0.216438 -0.94181 100.395"; + scale = "1.6 1.6 1.6"; + shapeName = "borg1.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "44 460 152.1"; + rotation = "0.785524 0.367614 -0.497808 27.7109"; + scale = "0.7 0.7 0.7"; + shapeName = "borg1.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "-27.9992 -132.002 129.15"; + rotation = "0.00904323 -0.00348301 -0.999953 79.0023"; + scale = "1.6 1.6 1.6"; + shapeName = "borg1.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "-300 300 129.288"; + rotation = "0 0 1 107"; + scale = "1 1 1"; + shapeName = "borg1.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "52 148 167.147"; + rotation = "0.320545 -0.0696586 -0.944669 114.99"; + scale = "2 2 2"; + shapeName = "borg1.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "-140 -92 129.288"; + rotation = "0 0 -1 41"; + scale = "2 2 2"; + shapeName = "borg1.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "-572 -12 129.678"; + rotation = "-0.15546 0.121266 0.980371 213.369"; + scale = "2 2 2"; + shapeName = "borg1.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "68 340 133.022"; + rotation = "0.185558 0.235852 0.953909 127.185"; + scale = "1.6 1.6 1.6"; + shapeName = "borg1.dts"; + + locked = "true"; + }; + }; + new TSStatic() { + position = "-740.673 129.85 139.443"; + rotation = "0 0 1 235.095"; + scale = "1 1 1"; + shapeName = "borg18.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "-538.483 -131.363 127.001"; + rotation = "0 0 -1 44.1178"; + scale = "1 1.07701 1"; + shapeName = "borg19.dts"; + + locked = "true"; + }; + new SimGroup(Addition1BESmTree17) { + + powerCount = "0"; + + new TSStatic() { + position = "-47.5 355.5 129.361"; + rotation = "0 0 1 35"; + scale = "0.7 0.7 0.7"; + shapeName = "borg17.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "-552.5 -791.5 128.607"; + rotation = "0 0 1 202"; + scale = "1.4 1.4 1.4"; + shapeName = "borg17.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "-382.5 -460.5 128.938"; + rotation = "0 0 1 187"; + scale = "1.2 1.2 1.2"; + shapeName = "borg17.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "234.5 -939.5 129.09"; + rotation = "0 0 1 110"; + scale = "1.4 1.4 1.4"; + shapeName = "borg17.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "-567.439 -379.794 129.179"; + rotation = "0 0 1 33.8327"; + scale = "1.1 1.1 1.1"; + shapeName = "borg17.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "160.5 -879.5 128.938"; + rotation = "0 0 -1 119"; + scale = "1.4 1.4 1.4"; + shapeName = "borg17.dts"; + + locked = "true"; + }; + }; + new TSStatic() { + position = "-353.375 -549.332 130.415"; + rotation = "0 0 1 67.0361"; + scale = "1 1.47973 0.940896"; + shapeName = "borg17.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "-514.178 494.43 128.51"; + rotation = "0 0 -1 34.9504"; + scale = "1 1 1"; + shapeName = "borg18.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "-482.358 465.83 128.431"; + rotation = "0 0 1 64.7442"; + scale = "1 1 1"; + shapeName = "borg17.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "178.9 -576.324 127.147"; + rotation = "0 0 1 40.107"; + scale = "1 1 1"; + shapeName = "borg19.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "116.51 -312.701 128.69"; + rotation = "0 0 1 138.083"; + scale = "1.29596 1.34204 1"; + shapeName = "borg19.dts"; + + locked = "true"; + }; + new SimGroup(Addition2BELgTree18) { + + powerCount = "0"; + + new TSStatic() { + position = "-563.5 563.5 128.232"; + rotation = "0 0 1 235"; + scale = "1.5 1.5 1.5"; + shapeName = "borg18.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "-404.5 -818.5 129.312"; + rotation = "0 0 1 233"; + scale = "1.5 1.5 1.5"; + shapeName = "borg18.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "157.5 501.5 128.992"; + rotation = "0 0 -1 17"; + scale = "1.6 1.6 1.6"; + shapeName = "borg18.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "-893.5 544.5 128.938"; + rotation = "0 0 -1 82"; + scale = "1.5 1.5 1.5"; + shapeName = "borg18.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "365.5 -320.5 128.938"; + rotation = "0 0 1 216"; + scale = "1.3 1.3 1.3"; + shapeName = "borg18.dts"; + + locked = "true"; + }; + }; + }; + new Sky(Sky) { + position = "-1024 -1024 0"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + cloudHeightPer[0] = "0.349971"; + cloudHeightPer[1] = "0.25"; + cloudHeightPer[2] = "0.199973"; + cloudSpeed1 = "0.0001"; + cloudSpeed2 = "0.0002"; + cloudSpeed3 = "0.0003"; + visibleDistance = "500"; + useSkyTextures = "1"; + renderBottomTexture = "0"; + SkySolidColor = "0.390000 0.390000 0.390000 0.000000"; + fogDistance = "280"; + fogColor = "0.500000 0.500000 0.500000 1.000000"; + fogVolume1 = "0 0 0"; + fogVolume2 = "100 100 120"; + fogVolume3 = "0 0 0"; + materialList = "Lush_l4.dml"; + windVelocity = "1 0 0"; + windEffectPrecipitation = "0"; + fogVolumeColor1 = "128.000000 128.000000 128.000000 -0.040112"; + fogVolumeColor2 = "128.000000 128.000000 128.000000 0.742938"; + fogVolumeColor3 = "128.000000 128.000000 128.000000 0.000000"; + high_visibleDistance = "-1"; + high_fogDistance = "-1"; + high_fogVolume1 = "-1 -nan -nan"; + high_fogVolume2 = "-1 -nan -nan"; + high_fogVolume3 = "-1 -nan -nan"; + + locked = "true"; + cloudSpeed0 = "0.000000 0.000000"; + }; + new SimGroup(Teams) { + + powerCount = "0"; + + new SimGroup(Team1) { + + powerCount = "0"; + + new SimGroup(spawnspheres) { + + powerCount = "0"; + + new SpawnSphere() { + position = "-74.927 -40.2688 128.938"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "SpawnSphereMarker"; + lockCount = "0"; + homingCount = "0"; + radius = "70"; + sphereWeight = "100"; + indoorWeight = "100"; + outdoorWeight = "100"; + + locked = "1"; + }; + }; + new SimGroup(base0) { + + new InteriorInstance() { + position = "-99.074 -115 126.206"; + rotation = "0 0 1 180"; + scale = "1 1 1"; + interiorFile = "bbunkd.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new WayPoint() { + position = "-99.066 -115.183 134.62"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + nameTag = "HeadQuarters"; + dataBlock = "WayPointMarker"; + lockCount = "0"; + homingCount = "0"; + name = "HeadQuarters"; + team = "0"; + + locked = "1"; + }; + new StaticShape(TeamSensorMediumPulse1) { + position = "-99.0642 -109.562 135.186"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + nameTag = "Main"; + dataBlock = "SensorMediumPulse"; + lockCount = "0"; + homingCount = "0"; + + Target = "35"; + locked = "1"; + }; + new StaticShape(TeamStationInventory1) { + position = "-99.0501 -116.179 127.213"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + nameTag = "Main"; + dataBlock = "StationInventory"; + lockCount = "0"; + homingCount = "0"; + + Target = "34"; + locked = "1"; + Trigger = "10775"; + }; + new Camera(Camera03) { + position = "-179.281 -16.8454 161.48"; + rotation = "0.0617406 -0.167472 0.983942 140.124"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + locked = "1"; + team = "1"; + }; + }; + new StaticShape(TeamSolarPanel1) { + position = "-99.066 -115.183 134.62"; + rotation = "1 0 0 0"; + scale = "1.24627 1.50298 1.25212"; + nameTag = "Main"; + dataBlock = "SolarPanel"; + lockCount = "0"; + homingCount = "0"; + + Target = "33"; + locked = "1"; + }; + new Item() { + position = "-99.0633 -110.548 130.216"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "RepairPack"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "0"; + rotate = "0"; + + Target = "-1"; + locked = "1"; + }; + new SimGroup(AIObjectives) { + + new AIObjective(AIORepairObject) { + position = "-99.0642 -109.562 137.706"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Repair the SensorMediumPulse"; + targetObject = "TeamSensorMediumPulse1"; + targetClientId = "-1"; + targetObjectId = "10406"; + location = "-99.0642 -109.562 137.706"; + weightLevel1 = "3100"; + weightLevel2 = "1000"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "0"; + defense = "1"; + equipment = "RepairPack"; + buyEquipmentSet = "MediumRepairSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + }; + new AIObjective(AIOMortarObject) { + position = "-99.0642 -109.562 137.706"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Mortar the SensorMediumPulse"; + targetObject = "TeamSensorMediumPulse1"; + targetClientId = "-1"; + targetObjectId = "10406"; + location = "-99.0642 -109.562 137.706"; + weightLevel1 = "3400"; + weightLevel2 = "1000"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "1"; + defense = "0"; + equipment = "Mortar MortarAmmo"; + buyEquipmentSet = "HeavyAmmoSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + }; + new AIObjective(AIORepairObject) { + position = "-99.0501 -116.179 128.778"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Repair the StationInventory"; + targetObject = "TeamStationInventory1"; + targetClientId = "-1"; + targetObjectId = "10774"; + location = "-99.0501 -116.179 128.778"; + weightLevel1 = "2900"; + weightLevel2 = "1400"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "0"; + defense = "1"; + equipment = "RepairPack"; + buyEquipmentSet = "MediumRepairSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + }; + new AIObjective(AIOAttackObject) { + position = "-99.0501 -116.179 128.778"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Attack the StationInventory"; + targetObject = "TeamStationInventory1"; + targetClientId = "-1"; + targetObjectId = "10774"; + location = "-99.0501 -116.179 128.778"; + weightLevel1 = "2900"; + weightLevel2 = "1400"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "1"; + defense = "0"; + desiredEquipment = "ShieldPack"; + buyEquipmentSet = "HeavyAmmoSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + }; + new AIObjective(AIORepairObject) { + position = "-99.066 -114.701 135.741"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Repair the SolarPanel"; + targetObject = "TeamSolarPanel1"; + targetClientId = "-1"; + targetObjectId = "9237"; + location = "-99.066 -114.701 135.741"; + weightLevel1 = "3200"; + weightLevel2 = "1600"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "0"; + defense = "1"; + equipment = "RepairPack"; + buyEquipmentSet = "MediumRepairSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + }; + new AIObjective(AIOAttackObject) { + position = "-99.066 -114.701 135.741"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Attack the SolarPanel"; + targetObject = "TeamSolarPanel1"; + targetClientId = "-1"; + targetObjectId = "9237"; + location = "-99.066 -114.701 135.741"; + weightLevel1 = "3100"; + weightLevel2 = "1600"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "1"; + defense = "0"; + desiredEquipment = "ShieldPack"; + buyEquipmentSet = "HeavyAmmoSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + }; + new AIObjective(AIODefendLocation) { + position = "-99.066 -114.701 135.741"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Defend the SolarPanel"; + targetObject = "TeamSolarPanel1"; + targetClientId = "-1"; + targetObjectId = "9237"; + location = "-99.066 -114.701 135.741"; + weightLevel1 = "3100"; + weightLevel2 = "1500"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "0"; + defense = "1"; + desiredEquipment = "ShieldPack Plasma PlasmaAmmo"; + buyEquipmentSet = "HeavyShieldSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + }; + }; + }; + new SimGroup(Team2) { + + powerCount = "0"; + + new SimGroup(spawnspheres) { + + powerCount = "0"; + + new SpawnSphere() { + position = "-415.667 -497.317 128.938"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "SpawnSphereMarker"; + lockCount = "0"; + homingCount = "0"; + radius = "70"; + sphereWeight = "100"; + indoorWeight = "100"; + outdoorWeight = "100"; + + locked = "1"; + }; + new SpawnSphere() { + position = "-293.697 283.488 128.938"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "SpawnSphereMarker"; + lockCount = "0"; + homingCount = "0"; + radius = "50"; + sphereWeight = "100"; + indoorWeight = "100"; + outdoorWeight = "100"; + + locked = "1"; + }; + new SpawnSphere() { + position = "342.868 465.127 131.024"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "SpawnSphereMarker"; + lockCount = "0"; + homingCount = "0"; + radius = "70"; + sphereWeight = "100"; + indoorWeight = "100"; + outdoorWeight = "100"; + + locked = "1"; + }; + new SpawnSphere() { + position = "317.584 -508.799 128.269"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "SpawnSphereMarker"; + lockCount = "0"; + homingCount = "0"; + radius = "70"; + sphereWeight = "100"; + indoorWeight = "100"; + outdoorWeight = "100"; + + locked = "1"; + }; + }; + new SimGroup(AIObjectives) { + + new AIObjective(AIORepairObject) { + position = "-99.0642 -109.562 137.706"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Repair the SensorMediumPulse"; + targetObject = "TeamSensorMediumPulse1"; + targetClientId = "-1"; + targetObjectId = "10406"; + location = "-99.0642 -109.562 137.706"; + weightLevel1 = "3100"; + weightLevel2 = "1000"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "0"; + defense = "1"; + equipment = "RepairPack"; + buyEquipmentSet = "MediumRepairSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + }; + new AIObjective(AIOMortarObject) { + position = "-99.0642 -109.562 137.706"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Mortar the SensorMediumPulse"; + targetObject = "TeamSensorMediumPulse1"; + targetClientId = "-1"; + targetObjectId = "10406"; + location = "-99.0642 -109.562 137.706"; + weightLevel1 = "3400"; + weightLevel2 = "1000"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "1"; + defense = "0"; + equipment = "Mortar MortarAmmo"; + buyEquipmentSet = "HeavyAmmoSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + }; + new AIObjective(AIORepairObject) { + position = "-99.0501 -116.179 128.778"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Repair the StationInventory"; + targetObject = "TeamStationInventory1"; + targetClientId = "-1"; + targetObjectId = "10774"; + location = "-99.0501 -116.179 128.778"; + weightLevel1 = "2900"; + weightLevel2 = "1400"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "0"; + defense = "1"; + equipment = "RepairPack"; + buyEquipmentSet = "MediumRepairSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + }; + new AIObjective(AIOAttackObject) { + position = "-99.0501 -116.179 128.778"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Attack the StationInventory"; + targetObject = "TeamStationInventory1"; + targetClientId = "-1"; + targetObjectId = "10774"; + location = "-99.0501 -116.179 128.778"; + weightLevel1 = "2900"; + weightLevel2 = "1400"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "1"; + defense = "0"; + desiredEquipment = "ShieldPack"; + buyEquipmentSet = "HeavyAmmoSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + }; + new AIObjective(AIORepairObject) { + position = "-99.066 -114.701 135.741"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Repair the SolarPanel"; + targetObject = "TeamSolarPanel1"; + targetClientId = "-1"; + targetObjectId = "9237"; + location = "-99.066 -114.701 135.741"; + weightLevel1 = "3200"; + weightLevel2 = "1600"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "0"; + defense = "1"; + equipment = "RepairPack"; + buyEquipmentSet = "MediumRepairSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + }; + new AIObjective(AIOAttackObject) { + position = "-99.066 -114.701 135.741"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Attack the SolarPanel"; + targetObject = "TeamSolarPanel1"; + targetClientId = "-1"; + targetObjectId = "9237"; + location = "-99.066 -114.701 135.741"; + weightLevel1 = "3100"; + weightLevel2 = "1600"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "1"; + defense = "0"; + desiredEquipment = "ShieldPack"; + buyEquipmentSet = "HeavyAmmoSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + }; + new AIObjective(AIODefendLocation) { + position = "-99.066 -114.701 135.741"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "AIObjectiveMarker"; + lockCount = "0"; + homingCount = "0"; + description = "Defend the SolarPanel"; + targetObject = "TeamSolarPanel1"; + targetClientId = "-1"; + targetObjectId = "9237"; + location = "-99.066 -114.701 135.741"; + weightLevel1 = "3100"; + weightLevel2 = "1500"; + weightLevel3 = "0"; + weightLevel4 = "0"; + offense = "0"; + defense = "1"; + desiredEquipment = "ShieldPack Plasma PlasmaAmmo"; + buyEquipmentSet = "HeavyShieldSet"; + issuedByHuman = "0"; + issuedByClientId = "-1"; + forceClientId = "-1"; + locked = "0"; + }; + }; + }; + new SimGroup(team0) { + + powerCount = "0"; + + new SimGroup(AIObjectives) { + + powerCount = "0"; + }; + }; + }; + new SimGroup(ObserverDropPoints) { + + powerCount = "0"; + + new Camera(Camera01) { + position = "-54.7021 -73.726 158.935"; + rotation = "-0.0963814 -0.242121 0.965447 222.045"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + locked = "1"; + team = "1"; + }; + new Camera(Camera02) { + position = "-98.6944 -131.848 137.766"; + rotation = "0.997549 0.0171719 -0.0678376 28.4771"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + locked = "1"; + team = "1"; + }; + }; + new SimGroup(Miskellany) { + + powerCount = "0"; + + new InteriorInstance() { + position = "293.3 -393.442 128.618"; + rotation = "0 0 1 47.5555"; + scale = "1 1 1"; + interiorFile = "bbunk9.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + new InteriorInstance() { + position = "-741.056 50.94 127.615"; + rotation = "0 0 1 89.9544"; + scale = "1 1 1"; + interiorFile = "bbunkd.dif"; + showTerrainInside = "0"; + + locked = "true"; + }; + }; + new SimGroup(Ambiance) { + + powerCount = "0"; + + new AudioEmitter() { + position = "-87.88 -700.815 191.107"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + fileName = "fx/environment/bird_echo5.wav"; + useProfileDescription = "0"; + outsideAmbient = "1"; + volume = "1"; + isLooping = "1"; + is3D = "1"; + minDistance = "20"; + maxDistance = "1280"; + coneInsideAngle = "360"; + coneOutsideAngle = "360"; + coneOutsideVolume = "1"; + coneVector = "0 0 1"; + loopCount = "-1"; + minLoopGap = "10000"; + maxLoopGap = "40000"; + type = "EffectAudioType"; + + locked = "true"; + }; + new AudioEmitter() { + position = "-168.263 -2.47 139.564"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + fileName = "fx/environment/bird_echo1.wav"; + useProfileDescription = "0"; + outsideAmbient = "1"; + volume = "1"; + isLooping = "1"; + is3D = "1"; + minDistance = "20"; + maxDistance = "1280"; + coneInsideAngle = "360"; + coneOutsideAngle = "360"; + coneOutsideVolume = "1"; + coneVector = "0 0 1"; + loopCount = "-1"; + minLoopGap = "10000"; + maxLoopGap = "40000"; + type = "EffectAudioType"; + + locked = "true"; + }; + new AudioEmitter() { + position = "-573.301 606.13 141.004"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + fileName = "fx/environment/bird_echo3.wav"; + useProfileDescription = "0"; + outsideAmbient = "1"; + volume = "1"; + isLooping = "1"; + is3D = "1"; + minDistance = "20"; + maxDistance = "1280"; + coneInsideAngle = "360"; + coneOutsideAngle = "360"; + coneOutsideVolume = "1"; + coneVector = "0 0 1"; + loopCount = "-1"; + minLoopGap = "10000"; + maxLoopGap = "40000"; + type = "EffectAudioType"; + + locked = "true"; + }; + new AudioEmitter() { + position = "360.77 -363.742 158.176"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + fileName = "fx/environment/bird_echo2.wav"; + useProfileDescription = "0"; + outsideAmbient = "1"; + volume = "1"; + isLooping = "1"; + is3D = "1"; + minDistance = "20"; + maxDistance = "1280"; + coneInsideAngle = "360"; + coneOutsideAngle = "360"; + coneOutsideVolume = "1"; + coneVector = "0 0 1"; + loopCount = "-1"; + minLoopGap = "50000"; + maxLoopGap = "70000"; + type = "EffectAudioType"; + + locked = "true"; + }; + new AudioEmitter() { + position = "-212.09 -229.039 142.75"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + fileName = "fx/environment/bird_echo1.wav"; + useProfileDescription = "0"; + outsideAmbient = "1"; + volume = "1"; + isLooping = "1"; + is3D = "1"; + minDistance = "20"; + maxDistance = "1280"; + coneInsideAngle = "360"; + coneOutsideAngle = "360"; + coneOutsideVolume = "1"; + coneVector = "0 0 1"; + loopCount = "-1"; + minLoopGap = "20000"; + maxLoopGap = "60000"; + type = "EffectAudioType"; + + locked = "true"; + }; + new AudioEmitter() { + position = "-392.039 141.68 152.835"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + fileName = "fx/environment/bird_echo4.wav"; + useProfileDescription = "0"; + outsideAmbient = "1"; + volume = "1"; + isLooping = "1"; + is3D = "1"; + minDistance = "20"; + maxDistance = "1280"; + coneInsideAngle = "360"; + coneOutsideAngle = "360"; + coneOutsideVolume = "1"; + coneVector = "0 0 1"; + loopCount = "-1"; + minLoopGap = "10000"; + maxLoopGap = "30000"; + type = "EffectAudioType"; + + locked = "true"; + }; + new TSStatic() { + position = "405.613 599.739 128.641"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + shapeName = "statue_base.dts"; + + locked = "true"; + }; + new TSStatic() { + position = "405.92 599.28 131.892"; + rotation = "0 0 1 179.909"; + scale = "1 1 1"; + shapeName = "statue_hmale.dts"; + + locked = "true"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/missions/Training.mis b/missions/Training.mis index c935fb9..88d45be 100644 --- a/missions/Training.mis +++ b/missions/Training.mis @@ -1,295 +1,295 @@ -// MissionTypes = SinglePlayer -// DisplayName = Recruit - -//--- MISSION BRIEFING BEGIN --- -//I am Raptor, your trainer.. -//--- MISSION BRIEFING END --- - -// PlanetName = Xeron, 3960 CE -// Bitmap = trn_5draconis - -//--- MISSION STRING BEGIN --- -//OBJECTIVES: -//Bleck -//--- MISSION STRING END --- - -//--- MISSION BLURB BEGIN --- -//In the year 3060 CE, the first Alpha Viper training facility was built. It is now 900 years old on the day of your last training session before the war. -//--- MISSION BLURB END --- - -//--- OBJECT WRITE BEGIN --- -new SimGroup(MissionGroup) { - - cdTrack = "6"; - powerCount = "0"; - musicTrack = "desert"; - - new MissionArea(MissionArea) { - area = "-1024 -1024 2048 2048"; - flightCeiling = "4000"; - flightCeilingRange = "20"; - - locked = "true"; - }; - new SimGroup(Teams) { - - powerCount = "0"; - - new SimGroup(Team1) { - - powerCount = "0"; - - new SimGroup(spawnspheres) { - - powerCount = "0"; - }; - new SimGroup(base0) { - - new InteriorInstance() { - position = "415.795 109.654 111.4"; - rotation = "0 0 1 139.229"; - scale = "1 1 1"; - interiorFile = "dbase_nefRaindance.dif"; - showTerrainInside = "0"; - }; - new StaticShape() { - position = "452.967 135.507 98.3632"; - rotation = "0 0 -1 40.107"; - scale = "1 1 1"; - nameTag = "Main"; - dataBlock = "GeneratorLarge"; - lockCount = "0"; - homingCount = "0"; - - Target = "33"; - }; - new StaticShape() { - position = "441.541 148.661 98.3793"; - rotation = "0 0 1 139.802"; - scale = "1 1 1"; - nameTag = "Main"; - dataBlock = "GeneratorLarge"; - lockCount = "0"; - homingCount = "0"; - - Target = "34"; - }; - new StaticShape() { - position = "453.912 147.716 98.357"; - rotation = "0 0 1 229.183"; - scale = "1 1 1"; - nameTag = "Main"; - dataBlock = "GeneratorLarge"; - lockCount = "0"; - homingCount = "0"; - - Target = "35"; - }; - new StaticShape() { - position = "438.218 134.772 120.525"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - nameTag = "Main"; - dataBlock = "SensorLargePulse"; - lockCount = "0"; - homingCount = "0"; - - Target = "36"; - }; - }; - new SimGroup(dropPoints) { - - new SimGroup(respawns) { - - new Camera(RaptorSpawn) { - position = "428.742 126.147 99.5136"; - rotation = "0 0 1 50.4203"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - - team = "1"; - }; - new Camera(PlayerSpawn) { - position = "432.421 129.211 99.1953"; - rotation = "0 0 1 50.9932"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - - team = "0"; - }; - new Camera(Spawn01) { - position = "434.675 126.105 99.4532"; - rotation = "0 0 1 48.7014"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - - team = "0"; - }; - new Camera(Spawn02) { - position = "430.299 131.876 99.634"; - rotation = "0 0 1 51.5662"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - - team = "0"; - }; - }; - }; - }; - new SimGroup(team0) { - - powerCount = "0"; - }; - new Sun(Sun) { - position = "0 0 0"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - direction = "0.57735 0.57735 -0.57735"; - color = "1.000000 1.000000 1.000000 1.000000"; - ambient = "0.500000 0.500000 0.500000 1.000000"; - texture[0] = "special/sunFlare"; - texture[1] = "special/sunFlare02"; - texture[2] = "special/LensFlare/flare01"; - texture[3] = "special/LensFlare/flare02"; - texture[4] = "special/LensFlare/flare03"; - lensFlareScale = "0.7"; - lensFlareIntensity = "1"; - frontFlareSize = "300"; - backFlareSize = "450"; - flareColor = "1.000000 1.000000 1.000000 1.000000"; - - locked = "true"; - }; - new TerrainBlock(Terrain) { - rotation = "1 0 0 0"; - scale = "1 1 1"; - detailTexture = "details/lavadet1"; - terrainFile = "Training.ter"; - squareSize = "8"; - emptySquares = "217661 217676 86852 152390 87108 152646 218429 218444 232883 233139 364467 299189 364981 299702 234423"; - - position = "-1024 -1024 0"; - }; - new NavigationGraph(NavGraph) { - conjoinAngleDev = "50"; - cullDensity = "0.3"; - customArea = "0 0 0 0"; - - rotation = "0 0 0 0"; - locked = "true"; - scale = "1 1 1"; - coverage = "0"; - conjoinBowlDev = "20"; - GraphFile = "Training.nav"; - position = "0 0 0 1"; - }; - new SimGroup(ObserverDropPoints) { - - powerCount = "0"; - - new Camera() { - position = "0 0 200"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "Observer"; - lockCount = "0"; - homingCount = "0"; - - team = "0"; - locked = "true"; - }; - }; - new Sky(Sky) { - position = "692 -352 0"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - cloudHeightPer[0] = "0.349971"; - cloudHeightPer[1] = "0.25"; - cloudHeightPer[2] = "0.199973"; - cloudSpeed1 = "0.0001"; - cloudSpeed2 = "0.0002"; - cloudSpeed3 = "0.0003"; - visibleDistance = "550"; - useSkyTextures = "1"; - renderBottomTexture = "0"; - SkySolidColor = "0.300000 0.100000 0.000000 0.800000"; - fogDistance = "250"; - fogColor = "0.300000 0.100000 0.000000 0.800000"; - fogVolume1 = "100 0 85"; - fogVolume2 = "600 85 270"; - fogVolume3 = "0 0 0"; - materialList = "sky_lava_starrynight.dml"; - windVelocity = "1 0 0"; - windEffectPrecipitation = "0"; - fogVolumeColor1 = "128.000000 128.000000 128.000000 0.000000"; - fogVolumeColor2 = "128.000000 128.000000 128.000000 0.000000"; - fogVolumeColor3 = "128.000000 128.000000 128.000000 0.000000"; - high_visibleDistance = "-1"; - high_fogDistance = "-1"; - high_fogVolume1 = "-1 5.98911e+07 1.03256e-38"; - high_fogVolume2 = "-1 4.39735e+21 1.1119e-16"; - high_fogVolume3 = "-1 6.71258e+22 1.21749e+22"; - - locked = "true"; - }; - }; - new SimGroup(RandomOrganics) { - - new TSStatic() { - position = "352.297 188.881 160.856"; - rotation = "0 0 1 136.364"; - scale = "1 1 1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "380.548 229.443 175.643"; - rotation = "0 0 -1 1.71778"; - scale = "1 1 1"; - shapeName = "dorg17.dts"; - }; - new TSStatic() { - position = "333.627 257.188 177.605"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "567.086 57.3387 137.477"; - rotation = "0 0 1 141.521"; - scale = "1 1 1"; - shapeName = "dorg16.dts"; - }; - new TSStatic() { - position = "477.072 -72.6936 150.153"; - rotation = "0 0 1 132.353"; - scale = "1 1 1"; - shapeName = "dorg19.dts"; - }; - new TSStatic() { - position = "488.239 8.63118 159.288"; - rotation = "0 0 1 91.1003"; - scale = "1 1 1"; - shapeName = "dorg18.dts"; - }; - new TSStatic() { - position = "558.369 176.842 152.425"; - rotation = "0 0 1 27.502"; - scale = "1 1 1"; - shapeName = "dorg16.dts"; - }; - }; - new SimGroup(environment) { - }; -}; -//--- OBJECT WRITE END --- - -//Execute our mission script. -exec("scripts/Training.cs"); +// MissionTypes = SinglePlayer +// DisplayName = Recruit + +//--- MISSION BRIEFING BEGIN --- +//I am Raptor, your trainer.. +//--- MISSION BRIEFING END --- + +// PlanetName = Xeron, 3960 CE +// Bitmap = trn_5draconis + +//--- MISSION STRING BEGIN --- +//OBJECTIVES: +//Bleck +//--- MISSION STRING END --- + +//--- MISSION BLURB BEGIN --- +//In the year 3060 CE, the first Alpha Viper training facility was built. It is now 900 years old on the day of your last training session before the war. +//--- MISSION BLURB END --- + +//--- OBJECT WRITE BEGIN --- +new SimGroup(MissionGroup) { + + cdTrack = "6"; + powerCount = "0"; + musicTrack = "desert"; + + new MissionArea(MissionArea) { + area = "-1024 -1024 2048 2048"; + flightCeiling = "4000"; + flightCeilingRange = "20"; + + locked = "true"; + }; + new SimGroup(Teams) { + + powerCount = "0"; + + new SimGroup(Team1) { + + powerCount = "0"; + + new SimGroup(spawnspheres) { + + powerCount = "0"; + }; + new SimGroup(base0) { + + new InteriorInstance() { + position = "415.795 109.654 111.4"; + rotation = "0 0 1 139.229"; + scale = "1 1 1"; + interiorFile = "dbase_nefRaindance.dif"; + showTerrainInside = "0"; + }; + new StaticShape() { + position = "452.967 135.507 98.3632"; + rotation = "0 0 -1 40.107"; + scale = "1 1 1"; + nameTag = "Main"; + dataBlock = "GeneratorLarge"; + lockCount = "0"; + homingCount = "0"; + + Target = "33"; + }; + new StaticShape() { + position = "441.541 148.661 98.3793"; + rotation = "0 0 1 139.802"; + scale = "1 1 1"; + nameTag = "Main"; + dataBlock = "GeneratorLarge"; + lockCount = "0"; + homingCount = "0"; + + Target = "34"; + }; + new StaticShape() { + position = "453.912 147.716 98.357"; + rotation = "0 0 1 229.183"; + scale = "1 1 1"; + nameTag = "Main"; + dataBlock = "GeneratorLarge"; + lockCount = "0"; + homingCount = "0"; + + Target = "35"; + }; + new StaticShape() { + position = "438.218 134.772 120.525"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + nameTag = "Main"; + dataBlock = "SensorLargePulse"; + lockCount = "0"; + homingCount = "0"; + + Target = "36"; + }; + }; + new SimGroup(dropPoints) { + + new SimGroup(respawns) { + + new Camera(RaptorSpawn) { + position = "428.742 126.147 99.5136"; + rotation = "0 0 1 50.4203"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + team = "1"; + }; + new Camera(PlayerSpawn) { + position = "432.421 129.211 99.1953"; + rotation = "0 0 1 50.9932"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + team = "0"; + }; + new Camera(Spawn01) { + position = "434.675 126.105 99.4532"; + rotation = "0 0 1 48.7014"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + team = "0"; + }; + new Camera(Spawn02) { + position = "430.299 131.876 99.634"; + rotation = "0 0 1 51.5662"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + team = "0"; + }; + }; + }; + }; + new SimGroup(team0) { + + powerCount = "0"; + }; + new Sun(Sun) { + position = "0 0 0"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + direction = "0.57735 0.57735 -0.57735"; + color = "1.000000 1.000000 1.000000 1.000000"; + ambient = "0.500000 0.500000 0.500000 1.000000"; + texture[0] = "special/sunFlare"; + texture[1] = "special/sunFlare02"; + texture[2] = "special/LensFlare/flare01"; + texture[3] = "special/LensFlare/flare02"; + texture[4] = "special/LensFlare/flare03"; + lensFlareScale = "0.7"; + lensFlareIntensity = "1"; + frontFlareSize = "300"; + backFlareSize = "450"; + flareColor = "1.000000 1.000000 1.000000 1.000000"; + + locked = "true"; + }; + new TerrainBlock(Terrain) { + rotation = "1 0 0 0"; + scale = "1 1 1"; + detailTexture = "details/lavadet1"; + terrainFile = "Training.ter"; + squareSize = "8"; + emptySquares = "217661 217676 86852 152390 87108 152646 218429 218444 232883 233139 364467 299189 364981 299702 234423"; + + position = "-1024 -1024 0"; + }; + new NavigationGraph(NavGraph) { + conjoinAngleDev = "50"; + cullDensity = "0.3"; + customArea = "0 0 0 0"; + + rotation = "0 0 0 0"; + locked = "true"; + scale = "1 1 1"; + coverage = "0"; + conjoinBowlDev = "20"; + GraphFile = "Training.nav"; + position = "0 0 0 1"; + }; + new SimGroup(ObserverDropPoints) { + + powerCount = "0"; + + new Camera() { + position = "0 0 200"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + team = "0"; + locked = "true"; + }; + }; + new Sky(Sky) { + position = "692 -352 0"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + cloudHeightPer[0] = "0.349971"; + cloudHeightPer[1] = "0.25"; + cloudHeightPer[2] = "0.199973"; + cloudSpeed1 = "0.0001"; + cloudSpeed2 = "0.0002"; + cloudSpeed3 = "0.0003"; + visibleDistance = "550"; + useSkyTextures = "1"; + renderBottomTexture = "0"; + SkySolidColor = "0.300000 0.100000 0.000000 0.800000"; + fogDistance = "250"; + fogColor = "0.300000 0.100000 0.000000 0.800000"; + fogVolume1 = "100 0 85"; + fogVolume2 = "600 85 270"; + fogVolume3 = "0 0 0"; + materialList = "sky_lava_starrynight.dml"; + windVelocity = "1 0 0"; + windEffectPrecipitation = "0"; + fogVolumeColor1 = "128.000000 128.000000 128.000000 0.000000"; + fogVolumeColor2 = "128.000000 128.000000 128.000000 0.000000"; + fogVolumeColor3 = "128.000000 128.000000 128.000000 0.000000"; + high_visibleDistance = "-1"; + high_fogDistance = "-1"; + high_fogVolume1 = "-1 5.98911e+07 1.03256e-38"; + high_fogVolume2 = "-1 4.39735e+21 1.1119e-16"; + high_fogVolume3 = "-1 6.71258e+22 1.21749e+22"; + + locked = "true"; + }; + }; + new SimGroup(RandomOrganics) { + + new TSStatic() { + position = "352.297 188.881 160.856"; + rotation = "0 0 1 136.364"; + scale = "1 1 1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "380.548 229.443 175.643"; + rotation = "0 0 -1 1.71778"; + scale = "1 1 1"; + shapeName = "dorg17.dts"; + }; + new TSStatic() { + position = "333.627 257.188 177.605"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "567.086 57.3387 137.477"; + rotation = "0 0 1 141.521"; + scale = "1 1 1"; + shapeName = "dorg16.dts"; + }; + new TSStatic() { + position = "477.072 -72.6936 150.153"; + rotation = "0 0 1 132.353"; + scale = "1 1 1"; + shapeName = "dorg19.dts"; + }; + new TSStatic() { + position = "488.239 8.63118 159.288"; + rotation = "0 0 1 91.1003"; + scale = "1 1 1"; + shapeName = "dorg18.dts"; + }; + new TSStatic() { + position = "558.369 176.842 152.425"; + rotation = "0 0 1 27.502"; + scale = "1 1 1"; + shapeName = "dorg16.dts"; + }; + }; + new SimGroup(environment) { + }; +}; +//--- OBJECT WRITE END --- + +//Execute our mission script. +exec("scripts/Training.cs"); diff --git a/missions/rpg_new.mis b/missions/rpg_new.mis index 72f47a4..279aef4 100644 --- a/missions/rpg_new.mis +++ b/missions/rpg_new.mis @@ -1,624 +1,624 @@ -// DisplayName = T2BOL Testing Map -// MissionTypes = RPG - -//--- MISSION QUOTE BEGIN --- -// Is it so arrogant to think 'we' as Humans are special? -// -- Dark Dragon DX -//--- MISSION QUOTE END --- - -//--- MISSION STRING BEGIN --- -// -// Role play time..? -// -//--- MISSION STRING END --- - -//--- OBJECT WRITE BEGIN --- -new SimGroup(MissionGroup) { - - cdTrack = "2"; - CTF_scoreLimit = "6"; - powerCount = "0"; - musicTrack = "lush"; - CTF_timeLimit = "25"; - - new MissionArea(MissionArea) { - area = "-512 -384 1040 1040"; - flightCeiling = "2000"; - flightCeilingRange = "50"; - - locked = "true"; - }; - new Sun() { - position = "-1216 -848 0"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - direction = "0.57735 0.57735 -0.57735"; - color = "0.600000 0.600000 0.600000 1.000000"; - ambient = "0.200000 0.200000 0.200000 1.000000"; - texture[0] = "special/sunFlare"; - texture[1] = "special/sunFlare02"; - texture[2] = "special/LensFlare/flare01"; - texture[3] = "special/LensFlare/flare02"; - texture[4] = "special/LensFlare/flare03"; - lensFlareScale = "0.7"; - lensFlareIntensity = "1"; - frontFlareSize = "300"; - backFlareSize = "450"; - flareColor = "1.000000 1.000000 1.000000 1.000000"; - - locked = "true"; - }; - new TerrainBlock(Terrain) { - rotation = "1 0 0 0"; - scale = "1 1 1"; - detailTexture = "details/lushdet1"; - terrainFile = "SunDried.ter"; - squareSize = "8"; - - visibleDistance = "1200"; - locked = "true"; - position = "-1024 -1024 0"; - hazeDistance = "250"; - }; - new NavigationGraph(NavGraph) { - conjoinAngleDev = "45"; - cullDensity = "0.3"; - customArea = "0 0 0 0"; - - conjoinBowlDev = "20"; - scale = "1 1 1"; - coverage = "0"; - YDimOverSize = "0"; - locked = "true"; - GraphFile = "rpg_new.nav"; - position = "0 0 0 1"; - XDimOverSize = "0"; - rotation = "0 0 0 0"; - }; - new Sky(Sky) { - position = "-1216 -848 0"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - cloudHeightPer[0] = "0.349971"; - cloudHeightPer[1] = "0.25"; - cloudHeightPer[2] = "0.199973"; - cloudSpeed1 = "0.0001"; - cloudSpeed2 = "0.0002"; - cloudSpeed3 = "0.0003"; - visibleDistance = "520"; - useSkyTextures = "1"; - renderBottomTexture = "0"; - SkySolidColor = "0.390000 0.390000 0.390000 0.000000"; - fogDistance = "220"; - fogColor = "0.500000 0.500000 0.500000 1.000000"; - fogVolume1 = "0 0 0"; - fogVolume2 = "0 0 0"; - fogVolume3 = "0 0 0"; - materialList = "Lush_l4.dml"; - windVelocity = "1 0 0"; - windEffectPrecipitation = "0"; - fogVolumeColor1 = "128.000000 128.000000 128.000000 0.000000"; - fogVolumeColor2 = "128.000000 128.000000 128.000000 -198748244414614883000000000000000000000.000000"; - fogVolumeColor3 = "128.000000 128.000000 128.000000 -222768174765569861000000000000000000000.000000"; - high_visibleDistance = "-1"; - high_fogDistance = "-1"; - high_fogVolume1 = "-1 6.30562e+30 3.20554e-19"; - high_fogVolume2 = "-1 -4.21969e-13 -8.95185e-12"; - high_fogVolume3 = "-1 1648.2 5.54621e+30"; - - locked = "true"; - cloudSpeed0 = "0.000000 0.000000"; - }; - new SimGroup(Teams) { - - powerCount = "0"; - - new SimGroup(team0) { - - powerCount = "0"; - - new SimGroup(base0) { - - - new InteriorInstance() { - position = "-8.70542 359.879 91.1271"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "bbunk1.dif"; - showTerrainInside = "0"; - }; - new Waypoint() { - datablock = WaypointMarker; - position = "-8.74728 352.561 85.4501"; - name = "Store"; - team = "0"; - }; - new Trigger() { - position = "-14.5232 364.273 85.0062"; - rotation = "1 0 0 0"; - scale = "12.5884 23.0483 10.7122"; - dataBlock = "gameTrigger"; - lockCount = "0"; - homingCount = "0"; - polyhedron = "0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 -0.0000000 -1.0000000 -0.0000000 -0.0000000 -0.0000000 1.0000000"; - - type = "store"; - }; - - - new InteriorInstance() { - position = "-113.234 290.899 90.3057"; - rotation = "0 0 1 68.7549"; - scale = "1 1 1"; - interiorFile = "bbunk1.dif"; - showTerrainInside = "0"; - }; - new Waypoint() { - datablock = WaypointMarker; - position = "-120.237 288.166 84.7063"; - name = "Bot Factory"; - team = "0"; - }; - new Trigger() { - position = "-126.606 294.343 84.1904"; - rotation = "1 0 0 0"; - scale = "14.2074 14.4932 4.60823"; - dataBlock = "gameTrigger"; - lockCount = "0"; - homingCount = "0"; - polyhedron = "0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 -0.0000000 -1.0000000 -0.0000000 -0.0000000 -0.0000000 1.0000000"; - - type = "Bstore"; - }; - - new InteriorInstance() { - position = "97.1223 287.612 90.5094"; - rotation = "0 0 1 115.165"; - scale = "1 1 1"; - interiorFile = "bbunk1.dif"; - showTerrainInside = "0"; - }; - new Waypoint() { - datablock = WaypointMarker; - position = "90.3171 290.812 84.9062"; - name = "Pet Store"; - team = "0"; - }; - new Trigger() { - position = "81.7358 295.153 84.6062"; - rotation = "1 0 0 0"; - scale = "13.6906 8.92087 4.52381"; - dataBlock = "gameTrigger"; - lockCount = "0"; - homingCount = "0"; - polyhedron = "0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 -0.0000000 -1.0000000 -0.0000000 -0.0000000 -0.0000000 1.0000000"; - - type = "Pstore"; - }; - - new InteriorInstance(TutInterior) { - position = "-95.3852 355.658 -723.294"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - interiorFile = "pbase_nef_vbase1.dif"; - showTerrainInside = "0"; - }; - }; - }; - new SimGroup(Team1) { - - new SimGroup(spawnspheres) { - - new SpawnSphere() { - position = "-108.401 -780.456 101.312"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "SpawnSphereMarker"; - lockCount = "0"; - homingCount = "0"; - radius = "100"; - sphereWeight = "100"; - indoorWeight = "100"; - outdoorWeight = "100"; - }; - }; - new SimGroup(Base0) { - new Trigger() { - position = "-82.2349 -729.56 83.4062"; - rotation = "0 0 1 89.9544"; - scale = "110.919 61.0573 88.2534"; - dataBlock = "GameTrigger"; - type = "Human"; - }; - new InteriorInstance() { - position = "-105.033 -797.673 100.182"; - rotation = "0 0 1 193.66"; - scale = "1 1 1"; - interiorFile = "xbunk9.dif"; - showTerrainInside = "0"; - }; - new StaticShape() { - position = "-108.019 -809.726 102.081"; - rotation = "0 0 1 13.751"; - scale = "1 1 1"; - nameTag = "Main"; - dataBlock = "GeneratorLarge"; - lockCount = "0"; - homingCount = "0"; - - Target = "33"; - }; - new StaticShape() { - position = "-104.17 -812.317 102.209"; - rotation = "0 0 1 167.303"; - scale = "1 1 1"; - nameTag = "Main"; - dataBlock = "StationInventory"; - lockCount = "0"; - homingCount = "0"; - - Target = "34"; - Trigger = "9576"; - }; - new StaticShape() { - position = "-112.385 -809.973 102.178"; - rotation = "0 0 1 214.286"; - scale = "1 1 1"; - nameTag = "Main"; - dataBlock = "StationInventory"; - lockCount = "0"; - homingCount = "0"; - - Target = "35"; - Trigger = "9724"; - }; - new Turret() { - position = "-106.25 -802.944 108.275"; - rotation = "0 0 1 14.897"; - scale = "1 1 1"; - nameTag = "Main"; - dataBlock = "SentryTurret"; - lockCount = "0"; - homingCount = "0"; - initialBarrel = "SentryTurretBarrel"; - - Target = "36"; - }; - new Turret() { - position = "-105.637 -798.913 109.928"; - rotation = "0 0 1 16.0428"; - scale = "1 1 1"; - nameTag = "Main"; - dataBlock = "TurretBaseLarge"; - lockCount = "0"; - homingCount = "0"; - - Target = "37"; - }; - new StaticShape() { - position = "-101.88 -750.822 99.0965"; - rotation = "0 0 1 182.201"; - scale = "1 1 1"; - nameTag = "Main"; - dataBlock = "StationVehiclePad"; - lockCount = "0"; - homingCount = "0"; - - Target = "38"; - Ready = "1"; - station = "10533"; - }; - new StaticShape() { - position = "-90.657 -768.113 102.36"; - rotation = "0 0 1 90.5273"; - scale = "1 1 1"; - nameTag = "Main"; - dataBlock = "StationInventory"; - lockCount = "0"; - homingCount = "0"; - - Target = "39"; - Trigger = "10756"; - }; - }; - }; - new SimGroup(Team2) { - - new SimGroup(Base0) { - - new StaticShape() { - position = "331.804 93.0886 102.138"; - rotation = "0 0 1 90.5273"; - scale = "1 1 1"; - nameTag = "\x01763"; - dataBlock = "StationInventory"; - lockCount = "0"; - homingCount = "0"; - - Target = "40"; - Trigger = "10923"; - }; - new StaticShape() { - position = "320.581 110.38 98.8746"; - rotation = "0 0 1 182.201"; - scale = "1 1 1"; - nameTag = "\x01763"; - dataBlock = "StationVehiclePad"; - lockCount = "0"; - homingCount = "0"; - - Target = "41"; - Ready = "1"; - station = "10949"; - }; - new Turret() { - position = "316.824 62.2885 109.706"; - rotation = "0 0 1 16.0428"; - scale = "1 1 1"; - nameTag = "\x01763"; - dataBlock = "TurretBaseLarge"; - lockCount = "0"; - homingCount = "0"; - - Target = "42"; - }; - new Trigger() { - position = "349.812 132.225 83.4062"; - rotation = "0 0 1 89.9544"; - scale = "110.919 61.0573 88.2534"; - dataBlock = "GameTrigger"; - type = "Bioderm"; - }; - new Turret() { - position = "316.211 58.2576 108.053"; - rotation = "0 0 1 14.897"; - scale = "1 1 1"; - nameTag = "\x01763"; - dataBlock = "SentryTurret"; - lockCount = "0"; - homingCount = "0"; - initialBarrel = "SentryTurretBarrel"; - - Target = "43"; - }; - new StaticShape() { - position = "310.076 51.2285 101.956"; - rotation = "0 0 1 214.286"; - scale = "1 1 1"; - nameTag = "\x01763"; - dataBlock = "StationInventory"; - lockCount = "0"; - homingCount = "0"; - - Target = "44"; - Trigger = "10928"; - }; - new StaticShape() { - position = "318.291 48.8845 101.987"; - rotation = "0 0 1 167.303"; - scale = "1 1 1"; - nameTag = "\x01763"; - dataBlock = "StationInventory"; - lockCount = "0"; - homingCount = "0"; - - Target = "45"; - Trigger = "10930"; - }; - new StaticShape() { - position = "314.442 51.4755 101.859"; - rotation = "0 0 1 13.751"; - scale = "1 1 1"; - nameTag = "\x01763"; - dataBlock = "GeneratorLarge"; - lockCount = "0"; - homingCount = "0"; - - Target = "46"; - }; - new InteriorInstance() { - position = "317.428 63.5286 99.9602"; - rotation = "0 0 1 193.66"; - scale = "1 1 1"; - interiorFile = "xbunk9.dif"; - showTerrainInside = "0"; - }; - }; - new SimGroup(spawnspheres) { - - new SpawnSphere() { - position = "301.797 84.2394 110.21"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "SpawnSphereMarker"; - lockCount = "0"; - homingCount = "0"; - radius = "100"; - sphereWeight = "100"; - indoorWeight = "100"; - outdoorWeight = "100"; - }; - }; - }; - new SimGroup(Team3) { - - new SimGroup(Base0) { - - new Item() { - position = "-85.4834 641.251 83.9062"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "MiningTool"; - lockCount = "0"; - homingCount = "0"; - collideable = "0"; - static = "1"; - rotate = "0"; - Target = "-1"; - team = "0"; - locked = "true"; - }; - - new WayPoint() { - position = "-85.5611 641.271 84.0561"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "WayPointMarker"; - lockCount = "0"; - homingCount = "0"; - name = "Free Mining Tool"; - team = "3"; - locked = "true"; - }; - - - new StaticShape() { - position = "-66.4225 643.133 83.5218"; - rotation = "1 0 0 0"; - scale = "0.711179 1.02006 5.10966"; - dataBlock = "MiningBox"; - lockCount = "0"; - homingCount = "0"; - mineral = "Steel"; - }; - - new InteriorInstance(InteriorInstance) { - position = "-61.4344 642.47 84.0561"; - rotation = "0 1 0 88.2355"; - scale = "0.1 0.1 0.23867"; - interiorFile = "prockc.dif"; - showTerrainInside = "0"; - }; - - new StaticShape() { - position = "-184.724 660.839 85.3082"; - rotation = "-0 0 -1 16.7983"; - scale = "1 1 1"; - nameTag = "\x01763"; - dataBlock = "StationInventory"; - lockCount = "0"; - homingCount = "0"; - - Target = "47"; - Trigger = "11067"; - }; - new StaticShape() { - position = "-197.888 644.976 82.0447"; - rotation = "0 0 1 74.8754"; - scale = "1 1 1"; - nameTag = "\x01763"; - dataBlock = "StationVehiclePad"; - lockCount = "0"; - homingCount = "0"; - - Target = "48"; - Ready = "1"; - station = "11096"; - }; - new Turret() { - position = "-150.86 655.711 92.8762"; - rotation = "0 0 -1 91.2828"; - scale = "1 1 1"; - nameTag = "\x01763"; - dataBlock = "TurretBaseLarge"; - lockCount = "0"; - homingCount = "0"; - - Target = "49"; - }; - new Turret() { - position = "-146.829 656.326 91.2232"; - rotation = "0 0 -1 92.4286"; - scale = "1 1 1"; - nameTag = "\x01763"; - dataBlock = "SentryTurret"; - lockCount = "0"; - homingCount = "0"; - initialBarrel = "SentryTurretBarrel"; - - Target = "50"; - }; - new StaticShape() { - position = "-138.292 652.563 85.1262"; - rotation = "0 0 1 106.96"; - scale = "1 1 1"; - nameTag = "\x01763"; - dataBlock = "StationInventory"; - lockCount = "0"; - homingCount = "0"; - - Target = "51"; - Trigger = "11072"; - }; - new StaticShape() { - position = "-138.501 661.103 85.1572"; - rotation = "0 0 1 59.9774"; - scale = "1 1 1"; - nameTag = "\x01763"; - dataBlock = "StationInventory"; - lockCount = "0"; - homingCount = "0"; - - Target = "52"; - Trigger = "11074"; - }; - new Trigger() { - position = "-235.766 663.964 83.4062"; - rotation = "0 0 -1 12.0321"; - scale = "110.919 61.0573 88.2534"; - dataBlock = "GameTrigger"; - type = "Draakan"; - }; - new StaticShape() { - position = "-139.828 656.657 85.0292"; - rotation = "0 0 -1 93.5746"; - scale = "1 1 1"; - nameTag = "\x01763"; - dataBlock = "GeneratorLarge"; - lockCount = "0"; - homingCount = "0"; - - Target = "53"; - }; - new InteriorInstance() { - position = "-152.224 655.918 83.1302"; - rotation = "0 0 1 86.3344"; - scale = "1 1 1"; - interiorFile = "xbunk9.dif"; - showTerrainInside = "0"; - }; - }; - new SimGroup(spawnspheres) { - - new SpawnSphere() { - position = "-168.559 631.825 89.4416"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "SpawnSphereMarker"; - lockCount = "0"; - homingCount = "0"; - radius = "100"; - sphereWeight = "100"; - indoorWeight = "100"; - outdoorWeight = "100"; - }; - }; - }; - }; - new SimGroup(Ambiance) { - - powerCount = "0"; - }; - new SimGroup(RandomOrganics) { - - powerCount = "0"; - }; - new SimGroup(ObserverDropPoints) { - - powerCount = "0"; - }; -}; -//--- OBJECT WRITE END --- - -//Define AI spawns -DefineGenericAISpawn("Clerk","Bioderm",0,"Male","Derm3",1,"Horde","Light","-8.73565 352.353 85.4186 0 0 1 3.11681",0); +// DisplayName = T2BOL Testing Map +// MissionTypes = RPG + +//--- MISSION QUOTE BEGIN --- +// Is it so arrogant to think 'we' as Humans are special? +// -- Dark Dragon DX +//--- MISSION QUOTE END --- + +//--- MISSION STRING BEGIN --- +// +// Role play time..? +// +//--- MISSION STRING END --- + +//--- OBJECT WRITE BEGIN --- +new SimGroup(MissionGroup) { + + cdTrack = "2"; + CTF_scoreLimit = "6"; + powerCount = "0"; + musicTrack = "lush"; + CTF_timeLimit = "25"; + + new MissionArea(MissionArea) { + area = "-512 -384 1040 1040"; + flightCeiling = "2000"; + flightCeilingRange = "50"; + + locked = "true"; + }; + new Sun() { + position = "-1216 -848 0"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + direction = "0.57735 0.57735 -0.57735"; + color = "0.600000 0.600000 0.600000 1.000000"; + ambient = "0.200000 0.200000 0.200000 1.000000"; + texture[0] = "special/sunFlare"; + texture[1] = "special/sunFlare02"; + texture[2] = "special/LensFlare/flare01"; + texture[3] = "special/LensFlare/flare02"; + texture[4] = "special/LensFlare/flare03"; + lensFlareScale = "0.7"; + lensFlareIntensity = "1"; + frontFlareSize = "300"; + backFlareSize = "450"; + flareColor = "1.000000 1.000000 1.000000 1.000000"; + + locked = "true"; + }; + new TerrainBlock(Terrain) { + rotation = "1 0 0 0"; + scale = "1 1 1"; + detailTexture = "details/lushdet1"; + terrainFile = "SunDried.ter"; + squareSize = "8"; + + visibleDistance = "1200"; + locked = "true"; + position = "-1024 -1024 0"; + hazeDistance = "250"; + }; + new NavigationGraph(NavGraph) { + conjoinAngleDev = "45"; + cullDensity = "0.3"; + customArea = "0 0 0 0"; + + conjoinBowlDev = "20"; + scale = "1 1 1"; + coverage = "0"; + YDimOverSize = "0"; + locked = "true"; + GraphFile = "rpg_new.nav"; + position = "0 0 0 1"; + XDimOverSize = "0"; + rotation = "0 0 0 0"; + }; + new Sky(Sky) { + position = "-1216 -848 0"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + cloudHeightPer[0] = "0.349971"; + cloudHeightPer[1] = "0.25"; + cloudHeightPer[2] = "0.199973"; + cloudSpeed1 = "0.0001"; + cloudSpeed2 = "0.0002"; + cloudSpeed3 = "0.0003"; + visibleDistance = "520"; + useSkyTextures = "1"; + renderBottomTexture = "0"; + SkySolidColor = "0.390000 0.390000 0.390000 0.000000"; + fogDistance = "220"; + fogColor = "0.500000 0.500000 0.500000 1.000000"; + fogVolume1 = "0 0 0"; + fogVolume2 = "0 0 0"; + fogVolume3 = "0 0 0"; + materialList = "Lush_l4.dml"; + windVelocity = "1 0 0"; + windEffectPrecipitation = "0"; + fogVolumeColor1 = "128.000000 128.000000 128.000000 0.000000"; + fogVolumeColor2 = "128.000000 128.000000 128.000000 -198748244414614883000000000000000000000.000000"; + fogVolumeColor3 = "128.000000 128.000000 128.000000 -222768174765569861000000000000000000000.000000"; + high_visibleDistance = "-1"; + high_fogDistance = "-1"; + high_fogVolume1 = "-1 6.30562e+30 3.20554e-19"; + high_fogVolume2 = "-1 -4.21969e-13 -8.95185e-12"; + high_fogVolume3 = "-1 1648.2 5.54621e+30"; + + locked = "true"; + cloudSpeed0 = "0.000000 0.000000"; + }; + new SimGroup(Teams) { + + powerCount = "0"; + + new SimGroup(team0) { + + powerCount = "0"; + + new SimGroup(base0) { + + + new InteriorInstance() { + position = "-8.70542 359.879 91.1271"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "bbunk1.dif"; + showTerrainInside = "0"; + }; + new Waypoint() { + datablock = WaypointMarker; + position = "-8.74728 352.561 85.4501"; + name = "Store"; + team = "0"; + }; + new Trigger() { + position = "-14.5232 364.273 85.0062"; + rotation = "1 0 0 0"; + scale = "12.5884 23.0483 10.7122"; + dataBlock = "gameTrigger"; + lockCount = "0"; + homingCount = "0"; + polyhedron = "0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 -0.0000000 -1.0000000 -0.0000000 -0.0000000 -0.0000000 1.0000000"; + + type = "store"; + }; + + + new InteriorInstance() { + position = "-113.234 290.899 90.3057"; + rotation = "0 0 1 68.7549"; + scale = "1 1 1"; + interiorFile = "bbunk1.dif"; + showTerrainInside = "0"; + }; + new Waypoint() { + datablock = WaypointMarker; + position = "-120.237 288.166 84.7063"; + name = "Bot Factory"; + team = "0"; + }; + new Trigger() { + position = "-126.606 294.343 84.1904"; + rotation = "1 0 0 0"; + scale = "14.2074 14.4932 4.60823"; + dataBlock = "gameTrigger"; + lockCount = "0"; + homingCount = "0"; + polyhedron = "0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 -0.0000000 -1.0000000 -0.0000000 -0.0000000 -0.0000000 1.0000000"; + + type = "Bstore"; + }; + + new InteriorInstance() { + position = "97.1223 287.612 90.5094"; + rotation = "0 0 1 115.165"; + scale = "1 1 1"; + interiorFile = "bbunk1.dif"; + showTerrainInside = "0"; + }; + new Waypoint() { + datablock = WaypointMarker; + position = "90.3171 290.812 84.9062"; + name = "Pet Store"; + team = "0"; + }; + new Trigger() { + position = "81.7358 295.153 84.6062"; + rotation = "1 0 0 0"; + scale = "13.6906 8.92087 4.52381"; + dataBlock = "gameTrigger"; + lockCount = "0"; + homingCount = "0"; + polyhedron = "0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 -0.0000000 -1.0000000 -0.0000000 -0.0000000 -0.0000000 1.0000000"; + + type = "Pstore"; + }; + + new InteriorInstance(TutInterior) { + position = "-95.3852 355.658 -723.294"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "pbase_nef_vbase1.dif"; + showTerrainInside = "0"; + }; + }; + }; + new SimGroup(Team1) { + + new SimGroup(spawnspheres) { + + new SpawnSphere() { + position = "-108.401 -780.456 101.312"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "SpawnSphereMarker"; + lockCount = "0"; + homingCount = "0"; + radius = "100"; + sphereWeight = "100"; + indoorWeight = "100"; + outdoorWeight = "100"; + }; + }; + new SimGroup(Base0) { + new Trigger() { + position = "-82.2349 -729.56 83.4062"; + rotation = "0 0 1 89.9544"; + scale = "110.919 61.0573 88.2534"; + dataBlock = "GameTrigger"; + type = "Human"; + }; + new InteriorInstance() { + position = "-105.033 -797.673 100.182"; + rotation = "0 0 1 193.66"; + scale = "1 1 1"; + interiorFile = "xbunk9.dif"; + showTerrainInside = "0"; + }; + new StaticShape() { + position = "-108.019 -809.726 102.081"; + rotation = "0 0 1 13.751"; + scale = "1 1 1"; + nameTag = "Main"; + dataBlock = "GeneratorLarge"; + lockCount = "0"; + homingCount = "0"; + + Target = "33"; + }; + new StaticShape() { + position = "-104.17 -812.317 102.209"; + rotation = "0 0 1 167.303"; + scale = "1 1 1"; + nameTag = "Main"; + dataBlock = "StationInventory"; + lockCount = "0"; + homingCount = "0"; + + Target = "34"; + Trigger = "9576"; + }; + new StaticShape() { + position = "-112.385 -809.973 102.178"; + rotation = "0 0 1 214.286"; + scale = "1 1 1"; + nameTag = "Main"; + dataBlock = "StationInventory"; + lockCount = "0"; + homingCount = "0"; + + Target = "35"; + Trigger = "9724"; + }; + new Turret() { + position = "-106.25 -802.944 108.275"; + rotation = "0 0 1 14.897"; + scale = "1 1 1"; + nameTag = "Main"; + dataBlock = "SentryTurret"; + lockCount = "0"; + homingCount = "0"; + initialBarrel = "SentryTurretBarrel"; + + Target = "36"; + }; + new Turret() { + position = "-105.637 -798.913 109.928"; + rotation = "0 0 1 16.0428"; + scale = "1 1 1"; + nameTag = "Main"; + dataBlock = "TurretBaseLarge"; + lockCount = "0"; + homingCount = "0"; + + Target = "37"; + }; + new StaticShape() { + position = "-101.88 -750.822 99.0965"; + rotation = "0 0 1 182.201"; + scale = "1 1 1"; + nameTag = "Main"; + dataBlock = "StationVehiclePad"; + lockCount = "0"; + homingCount = "0"; + + Target = "38"; + Ready = "1"; + station = "10533"; + }; + new StaticShape() { + position = "-90.657 -768.113 102.36"; + rotation = "0 0 1 90.5273"; + scale = "1 1 1"; + nameTag = "Main"; + dataBlock = "StationInventory"; + lockCount = "0"; + homingCount = "0"; + + Target = "39"; + Trigger = "10756"; + }; + }; + }; + new SimGroup(Team2) { + + new SimGroup(Base0) { + + new StaticShape() { + position = "331.804 93.0886 102.138"; + rotation = "0 0 1 90.5273"; + scale = "1 1 1"; + nameTag = "\x01763"; + dataBlock = "StationInventory"; + lockCount = "0"; + homingCount = "0"; + + Target = "40"; + Trigger = "10923"; + }; + new StaticShape() { + position = "320.581 110.38 98.8746"; + rotation = "0 0 1 182.201"; + scale = "1 1 1"; + nameTag = "\x01763"; + dataBlock = "StationVehiclePad"; + lockCount = "0"; + homingCount = "0"; + + Target = "41"; + Ready = "1"; + station = "10949"; + }; + new Turret() { + position = "316.824 62.2885 109.706"; + rotation = "0 0 1 16.0428"; + scale = "1 1 1"; + nameTag = "\x01763"; + dataBlock = "TurretBaseLarge"; + lockCount = "0"; + homingCount = "0"; + + Target = "42"; + }; + new Trigger() { + position = "349.812 132.225 83.4062"; + rotation = "0 0 1 89.9544"; + scale = "110.919 61.0573 88.2534"; + dataBlock = "GameTrigger"; + type = "Bioderm"; + }; + new Turret() { + position = "316.211 58.2576 108.053"; + rotation = "0 0 1 14.897"; + scale = "1 1 1"; + nameTag = "\x01763"; + dataBlock = "SentryTurret"; + lockCount = "0"; + homingCount = "0"; + initialBarrel = "SentryTurretBarrel"; + + Target = "43"; + }; + new StaticShape() { + position = "310.076 51.2285 101.956"; + rotation = "0 0 1 214.286"; + scale = "1 1 1"; + nameTag = "\x01763"; + dataBlock = "StationInventory"; + lockCount = "0"; + homingCount = "0"; + + Target = "44"; + Trigger = "10928"; + }; + new StaticShape() { + position = "318.291 48.8845 101.987"; + rotation = "0 0 1 167.303"; + scale = "1 1 1"; + nameTag = "\x01763"; + dataBlock = "StationInventory"; + lockCount = "0"; + homingCount = "0"; + + Target = "45"; + Trigger = "10930"; + }; + new StaticShape() { + position = "314.442 51.4755 101.859"; + rotation = "0 0 1 13.751"; + scale = "1 1 1"; + nameTag = "\x01763"; + dataBlock = "GeneratorLarge"; + lockCount = "0"; + homingCount = "0"; + + Target = "46"; + }; + new InteriorInstance() { + position = "317.428 63.5286 99.9602"; + rotation = "0 0 1 193.66"; + scale = "1 1 1"; + interiorFile = "xbunk9.dif"; + showTerrainInside = "0"; + }; + }; + new SimGroup(spawnspheres) { + + new SpawnSphere() { + position = "301.797 84.2394 110.21"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "SpawnSphereMarker"; + lockCount = "0"; + homingCount = "0"; + radius = "100"; + sphereWeight = "100"; + indoorWeight = "100"; + outdoorWeight = "100"; + }; + }; + }; + new SimGroup(Team3) { + + new SimGroup(Base0) { + + new Item() { + position = "-85.4834 641.251 83.9062"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "MiningTool"; + lockCount = "0"; + homingCount = "0"; + collideable = "0"; + static = "1"; + rotate = "0"; + Target = "-1"; + team = "0"; + locked = "true"; + }; + + new WayPoint() { + position = "-85.5611 641.271 84.0561"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "WayPointMarker"; + lockCount = "0"; + homingCount = "0"; + name = "Free Mining Tool"; + team = "3"; + locked = "true"; + }; + + + new StaticShape() { + position = "-66.4225 643.133 83.5218"; + rotation = "1 0 0 0"; + scale = "0.711179 1.02006 5.10966"; + dataBlock = "MiningBox"; + lockCount = "0"; + homingCount = "0"; + mineral = "Steel"; + }; + + new InteriorInstance(InteriorInstance) { + position = "-61.4344 642.47 84.0561"; + rotation = "0 1 0 88.2355"; + scale = "0.1 0.1 0.23867"; + interiorFile = "prockc.dif"; + showTerrainInside = "0"; + }; + + new StaticShape() { + position = "-184.724 660.839 85.3082"; + rotation = "-0 0 -1 16.7983"; + scale = "1 1 1"; + nameTag = "\x01763"; + dataBlock = "StationInventory"; + lockCount = "0"; + homingCount = "0"; + + Target = "47"; + Trigger = "11067"; + }; + new StaticShape() { + position = "-197.888 644.976 82.0447"; + rotation = "0 0 1 74.8754"; + scale = "1 1 1"; + nameTag = "\x01763"; + dataBlock = "StationVehiclePad"; + lockCount = "0"; + homingCount = "0"; + + Target = "48"; + Ready = "1"; + station = "11096"; + }; + new Turret() { + position = "-150.86 655.711 92.8762"; + rotation = "0 0 -1 91.2828"; + scale = "1 1 1"; + nameTag = "\x01763"; + dataBlock = "TurretBaseLarge"; + lockCount = "0"; + homingCount = "0"; + + Target = "49"; + }; + new Turret() { + position = "-146.829 656.326 91.2232"; + rotation = "0 0 -1 92.4286"; + scale = "1 1 1"; + nameTag = "\x01763"; + dataBlock = "SentryTurret"; + lockCount = "0"; + homingCount = "0"; + initialBarrel = "SentryTurretBarrel"; + + Target = "50"; + }; + new StaticShape() { + position = "-138.292 652.563 85.1262"; + rotation = "0 0 1 106.96"; + scale = "1 1 1"; + nameTag = "\x01763"; + dataBlock = "StationInventory"; + lockCount = "0"; + homingCount = "0"; + + Target = "51"; + Trigger = "11072"; + }; + new StaticShape() { + position = "-138.501 661.103 85.1572"; + rotation = "0 0 1 59.9774"; + scale = "1 1 1"; + nameTag = "\x01763"; + dataBlock = "StationInventory"; + lockCount = "0"; + homingCount = "0"; + + Target = "52"; + Trigger = "11074"; + }; + new Trigger() { + position = "-235.766 663.964 83.4062"; + rotation = "0 0 -1 12.0321"; + scale = "110.919 61.0573 88.2534"; + dataBlock = "GameTrigger"; + type = "Draakan"; + }; + new StaticShape() { + position = "-139.828 656.657 85.0292"; + rotation = "0 0 -1 93.5746"; + scale = "1 1 1"; + nameTag = "\x01763"; + dataBlock = "GeneratorLarge"; + lockCount = "0"; + homingCount = "0"; + + Target = "53"; + }; + new InteriorInstance() { + position = "-152.224 655.918 83.1302"; + rotation = "0 0 1 86.3344"; + scale = "1 1 1"; + interiorFile = "xbunk9.dif"; + showTerrainInside = "0"; + }; + }; + new SimGroup(spawnspheres) { + + new SpawnSphere() { + position = "-168.559 631.825 89.4416"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "SpawnSphereMarker"; + lockCount = "0"; + homingCount = "0"; + radius = "100"; + sphereWeight = "100"; + indoorWeight = "100"; + outdoorWeight = "100"; + }; + }; + }; + }; + new SimGroup(Ambiance) { + + powerCount = "0"; + }; + new SimGroup(RandomOrganics) { + + powerCount = "0"; + }; + new SimGroup(ObserverDropPoints) { + + powerCount = "0"; + }; +}; +//--- OBJECT WRITE END --- + +//Define AI spawns +DefineGenericAISpawn("Clerk","Bioderm",0,"Male","Derm3",1,"Horde","Light","-8.73565 352.353 85.4186 0 0 1 3.11681",0); diff --git a/prefs/Bot Profiles.conf b/prefs/Bot Profiles.conf new file mode 100644 index 0000000..46bf10b --- /dev/null +++ b/prefs/Bot Profiles.conf @@ -0,0 +1,42 @@ +-- Human +[Bot] +Name = Commander Jackson; +Skill = 0.95; +Offense = true; +voicePitch = 0.90; +Race = Human; +Skin = Beagle; +Voice = Male4; +Sex = Male; + +[Bot] +Name = Cynthia Fisher; +Skill = 0.92; +Offense = false; +voicePitch = 0.94; +Race = Human; +Skin = SWolf; +Voice = Fem3; +Sex = Female; + +-- Draakan +[Bot] +Name = Nyoka; +Skill = 1; +Offense = true; +voicePitch = 0.98; +Race = Draakan; +Skin = Gecko; +Voice = Derm2; +Sex = Female; + +[Bot] +Name = Kiaro; +Skill = 99; +Offense = true; +voicePitch = 0.98; +Race = Draakan; +Skin = Gecko; +Voice = Derm2; +Sex = Male; + diff --git a/prefs/WebServer.conf b/prefs/WebServer.conf new file mode 100644 index 0000000..460b891 --- /dev/null +++ b/prefs/WebServer.conf @@ -0,0 +1,14 @@ + +[Generic] +Enabled=true; +Host=0.0.0.0; +Root= ; +Port=27000; +StartWorkers=32; + +[StatusCodes] +404=none; +403=none; + +[MINE] +Test=none; \ No newline at end of file diff --git a/scripts/CTFGame.cs b/scripts/CTFGame.cs index 74aa056..48d1c02 100644 --- a/scripts/CTFGame.cs +++ b/scripts/CTFGame.cs @@ -1,2096 +1,2096 @@ -// DisplayName = Capture the Flag - -//--- GAME RULES BEGIN --- -//Prevent enemy from capturing your flag -//Score one point for grabbing the enemy's flag -//To capture, your flag must be at its stand -//Score 100 points each time enemy flag is captured -//--- GAME RULES END --- - -$InvBanList[CTF, "MiningTool"] = 1; - -//exec the AI scripts -exec("scripts/aiCTF.cs"); - -//-- tracking --- -function CTFGame::initGameVars(%game) -{ - // --------------------------------------------------- - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - %game.SCORE_PER_SUICIDE = 0; // z0dd - ZOD, 8/19/02. No penalty for suicide! Was -10 - %game.SCORE_PER_TEAMKILL = -10; - %game.SCORE_PER_DEATH = 0; - %game.SCORE_PER_TK_DESTROY = -10; // z0dd - ZOD, 10/03/02. Penalty for TKing equiptment. - - %game.SCORE_PER_KILL = 10; - %game.SCORE_PER_PLYR_FLAG_CAP = 30; - %game.SCORE_PER_PLYR_FLAG_TOUCH = 20; - %game.SCORE_PER_TEAM_FLAG_CAP = 100; - %game.SCORE_PER_TEAM_FLAG_TOUCH = 1; - %game.SCORE_PER_ESCORT_ASSIST = 5; - %game.SCORE_PER_HEADSHOT = 1; - %game.SCORE_PER_REARSHOT = 1; // z0dd - ZOD, 8/25/02. Added Lance rear shot messages - - %game.SCORE_PER_TURRET_KILL = 10; // controlled - %game.SCORE_PER_TURRET_KILL_AUTO = 3; // uncontrolled - %game.SCORE_PER_FLAG_DEFEND = 5; - %game.SCORE_PER_CARRIER_KILL = 5; - %game.SCORE_PER_FLAG_RETURN = 10; - %game.SCORE_PER_STALEMATE_RETURN = 15; - %game.SCORE_PER_GEN_DEFEND = 5; - - %game.SCORE_PER_DESTROY_GEN = 10; - %game.SCORE_PER_DESTROY_SENSOR = 4; - %game.SCORE_PER_DESTROY_TURRET = 5; - %game.SCORE_PER_DESTROY_ISTATION = 2; - %game.SCORE_PER_DESTROY_VSTATION = 5; - %game.SCORE_PER_DESTROY_MPBTSTATION = 3; // z0dd - ZOD, 4/24/02. MPB Teleporter - %game.SCORE_PER_DESTROY_SOLAR = 5; - %game.SCORE_PER_DESTROY_SENTRY = 4; - %game.SCORE_PER_DESTROY_DEP_SENSOR = 1; - %game.SCORE_PER_DESTROY_DEP_INV = 2; - %game.SCORE_PER_DESTROY_DEP_TUR = 3; - - %game.SCORE_PER_DESTROY_SHRIKE = 5; - %game.SCORE_PER_DESTROY_BOMBER = 8; - %game.SCORE_PER_DESTROY_TRANSPORT = 5; - %game.SCORE_PER_DESTROY_WILDCAT = 5; - %game.SCORE_PER_DESTROY_TANK = 8; - %game.SCORE_PER_DESTROY_MPB = 12; - %game.SCORE_PER_PASSENGER = 2; - - %game.SCORE_PER_REPAIR_GEN = 8; - %game.SCORE_PER_REPAIR_SENSOR = 1; - %game.SCORE_PER_REPAIR_TURRET = 4; - %game.SCORE_PER_REPAIR_ISTATION = 2; - %game.SCORE_PER_REPAIR_VSTATION = 4; - %game.SCORE_PER_REPAIR_MPBTSTATION = 3; // z0dd - ZOD, 4/24/02. MPB Teleporter - %game.SCORE_PER_REPAIR_SOLAR = 4; - %game.SCORE_PER_REPAIR_SENTRY = 2; - %game.SCORE_PER_REPAIR_DEP_TUR = 3; - %game.SCORE_PER_REPAIR_DEP_INV = 2; - - %game.FLAG_RETURN_DELAY = 45 * 1000; //45 seconds - - %game.TIME_CONSIDERED_FLAGCARRIER_THREAT = 3 * 1000; //after damaging enemy flag carrier - %game.RADIUS_GEN_DEFENSE = 20; //meters - %game.RADIUS_FLAG_DEFENSE = 20; //meters - - %game.TOUCH_DELAY_MS = 20000; //20 secs - - %game.fadeTimeMS = 2000; - - %game.notifyMineDist = 7.5; - - %game.stalemate = false; - %game.stalemateObjsVisible = false; - %game.stalemateTimeMS = 60000; - %game.stalemateFreqMS = 15000; - %game.stalemateDurationMS = 6000; - // --------------------------------------------------- - - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here -} - -package CTFGame -{ -function ShapeBaseData::onDestroyed(%data, %obj) -{ - %scorer = %obj.lastDamagedBy; - if(!isObject(%scorer)) - return; - - if( (%scorer.getType() & $TypeMasks::GameBaseObjectType) && %scorer.getDataBlock().catagory $= "Vehicles" ) - { - // z0dd - ZOD, 6/18/02. %name was never defined. - %name = %scorer.getDatablock().getName(); - if(%name $= "BomberFlyer" || %name $= "AssaultVehicle") - %gunnerNode = 1; - else - %gunnerNode = 0; - - if(%scorer.getMountNodeObject(%gunnerNode)) - { - %destroyer = %scorer.getMountNodeObject(%gunnerNode).client; - %scorer = %destroyer; - %damagingTeam = %scorer.team; - } - } - else if(%scorer.getClassName() $= "Turret") - { - if(%scorer.getControllingClient()) - { - //manned turret - %destroyer = %scorer.getControllingClient(); - %scorer = %destroyer; - %damagingTeam = %scorer.team; - } - else - { - return; //unmanned turret - } - } - if(!%damagingTeam) - %damagingTeam = %scorer.team; - - // z0dd - ZOD, 10/03/02. Total re-write from here down. - if(%damagingTeam == %obj.team) - { - if(!%obj.getDataBlock().deployedObject) - { - teamDestroyMessage(%scorer, 'msgTkDes', '\c5Teammate %1 destroyed your team\'s %2!', %scorer.name, Game.cleanWord(%obj.getDataBlock().targetTypeTag)); - Game.awardScoreTkDestroy(%scorer); - } - return; - } - - %objType = %obj.getDataBlock().getName(); - switch$ ( %objType ) - { - case "GeneratorLarge": - teamDestroyMessage(%scorer, 'msgGenDestroyed', '\c5%1 destroyed a %2 Generator!', %scorer.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - %score = game.awardScoreGenDestroy(%scorer); - - case "SolarPanel": - teamDestroyMessage(%scorer, 'msgSolarDestroyed', '\c5%1 destroyed a %2 Solar Panel!', %scorer.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - %score = game.awardScoreSolarDestroy(%scorer); - game.shareScore(%score, %score); - - case "SensorLargePulse": - teamDestroyMessage(%scorer, 'msgSensorDestroyed', '\c5%1 destroyed a %2 Sensor!', %scorer.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - %score = game.awardScoreSensorDestroy(%scorer); - - case "SensorMediumPulse": - teamDestroyMessage(%scorer, 'msgSensorDestroyed', '\c5%1 destroyed a %2 Sensor!', %scorer.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - %score = game.awardScoreSensorDestroy(%scorer); - - case "DeployedMotionSensor": - teamDestroyMessage(%scorer, 'msgDepSenDestroyed', '\c5%1 destroyed a Deployable Sensor!', %scorer.name); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - %score = game.awardScoreDepSensorDestroy(%scorer); - - case "DeployedPulseSensor": - teamDestroyMessage(%scorer, 'msgDepSenDestroyed', '\c5%1 destroyed a Deployable Sensor!', %scorer.name); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - %score = game.awardScoreDepSensorDestroy(%scorer); - - case "StationInventory": - teamDestroyMessage(%scorer, 'msgInvDestroyed', '\c5%1 destroyed a %2 Inventory Station!', %scorer.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - %score = game.awardScoreInvDestroy(%scorer); - - case "StationAmmo": - teamDestroyMessage(%scorer, 'msgInvDestroyed', '\c5%1 destroyed a %2 Ammo Station!', %scorer.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - %score = game.awardScoreInvDestroy(%scorer); - - case "StationVehicle": - teamDestroyMessage(%scorer, 'msgVehStationDestroyed', '\c5%1 destroyed a Vehicle Station!', %scorer.name); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - %score = game.awardScoreVehicleStationDestroy(%scorer); - - case "MPBTeleporter": // z0dd - ZOD, 4/24/02. MPB teleporter - teamDestroyMessage(%scorer, 'msgTeleporterDestroyed', '\c5%1 destroyed a MPB Teleport Station!', %scorer.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - %score = game.awardScoreMPBTeleporterDestroy(%scorer); - - case "DeployedStationInventory": - teamDestroyMessage(%scorer, 'msgDepInvDestroyed', '\c5%1 destroyed a Deployable Inventory!', %scorer.name); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - %score = game.awardScoreDepStationDestroy(%scorer); - - case "TurretBaseLarge": - teamDestroyMessage(%scorer, 'msgTurDestroyed', '\c5%1 destroyed a %2 Turret!', %scorer.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - %score = game.awardScoreTurretDestroy(%scorer); - - case "SentryTurret": - teamDestroyMessage(%scorer, 'msgSentryDestroyed', '\c5%1 destroyed a %2 Sentry Turret!', %scorer.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - %score = game.awardScoreSentryDestroy(%scorer); - - case "TurretDeployedFloorIndoor": - teamDestroyMessage(%scorer, 'msgDepTurDestroyed', '\c5%1 destroyed a Spider Clamp Turret!', %scorer.name); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - %score = game.awardScoreDepTurretDestroy(%scorer); - - case "TurretDeployedWallIndoor": - teamDestroyMessage(%scorer, 'msgDepTurDestroyed', '\c5%1 destroyed a Spider Clamp Turret!', %scorer.name); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - %score = game.awardScoreDepTurretDestroy(%scorer); - - case "TurretDeployedCeilingIndoor": - teamDestroyMessage(%scorer, 'msgDepTurDestroyed', '\c5%1 destroyed a Spider Clamp Turret!', %scorer.name); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - %score = game.awardScoreDepTurretDestroy(%scorer); - - case "TurretDeployedOutdoor": - teamDestroyMessage(%scorer, 'msgDepTurDestroyed', '\c5%1 destroyed a Landspike Turret!', %scorer.name); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - %score = game.awardScoreDepTurretDestroy(%scorer); - - default: - return; - } - - if(!%obj.soiledByEnemyRepair) - { - game.shareScore(%scorer, %score); - } -} - -function ShapeBaseData::onDisabled(%data, %obj) -{ - %obj.wasDisabled = true; - Parent::onDisabled(%data, %obj); -} - -function RepairGunImage::onRepair(%this, %obj, %slot) -{ - Parent::onRepair(%this, %obj, %slot); - %target = %obj.repairing; - if(%target && %target.team != %obj.team) - { - //error("Enemy stuff("@%obj@") is being repaired (by "@%target@")"); - %target.soiledByEnemyRepair = true; - } -} - -function Flag::objectiveInit(%data, %flag) -{ - if (!%flag.isTeamSkinned) - { - %pos = %flag.getTransform(); - %group = %flag.getGroup(); - } - %flag.originalPosition = %flag.getTransform(); - $flagPos[%flag.team] = %flag.originalPosition; - %flag.isHome = true; - %flag.carrier = ""; - %flag.grabber = ""; - setTargetSkin(%flag.getTarget(), CTFGame::getTeamSkin(CTFGame, %flag.team)); - setTargetSensorGroup(%flag.getTarget(), %flag.team); - setTargetAlwaysVisMask(%flag.getTarget(), 0x7); - setTargetRenderMask(%flag.getTarget(), getTargetRenderMask(%flag.getTarget()) | 0x2); - %flag.scopeWhenSensorVisible(true); - $flagStatus[%flag.team] = ""; - - //Point the flag and stand at each other - %group = %flag.getGroup(); - %count = %group.getCount(); - %flag.stand = ""; - for(%i = 0; %i < %count; %i++) - { - %this = %group.getObject(%i); - //--------------------------------------------------------------------------------------------------------------------------- - // z0dd - ZOD, 3/16/02. Added TSStatic, console spam fix. - if(%this.getClassName() !$= "InteriorInstance" && %this.getClassName() !$= "SimGroup" && %this.getClassName() !$= "TSStatic") - { - if(%this.getDataBlock().getName() $= "ExteriorFlagStand") - { - %flag.stand = %this; - %this.flag = %flag; - } - } - } - - // set the nametag on the target - setTargetName(%flag.getTarget(), CTFGame::getTeamName(CTFGame, %flag.team)); - - // create a marker on this guy - %flag.waypoint = new MissionMarker() { - position = %flag.getTransform(); - dataBlock = "FlagMarker"; - }; - MissionCleanup.add(%flag.waypoint); - - // create a target for this (there is no MissionMarker::onAdd script call) - %target = createTarget(%flag.waypoint, CTFGame::getTeamName( CTFGame, %flag.team), "", "", 'Base', %flag.team, 0); - setTargetAlwaysVisMask(%target, 0xffffffff); - - //store the flag in an array - $TeamFlag[%flag.team] = %flag; - - // -------------------------------------------------------- - // z0dd - ZOD, 5/26/02. Don't let flag hover over defenders - %flag.static = true; - - // ------------------------------------------------------------------------------------------- - // z0dd - ZOD, 10/03/02. Use triggers for flags that are at home, hack for flag collision bug. - %flag.trigger = new Trigger() - { - dataBlock = flagTrigger; - polyhedron = "-0.6 0.6 0.1 1.2 0.0 0.0 0.0 -1.2 0.0 0.0 0.0 2.5"; - position = %flag.position; - rotation = %flag.rotation; - }; - MissionCleanup.add(%flag.trigger); - %flag.trigger.flag = %flag; - // ------------------------------------------------------------------------------------------- -} - -function Flag::onEnterLiquid(%data, %obj, %coverage, %type) -{ - if(%type > 3) // 1-3 are water, 4+ is lava and quicksand(?) - { - //error("flag("@%obj@") is in liquid type" SPC %type); - game.schedule(3000, flagReturn, %obj); - } -} -}; - -//-------------------------------------------------------------------------- -// need to have this for the corporate maps which could not be fixed -function SimObject::clearFlagWaypoints(%this) -{ -} - -function WayPoint::clearFlagWaypoints(%this) -{ - logEcho("Removing flag waypoint: " @ %this); - if(%this.nameTag $= "Flag") - %this.delete(); -} - -function SimGroup::clearFlagWaypoints(%this) -{ - for(%i = %this.getCount() - 1; %i >= 0; %i--) - %this.getObject(%i).clearFlagWaypoints(); -} - -function CTFGame::getTeamSkin(%game, %team) -{ - if($host::tournamentMode) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - { - return $teamSkin[%team]; - } - - else - { - //error("CTFGame::getTeamSkin"); - if(!$host::useCustomSkins) - { - %terrain = MissionGroup.musicTrack; - //error("Terrain type is: " SPC %terrain); - switch$(%terrain) - { - case "lush": - if(%team == 1) - %skin = 'beagle'; - else if(%team == 2) - %skin = 'dsword'; - else %skin = 'base'; - - case "badlands": - if(%team == 1) - %skin = 'swolf'; - else if(%team == 2) - %skin = 'dsword'; - else %skin = 'base'; - - case "ice": - if(%team == 1) - %skin = 'swolf'; - else if(%team == 2) - %skin = 'beagle'; - else %skin = 'base'; - - case "desert": - if(%team == 1) - %skin = 'cotp'; - else if(%team == 2) - %skin = 'beagle'; - else %skin = 'base'; - - case "Volcanic": - if(%team == 1) - %skin = 'dsword'; - else if(%team == 2) - %skin = 'cotp'; - else %skin = 'base'; - - default: - if(%team == 2) - %skin = 'baseb'; - else %skin = 'base'; - } - } - else %skin = $teamSkin[%team]; - - //error("%skin = " SPC getTaggedString(%skin)); - return %skin; -} -} - -function CTFGame::getTeamName(%game, %team) -{ - // --------------------------------------------------- - // z0dd - ZOD 3/30/02. Only display default team names - //if ( isDemo() || $host::tournamentMode) - return $TeamName[%team]; - // --------------------------------------------------- -} - -//-------------------------------------------------------------------------- -function CTFGame::missionLoadDone(%game) -{ - //default version sets up teams - must be called first... - DefaultGame::missionLoadDone(%game); - - for(%i = 1; %i < (%game.numTeams + 1); %i++) - $teamScore[%i] = 0; - - // remove - MissionGroup.clearFlagWaypoints(); - - //reset some globals, just in case... - $dontScoreTimer[1] = false; - $dontScoreTimer[2] = false; - - echo( "starting camp thread..." ); - %game.campThread_1 = schedule( 1000, 0, "checkVehicleCamping", 1 ); - %game.campThread_2 = schedule( 1000, 0, "checkVehicleCamping", 2 ); -} - -function CTFGame::playerTouchFlag(%game, %player, %flag) -{ - %client = %player.client; - if ((%flag.carrier $= "") && (%player.getState() !$= "Dead")) - { - //flag isn't held and has been touched by a live player - if (%client.team == %flag.team) - %game.playerTouchOwnFlag(%player, %flag); - else - %game.playerTouchEnemyFlag(%player, %flag); - } - // toggle visibility of the flag - setTargetRenderMask(%flag.waypoint.getTarget(), %flag.isHome ? 0 : 1); -} - -function CTFGame::playerTouchOwnFlag(%game, %player, %flag) -{ - if(%flag.isHome) - { - if (%player.holdingFlag !$= "") - %game.flagCap(%player); - } - else - %game.flagReturn(%flag, %player); - - //call the AI function - %game.AIplayerTouchOwnFlag(%player, %flag); -} - -function CTFGame::playerTouchEnemyFlag(%game, %player, %flag) -{ - // --------------------------------------------------------------- - // z0dd, ZOD - 9/27/02. Player must wait to grab after throwing it - if((%player.flagTossWait !$= "") && %player.flagTossWait) - return false; - // --------------------------------------------------------------- - - cancel(%flag.searchSchedule); // z0dd - ZOD, 9/28/02. Hack for flag collision bug. SquirrelOfDeath, 10/02/02: Moved from PlayerTouchFlag - - cancel(%game.updateFlagThread[%flag]); // z0dd - ZOD, 8/4/02. Cancel this flag's thread to KineticPoet's flag updater - %game.flagHeldTime[%flag] = getSimTime(); // z0dd - ZOD, 8/15/02. Store time player grabbed flag. - - %client = %player.client; - %player.holdingFlag = %flag; //%player has this flag - %flag.carrier = %player; //this %flag is carried by %player - - %player.mountImage(FlagImage, $FlagSlot, true, %game.getTeamSkin(%flag.team)); - - %game.playerGotFlagTarget(%player); - //only cancel the return timer if the player is in bounds... - if (!%client.outOfBounds) - { - cancel($FlagReturnTimer[%flag]); - $FlagReturnTimer[%flag] = ""; - } - - //if this flag was "at home", see if both flags have now been taken - if (%flag.isHome) - { - // tiebreaker score - game.awardScoreFlagTouch( %client, %flag ); - - %startStalemate = false; - if ($TeamFlag[1] == %flag) - %startStalemate = !$TeamFlag[2].isHome; - else - %startStalemate = !$TeamFlag[1].isHome; - - if (%startStalemate) - %game.stalemateSchedule = %game.schedule(%game.stalemateTimeMS, beginStalemate); - - } - %flag.hide(true); - %flag.startFade(0, 0, false); - %flag.isHome = false; - if(%flag.stand) - %flag.stand.getDataBlock().onFlagTaken(%flag.stand);//animate, if exterior stand - - $flagStatus[%flag.team] = %client.nameBase; - %teamName = %game.getTeamName(%flag.team); - messageTeamExcept(%client, 'MsgCTFFlagTaken', '\c2Teammate %1 took the %2 flag.~wfx/misc/flag_snatch.wav', %client.name, %teamName, %flag.team, %client.nameBase); - messageTeam(%flag.team, 'MsgCTFFlagTaken', '\c2Your flag has been taken by %1!~wfx/misc/flag_taken.wav',%client.name, 0, %flag.team, %client.nameBase); - messageTeam(0, 'MsgCTFFlagTaken', '\c2%1 took the %2 flag.~wfx/misc/flag_snatch.wav', %client.name, %teamName, %flag.team, %client.nameBase); - messageClient(%client, 'MsgCTFFlagTaken', '\c2You took the %2 flag.~wfx/misc/flag_snatch.wav', %client.name, %teamName, %flag.team, %client.nameBase); - logEcho(%client.nameBase@" (pl "@%player@"/cl "@%client@") took team "@%flag.team@" flag"); - - //call the AI function - %game.AIplayerTouchEnemyFlag(%player, %flag); - - //if the player is out of bounds, then in 3 seconds, it should be thrown back towards the in bounds area... - if (%client.outOfBounds) - %game.schedule(3000, "boundaryLoseFlag", %player); -} - -function CTFGame::playerGotFlagTarget(%game, %player) -{ - %player.scopeWhenSensorVisible(true); - %target = %player.getTarget(); - setTargetRenderMask(%target, getTargetRenderMask(%target) | 0x2); - if(%game.stalemateObjsVisible) - setTargetAlwaysVisMask(%target, 0x7); -} - -function CTFGame::playerLostFlagTarget(%game, %player) -{ - %player.scopeWhenSensorVisible(false); - %target = %player.getTarget(); - setTargetRenderMask(%target, getTargetRenderMask(%target) & ~0x2); - // clear his always vis target mask - setTargetAlwaysVisMask(%target, (1 << getTargetSensorGroup(%target))); -} - -//---------------------------------------------------------------------------------------- -// z0dd - ZOD, 8/4/02: KineticPoet's flag updater code -function CTFGame::updateFlagTransform(%game, %flag) -{ - %flag.setTransform(%flag.getTransform()); - %game.updateFlagThread[%flag] = %game.schedule(100, "updateFlagTransform", %flag); -} -//---------------------------------------------------------------------------------------- - -function CTFGame::playerDroppedFlag(%game, %player) -{ - %client = %player.client; - %flag = %player.holdingFlag; - %game.updateFlagTransform(%flag); // z0dd - ZOD, 8/4/02, Call to KineticPoet's flag updater - %held = %game.formatTime(getSimTime() - %game.flagHeldTime[%flag], false); // z0dd - ZOD, 8/15/02. How long did player hold flag? - - %game.playerLostFlagTarget(%player); - - %player.holdingFlag = ""; //player isn't holding a flag anymore - %flag.carrier = ""; //flag isn't held anymore - $flagStatus[%flag.team] = ""; - - %player.unMountImage($FlagSlot); - %flag.hide(false); //Does the throwItem function handle this? - - %teamName = %game.getTeamName(%flag.team); - messageTeamExcept(%client, 'MsgCTFFlagDropped', '\c2Teammate %1 dropped the %2 flag. (Held: %4)~wfx/misc/flag_drop.wav', %client.name, %teamName, %flag.team, %held); // z0dd - ZOD, 8/15/02. How long flag was held - messageTeam(%flag.team, 'MsgCTFFlagDropped', '\c2Your flag has been dropped by %1! (Held: %4)~wfx/misc/flag_drop.wav', %client.name, 0, %flag.team, %held); // z0dd - ZOD, 8/15/02. How long flag was held - messageTeam(0, 'MsgCTFFlagDropped', '\c2%1 dropped the %2 flag. (Held: %4)~wfx/misc/flag_drop.wav', %client.name, %teamName, %flag.team, %held); // z0dd - ZOD, 8/15/02. How long flag was held - if(!%player.client.outOfBounds) - messageClient(%client, 'MsgCTFFlagDropped', '\c2You dropped the %2 flag. (Held: %4)~wfx/misc/flag_drop.wav', %client.name, %teamName, %flag.team, %held); // z0dd - ZOD, 8/15/02. How long flag was held - // Yogi, 8/18/02. 3rd param changed 0 -> %client.name - logEcho(%client.nameBase@" (pl "@%player@"/cl "@%client@") dropped team "@%flag.team@" flag"@" (Held: "@%held@")"); - - //don't duplicate the schedule if there's already one in progress... - if ($FlagReturnTimer[%flag] <= 0) - $FlagReturnTimer[%flag] = %game.schedule(%game.FLAG_RETURN_DELAY - %game.fadeTimeMS, "flagReturnFade", %flag); - - //call the AI function - %game.AIplayerDroppedFlag(%player, %flag); -} - -function CTFGame::flagCap(%game, %player) -{ - %client = %player.client; - - //Increment our caps.. - $Data::Caps[%client.guid]++; - - %flag = %player.holdingFlag; - %flag.carrier = ""; - - %held = %game.formatTime(getSimTime() - %game.flagHeldTime[%flag], false); // z0dd - ZOD, 8/15/02. How long did player hold flag? - - %game.playerLostFlagTarget(%player); - //award points to player and team - %teamName = %game.getTeamName(%flag.team); - messageTeamExcept(%client, 'MsgCTFFlagCapped', '\c2%1 captured the %2 flag! (Held: %5)~wfx/misc/flag_capture.wav', %client.name, %teamName, %flag.team, %client.team, %held); - messageTeam(%flag.team, 'MsgCTFFlagCapped', '\c2Your flag was captured by %1. (Held: %5)~wfx/misc/flag_lost.wav', %client.name, 0, %flag.team, %client.team, %held); - messageTeam(0, 'MsgCTFFlagCapped', '\c2%1 captured the %2 flag! (Held: %5)~wfx/misc/flag_capture.wav', %client.name, %teamName, %flag.team, %client.team, %held); - messageClient(%client, 'MsgCTFFlagCapped', '\c2You captured the %2 flag! (Held: %5)~wfx/misc/flag_capture.wav', %client.name, %teamName, %flag.team, %client.team, %held); // Yogi, 8/18/02. 3rd param changed 0 -> %client.name - - logEcho(%client.nameBase@" (pl "@%player@"/cl "@%client@") capped team "@%client.team@" flag"@" (Held: "@%held@")"); - %player.holdingFlag = ""; //no longer holding it. - %player.unMountImage($FlagSlot); - %game.awardScoreFlagCap(%client, %flag); - %game.flagReset(%flag); - - //call the AI function - %game.AIflagCap(%player, %flag); - - //if this cap didn't end the game, play the announcer... - if ($missionRunning) - { - if (%game.getTeamName(%client.team) $= 'Inferno') - messageAll("", '~wvoice/announcer/ann.infscores.wav'); - else if (%game.getTeamName(%client.team) $= 'Storm') - messageAll("", '~wvoice/announcer/ann.stoscores.wav'); - else if (%game.getTeamName(%client.team) $= 'Phoenix') - messageAll("", '~wvoice/announcer/ann.pxscore.wav'); - else if (%game.getTeamName(%client.team) $= 'Blood Eagle') - messageAll("", '~wvoice/announcer/ann.bescore.wav'); - else if (%game.getTeamName(%client.team) $= 'Diamond Sword') - messageAll("", '~wvoice/announcer/ann.dsscore.wav'); - else if (%game.getTeamName(%client.team) $= 'Starwolf') - messageAll("", '~wvoice/announcer/ann.swscore.wav'); - } -} - -function CTFGame::flagReturnFade(%game, %flag) -{ - $FlagReturnTimer[%flag] = %game.schedule(%game.fadeTimeMS, "flagReturn", %flag); - %flag.startFade(%game.fadeTimeMS, 0, true); -} - -function CTFGame::flagReturn(%game, %flag, %player) -{ - cancel($FlagReturnTimer[%flag]); - $FlagReturnTimer[%flag] = ""; - - if(%flag.team == 1) - %otherTeam = 2; - else - %otherTeam = 1; - %teamName = %game.getTeamName(%flag.team); - if (%player !$= "") - { - //a player returned it - %client = %player.client; - - //Increment flag returns - $Data::FlagReturns[%client.guid]++; - - messageTeamExcept(%client, 'MsgCTFFlagReturned', '\c2Teammate %1 returned your flag to base.~wfx/misc/flag_return.wav', %client.name, 0, %flag.team); - messageTeam(%otherTeam, 'MsgCTFFlagReturned', '\c2Enemy %1 returned the %2 flag.~wfx/misc/flag_return.wav', %client.name, %teamName, %flag.team); - messageTeam(0, 'MsgCTFFlagReturned', '\c2%1 returned the %2 flag.~wfx/misc/flag_return.wav', %client.name, %teamName, %flag.team); - messageClient(%client, 'MsgCTFFlagReturned', '\c2You returned your flag.~wfx/misc/flag_return.wav', %client.name, %teamName, %flag.team); // Yogi, 8/18/02. 3rd param changed 0 -> %client.name - logEcho(%client.nameBase@" (pl "@%player@"/cl "@%client@") returned team "@%flag.team@" flag"); - - // find out what type of return it is - // stalemate return? - - // --------------------------------------------------- - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - if(%game.stalemate) - { - //error("Stalemate return!!!"); - %game.awardScoreStalemateReturn(%player.client); - } - // regular return - else - { - %enemyFlagDist = vectorDist($flagPos[%flag.team], $flagPos[%otherTeam]); - %dist = vectorDist(%flag.position, %flag.originalPosition); - - %rawRatio = %dist/%enemyFlagDist; - %ratio = %rawRatio < 1 ? %rawRatio : 1; - %percentage = mFloor( (%ratio) * 10 ) * 10; - %game.awardScoreFlagReturn(%player.client, %percentage); - } - // --------------------------------------------------- - } - else - { - //returned due to timer - messageTeam(%otherTeam, 'MsgCTFFlagReturned', '\c2The %2 flag was returned to base.~wfx/misc/flag_return.wav', 0, %teamName, %flag.team); //because it was dropped for too long - messageTeam(%flag.team, 'MsgCTFFlagReturned', '\c2Your flag was returned.~wfx/misc/flag_return.wav', 0, 0, %flag.team); - messageTeam(0, 'MsgCTFFlagReturned', '\c2The %2 flag was returned to base.~wfx/misc/flag_return.wav', 0, %teamName, %flag.team); - logEcho("team "@%flag.team@" flag returned (timeout)"); - } - %game.flagReset(%flag); -} - -function CTFGame::showStalemateTargets(%game) -{ - cancel(%game.stalemateSchedule); - - //show the targets - for (%i = 1; %i <= 2; %i++) - { - %flag = $TeamFlag[%i]; - - //find the object to scope/waypoint.... - //render the target hud icon for slot 1 (a centermass flag) - //if we just set him as always sensor vis, it'll work fine. - if (isObject(%flag.carrier)) - setTargetAlwaysVisMask(%flag.carrier.getTarget(), 0x7); - } - //schedule the targets to hide - %game.stalemateObjsVisible = true; - %game.stalemateSchedule = %game.schedule(%game.stalemateDurationMS, hideStalemateTargets); -} - -function CTFGame::hideStalemateTargets(%game) -{ - cancel(%game.stalemateSchedule); - - //hide the targets - for (%i = 1; %i <= 2; %i++) - { - %flag = $TeamFlag[%i]; - if (isObject(%flag.carrier)) - { - %target = %flag.carrier.getTarget(); - setTargetAlwaysVisMask(%target, (1 << getTargetSensorGroup(%target))); - } - } - //schedule the targets to show again - %game.stalemateObjsVisible = false; - %game.stalemateSchedule = %game.schedule(%game.stalemateFreqMS, showStalemateTargets); -} - -function CTFGame::beginStalemate(%game) -{ - %game.stalemate = true; - %game.showStalemateTargets(); -} - -function CTFGame::endStalemate(%game) -{ - %game.stalemate = false; - %game.hideStalemateTargets(); - cancel(%game.stalemateSchedule); -} - -function CTFGame::flagReset(%game, %flag) -{ - cancel(%game.updateFlagThread[%flag]); // z0dd - ZOD, 8/4/02. Cancel this flag's thread to KineticPoet's flag updater - - //any time a flag is reset, kill the stalemate schedule - %game.endStalemate(); - - //make sure if there's a player carrying it (probably one out of bounds...), it is stripped first - if (isObject(%flag.carrier)) - { - //hide the target hud icon for slot 2 (a centermass flag - visible only as part of a teams sensor network) - %game.playerLostFlagTarget(%flag.carrier); - %flag.carrier.holdingFlag = ""; //no longer holding it. - %flag.carrier.unMountImage($FlagSlot); - } - //fades, restore default position, home, velocity, general status, etc. - %flag.setVelocity("0 0 0"); - %flag.setTransform(%flag.originalPosition); - %flag.isHome = true; - %flag.carrier = ""; - %flag.grabber = ""; - $flagStatus[%flag.team] = ""; - %flag.hide(false); - if(%flag.stand) - %flag.stand.getDataBlock().onFlagReturn(%flag.stand);//animate, if exterior stand - - //fade the flag in... - %flag.startFade(%game.fadeTimeMS, 0, false); - - // dont render base target - setTargetRenderMask(%flag.waypoint.getTarget(), 0); - - //call the AI function - %game.AIflagReset(%flag); - - // -------------------------------------------------------- - // z0dd - ZOD, 5/26/02. Don't let flag hover over defenders - %flag.static = true; - - // -------------------------------------------------------------------------- - // z0dd - ZOD, 9/28/02. Hack for flag collision bug. - if(%flag.searchSchedule !$="") - { - cancel(%flag.searchSchedule); - } - // -------------------------------------------------------------------------- -} - -function CTFGame::timeLimitReached(%game) -{ - logEcho("game over (timelimit)"); - %game.gameOver(); - cycleMissions(); -} - -function CTFGame::scoreLimitReached(%game) -{ - logEcho("game over (scorelimit)"); - %game.gameOver(); - cycleMissions(); -} - -function CTFGame::notifyMineDeployed(%game, %mine) -{ - //see if the mine is within 5 meters of the flag stand... - %mineTeam = %mine.sourceObject.team; - %homeFlag = $TeamFlag[%mineTeam]; - if (isObject(%homeFlag)) - { - %dist = VectorDist(%homeFlag.originalPosition, %mine.position); - if (%dist <= %game.notifyMineDist) - { - messageTeam(%mineTeam, 'MsgCTFFlagMined', "The flag has been mined.~wvoice/announcer/flag_minedFem.wav" ); - } - } -} - -function CTFGame::gameOver(%game) -{ - // z0dd - ZOD, 9/28/02. Hack for flag collision bug. - for(%f = 1; %f <= %game.numTeams; %f++) - { - cancel($TeamFlag[%f].searchSchedule); - } - - // ------------------------------------------- - // z0dd - ZOD, 9/28/02. Cancel camp schedules. - if( Game.campThread_1 !$= "" ) - cancel(Game.campThread_1); - - if( Game.campThread_2 !$= "" ) - cancel(Game.campThread_2); - // ------------------------------------------- - - //call the default - DefaultGame::gameOver(%game); - - //send the winner message - %winner = ""; - if ($teamScore[1] > $teamScore[2]) - { - %winner = %game.getTeamName(1); - %team = 1; - } - else if ($teamScore[2] > $teamScore[1]) - { - %winner = %game.getTeamName(2); - %team = 2; - } - - for (%i = 0; %i < ClientGroup.getCount(); %i++) - { - %cl = ClientGroup.getObject(%i); - if (%cl.team == %team) - $Data::Won[%cl.guid]++; - else - $Data::Lost[%cl.guid]++; - } - - //Ok, increment wins/losses - - if (%winner $= 'Storm') - messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.stowins.wav" ); - else if (%winner $= 'Inferno') - messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.infwins.wav" ); - else if (%winner $= 'Starwolf') - messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.swwin.wav" ); - else if (%winner $= 'Blood Eagle') - messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.bewin.wav" ); - else if (%winner $= 'Diamond Sword') - messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.dswin.wav" ); - else if (%winner $= 'Phoenix') - messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.pxwin.wav" ); - else - messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.gameover.wav" ); - - messageAll('MsgClearObjHud', ""); - for(%i = 0; %i < ClientGroup.getCount(); %i ++) - { - %client = ClientGroup.getObject(%i); - %game.resetScore(%client); - } - for(%j = 1; %j <= %game.numTeams; %j++) - $TeamScore[%j] = 0; -} - -function CTFGame::onClientDamaged(%game, %clVictim, %clAttacker, %damageType, %implement, %damageLoc) -{ - if(%clVictim.headshot && %damageType == $DamageType::Laser && %clVictim.team != %clAttacker.team) - { - %clAttacker.scoreHeadshot++; - if (%game.SCORE_PER_HEADSHOT != 0) - { - messageClient(%clAttacker, 'msgHeadshot', '\c0You received a %1 point bonus for a successful headshot.', %game.SCORE_PER_HEADSHOT); - messageTeamExcept(%clAttacker, 'msgHeadshot', '\c5%1 hit a sniper rifle headshot.', %clAttacker.name); // z0dd - ZOD, 8/15/02. Tell team - } - %game.recalcScore(%clAttacker); - } - - // ----------------------------------------------- - // z0dd - ZOD, 8/25/02. Rear Lance hits - if(%clVictim.rearshot && %damageType == $DamageType::ShockLance && %clVictim.team != %clAttacker.team) - { - %clAttacker.scoreRearshot++; - if (%game.SCORE_PER_REARSHOT != 0) - { - messageClient(%clAttacker, 'msgRearshot', '\c0You received a %1 point bonus for a successful rearshot.', %game.SCORE_PER_REARSHOT); - messageTeamExcept(%clAttacker, 'msgRearshot', '\c5%1 hit a shocklance rearshot.', %clAttacker.name); - } - %game.recalcScore(%clAttacker); - } - // ----------------------------------------------- - - //the DefaultGame will set some vars - DefaultGame::onClientDamaged(%game, %clVictim, %clAttacker, %damageType, %implement, %damageLoc); - - //if victim is carrying a flag and is not on the attackers team, mark the attacker as a threat for x seconds(for scoring purposes) - if ((%clVictim.holdingFlag !$= "") && (%clVictim.team != %clAttacker.team)) - { - %clAttacker.dmgdFlagCarrier = true; - cancel(%clAttacker.threatTimer); //restart timer - %clAttacker.threatTimer = schedule(%game.TIME_CONSIDERED_FLAGCARRIER_THREAT, %clAttacker.dmgdFlagCarrier = false); - } -} - -//////////////////////////////////////////////////////////////////////////////////////// -function CTFGame::clientMissionDropReady(%game, %client) -{ - messageClient(%client, 'MsgClientReady',"", %game.class); - %game.resetScore(%client); - for(%i = 1; %i <= %game.numTeams; %i++) - { - $Teams[%i].score = 0; - messageClient(%client, 'MsgCTFAddTeam', "", %i, %game.getTeamName(%i), $flagStatus[%i], $TeamScore[%i]); - } - //%game.populateTeamRankArray(%client); - - //messageClient(%client, 'MsgYourRankIs', "", -1); - - messageClient(%client, 'MsgMissionDropInfo', '\c0You are in mission %1 (%2).', $MissionDisplayName, $MissionTypeDisplayName, $ServerName ); - - DefaultGame::clientMissionDropReady(%game, %client); -} - -function CTFGame::assignClientTeam(%game, %client, %respawn) -{ - DefaultGame::assignClientTeam(%game, %client, %respawn); - // if player's team is not on top of objective hud, switch lines - messageClient(%client, 'MsgCheckTeamLines', "", %client.team); -} - -function CTFGame::recalcScore(%game, %cl) -{ - %killValue = %cl.kills * %game.SCORE_PER_KILL; - %deathValue = %cl.deaths * %game.SCORE_PER_DEATH; - - if (%killValue - %deathValue == 0) - %killPoints = 0; - else - %killPoints = (%killValue * %killValue) / (%killValue - %deathValue); - - // --------------------------------------------------- - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - %cl.offenseScore = %killPoints + - %cl.suicides * %game.SCORE_PER_SUICIDE + - %cl.escortAssists * %game.SCORE_PER_ESCORT_ASSIST + - %cl.teamKills * %game.SCORE_PER_TEAMKILL + - %cl.tkDestroys * %game.SCORE_PER_TK_DESTROY + // z0dd - ZOD, 10/03/02. Penalty for tking equiptment. - %cl.scoreHeadshot * %game.SCORE_PER_HEADSHOT + - %cl.scoreRearshot * %game.SCORE_PER_REARSHOT + // z0dd - ZOD, 8/25/02. Added Lance rear shot messages - %cl.flagCaps * %game.SCORE_PER_PLYR_FLAG_CAP + - %cl.flagGrabs * %game.SCORE_PER_PLYR_FLAG_TOUCH + - %cl.genDestroys * %game.SCORE_PER_DESTROY_GEN + - %cl.sensorDestroys * %game.SCORE_PER_DESTROY_SENSOR + - %cl.turretDestroys * %game.SCORE_PER_DESTROY_TURRET + - %cl.iStationDestroys * %game.SCORE_PER_DESTROY_ISTATION + - %cl.vstationDestroys * %game.SCORE_PER_DESTROY_VSTATION + - %cl.mpbtstationDestroys * %game.SCORE_PER_DESTROY_MPBTSTATION + // z0dd - ZOD 3/30/02. MPB Teleporter - %cl.solarDestroys * %game.SCORE_PER_DESTROY_SOLAR + - %cl.sentryDestroys * %game.SCORE_PER_DESTROY_SENTRY + - %cl.depSensorDestroys * %game.SCORE_PER_DESTROY_DEP_SENSOR + - %cl.depTurretDestroys * %game.SCORE_PER_DESTROY_DEP_TUR + - %cl.depStationDestroys * %game.SCORE_PER_DESTROY_DEP_INV + - %cl.vehicleScore + %cl.vehicleBonus; - - %cl.defenseScore = %cl.genDefends * %game.SCORE_PER_GEN_DEFEND + - %cl.flagDefends * %game.SCORE_PER_FLAG_DEFEND + - %cl.carrierKills * %game.SCORE_PER_CARRIER_KILL + - %cl.escortAssists * %game.SCORE_PER_ESCORT_ASSIST + - %cl.turretKills * %game.SCORE_PER_TURRET_KILL_AUTO + - %cl.mannedturretKills * %game.SCORE_PER_TURRET_KILL + - %cl.genRepairs * %game.SCORE_PER_REPAIR_GEN + - %cl.SensorRepairs * %game.SCORE_PER_REPAIR_SENSOR + - %cl.TurretRepairs * %game.SCORE_PER_REPAIR_TURRET + - %cl.StationRepairs * %game.SCORE_PER_REPAIR_ISTATION + - %cl.VStationRepairs * %game.SCORE_PER_REPAIR_VSTATION + - %cl.mpbtstationRepairs * %game.SCORE_PER_REPAIR_MPBTSTATION + // z0dd - ZOD 3/30/02. MPB Teleporter - %cl.solarRepairs * %game.SCORE_PER_REPAIR_SOLAR + - %cl.sentryRepairs * %game.SCORE_PER_REPAIR_SENTRY + - %cl.depInvRepairs * %game.SCORE_PER_REPAIR_DEP_INV + - %cl.depTurretRepairs * %game.SCORE_PER_REPAIR_DEP_TUR + - %cl.returnPts; - // --------------------------------------------------- - - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - - %cl.score = mFloor(%cl.offenseScore + %cl.defenseScore); - - %game.recalcTeamRanks(%cl); -} - -function CTFGame::updateKillScores(%game, %clVictim, %clKiller, %damageType, %implement) -{ -// is this a vehicle kill rather than a player kill - - // console error message suppression - if( isObject( %implement ) ) - { - if( %implement.getDataBlock().getName() $= "AssaultPlasmaTurret" || %implement.getDataBlock().getName() $= "BomberTurret" ) // gunner - %clKiller = %implement.vehicleMounted.getMountNodeObject(1).client; - else if(%implement.getDataBlock().catagory $= "Vehicles") // pilot - %clKiller = %implement.getMountNodeObject(0).client; - } - - if(%game.testTurretKill(%implement)) //check for turretkill before awarded a non client points for a kill - %game.awardScoreTurretKill(%clVictim, %implement); - else if (%game.testKill(%clVictim, %clKiller)) //verify victim was an enemy - { - %value = %game.awardScoreKill(%clKiller); - %game.shareScore(%clKiller, %value); - %game.awardScoreDeath(%clVictim); - - if (%game.testGenDefend(%clVictim, %clKiller)) - %game.awardScoreGenDefend(%clKiller); - - if(%game.testCarrierKill(%clVictim, %clKiller)) - %game.awardScoreCarrierKill(%clKiller); - else - { - if (%game.testFlagDefend(%clVictim, %clKiller)) - %game.awardScoreFlagDefend(%clKiller); - } - if (%game.testEscortAssist(%clVictim, %clKiller)) - %game.awardScoreEscortAssist(%clKiller); - } - else - { - if (%game.testSuicide(%clVictim, %clKiller, %damageType)) //otherwise test for suicide - { - %game.awardScoreSuicide(%clVictim); - } - else - { - if (%game.testTeamKill(%clVictim, %clKiller)) //otherwise test for a teamkill - %game.awardScoreTeamKill(%clVictim, %clKiller); - } - } -} - -function CTFGame::testFlagDefend(%game, %victimID, %killerID) -{ - InitContainerRadiusSearch(%victimID.plyrPointOfDeath, %game.RADIUS_FLAG_DEFENSE, $TypeMasks::ItemObjectType); - %objID = containerSearchNext(); - while(%objID != 0) - { - %objType = %objID.getDataBlock().getName(); - if ((%objType $= "Flag") && (%objID.team == %killerID.team)) - return true; //found the(a) killer's flag near the victim's point of death - else - %objID = containerSearchNext(); - } - return false; //didn't find a qualifying flag within required radius of victims point of death -} - -function CTFGame::testGenDefend(%game, %victimID, %killerID) -{ - InitContainerRadiusSearch(%victimID.plyrPointOfDeath, %game.RADIUS_GEN_DEFENSE, $TypeMasks::StaticShapeObjectType); - %objID = containerSearchNext(); - while(%objID != 0) - { - %objType = %objID.getDataBlock().ClassName; - if ((%objType $= "generator") && (%objID.team == %killerID.team)) - return true; //found a killer's generator within required radius of victim's death - else - %objID = containerSearchNext(); - } - return false; //didn't find a qualifying gen within required radius of victim's point of death -} - -function CTFGame::testCarrierKill(%game, %victimID, %killerID) -{ - %flag = %victimID.plyrDiedHoldingFlag; - return ((%flag !$= "") && (%flag.team == %killerID.team)); -} - -function CTFGame::testEscortAssist(%game, %victimID, %killerID) -{ - return (%victimID.dmgdFlagCarrier); -} - -function CTFGame::testValidRepair(%game, %obj) -{ - if(!%obj.wasDisabled) - { - //error(%obj SPC "was never disabled"); - return false; - } - else if(%obj.lastDamagedByTeam == %obj.team) - { - //error(%obj SPC "was last damaged by a friendly"); - return false; - } - else if(%obj.team != %obj.repairedBy.team) - { - //error(%obj SPC "was repaired by an enemy"); - return false; - } - else - { - if(%obj.soiledByEnemyRepair) - %obj.soiledByEnemyRepair = false; - return true; - } -} - -function CTFGame::awardScoreFlagCap(%game, %cl, %flag) -{ - %cl.flagCaps++; - $TeamScore[%cl.team] += %game.SCORE_PER_TEAM_FLAG_CAP; - messageAll('MsgTeamScoreIs', "", %cl.team, $TeamScore[%cl.team]); - - %flag.grabber.flagGrabs++; - - if (%game.SCORE_PER_TEAM_FLAG_CAP > 0) - { - %plural = (%game.SCORE_PER_PLYR_FLAG_CAP != 1 ? 's' : ""); - %plural2 = (%game.SCORE_PER_PLYR_FLAG_TOUCH != 1 ? 's' : ""); - - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - if(%cl == %flag.grabber) - { - messageClient(%cl, 'msgCTFFriendCap', '\c0You receive %1 point%2 for stealing and capturing the enemy flag!', %game.SCORE_PER_PLYR_FLAG_CAP+%game.SCORE_PER_PLYR_FLAG_TOUCH, %plural); - messageTeam(%flag.team, 'msgCTFEnemyCap', '\c0Enemy %1 received %2 point%3 for capturing your flag!', %cl.name, %game.SCORE_PER_PLYR_FLAG_CAP+%game.SCORE_PER_PLYR_FLAG_TOUCH, %plural); - //messageTeamExcept(%cl, 'msgCTFFriendCap', '\c0Teammate %1 receives %2 point%3 for capturing the enemy flag!', %cl.name, %game.SCORE_PER_PLYR_FLAG_CAP+%game.SCORE_PER_PLYR_FLAG_TOUCH, %plural); // z0dd - ZOD, 8/15/02. Message is pointless - } - else - { - if(isObject(%flag.grabber)) // is the grabber still here? - { - messageClient(%cl, 'msgCTFFriendCap', '\c0You receive %1 point%2 for capturing the enemy flag! %3 gets %4 point%5 for the steal assist.', %game.SCORE_PER_PLYR_FLAG_CAP, %plural, %flag.grabber.name, %game.SCORE_PER_PLYR_FLAG_TOUCH, %plural2); - messageClient(%flag.grabber, 'msgCTFFriendCap', '\c0You receive %1 point%2 for stealing a flag that was subsequently capped by %3.', %game.SCORE_PER_PLYR_FLAG_TOUCH, %plural2, %cl.name); - } - else - messageClient(%cl, 'msgCTFFriendCap', '\c0You receive %1 point%2 for capturing the enemy flag!', %game.SCORE_PER_PLYR_FLAG_CAP, %plural); - - //messageTeamExcept(%cl, 'msgCTFFriendCap', '\c0Teammate %1 receives %2 point%3 for capturing the enemy flag!', %cl.name, %game.SCORE_PER_PLYR_FLAG_CAP, %plural); // z0dd - ZOD, 8/15/02. Message is pointless - //messageTeam(%flag.team, 'msgCTFEnemyCap', '\c0Enemy %1 received %2 point%3 for capturing your flag!', %cl.name, %game.SCORE_PER_PLYR_FLAG_CAP, %plural); // z0dd - ZOD, 8/15/02. Message is pointless - } - // --------------------------------------------------- - } - - %game.recalcScore(%cl); - - if(isObject(%flag.grabber)) - %game.recalcScore(%flag.grabber); - - %game.checkScoreLimit(%cl.team); -} - - -function CTFGame::awardScoreFlagTouch(%game, %cl, %flag) -{ - - %flag.grabber = %cl; - %team = %cl.team; - if( $DontScoreTimer[%team] ) - return; - - $dontScoreTimer[%team] = true; - //tinman - needed to remove all game calls to "eval" for the PURE server... - %game.schedule(%game.TOUCH_DELAY_MS, resetDontScoreTimer, %team); - //schedule(%game.TOUCH_DELAY_MS, 0, eval, "$dontScoreTimer["@%team@"] = false;"); - schedule(%game.TOUCH_DELAY_MS, 0, eval, "$dontScoreTimer["@%team@"] = false;"); - $TeamScore[%team] += %game.SCORE_PER_TEAM_FLAG_TOUCH; - messageAll('MsgTeamScoreIs', "", %team, $TeamScore[%team]); - - if (%game.SCORE_PER_TEAM_FLAG_TOUCH > 0) - { - %plural = (%game.SCORE_PER_TEAM_FLAG_TOUCH != 1 ? 's' : ""); - messageTeam(%team, 'msgCTFFriendFlagTouch', '\c0Your team receives %1 point%2 for grabbing the enemy flag!', %game.SCORE_PER_TEAM_FLAG_TOUCH, %plural); - messageTeam(%flag.team, 'msgCTFEnemyFlagTouch', '\c0Enemy %1 receives %2 point%3 for grabbing your flag!', %cl.name, %game.SCORE_PER_TEAM_FLAG_TOUCH, %plural); - } - %game.recalcScore(%cl); - %game.checkScoreLimit(%team); -} - -function CTFGame::resetDontScoreTimer(%game, %team) -{ - $dontScoreTimer[%team] = false; -} - -function CTFGame::checkScoreLimit(%game, %team) -{ - %scoreLimit = MissionGroup.CTF_scoreLimit * %game.SCORE_PER_TEAM_FLAG_CAP; - // default of 5 if scoreLimit not defined - if(%scoreLimit $= "") - %scoreLimit = 5 * %game.SCORE_PER_TEAM_FLAG_CAP; - if($TeamScore[%team] >= %scoreLimit) - %game.scoreLimitReached(); -} - -function CTFGame::awardScoreFlagReturn(%game, %cl, %perc) -{ - // --------------------------------------------------- - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - if (%game.SCORE_PER_FLAG_RETURN != 0) - { - %pts = mfloor( %game.SCORE_PER_FLAG_RETURN * (%perc/100) ); - if(%perc == 100) - messageClient(%cl, 'scoreFlaRetMsg', 'Flag return - exceeded capping distance - %1 point bonus.', %pts, %perc); - else if(%perc == 0) - messageClient(%cl, 'scoreFlaRetMsg', 'You gently place the flag back on the stand.', %pts, %perc); - else - messageClient(%cl, 'scoreFlaRetMsg', '\c0Flag return from %2%% of capping distance - %1 point bonus.', %pts, %perc); - %cl.returnPts += %pts; - } - %game.recalcScore(%cl); - return %game.SCORE_PER_FLAG_RETURN; - // --------------------------------------------------- -} - -function CTFGame::awardScoreStalemateReturn(%game, %cl) -{ - if (%game.SCORE_PER_STALEMATE_RETURN != 0) - { - messageClient(%cl, 'scoreStaleRetMsg', '\c0You received a %1 point bonus for a stalemate-breaking, flag return.', %game.SCORE_PER_STALEMATE_RETURN); - %cl.returnPts += %game.SCORE_PER_STALEMATE_RETURN; - } - %game.recalcScore(%cl); - return %game.SCORE_PER_STALEMATE_RETURN; -} - -// Asset Destruction scoring -function CTFGame::awardScoreGenDestroy(%game,%cl) -{ - %cl.genDestroys++; - if (%game.SCORE_PER_DESTROY_GEN != 0) - { - messageClient(%cl, 'msgGenDes', '\c0You received a %1 point bonus for destroying an enemy generator.', %game.SCORE_PER_DESTROY_GEN); - //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); - } - %game.recalcScore(%cl); - return %game.SCORE_PER_DESTROY_GEN; -} - -function CTFGame::awardScoreSensorDestroy(%game,%cl) -{ - %cl.sensorDestroys++; - if (%game.SCORE_PER_DESTROY_SENSOR != 0) - { - messageClient(%cl, 'msgSensorDes', '\c0You received a %1 point bonus for destroying an enemy sensor.', %game.SCORE_PER_DESTROY_SENSOR); - //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); - } - %game.recalcScore(%cl); - return %game.SCORE_PER_DESTROY_SENSOR; -} - -function CTFGame::awardScoreTurretDestroy(%game,%cl) -{ - %cl.turretDestroys++; - if (%game.SCORE_PER_DESTROY_TURRET != 0) - { - messageClient(%cl, 'msgTurretDes', '\c0You received a %1 point bonus for destroying an enemy turret.', %game.SCORE_PER_DESTROY_TURRET); - //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); - } - %game.recalcScore(%cl); - return %game.SCORE_PER_DESTROY_TURRET; -} - -function CTFGame::awardScoreInvDestroy(%game,%cl) -{ - %cl.IStationDestroys++; - if (%game.SCORE_PER_DESTROY_ISTATION != 0) - { - messageClient(%cl, 'msgInvDes', '\c0You received a %1 point bonus for destroying an enemy inventory station.', %game.SCORE_PER_DESTROY_ISTATION); - //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); - } - %game.recalcScore(%cl); - return %game.SCORE_PER_DESTROY_ISTATION; -} - -function CTFGame::awardScoreVehicleStationDestroy(%game,%cl) -{ - %cl.VStationDestroys++; - if (%game.SCORE_PER_DESTROY_VSTATION != 0) - { - messageClient(%cl, 'msgVSDes', '\c0You received a %1 point bonus for destroying an enemy vehicle station.', %game.SCORE_PER_DESTROY_VSTATION); - //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); - } - %game.recalcScore(%cl); - return %game.SCORE_PER_DESTROY_VSTATION; -} - -// --------------------------------------------------------- -// z0dd - ZOD 3/30/02. MBP Teleporter -function CTFGame::awardScoreMPBTeleporterDestroy(%game,%cl) -{ - %cl.mpbtstationDestroys++; - if (%game.SCORE_PER_DESTROY_MPBTSTATION != 0) - { - messageClient(%cl, 'msgMPBTeleDes', '\c0You received a %1 point bonus for destroying an enemy MPB teleport station.', %game.SCORE_PER_DESTROY_MPBTSTATION); - //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); - } - %game.recalcScore(%cl); - return %game.SCORE_PER_DESTROY_MPBTSTATION; -} -// --------------------------------------------------------- - -function CTFGame::awardScoreSolarDestroy(%game,%cl) -{ - %cl.SolarDestroys++; - if (%game.SCORE_PER_DESTROY_SOLAR != 0) - { - messageClient(%cl, 'msgSolarDes', '\c0You received a %1 point bonus for destroying an enemy solar panel.', %game.SCORE_PER_DESTROY_SOLAR); - //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); - } - %game.recalcScore(%cl); - return %game.SCORE_PER_DESTROY_SOLAR; -} - -function CTFGame::awardScoreSentryDestroy(%game,%cl) -{ - %cl.sentryDestroys++; - if (%game.SCORE_PER_DESTROY_SENTRY != 0) - { - messageClient(%cl, 'msgSentryDes', '\c0You received a %1 point bonus for destroying an enemy sentry turret.', %game.SCORE_PER_DESTROY_SENTRY); - //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); - } - %game.recalcScore(%cl); - return %game.SCORE_PER_DESTROY_SENTRY; -} - -function CTFGame::awardScoreDepSensorDestroy(%game,%cl) -{ - %cl.depSensorDestroys++; - if (%game.SCORE_PER_DESTROY_DEP_SENSOR != 0) - { - messageClient(%cl, 'msgDepSensorDes', '\c0You received a %1 point bonus for destroying an enemy deployable sensor.', %game.SCORE_PER_DESTROY_DEP_SENSOR); // z0dd - ZOD, 8/15/02. Added "sensor" - //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); - } - %game.recalcScore(%cl); - return %game.SCORE_PER_DESTROY_DEP_SENSOR; -} - -function CTFGame::awardScoreDepTurretDestroy(%game,%cl) -{ - %cl.depTurretDestroys++; - if (%game.SCORE_PER_DESTROY_DEP_TUR != 0) - { - messageClient(%cl, 'msgDepTurDes', '\c0You received a %1 point bonus for destroying an enemy deployed turret.', %game.SCORE_PER_DESTROY_DEP_TUR); - //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); - } - %game.recalcScore(%cl); - return %game.SCORE_PER_DESTROY_DEP_TUR; -} - -function CTFGame::awardScoreDepStationDestroy(%game,%cl) -{ - %cl.depStationDestroys++; - if (%game.SCORE_PER_DESTROY_DEP_INV != 0) - { - messageClient(%cl, 'msgDepInvDes', '\c0You received a %1 point bonus for destroying an enemy deployed station.', %game.SCORE_PER_DESTROY_DEP_INV); - //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); - } - %game.recalcScore(%cl); - return %game.SCORE_PER_DESTROY_DEP_INV; -} - -// --------------------------------------------------------- -// z0dd - ZOD, 10/03/02. Penalty for TKing equiptment. -function CTFGame::awardScoreTkDestroy(%game, %cl) -{ - %cl.tkDestroys++; - if (%game.SCORE_PER_TK_DESTROY != 0) - { - messageClient(%cl, 'msgTkDes', '\c0You have been penalized %1 points for destroying your teams equiptment.', %game.SCORE_PER_TK_DESTROY); - } - %game.recalcScore(%cl); - return %game.SCORE_PER_TK_DESTROY; -} -// --------------------------------------------------------- - -function CTFGame::awardScoreGenDefend(%game, %killerID) -{ - %killerID.genDefends++; - if (%game.SCORE_PER_GEN_DEFEND != 0) - { - messageClient(%killerID, 'msgGenDef', '\c0You received a %1 point bonus for defending a generator.', %game.SCORE_PER_GEN_DEFEND); - messageTeamExcept(%killerID, 'msgGenDef', '\c2%1 defended our generator from an attack.', %killerID.name); // z0dd - ZOD, 8/15/02. Tell team - //messageTeamExcept(%killerID, 'msgGenDef', '\c0Teammate %1 received a %2 point bonus for defending a generator.', %killerID.name, %game.SCORE_PER_GEN_DEFEND); - } - %game.recalcScore(%cl); - return %game.SCORE_PER_GEN_DEFEND; -} - -function CTFGame::awardScoreCarrierKill(%game, %killerID) -{ - %killerID.carrierKills++; - if (%game.SCORE_PER_CARRIER_KILL != 0) - { - messageClient(%killerID, 'msgCarKill', '\c0You received a %1 point bonus for stopping the enemy flag carrier!', %game.SCORE_PER_CARRIER_KILL); - messageTeamExcept(%killerID, 'msgCarKill', '\c2%1 stopped the enemy flag carrier.', %killerID.name); // z0dd - ZOD, 8/15/02. Tell team - //messageTeamExcept(%killerID, 'msgCarKill', '\c0Teammate %1 received a %2 point bonus for stopping the enemy flag carrier!', %killerID.name, %game.SCORE_PER_CARRIER_KILL); - } - %game.recalcScore(%killerID); - return %game.SCORE_PER_CARRIER_KILL; -} - -function CTFGame::awardScoreFlagDefend(%game, %killerID) -{ - %killerID.flagDefends++; - if (%game.SCORE_PER_FLAG_DEFEND != 0) - { - messageClient(%killerID, 'msgFlagDef', '\c0You received a %1 point bonus for defending your flag!', %game.SCORE_PER_FLAG_DEFEND); - messageTeamExcept(%killerID, 'msgFlagDef', '\c2%1 defended our flag.', %killerID.name); // z0dd - ZOD, 8/15/02. Tell team - //messageTeamExcept(%killerID, 'msgFlagDef', '\c0Teammate %1 received a %2 point bonus for defending your flag!', %killerID.name, %game.SCORE_PER_FLAG_DEFEND); - } - %game.recalcScore(%killerID); - return %game.SCORE_PER_FLAG_DEFEND; -} - -function CTFGame::awardScoreEscortAssist(%game, %killerID) -{ - %killerID.escortAssists++; - if (%game.SCORE_PER_ESCORT_ASSIST != 0) - { - messageClient(%killerID, 'msgEscAsst', '\c0You received a %1 point bonus for protecting the flag carrier!', %game.SCORE_PER_ESCORT_ASSIST); - messageTeamExcept(%killerID, 'msgEscAsst', '\c2%1 protected our flag carrier.', %killerID.name); // z0dd - ZOD, 8/15/02. Tell team - //messageTeamExcept(%killerID, 'msgEscAsst', '\c0Teammate %1 received a %2 point bonus for protecting the flag carrier!', %killerID.name, %game.SCORE_PER_ESCORT_ASSIST); - } - %game.recalcScore(%killerID); - return %game.SCORE_PER_ESCORT_ASSIST; -} - -function CTFGame::resetScore(%game, %client) -{ - %client.offenseScore = 0; - %client.kills = 0; - %client.deaths = 0; - %client.suicides = 0; - %client.escortAssists = 0; - %client.teamKills = 0; - %client.tkDestroys = 0; // z0dd - ZOD, 10/03/02. Penalty for tking equiptment. - %client.flagCaps = 0; - %client.flagGrabs = 0; - %client.genDestroys = 0; - %client.sensorDestroys = 0; - %client.turretDestroys = 0; - %client.iStationDestroys = 0; - %client.vstationDestroys = 0; - %client.mpbtstationDestroys = 0; // z0dd - ZOD 3/30/02. MPB Teleporter - %client.solarDestroys = 0; - %client.sentryDestroys = 0; - %client.depSensorDestroys = 0; - %client.depTurretDestroys = 0; - %client.depStationDestroys = 0; - %client.vehicleScore = 0; - %client.vehicleBonus = 0; - - %client.flagDefends = 0; - %client.defenseScore = 0; - %client.genDefends = 0; - %client.carrierKills = 0; - %client.escortAssists = 0; - %client.turretKills = 0; - %client.mannedTurretKills = 0; - %client.flagReturns = 0; - %client.genRepairs = 0; - %client.SensorRepairs =0; - %client.TurretRepairs =0; - %client.StationRepairs =0; - %client.VStationRepairs =0; - %client.mpbtstationRepairs = 0; // z0dd - ZOD 3/30/02. MPB Teleporter - %client.solarRepairs =0; - %client.sentryRepairs =0; - %client.depInvRepairs =0; - %client.depTurretRepairs=0; - %client.returnPts = 0; - %client.score = 0; -} - -function CTFGame::objectRepaired(%game, %obj, %objName) -{ - %item = %obj.getDataBlock().getName(); - switch$ (%item) - { - case generatorLarge : - %game.genOnRepaired(%obj, %objName); - case sensorMediumPulse : - %game.sensorOnRepaired(%obj, %objName); - case sensorLargePulse : - %game.sensorOnRepaired(%obj, %objName); - case stationInventory : - %game.stationOnRepaired(%obj, %objName); - case turretBaseLarge : - %game.turretOnRepaired(%obj, %objName); - case stationVehicle : - %game.vStationOnRepaired(%obj, %objName); - case MPBTeleporter : // z0dd - ZOD 3/30/02. MPB Teleporter - %game.mpbTStationOnRepaired(%obj, %objName); - case solarPanel : - %game.solarPanelOnRepaired(%obj, %objName); - case sentryTurret : - %game.sentryTurretOnRepaired(%obj, %objName); - case TurretDeployedWallIndoor: - %game.depTurretOnRepaired(%obj, %objName); - case TurretDeployedFloorIndoor: - %game.depTurretOnRepaired(%obj, %objName); - case TurretDeployedCeilingIndoor: - %game.depTurretOnRepaired(%obj, %objName); - case TurretDeployedOutdoor: - %game.depTurretOnRepaired(%obj, %objName); - } - %obj.wasDisabled = false; -} - -function CTFGame::genOnRepaired(%game, %obj, %objName) -{ - - if (%game.testValidRepair(%obj)) - { - %repairman = %obj.repairedBy; - teamRepairMessage(%repairman, 'msgGenRepaired', '\c0%1 repaired a %2 Generator!', %repairman.name, %obj.nameTag); - %game.awardScoreGenRepair(%obj.repairedBy); - } -} - -function CTFGame::stationOnRepaired(%game, %obj, %objName) -{ - if (%game.testValidRepair(%obj)) - { - %repairman = %obj.repairedBy; - teamRepairMessage(%repairman, 'msgStationRepaired', '\c0%1 repaired a %2 Inventory Station!', %repairman.name, %obj.nameTag); - %game.awardScoreStationRepair(%obj.repairedBy); - } -} - -function CTFGame::sensorOnRepaired(%game, %obj, %objName) -{ - if (%game.testValidRepair(%obj)) - { - %repairman = %obj.repairedBy; - teamRepairMessage(%repairman, 'msgSensorRepaired', '\c0%1 repaired a %2 Pulse Sensor!', %repairman.name, %obj.nameTag); - %game.awardScoreSensorRepair(%obj.repairedBy); - } -} - -function CTFGame::turretOnRepaired(%game, %obj, %objName) -{ - if (%game.testValidRepair(%obj)) - { - %repairman = %obj.repairedBy; - teamRepairMessage(%repairman, 'msgTurretRepaired', '\c0%1 repaired a %2 Turret!', %repairman.name, %obj.nameTag); - %game.awardScoreTurretRepair(%obj.repairedBy); - } -} - -function CTFGame::vStationOnRepaired(%game, %obj, %objName) -{ - if (%game.testValidRepair(%obj)) - { - %repairman = %obj.repairedBy; - teamRepairMessage(%repairman, 'msgvstationRepaired', '\c0%1 repaired a Vehicle Station!', %repairman.name); - %game.awardScoreVStationRepair(%obj.repairedBy); - } -} - -// z0dd - ZOD 3/17/02. Score for repairing MPB Teleporter station. -function CTFGame::mpbTStationOnRepaired(%game, %obj, %objName) -{ - if (%game.testValidRepair(%obj)) - { - %repairman = %obj.repairedBy; - teamRepairMessage(%repairman, 'msgTeleporterRepaired', '\c0%1 repaired a MPB Teleport Station!', %repairman.name); - %game.awardScoreMpbTStationRepair(%obj.repairedBy); - } -} - -function CTFGame::solarPanelOnRepaired(%game, %obj, %objName) -{ - if (%game.testValidRepair(%obj)) - { - %repairman = %obj.repairedBy; - teamRepairMessage(%repairman, 'msgsolarRepaired', '\c0%1 repaired a %2 Solar Panel!', %repairman.name, %obj.nameTag); - %game.awardScoreSolarRepair(%obj.repairedBy); - } -} - -function CTFGame::sentryTurretOnRepaired(%game, %obj, %objName) -{ - if (%game.testValidRepair(%obj)) - { - %repairman = %obj.repairedBy; - teamRepairMessage(%repairman, 'msgsentryTurretRepaired', '\c0%1 repaired a %2 Sentry Turret!', %repairman.name, %obj.nameTag); - %game.awardScoreSentryRepair(%obj.repairedBy); - } -} - -function CTFGame::depTurretOnRepaired(%game, %obj, %objName) -{ - if (%game.testValidRepair(%obj)) - { - %repairman = %obj.repairedBy; - teamRepairMessage(%repairman, 'msgdepTurretRepaired', '\c0%1 repaired a %2 Deployable Turret!', %repairman.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Added this line - %game.awardScoreDepTurretRepair(%obj.repairedBy); - } -} - -function CTFGame::depInvOnRepaired(%game, %obj, %objName) -{ - if (%game.testValidRepair(%obj)) - { - teamRepairMessage(%repairman, 'msgdepInvRepaired', '\c0%1 repaired a %2 Deployable Inventory!', %repairman.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Added this line - %repairman = %obj.repairedBy; - %game.awardScoreDepInvRepair(%obj.repairedBy); - } -} - -function CTFGame::awardScoreGenRepair(%game, %cl) -{ - %cl.genRepairs++; - if (%game.SCORE_PER_REPAIR_GEN != 0) - { - messageClient(%cl, 'msgGenRep', '\c0You received a %1 point bonus for repairing a generator.', %game.SCORE_PER_REPAIR_GEN); - } - %game.recalcScore(%cl); -} - -function CTFGame::awardScoreStationRepair(%game, %cl) -{ - %cl.stationRepairs++; - if (%game.SCORE_PER_REPAIR_ISTATION != 0) - { - messageClient(%cl, 'msgIStationRep', '\c0You received a %1 point bonus for repairing a inventory station.', %game.SCORE_PER_REPAIR_ISTATION); - } - %game.recalcScore(%cl); -} - -function CTFGame::awardScoreSensorRepair(%game, %cl) -{ - %cl.sensorRepairs++; - if (%game.SCORE_PER_REPAIR_SENSOR != 0) - { - messageClient(%cl, 'msgSensorRep', '\c0You received a %1 point bonus for repairing a sensor.', %game.SCORE_PER_REPAIR_SENSOR); - } - %game.recalcScore(%cl); -} - -function CTFGame::awardScoreTurretRepair(%game, %cl) -{ - %cl.TurretRepairs++; - if (%game.SCORE_PER_REPAIR_TURRET != 0) - { - messageClient(%cl, 'msgTurretRep', '\c0You received a %1 point bonus for repairing a base turret.', %game.SCORE_PER_REPAIR_TURRET); - } - %game.recalcScore(%cl); -} - -function CTFGame::awardScoreVStationRepair(%game, %cl) -{ - %cl.VStationRepairs++; - if (%game.SCORE_PER_REPAIR_VSTATION != 0) - { - messageClient(%cl, 'msgVStationRep', '\c0You received a %1 point bonus for repairing a vehicle station.', %game.SCORE_PER_REPAIR_VSTATION); - } - %game.recalcScore(%cl); -} - -// z0dd - ZOD 3/17/02. Score for repairing MPB Teleporter station. -function CTFGame::awardScoreMpbTStationRepair(%game, %cl) -{ - %cl.mpbtstationRepairs++; - if (%game.SCORE_PER_REPAIR_MPBTSTATION != 0) - { - messageClient(%cl, 'msgVStationRep', '\c0You received a %1 point bonus for repairing a MPB teleporter station.', %game.SCORE_PER_REPAIR_TSTATION); - } - %game.recalcScore(%cl); -} - -function CTFGame::awardScoreSolarRepair(%game, %cl) -{ - %cl.solarRepairs++; - if (%game.SCORE_PER_REPAIR_SOLAR != 0) - { - messageClient(%cl, 'msgsolarRep', '\c0You received a %1 point bonus for repairing a solar panel.', %game.SCORE_PER_REPAIR_SOLAR); - } - %game.recalcScore(%cl); -} - -function CTFGame::awardScoreSentryRepair(%game, %cl) -{ - %cl.sentryRepairs++; - if (%game.SCORE_PER_REPAIR_SENTRY != 0) - { - messageClient(%cl, 'msgSentryRep', '\c0You received a %1 point bonus for repairing a sentry turret.', %game.SCORE_PER_REPAIR_SENTRY); - } - %game.recalcScore(%cl); -} - -function CTFGame::awardScoreDepTurretRepair(%game, %cl) -{ - %cl.depTurretRepairs++; - if (%game.SCORE_PER_REPAIR_DEP_TUR != 0) - { - messageClient(%cl, 'msgDepTurretRep', '\c0You received a %1 point bonus for repairing a deployed turret.', %game.SCORE_PER_REPAIR_DEP_TUR); - } - %game.recalcScore(%cl); -} - -function CTFGame::awardScoreDepInvRepair(%game, %cl) -{ - %cl.depInvRepairs++; - if (%game.SCORE_PER_REPAIR_DEP_INV != 0) - { - messageClient(%cl, 'msgDepInvRep', '\c0You received a %1 point bonus for repairing a deployed station.', %game.SCORE_PER_REPAIR_DEP_INV); - } - %game.recalcScore(%cl); -} - -function CTFGame::enterMissionArea(%game, %playerData, %player) -{ - if(%player.getState() $= "Dead") - return; - %player.client.outOfBounds = false; - messageClient(%player.client, 'EnterMissionArea', '\c1You are back in the mission area.'); - logEcho(%player.client.nameBase@" (pl "@%player@"/cl "@%player.client@") entered mission area"); - - //the instant a player leaves the mission boundary, the flag is dropped, and the return is scheduled... - if (%player.holdingFlag > 0) - { - cancel($FlagReturnTimer[%player.holdingFlag]); - $FlagReturnTimer[%player.holdingFlag] = ""; - } -} - -function CTFGame::leaveMissionArea(%game, %playerData, %player) -{ - if(%player.getState() $= "Dead") - return; - // maybe we'll do this just in case - %player.client.outOfBounds = true; - // if the player is holding a flag, strip it and throw it back into the mission area - // otherwise, just print a message - if(%player.holdingFlag > 0) - %game.boundaryLoseFlag(%player); - else - messageClient(%player.client, 'MsgLeaveMissionArea', '\c1You have left the mission area.~wfx/misc/warning_beep.wav'); - logEcho(%player.client.nameBase@" (pl "@%player@"/cl "@%player.client@") left mission area"); -} - -function CTFGame::boundaryLoseFlag(%game, %player) -{ - // this is called when a player goes out of the mission area while holding - // the enemy flag. - make sure the player is still out of bounds - if (!%player.client.outOfBounds || !isObject(%player.holdingFlag)) - return; - - // ------------------------------------------------------------------------------ - // z0dd - ZOD - SquirrelOfDeath, 9/27/02. Delay on grabbing flag after tossing it - %player.flagTossWait = true; - %player.schedule(1000, resetFlagTossWait); - // ------------------------------------------------------------------------------ - - %client = %player.client; - %flag = %player.holdingFlag; - %flag.setVelocity("0 0 0"); - %flag.setTransform(%player.getWorldBoxCenter()); - %flag.setCollisionTimeout(%player); - - %held = %game.formatTime(getSimTime() - %game.flagHeldTime[%flag], false); // z0dd - ZOD, 8/15/02. How long did player hold flag? - - %game.playerDroppedFlag(%player); - - // now for the tricky part -- throwing the flag back into the mission area - // let's try throwing it back towards its "home" - %home = %flag.originalPosition; - %vecx = firstWord(%home) - firstWord(%player.getWorldBoxCenter()); - %vecy = getWord(%home, 1) - getWord(%player.getWorldBoxCenter(), 1); - %vecz = getWord(%home, 2) - getWord(%player.getWorldBoxCenter(), 2); - %vec = %vecx SPC %vecy SPC %vecz; - - // normalize the vector, scale it, and add an extra "upwards" component - %vecNorm = VectorNormalize(%vec); - %vec = VectorScale(%vecNorm, 1500); - %vec = vectorAdd(%vec, "0 0 500"); - - // z0dd - ZOD, 6/09/02. Remove anti-hover so flag can be thrown properly - %flag.static = false; - - // z0dd - ZOD, 10/02/02. Hack for flag collision bug. - %flag.searchSchedule = %game.schedule(10, "startFlagCollisionSearch", %flag); - - // apply the impulse to the flag object - %flag.applyImpulse(%player.getWorldBoxCenter(), %vec); - - //don't forget to send the message - //messageClient(%player.client, 'MsgCTFFlagDropped', '\c1You have left the mission area and lost the flag.~wfx/misc/flag_drop.wav', 0, 0, %player.holdingFlag.team); - - // z0dd - ZOD 3/30/02. Above message was sending the wrong varible to objective hud. - messageClient(%player.client, 'MsgCTFFlagDropped', '\c1You have left the mission area and lost the flag. (Held: %4)~wfx/misc/flag_drop.wav', %client.name, 0, %flag.team, %held); // Yogi, 8/18/02. 3rd param changed 0 -> %client.name - logEcho(%player.client.nameBase@" (pl "@%player@"/cl "@%player.client@") lost flag (out of bounds)"@" (Held: "@%held@")"); -} - -function CTFGame::dropFlag(%game, %player) -{ - if(%player.holdingFlag > 0) - { - if (!%player.client.outOfBounds) - %player.throwObject(%player.holdingFlag); - else - %game.boundaryLoseFlag(%player); - } -} - -function CTFGame::applyConcussion(%game, %player) -{ - %game.dropFlag( %player ); -} - -function CTFGame::vehicleDestroyed(%game, %vehicle, %destroyer) -{ - //vehicle name - %data = %vehicle.getDataBlock(); - //%vehicleType = getTaggedString(%data.targetNameTag) SPC getTaggedString(%data.targetTypeTag); - %vehicleType = getTaggedString(%data.targetTypeTag); - if(%vehicleType !$= "MPB") - %vehicleType = strlwr(%vehicleType); - - %enemyTeam = ( %destroyer.team == 1 ) ? 2 : 1; - - %scorer = 0; - %multiplier = 1; - - %passengers = 0; - for(%i = 0; %i < %data.numMountPoints; %i++) - if(%vehicle.getMountNodeObject(%i)) - %passengers++; - - //what destroyed this vehicle - if(%destroyer.client) - { - //it was a player, or his mine, satchel, whatever... - %destroyer = %destroyer.client; - %scorer = %destroyer; - - // determine if the object used was a mine - if(%vehicle.lastDamageType == $DamageType::Mine) - %multiplier = 2; - } - else if(%destroyer.getClassName() $= "Turret") - { - if(%destroyer.getControllingClient()) - { - //manned turret - %destroyer = %destroyer.getControllingClient(); - %scorer = %destroyer; - } - else - { - %destroyerName = "A turret"; - %multiplier = 0; - } - } - else if(%destroyer.getDataBlock().catagory $= "Vehicles") - { - // Vehicle vs vehicle kill! - if(%name $= "BomberFlyer" || %name $= "AssaultVehicle") - %gunnerNode = 1; - else - %gunnerNode = 0; - - if(%destroyer.getMountNodeObject(%gunnerNode)) - { - %destroyer = %destroyer.getMountNodeObject(%gunnerNode).client; - %scorer = %destroyer; - } - %multiplier = 3; - } - else // Is there anything else we care about? - return; - - - if(%destroyerName $= "") - %destroyerName = %destroyer.name; - - if(%vehicle.team == %destroyer.team) // team kill - { - %pref = (%vehicleType $= "Assault Tank") ? "an" : "a"; - messageAll( 'msgVehicleTeamDestroy', '\c0%1 TEAMKILLED %3 %2!', %destroyerName, %vehicleType, %pref); - } - - else // legit kill - { - //messageTeamExcept(%destroyer, 'msgVehicleDestroy', '\c0%1 destroyed an enemy %2.', %destroyerName, %vehicleType); // z0dd - ZOD, 8/20/02. not needed with new messenger on line below - teamDestroyMessage(%destroyer, 'msgVehDestroyed', '\c5%1 destroyed an enemy %2!', %destroyerName, %vehicleType); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - messageTeam(%enemyTeam, 'msgVehicleDestroy', '\c0%1 destroyed your team\'s %2.', %destroyerName, %vehicleType); - //messageClient(%destroyer, 'msgVehicleDestroy', '\c0You destroyed an enemy %1.', %vehicleType); - - if(%scorer) - { - %value = %game.awardScoreVehicleDestroyed(%scorer, %vehicleType, %multiplier, %passengers); - %game.shareScore(%value); - } - } -} - -function CTFGame::awardScoreVehicleDestroyed(%game, %client, %vehicleType, %mult, %passengers) -{ - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - - if(%vehicleType $= "Grav Cycle") - %base = %game.SCORE_PER_DESTROY_WILDCAT; - else if(%vehicleType $= "Assault Tank") - %base = %game.SCORE_PER_DESTROY_TANK; - else if(%vehicleType $= "MPB") - %base = %game.SCORE_PER_DESTROY_MPB; - else if(%vehicleType $= "Turbograv") - %base = %game.SCORE_PER_DESTROY_SHRIKE; - else if(%vehicleType $= "Bomber") - %base = %game.SCORE_PER_DESTROY_BOMBER; - else if(%vehicleType $= "Heavy Transport") - %base = %game.SCORE_PER_DESTROY_TRANSPORT; - - %total = ( %base * %mult ) + ( %passengers * %game.SCORE_PER_PASSENGER ); - - %client.vehicleScore += %total; - - messageClient(%client, 'msgVehicleScore', '\c0You received a %1 point bonus for destroying an enemy %2.', %total, %vehicleType); - %game.recalcScore(%client); - return %total; -} - -function CTFGame::shareScore(%game, %client, %amount) -{ - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - - //error("share score of"SPC %amount SPC "from client:" SPC %client); - // all of the player in the bomber and tank share the points - // gained from any of the others - %vehicle = %client.vehicleMounted; - if(!%vehicle) - return 0; - %vehicleType = getTaggedString(%vehicle.getDataBlock().targetTypeTag); - if(%vehicleType $= "Bomber" || %vehicleType $= "Assault Tank") - { - for(%i = 0; %i < %vehicle.getDataBlock().numMountPoints; %i++) - { - %occupant = %vehicle.getMountNodeObject(%i); - if(%occupant) - { - %occCl = %occupant.client; - if(%occCl != %client && %occCl.team == %client.team) - { - // the vehicle has a valid teammate at this node - // share the score with them - %occCl.vehicleBonus += %amount; - %game.recalcScore(%occCl); - } - } - } - - } -} - -function CTFGame::awardScoreTurretKill(%game, %victimID, %implement) -{ - if ((%killer = %implement.getControllingClient()) != 0) //award whoever might be controlling the turret - { - if (%killer == %victimID) - %game.awardScoreSuicide(%victimID); - else if (%killer.team == %victimID.team) //player controlling a turret killed a teammate - { - %killer.teamKills++; - %game.awardScoreTurretTeamKill(%victimID, %killer); - %game.awardScoreDeath(%victimID); - } - else - { - %killer.mannedturretKills++; - %game.recalcScore(%killer); - %game.awardScoreDeath(%victimID); - } - } - else if ((%killer = %implement.owner) != 0) //if it isn't controlled, award score to whoever deployed it - { - if (%killer.team == %victimID.team) - { - %game.awardScoreDeath(%victimID); - } - else - { - %killer.turretKills++; - %game.recalcScore(%killer); - %game.awardScoreDeath(%victimID); - } - } - //default is, no one was controlling it, no one owned it. No score given. -} - -function CTFGame::testKill(%game, %victimID, %killerID) -{ - return ((%killerID !=0) && (%victimID.team != %killerID.team)); -} - -function CTFGame::awardScoreKill(%game, %killerID) -{ - %killerID.kills++; - %game.recalcScore(%killerID); - return %game.SCORE_PER_KILL; -} - - -function checkVehicleCamping( %team ) -{ - %position = $flagPos[%team]; - %radius = 5; - InitContainerRadiusSearch(%position, %radius, $TypeMasks::VehicleObjectType ); - - while ((%vehicle = containerSearchNext()) != 0) - { - %dist = containerSearchCurrRadDamageDist(); - - if (%dist > %radius) - continue; - else - { - //if( %vehicle.team == %team ) - applyVehicleCampDamage( %vehicle ); - } - } - - if( %team == 1 ) - Game.campThread_1 = schedule( 1000, 0, "checkVehicleCamping", 1 ); - else - Game.campThread_2 = schedule( 1000, 0, "checkVehicleCamping", 2 ); -} - -function applyVehicleCampDamage( %vehicle ) -{ - if( !isObject( %vehicle ) ) - return; - - if( %vehicle.getDamageState() $= "Destroyed" ) - return; - - %client = %vehicle.getMountNodeObject(0).client; // grab the pilot - - messageClient( %client, 'serverMessage', "Can't park vehicles in flag zones!" ); - %vehicle.getDataBlock().damageObject( %vehicle, 0, "0 0 0", 0.5, 0); -} - -// z0dd - ZOD, 10/02/02. Hack for flag collision bug. -function CTFGame::startFlagCollisionSearch(%game, %flag) -{ - %flag.searchSchedule = %game.schedule(10, "startFlagCollisionSearch", %flag); // SquirrelOfDeath, 10/02/02. Moved from after the while loop - %pos = %flag.getWorldBoxCenter(); - InitContainerRadiusSearch( %pos, 1.0, $TypeMasks::VehicleObjectType | $TypeMasks::CorpseObjectType | $TypeMasks::PlayerObjectType ); - while((%found = containerSearchNext()) != 0) - { - %flag.getDataBlock().onCollision(%flag, %found); - // SquirrelOfDeath, 10/02/02. Removed break to catch all players possibly intersecting with flag - } -} - - - +// DisplayName = Capture the Flag + +//--- GAME RULES BEGIN --- +//Prevent enemy from capturing your flag +//Score one point for grabbing the enemy's flag +//To capture, your flag must be at its stand +//Score 100 points each time enemy flag is captured +//--- GAME RULES END --- + +$InvBanList[CTF, "MiningTool"] = 1; + +//exec the AI scripts +exec("scripts/aiCTF.cs"); + +//-- tracking --- +function CTFGame::initGameVars(%game) +{ + // --------------------------------------------------- + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + %game.SCORE_PER_SUICIDE = 0; // z0dd - ZOD, 8/19/02. No penalty for suicide! Was -10 + %game.SCORE_PER_TEAMKILL = -10; + %game.SCORE_PER_DEATH = 0; + %game.SCORE_PER_TK_DESTROY = -10; // z0dd - ZOD, 10/03/02. Penalty for TKing equiptment. + + %game.SCORE_PER_KILL = 10; + %game.SCORE_PER_PLYR_FLAG_CAP = 30; + %game.SCORE_PER_PLYR_FLAG_TOUCH = 20; + %game.SCORE_PER_TEAM_FLAG_CAP = 100; + %game.SCORE_PER_TEAM_FLAG_TOUCH = 1; + %game.SCORE_PER_ESCORT_ASSIST = 5; + %game.SCORE_PER_HEADSHOT = 1; + %game.SCORE_PER_REARSHOT = 1; // z0dd - ZOD, 8/25/02. Added Lance rear shot messages + + %game.SCORE_PER_TURRET_KILL = 10; // controlled + %game.SCORE_PER_TURRET_KILL_AUTO = 3; // uncontrolled + %game.SCORE_PER_FLAG_DEFEND = 5; + %game.SCORE_PER_CARRIER_KILL = 5; + %game.SCORE_PER_FLAG_RETURN = 10; + %game.SCORE_PER_STALEMATE_RETURN = 15; + %game.SCORE_PER_GEN_DEFEND = 5; + + %game.SCORE_PER_DESTROY_GEN = 10; + %game.SCORE_PER_DESTROY_SENSOR = 4; + %game.SCORE_PER_DESTROY_TURRET = 5; + %game.SCORE_PER_DESTROY_ISTATION = 2; + %game.SCORE_PER_DESTROY_VSTATION = 5; + %game.SCORE_PER_DESTROY_MPBTSTATION = 3; // z0dd - ZOD, 4/24/02. MPB Teleporter + %game.SCORE_PER_DESTROY_SOLAR = 5; + %game.SCORE_PER_DESTROY_SENTRY = 4; + %game.SCORE_PER_DESTROY_DEP_SENSOR = 1; + %game.SCORE_PER_DESTROY_DEP_INV = 2; + %game.SCORE_PER_DESTROY_DEP_TUR = 3; + + %game.SCORE_PER_DESTROY_SHRIKE = 5; + %game.SCORE_PER_DESTROY_BOMBER = 8; + %game.SCORE_PER_DESTROY_TRANSPORT = 5; + %game.SCORE_PER_DESTROY_WILDCAT = 5; + %game.SCORE_PER_DESTROY_TANK = 8; + %game.SCORE_PER_DESTROY_MPB = 12; + %game.SCORE_PER_PASSENGER = 2; + + %game.SCORE_PER_REPAIR_GEN = 8; + %game.SCORE_PER_REPAIR_SENSOR = 1; + %game.SCORE_PER_REPAIR_TURRET = 4; + %game.SCORE_PER_REPAIR_ISTATION = 2; + %game.SCORE_PER_REPAIR_VSTATION = 4; + %game.SCORE_PER_REPAIR_MPBTSTATION = 3; // z0dd - ZOD, 4/24/02. MPB Teleporter + %game.SCORE_PER_REPAIR_SOLAR = 4; + %game.SCORE_PER_REPAIR_SENTRY = 2; + %game.SCORE_PER_REPAIR_DEP_TUR = 3; + %game.SCORE_PER_REPAIR_DEP_INV = 2; + + %game.FLAG_RETURN_DELAY = 45 * 1000; //45 seconds + + %game.TIME_CONSIDERED_FLAGCARRIER_THREAT = 3 * 1000; //after damaging enemy flag carrier + %game.RADIUS_GEN_DEFENSE = 20; //meters + %game.RADIUS_FLAG_DEFENSE = 20; //meters + + %game.TOUCH_DELAY_MS = 20000; //20 secs + + %game.fadeTimeMS = 2000; + + %game.notifyMineDist = 7.5; + + %game.stalemate = false; + %game.stalemateObjsVisible = false; + %game.stalemateTimeMS = 60000; + %game.stalemateFreqMS = 15000; + %game.stalemateDurationMS = 6000; + // --------------------------------------------------- + + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here +} + +package CTFGame +{ +function ShapeBaseData::onDestroyed(%data, %obj) +{ + %scorer = %obj.lastDamagedBy; + if(!isObject(%scorer)) + return; + + if( (%scorer.getType() & $TypeMasks::GameBaseObjectType) && %scorer.getDataBlock().catagory $= "Vehicles" ) + { + // z0dd - ZOD, 6/18/02. %name was never defined. + %name = %scorer.getDatablock().getName(); + if(%name $= "BomberFlyer" || %name $= "AssaultVehicle") + %gunnerNode = 1; + else + %gunnerNode = 0; + + if(%scorer.getMountNodeObject(%gunnerNode)) + { + %destroyer = %scorer.getMountNodeObject(%gunnerNode).client; + %scorer = %destroyer; + %damagingTeam = %scorer.team; + } + } + else if(%scorer.getClassName() $= "Turret") + { + if(%scorer.getControllingClient()) + { + //manned turret + %destroyer = %scorer.getControllingClient(); + %scorer = %destroyer; + %damagingTeam = %scorer.team; + } + else + { + return; //unmanned turret + } + } + if(!%damagingTeam) + %damagingTeam = %scorer.team; + + // z0dd - ZOD, 10/03/02. Total re-write from here down. + if(%damagingTeam == %obj.team) + { + if(!%obj.getDataBlock().deployedObject) + { + teamDestroyMessage(%scorer, 'msgTkDes', '\c5Teammate %1 destroyed your team\'s %2!', %scorer.name, Game.cleanWord(%obj.getDataBlock().targetTypeTag)); + Game.awardScoreTkDestroy(%scorer); + } + return; + } + + %objType = %obj.getDataBlock().getName(); + switch$ ( %objType ) + { + case "GeneratorLarge": + teamDestroyMessage(%scorer, 'msgGenDestroyed', '\c5%1 destroyed a %2 Generator!', %scorer.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + %score = game.awardScoreGenDestroy(%scorer); + + case "SolarPanel": + teamDestroyMessage(%scorer, 'msgSolarDestroyed', '\c5%1 destroyed a %2 Solar Panel!', %scorer.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + %score = game.awardScoreSolarDestroy(%scorer); + game.shareScore(%score, %score); + + case "SensorLargePulse": + teamDestroyMessage(%scorer, 'msgSensorDestroyed', '\c5%1 destroyed a %2 Sensor!', %scorer.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + %score = game.awardScoreSensorDestroy(%scorer); + + case "SensorMediumPulse": + teamDestroyMessage(%scorer, 'msgSensorDestroyed', '\c5%1 destroyed a %2 Sensor!', %scorer.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + %score = game.awardScoreSensorDestroy(%scorer); + + case "DeployedMotionSensor": + teamDestroyMessage(%scorer, 'msgDepSenDestroyed', '\c5%1 destroyed a Deployable Sensor!', %scorer.name); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + %score = game.awardScoreDepSensorDestroy(%scorer); + + case "DeployedPulseSensor": + teamDestroyMessage(%scorer, 'msgDepSenDestroyed', '\c5%1 destroyed a Deployable Sensor!', %scorer.name); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + %score = game.awardScoreDepSensorDestroy(%scorer); + + case "StationInventory": + teamDestroyMessage(%scorer, 'msgInvDestroyed', '\c5%1 destroyed a %2 Inventory Station!', %scorer.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + %score = game.awardScoreInvDestroy(%scorer); + + case "StationAmmo": + teamDestroyMessage(%scorer, 'msgInvDestroyed', '\c5%1 destroyed a %2 Ammo Station!', %scorer.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + %score = game.awardScoreInvDestroy(%scorer); + + case "StationVehicle": + teamDestroyMessage(%scorer, 'msgVehStationDestroyed', '\c5%1 destroyed a Vehicle Station!', %scorer.name); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + %score = game.awardScoreVehicleStationDestroy(%scorer); + + case "MPBTeleporter": // z0dd - ZOD, 4/24/02. MPB teleporter + teamDestroyMessage(%scorer, 'msgTeleporterDestroyed', '\c5%1 destroyed a MPB Teleport Station!', %scorer.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + %score = game.awardScoreMPBTeleporterDestroy(%scorer); + + case "DeployedStationInventory": + teamDestroyMessage(%scorer, 'msgDepInvDestroyed', '\c5%1 destroyed a Deployable Inventory!', %scorer.name); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + %score = game.awardScoreDepStationDestroy(%scorer); + + case "TurretBaseLarge": + teamDestroyMessage(%scorer, 'msgTurDestroyed', '\c5%1 destroyed a %2 Turret!', %scorer.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + %score = game.awardScoreTurretDestroy(%scorer); + + case "SentryTurret": + teamDestroyMessage(%scorer, 'msgSentryDestroyed', '\c5%1 destroyed a %2 Sentry Turret!', %scorer.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + %score = game.awardScoreSentryDestroy(%scorer); + + case "TurretDeployedFloorIndoor": + teamDestroyMessage(%scorer, 'msgDepTurDestroyed', '\c5%1 destroyed a Spider Clamp Turret!', %scorer.name); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + %score = game.awardScoreDepTurretDestroy(%scorer); + + case "TurretDeployedWallIndoor": + teamDestroyMessage(%scorer, 'msgDepTurDestroyed', '\c5%1 destroyed a Spider Clamp Turret!', %scorer.name); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + %score = game.awardScoreDepTurretDestroy(%scorer); + + case "TurretDeployedCeilingIndoor": + teamDestroyMessage(%scorer, 'msgDepTurDestroyed', '\c5%1 destroyed a Spider Clamp Turret!', %scorer.name); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + %score = game.awardScoreDepTurretDestroy(%scorer); + + case "TurretDeployedOutdoor": + teamDestroyMessage(%scorer, 'msgDepTurDestroyed', '\c5%1 destroyed a Landspike Turret!', %scorer.name); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + %score = game.awardScoreDepTurretDestroy(%scorer); + + default: + return; + } + + if(!%obj.soiledByEnemyRepair) + { + game.shareScore(%scorer, %score); + } +} + +function ShapeBaseData::onDisabled(%data, %obj) +{ + %obj.wasDisabled = true; + Parent::onDisabled(%data, %obj); +} + +function RepairGunImage::onRepair(%this, %obj, %slot) +{ + Parent::onRepair(%this, %obj, %slot); + %target = %obj.repairing; + if(%target && %target.team != %obj.team) + { + //error("Enemy stuff("@%obj@") is being repaired (by "@%target@")"); + %target.soiledByEnemyRepair = true; + } +} + +function Flag::objectiveInit(%data, %flag) +{ + if (!%flag.isTeamSkinned) + { + %pos = %flag.getTransform(); + %group = %flag.getGroup(); + } + %flag.originalPosition = %flag.getTransform(); + $flagPos[%flag.team] = %flag.originalPosition; + %flag.isHome = true; + %flag.carrier = ""; + %flag.grabber = ""; + setTargetSkin(%flag.getTarget(), CTFGame::getTeamSkin(CTFGame, %flag.team)); + setTargetSensorGroup(%flag.getTarget(), %flag.team); + setTargetAlwaysVisMask(%flag.getTarget(), 0x7); + setTargetRenderMask(%flag.getTarget(), getTargetRenderMask(%flag.getTarget()) | 0x2); + %flag.scopeWhenSensorVisible(true); + $flagStatus[%flag.team] = ""; + + //Point the flag and stand at each other + %group = %flag.getGroup(); + %count = %group.getCount(); + %flag.stand = ""; + for(%i = 0; %i < %count; %i++) + { + %this = %group.getObject(%i); + //--------------------------------------------------------------------------------------------------------------------------- + // z0dd - ZOD, 3/16/02. Added TSStatic, console spam fix. + if(%this.getClassName() !$= "InteriorInstance" && %this.getClassName() !$= "SimGroup" && %this.getClassName() !$= "TSStatic") + { + if(%this.getDataBlock().getName() $= "ExteriorFlagStand") + { + %flag.stand = %this; + %this.flag = %flag; + } + } + } + + // set the nametag on the target + setTargetName(%flag.getTarget(), CTFGame::getTeamName(CTFGame, %flag.team)); + + // create a marker on this guy + %flag.waypoint = new MissionMarker() { + position = %flag.getTransform(); + dataBlock = "FlagMarker"; + }; + MissionCleanup.add(%flag.waypoint); + + // create a target for this (there is no MissionMarker::onAdd script call) + %target = createTarget(%flag.waypoint, CTFGame::getTeamName( CTFGame, %flag.team), "", "", 'Base', %flag.team, 0); + setTargetAlwaysVisMask(%target, 0xffffffff); + + //store the flag in an array + $TeamFlag[%flag.team] = %flag; + + // -------------------------------------------------------- + // z0dd - ZOD, 5/26/02. Don't let flag hover over defenders + %flag.static = true; + + // ------------------------------------------------------------------------------------------- + // z0dd - ZOD, 10/03/02. Use triggers for flags that are at home, hack for flag collision bug. + %flag.trigger = new Trigger() + { + dataBlock = flagTrigger; + polyhedron = "-0.6 0.6 0.1 1.2 0.0 0.0 0.0 -1.2 0.0 0.0 0.0 2.5"; + position = %flag.position; + rotation = %flag.rotation; + }; + MissionCleanup.add(%flag.trigger); + %flag.trigger.flag = %flag; + // ------------------------------------------------------------------------------------------- +} + +function Flag::onEnterLiquid(%data, %obj, %coverage, %type) +{ + if(%type > 3) // 1-3 are water, 4+ is lava and quicksand(?) + { + //error("flag("@%obj@") is in liquid type" SPC %type); + game.schedule(3000, flagReturn, %obj); + } +} +}; + +//-------------------------------------------------------------------------- +// need to have this for the corporate maps which could not be fixed +function SimObject::clearFlagWaypoints(%this) +{ +} + +function WayPoint::clearFlagWaypoints(%this) +{ + logEcho("Removing flag waypoint: " @ %this); + if(%this.nameTag $= "Flag") + %this.delete(); +} + +function SimGroup::clearFlagWaypoints(%this) +{ + for(%i = %this.getCount() - 1; %i >= 0; %i--) + %this.getObject(%i).clearFlagWaypoints(); +} + +function CTFGame::getTeamSkin(%game, %team) +{ + if($host::tournamentMode) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + { + return $teamSkin[%team]; + } + + else + { + //error("CTFGame::getTeamSkin"); + if(!$host::useCustomSkins) + { + %terrain = MissionGroup.musicTrack; + //error("Terrain type is: " SPC %terrain); + switch$(%terrain) + { + case "lush": + if(%team == 1) + %skin = 'beagle'; + else if(%team == 2) + %skin = 'dsword'; + else %skin = 'base'; + + case "badlands": + if(%team == 1) + %skin = 'swolf'; + else if(%team == 2) + %skin = 'dsword'; + else %skin = 'base'; + + case "ice": + if(%team == 1) + %skin = 'swolf'; + else if(%team == 2) + %skin = 'beagle'; + else %skin = 'base'; + + case "desert": + if(%team == 1) + %skin = 'cotp'; + else if(%team == 2) + %skin = 'beagle'; + else %skin = 'base'; + + case "Volcanic": + if(%team == 1) + %skin = 'dsword'; + else if(%team == 2) + %skin = 'cotp'; + else %skin = 'base'; + + default: + if(%team == 2) + %skin = 'baseb'; + else %skin = 'base'; + } + } + else %skin = $teamSkin[%team]; + + //error("%skin = " SPC getTaggedString(%skin)); + return %skin; +} +} + +function CTFGame::getTeamName(%game, %team) +{ + // --------------------------------------------------- + // z0dd - ZOD 3/30/02. Only display default team names + //if ( isDemo() || $host::tournamentMode) + return $TeamName[%team]; + // --------------------------------------------------- +} + +//-------------------------------------------------------------------------- +function CTFGame::missionLoadDone(%game) +{ + //default version sets up teams - must be called first... + DefaultGame::missionLoadDone(%game); + + for(%i = 1; %i < (%game.numTeams + 1); %i++) + $teamScore[%i] = 0; + + // remove + MissionGroup.clearFlagWaypoints(); + + //reset some globals, just in case... + $dontScoreTimer[1] = false; + $dontScoreTimer[2] = false; + + echo( "starting camp thread..." ); + %game.campThread_1 = schedule( 1000, 0, "checkVehicleCamping", 1 ); + %game.campThread_2 = schedule( 1000, 0, "checkVehicleCamping", 2 ); +} + +function CTFGame::playerTouchFlag(%game, %player, %flag) +{ + %client = %player.client; + if ((%flag.carrier $= "") && (%player.getState() !$= "Dead")) + { + //flag isn't held and has been touched by a live player + if (%client.team == %flag.team) + %game.playerTouchOwnFlag(%player, %flag); + else + %game.playerTouchEnemyFlag(%player, %flag); + } + // toggle visibility of the flag + setTargetRenderMask(%flag.waypoint.getTarget(), %flag.isHome ? 0 : 1); +} + +function CTFGame::playerTouchOwnFlag(%game, %player, %flag) +{ + if(%flag.isHome) + { + if (%player.holdingFlag !$= "") + %game.flagCap(%player); + } + else + %game.flagReturn(%flag, %player); + + //call the AI function + %game.AIplayerTouchOwnFlag(%player, %flag); +} + +function CTFGame::playerTouchEnemyFlag(%game, %player, %flag) +{ + // --------------------------------------------------------------- + // z0dd, ZOD - 9/27/02. Player must wait to grab after throwing it + if((%player.flagTossWait !$= "") && %player.flagTossWait) + return false; + // --------------------------------------------------------------- + + cancel(%flag.searchSchedule); // z0dd - ZOD, 9/28/02. Hack for flag collision bug. SquirrelOfDeath, 10/02/02: Moved from PlayerTouchFlag + + cancel(%game.updateFlagThread[%flag]); // z0dd - ZOD, 8/4/02. Cancel this flag's thread to KineticPoet's flag updater + %game.flagHeldTime[%flag] = getSimTime(); // z0dd - ZOD, 8/15/02. Store time player grabbed flag. + + %client = %player.client; + %player.holdingFlag = %flag; //%player has this flag + %flag.carrier = %player; //this %flag is carried by %player + + %player.mountImage(FlagImage, $FlagSlot, true, %game.getTeamSkin(%flag.team)); + + %game.playerGotFlagTarget(%player); + //only cancel the return timer if the player is in bounds... + if (!%client.outOfBounds) + { + cancel($FlagReturnTimer[%flag]); + $FlagReturnTimer[%flag] = ""; + } + + //if this flag was "at home", see if both flags have now been taken + if (%flag.isHome) + { + // tiebreaker score + game.awardScoreFlagTouch( %client, %flag ); + + %startStalemate = false; + if ($TeamFlag[1] == %flag) + %startStalemate = !$TeamFlag[2].isHome; + else + %startStalemate = !$TeamFlag[1].isHome; + + if (%startStalemate) + %game.stalemateSchedule = %game.schedule(%game.stalemateTimeMS, beginStalemate); + + } + %flag.hide(true); + %flag.startFade(0, 0, false); + %flag.isHome = false; + if(%flag.stand) + %flag.stand.getDataBlock().onFlagTaken(%flag.stand);//animate, if exterior stand + + $flagStatus[%flag.team] = %client.nameBase; + %teamName = %game.getTeamName(%flag.team); + messageTeamExcept(%client, 'MsgCTFFlagTaken', '\c2Teammate %1 took the %2 flag.~wfx/misc/flag_snatch.wav', %client.name, %teamName, %flag.team, %client.nameBase); + messageTeam(%flag.team, 'MsgCTFFlagTaken', '\c2Your flag has been taken by %1!~wfx/misc/flag_taken.wav',%client.name, 0, %flag.team, %client.nameBase); + messageTeam(0, 'MsgCTFFlagTaken', '\c2%1 took the %2 flag.~wfx/misc/flag_snatch.wav', %client.name, %teamName, %flag.team, %client.nameBase); + messageClient(%client, 'MsgCTFFlagTaken', '\c2You took the %2 flag.~wfx/misc/flag_snatch.wav', %client.name, %teamName, %flag.team, %client.nameBase); + logEcho(%client.nameBase@" (pl "@%player@"/cl "@%client@") took team "@%flag.team@" flag"); + + //call the AI function + %game.AIplayerTouchEnemyFlag(%player, %flag); + + //if the player is out of bounds, then in 3 seconds, it should be thrown back towards the in bounds area... + if (%client.outOfBounds) + %game.schedule(3000, "boundaryLoseFlag", %player); +} + +function CTFGame::playerGotFlagTarget(%game, %player) +{ + %player.scopeWhenSensorVisible(true); + %target = %player.getTarget(); + setTargetRenderMask(%target, getTargetRenderMask(%target) | 0x2); + if(%game.stalemateObjsVisible) + setTargetAlwaysVisMask(%target, 0x7); +} + +function CTFGame::playerLostFlagTarget(%game, %player) +{ + %player.scopeWhenSensorVisible(false); + %target = %player.getTarget(); + setTargetRenderMask(%target, getTargetRenderMask(%target) & ~0x2); + // clear his always vis target mask + setTargetAlwaysVisMask(%target, (1 << getTargetSensorGroup(%target))); +} + +//---------------------------------------------------------------------------------------- +// z0dd - ZOD, 8/4/02: KineticPoet's flag updater code +function CTFGame::updateFlagTransform(%game, %flag) +{ + %flag.setTransform(%flag.getTransform()); + %game.updateFlagThread[%flag] = %game.schedule(100, "updateFlagTransform", %flag); +} +//---------------------------------------------------------------------------------------- + +function CTFGame::playerDroppedFlag(%game, %player) +{ + %client = %player.client; + %flag = %player.holdingFlag; + %game.updateFlagTransform(%flag); // z0dd - ZOD, 8/4/02, Call to KineticPoet's flag updater + %held = %game.formatTime(getSimTime() - %game.flagHeldTime[%flag], false); // z0dd - ZOD, 8/15/02. How long did player hold flag? + + %game.playerLostFlagTarget(%player); + + %player.holdingFlag = ""; //player isn't holding a flag anymore + %flag.carrier = ""; //flag isn't held anymore + $flagStatus[%flag.team] = ""; + + %player.unMountImage($FlagSlot); + %flag.hide(false); //Does the throwItem function handle this? + + %teamName = %game.getTeamName(%flag.team); + messageTeamExcept(%client, 'MsgCTFFlagDropped', '\c2Teammate %1 dropped the %2 flag. (Held: %4)~wfx/misc/flag_drop.wav', %client.name, %teamName, %flag.team, %held); // z0dd - ZOD, 8/15/02. How long flag was held + messageTeam(%flag.team, 'MsgCTFFlagDropped', '\c2Your flag has been dropped by %1! (Held: %4)~wfx/misc/flag_drop.wav', %client.name, 0, %flag.team, %held); // z0dd - ZOD, 8/15/02. How long flag was held + messageTeam(0, 'MsgCTFFlagDropped', '\c2%1 dropped the %2 flag. (Held: %4)~wfx/misc/flag_drop.wav', %client.name, %teamName, %flag.team, %held); // z0dd - ZOD, 8/15/02. How long flag was held + if(!%player.client.outOfBounds) + messageClient(%client, 'MsgCTFFlagDropped', '\c2You dropped the %2 flag. (Held: %4)~wfx/misc/flag_drop.wav', %client.name, %teamName, %flag.team, %held); // z0dd - ZOD, 8/15/02. How long flag was held + // Yogi, 8/18/02. 3rd param changed 0 -> %client.name + logEcho(%client.nameBase@" (pl "@%player@"/cl "@%client@") dropped team "@%flag.team@" flag"@" (Held: "@%held@")"); + + //don't duplicate the schedule if there's already one in progress... + if ($FlagReturnTimer[%flag] <= 0) + $FlagReturnTimer[%flag] = %game.schedule(%game.FLAG_RETURN_DELAY - %game.fadeTimeMS, "flagReturnFade", %flag); + + //call the AI function + %game.AIplayerDroppedFlag(%player, %flag); +} + +function CTFGame::flagCap(%game, %player) +{ + %client = %player.client; + + //Increment our caps.. + $Data::Caps[%client.guid]++; + + %flag = %player.holdingFlag; + %flag.carrier = ""; + + %held = %game.formatTime(getSimTime() - %game.flagHeldTime[%flag], false); // z0dd - ZOD, 8/15/02. How long did player hold flag? + + %game.playerLostFlagTarget(%player); + //award points to player and team + %teamName = %game.getTeamName(%flag.team); + messageTeamExcept(%client, 'MsgCTFFlagCapped', '\c2%1 captured the %2 flag! (Held: %5)~wfx/misc/flag_capture.wav', %client.name, %teamName, %flag.team, %client.team, %held); + messageTeam(%flag.team, 'MsgCTFFlagCapped', '\c2Your flag was captured by %1. (Held: %5)~wfx/misc/flag_lost.wav', %client.name, 0, %flag.team, %client.team, %held); + messageTeam(0, 'MsgCTFFlagCapped', '\c2%1 captured the %2 flag! (Held: %5)~wfx/misc/flag_capture.wav', %client.name, %teamName, %flag.team, %client.team, %held); + messageClient(%client, 'MsgCTFFlagCapped', '\c2You captured the %2 flag! (Held: %5)~wfx/misc/flag_capture.wav', %client.name, %teamName, %flag.team, %client.team, %held); // Yogi, 8/18/02. 3rd param changed 0 -> %client.name + + logEcho(%client.nameBase@" (pl "@%player@"/cl "@%client@") capped team "@%client.team@" flag"@" (Held: "@%held@")"); + %player.holdingFlag = ""; //no longer holding it. + %player.unMountImage($FlagSlot); + %game.awardScoreFlagCap(%client, %flag); + %game.flagReset(%flag); + + //call the AI function + %game.AIflagCap(%player, %flag); + + //if this cap didn't end the game, play the announcer... + if ($missionRunning) + { + if (%game.getTeamName(%client.team) $= 'Inferno') + messageAll("", '~wvoice/announcer/ann.infscores.wav'); + else if (%game.getTeamName(%client.team) $= 'Storm') + messageAll("", '~wvoice/announcer/ann.stoscores.wav'); + else if (%game.getTeamName(%client.team) $= 'Phoenix') + messageAll("", '~wvoice/announcer/ann.pxscore.wav'); + else if (%game.getTeamName(%client.team) $= 'Blood Eagle') + messageAll("", '~wvoice/announcer/ann.bescore.wav'); + else if (%game.getTeamName(%client.team) $= 'Diamond Sword') + messageAll("", '~wvoice/announcer/ann.dsscore.wav'); + else if (%game.getTeamName(%client.team) $= 'Starwolf') + messageAll("", '~wvoice/announcer/ann.swscore.wav'); + } +} + +function CTFGame::flagReturnFade(%game, %flag) +{ + $FlagReturnTimer[%flag] = %game.schedule(%game.fadeTimeMS, "flagReturn", %flag); + %flag.startFade(%game.fadeTimeMS, 0, true); +} + +function CTFGame::flagReturn(%game, %flag, %player) +{ + cancel($FlagReturnTimer[%flag]); + $FlagReturnTimer[%flag] = ""; + + if(%flag.team == 1) + %otherTeam = 2; + else + %otherTeam = 1; + %teamName = %game.getTeamName(%flag.team); + if (%player !$= "") + { + //a player returned it + %client = %player.client; + + //Increment flag returns + $Data::FlagReturns[%client.guid]++; + + messageTeamExcept(%client, 'MsgCTFFlagReturned', '\c2Teammate %1 returned your flag to base.~wfx/misc/flag_return.wav', %client.name, 0, %flag.team); + messageTeam(%otherTeam, 'MsgCTFFlagReturned', '\c2Enemy %1 returned the %2 flag.~wfx/misc/flag_return.wav', %client.name, %teamName, %flag.team); + messageTeam(0, 'MsgCTFFlagReturned', '\c2%1 returned the %2 flag.~wfx/misc/flag_return.wav', %client.name, %teamName, %flag.team); + messageClient(%client, 'MsgCTFFlagReturned', '\c2You returned your flag.~wfx/misc/flag_return.wav', %client.name, %teamName, %flag.team); // Yogi, 8/18/02. 3rd param changed 0 -> %client.name + logEcho(%client.nameBase@" (pl "@%player@"/cl "@%client@") returned team "@%flag.team@" flag"); + + // find out what type of return it is + // stalemate return? + + // --------------------------------------------------- + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + if(%game.stalemate) + { + //error("Stalemate return!!!"); + %game.awardScoreStalemateReturn(%player.client); + } + // regular return + else + { + %enemyFlagDist = vectorDist($flagPos[%flag.team], $flagPos[%otherTeam]); + %dist = vectorDist(%flag.position, %flag.originalPosition); + + %rawRatio = %dist/%enemyFlagDist; + %ratio = %rawRatio < 1 ? %rawRatio : 1; + %percentage = mFloor( (%ratio) * 10 ) * 10; + %game.awardScoreFlagReturn(%player.client, %percentage); + } + // --------------------------------------------------- + } + else + { + //returned due to timer + messageTeam(%otherTeam, 'MsgCTFFlagReturned', '\c2The %2 flag was returned to base.~wfx/misc/flag_return.wav', 0, %teamName, %flag.team); //because it was dropped for too long + messageTeam(%flag.team, 'MsgCTFFlagReturned', '\c2Your flag was returned.~wfx/misc/flag_return.wav', 0, 0, %flag.team); + messageTeam(0, 'MsgCTFFlagReturned', '\c2The %2 flag was returned to base.~wfx/misc/flag_return.wav', 0, %teamName, %flag.team); + logEcho("team "@%flag.team@" flag returned (timeout)"); + } + %game.flagReset(%flag); +} + +function CTFGame::showStalemateTargets(%game) +{ + cancel(%game.stalemateSchedule); + + //show the targets + for (%i = 1; %i <= 2; %i++) + { + %flag = $TeamFlag[%i]; + + //find the object to scope/waypoint.... + //render the target hud icon for slot 1 (a centermass flag) + //if we just set him as always sensor vis, it'll work fine. + if (isObject(%flag.carrier)) + setTargetAlwaysVisMask(%flag.carrier.getTarget(), 0x7); + } + //schedule the targets to hide + %game.stalemateObjsVisible = true; + %game.stalemateSchedule = %game.schedule(%game.stalemateDurationMS, hideStalemateTargets); +} + +function CTFGame::hideStalemateTargets(%game) +{ + cancel(%game.stalemateSchedule); + + //hide the targets + for (%i = 1; %i <= 2; %i++) + { + %flag = $TeamFlag[%i]; + if (isObject(%flag.carrier)) + { + %target = %flag.carrier.getTarget(); + setTargetAlwaysVisMask(%target, (1 << getTargetSensorGroup(%target))); + } + } + //schedule the targets to show again + %game.stalemateObjsVisible = false; + %game.stalemateSchedule = %game.schedule(%game.stalemateFreqMS, showStalemateTargets); +} + +function CTFGame::beginStalemate(%game) +{ + %game.stalemate = true; + %game.showStalemateTargets(); +} + +function CTFGame::endStalemate(%game) +{ + %game.stalemate = false; + %game.hideStalemateTargets(); + cancel(%game.stalemateSchedule); +} + +function CTFGame::flagReset(%game, %flag) +{ + cancel(%game.updateFlagThread[%flag]); // z0dd - ZOD, 8/4/02. Cancel this flag's thread to KineticPoet's flag updater + + //any time a flag is reset, kill the stalemate schedule + %game.endStalemate(); + + //make sure if there's a player carrying it (probably one out of bounds...), it is stripped first + if (isObject(%flag.carrier)) + { + //hide the target hud icon for slot 2 (a centermass flag - visible only as part of a teams sensor network) + %game.playerLostFlagTarget(%flag.carrier); + %flag.carrier.holdingFlag = ""; //no longer holding it. + %flag.carrier.unMountImage($FlagSlot); + } + //fades, restore default position, home, velocity, general status, etc. + %flag.setVelocity("0 0 0"); + %flag.setTransform(%flag.originalPosition); + %flag.isHome = true; + %flag.carrier = ""; + %flag.grabber = ""; + $flagStatus[%flag.team] = ""; + %flag.hide(false); + if(%flag.stand) + %flag.stand.getDataBlock().onFlagReturn(%flag.stand);//animate, if exterior stand + + //fade the flag in... + %flag.startFade(%game.fadeTimeMS, 0, false); + + // dont render base target + setTargetRenderMask(%flag.waypoint.getTarget(), 0); + + //call the AI function + %game.AIflagReset(%flag); + + // -------------------------------------------------------- + // z0dd - ZOD, 5/26/02. Don't let flag hover over defenders + %flag.static = true; + + // -------------------------------------------------------------------------- + // z0dd - ZOD, 9/28/02. Hack for flag collision bug. + if(%flag.searchSchedule !$="") + { + cancel(%flag.searchSchedule); + } + // -------------------------------------------------------------------------- +} + +function CTFGame::timeLimitReached(%game) +{ + logEcho("game over (timelimit)"); + %game.gameOver(); + cycleMissions(); +} + +function CTFGame::scoreLimitReached(%game) +{ + logEcho("game over (scorelimit)"); + %game.gameOver(); + cycleMissions(); +} + +function CTFGame::notifyMineDeployed(%game, %mine) +{ + //see if the mine is within 5 meters of the flag stand... + %mineTeam = %mine.sourceObject.team; + %homeFlag = $TeamFlag[%mineTeam]; + if (isObject(%homeFlag)) + { + %dist = VectorDist(%homeFlag.originalPosition, %mine.position); + if (%dist <= %game.notifyMineDist) + { + messageTeam(%mineTeam, 'MsgCTFFlagMined', "The flag has been mined.~wvoice/announcer/flag_minedFem.wav" ); + } + } +} + +function CTFGame::gameOver(%game) +{ + // z0dd - ZOD, 9/28/02. Hack for flag collision bug. + for(%f = 1; %f <= %game.numTeams; %f++) + { + cancel($TeamFlag[%f].searchSchedule); + } + + // ------------------------------------------- + // z0dd - ZOD, 9/28/02. Cancel camp schedules. + if( Game.campThread_1 !$= "" ) + cancel(Game.campThread_1); + + if( Game.campThread_2 !$= "" ) + cancel(Game.campThread_2); + // ------------------------------------------- + + //call the default + DefaultGame::gameOver(%game); + + //send the winner message + %winner = ""; + if ($teamScore[1] > $teamScore[2]) + { + %winner = %game.getTeamName(1); + %team = 1; + } + else if ($teamScore[2] > $teamScore[1]) + { + %winner = %game.getTeamName(2); + %team = 2; + } + + for (%i = 0; %i < ClientGroup.getCount(); %i++) + { + %cl = ClientGroup.getObject(%i); + if (%cl.team == %team) + $Data::Won[%cl.guid]++; + else + $Data::Lost[%cl.guid]++; + } + + //Ok, increment wins/losses + + if (%winner $= 'Storm') + messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.stowins.wav" ); + else if (%winner $= 'Inferno') + messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.infwins.wav" ); + else if (%winner $= 'Starwolf') + messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.swwin.wav" ); + else if (%winner $= 'Blood Eagle') + messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.bewin.wav" ); + else if (%winner $= 'Diamond Sword') + messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.dswin.wav" ); + else if (%winner $= 'Phoenix') + messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.pxwin.wav" ); + else + messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.gameover.wav" ); + + messageAll('MsgClearObjHud', ""); + for(%i = 0; %i < ClientGroup.getCount(); %i ++) + { + %client = ClientGroup.getObject(%i); + %game.resetScore(%client); + } + for(%j = 1; %j <= %game.numTeams; %j++) + $TeamScore[%j] = 0; +} + +function CTFGame::onClientDamaged(%game, %clVictim, %clAttacker, %damageType, %implement, %damageLoc) +{ + if(%clVictim.headshot && %damageType == $DamageType::Laser && %clVictim.team != %clAttacker.team) + { + %clAttacker.scoreHeadshot++; + if (%game.SCORE_PER_HEADSHOT != 0) + { + messageClient(%clAttacker, 'msgHeadshot', '\c0You received a %1 point bonus for a successful headshot.', %game.SCORE_PER_HEADSHOT); + messageTeamExcept(%clAttacker, 'msgHeadshot', '\c5%1 hit a sniper rifle headshot.', %clAttacker.name); // z0dd - ZOD, 8/15/02. Tell team + } + %game.recalcScore(%clAttacker); + } + + // ----------------------------------------------- + // z0dd - ZOD, 8/25/02. Rear Lance hits + if(%clVictim.rearshot && %damageType == $DamageType::ShockLance && %clVictim.team != %clAttacker.team) + { + %clAttacker.scoreRearshot++; + if (%game.SCORE_PER_REARSHOT != 0) + { + messageClient(%clAttacker, 'msgRearshot', '\c0You received a %1 point bonus for a successful rearshot.', %game.SCORE_PER_REARSHOT); + messageTeamExcept(%clAttacker, 'msgRearshot', '\c5%1 hit a shocklance rearshot.', %clAttacker.name); + } + %game.recalcScore(%clAttacker); + } + // ----------------------------------------------- + + //the DefaultGame will set some vars + DefaultGame::onClientDamaged(%game, %clVictim, %clAttacker, %damageType, %implement, %damageLoc); + + //if victim is carrying a flag and is not on the attackers team, mark the attacker as a threat for x seconds(for scoring purposes) + if ((%clVictim.holdingFlag !$= "") && (%clVictim.team != %clAttacker.team)) + { + %clAttacker.dmgdFlagCarrier = true; + cancel(%clAttacker.threatTimer); //restart timer + %clAttacker.threatTimer = schedule(%game.TIME_CONSIDERED_FLAGCARRIER_THREAT, %clAttacker.dmgdFlagCarrier = false); + } +} + +//////////////////////////////////////////////////////////////////////////////////////// +function CTFGame::clientMissionDropReady(%game, %client) +{ + messageClient(%client, 'MsgClientReady',"", %game.class); + %game.resetScore(%client); + for(%i = 1; %i <= %game.numTeams; %i++) + { + $Teams[%i].score = 0; + messageClient(%client, 'MsgCTFAddTeam', "", %i, %game.getTeamName(%i), $flagStatus[%i], $TeamScore[%i]); + } + //%game.populateTeamRankArray(%client); + + //messageClient(%client, 'MsgYourRankIs', "", -1); + + messageClient(%client, 'MsgMissionDropInfo', '\c0You are in mission %1 (%2).', $MissionDisplayName, $MissionTypeDisplayName, $ServerName ); + + DefaultGame::clientMissionDropReady(%game, %client); +} + +function CTFGame::assignClientTeam(%game, %client, %respawn) +{ + DefaultGame::assignClientTeam(%game, %client, %respawn); + // if player's team is not on top of objective hud, switch lines + messageClient(%client, 'MsgCheckTeamLines', "", %client.team); +} + +function CTFGame::recalcScore(%game, %cl) +{ + %killValue = %cl.kills * %game.SCORE_PER_KILL; + %deathValue = %cl.deaths * %game.SCORE_PER_DEATH; + + if (%killValue - %deathValue == 0) + %killPoints = 0; + else + %killPoints = (%killValue * %killValue) / (%killValue - %deathValue); + + // --------------------------------------------------- + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + %cl.offenseScore = %killPoints + + %cl.suicides * %game.SCORE_PER_SUICIDE + + %cl.escortAssists * %game.SCORE_PER_ESCORT_ASSIST + + %cl.teamKills * %game.SCORE_PER_TEAMKILL + + %cl.tkDestroys * %game.SCORE_PER_TK_DESTROY + // z0dd - ZOD, 10/03/02. Penalty for tking equiptment. + %cl.scoreHeadshot * %game.SCORE_PER_HEADSHOT + + %cl.scoreRearshot * %game.SCORE_PER_REARSHOT + // z0dd - ZOD, 8/25/02. Added Lance rear shot messages + %cl.flagCaps * %game.SCORE_PER_PLYR_FLAG_CAP + + %cl.flagGrabs * %game.SCORE_PER_PLYR_FLAG_TOUCH + + %cl.genDestroys * %game.SCORE_PER_DESTROY_GEN + + %cl.sensorDestroys * %game.SCORE_PER_DESTROY_SENSOR + + %cl.turretDestroys * %game.SCORE_PER_DESTROY_TURRET + + %cl.iStationDestroys * %game.SCORE_PER_DESTROY_ISTATION + + %cl.vstationDestroys * %game.SCORE_PER_DESTROY_VSTATION + + %cl.mpbtstationDestroys * %game.SCORE_PER_DESTROY_MPBTSTATION + // z0dd - ZOD 3/30/02. MPB Teleporter + %cl.solarDestroys * %game.SCORE_PER_DESTROY_SOLAR + + %cl.sentryDestroys * %game.SCORE_PER_DESTROY_SENTRY + + %cl.depSensorDestroys * %game.SCORE_PER_DESTROY_DEP_SENSOR + + %cl.depTurretDestroys * %game.SCORE_PER_DESTROY_DEP_TUR + + %cl.depStationDestroys * %game.SCORE_PER_DESTROY_DEP_INV + + %cl.vehicleScore + %cl.vehicleBonus; + + %cl.defenseScore = %cl.genDefends * %game.SCORE_PER_GEN_DEFEND + + %cl.flagDefends * %game.SCORE_PER_FLAG_DEFEND + + %cl.carrierKills * %game.SCORE_PER_CARRIER_KILL + + %cl.escortAssists * %game.SCORE_PER_ESCORT_ASSIST + + %cl.turretKills * %game.SCORE_PER_TURRET_KILL_AUTO + + %cl.mannedturretKills * %game.SCORE_PER_TURRET_KILL + + %cl.genRepairs * %game.SCORE_PER_REPAIR_GEN + + %cl.SensorRepairs * %game.SCORE_PER_REPAIR_SENSOR + + %cl.TurretRepairs * %game.SCORE_PER_REPAIR_TURRET + + %cl.StationRepairs * %game.SCORE_PER_REPAIR_ISTATION + + %cl.VStationRepairs * %game.SCORE_PER_REPAIR_VSTATION + + %cl.mpbtstationRepairs * %game.SCORE_PER_REPAIR_MPBTSTATION + // z0dd - ZOD 3/30/02. MPB Teleporter + %cl.solarRepairs * %game.SCORE_PER_REPAIR_SOLAR + + %cl.sentryRepairs * %game.SCORE_PER_REPAIR_SENTRY + + %cl.depInvRepairs * %game.SCORE_PER_REPAIR_DEP_INV + + %cl.depTurretRepairs * %game.SCORE_PER_REPAIR_DEP_TUR + + %cl.returnPts; + // --------------------------------------------------- + + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + + %cl.score = mFloor(%cl.offenseScore + %cl.defenseScore); + + %game.recalcTeamRanks(%cl); +} + +function CTFGame::updateKillScores(%game, %clVictim, %clKiller, %damageType, %implement) +{ +// is this a vehicle kill rather than a player kill + + // console error message suppression + if( isObject( %implement ) ) + { + if( %implement.getDataBlock().getName() $= "AssaultPlasmaTurret" || %implement.getDataBlock().getName() $= "BomberTurret" ) // gunner + %clKiller = %implement.vehicleMounted.getMountNodeObject(1).client; + else if(%implement.getDataBlock().catagory $= "Vehicles") // pilot + %clKiller = %implement.getMountNodeObject(0).client; + } + + if(%game.testTurretKill(%implement)) //check for turretkill before awarded a non client points for a kill + %game.awardScoreTurretKill(%clVictim, %implement); + else if (%game.testKill(%clVictim, %clKiller)) //verify victim was an enemy + { + %value = %game.awardScoreKill(%clKiller); + %game.shareScore(%clKiller, %value); + %game.awardScoreDeath(%clVictim); + + if (%game.testGenDefend(%clVictim, %clKiller)) + %game.awardScoreGenDefend(%clKiller); + + if(%game.testCarrierKill(%clVictim, %clKiller)) + %game.awardScoreCarrierKill(%clKiller); + else + { + if (%game.testFlagDefend(%clVictim, %clKiller)) + %game.awardScoreFlagDefend(%clKiller); + } + if (%game.testEscortAssist(%clVictim, %clKiller)) + %game.awardScoreEscortAssist(%clKiller); + } + else + { + if (%game.testSuicide(%clVictim, %clKiller, %damageType)) //otherwise test for suicide + { + %game.awardScoreSuicide(%clVictim); + } + else + { + if (%game.testTeamKill(%clVictim, %clKiller)) //otherwise test for a teamkill + %game.awardScoreTeamKill(%clVictim, %clKiller); + } + } +} + +function CTFGame::testFlagDefend(%game, %victimID, %killerID) +{ + InitContainerRadiusSearch(%victimID.plyrPointOfDeath, %game.RADIUS_FLAG_DEFENSE, $TypeMasks::ItemObjectType); + %objID = containerSearchNext(); + while(%objID != 0) + { + %objType = %objID.getDataBlock().getName(); + if ((%objType $= "Flag") && (%objID.team == %killerID.team)) + return true; //found the(a) killer's flag near the victim's point of death + else + %objID = containerSearchNext(); + } + return false; //didn't find a qualifying flag within required radius of victims point of death +} + +function CTFGame::testGenDefend(%game, %victimID, %killerID) +{ + InitContainerRadiusSearch(%victimID.plyrPointOfDeath, %game.RADIUS_GEN_DEFENSE, $TypeMasks::StaticShapeObjectType); + %objID = containerSearchNext(); + while(%objID != 0) + { + %objType = %objID.getDataBlock().ClassName; + if ((%objType $= "generator") && (%objID.team == %killerID.team)) + return true; //found a killer's generator within required radius of victim's death + else + %objID = containerSearchNext(); + } + return false; //didn't find a qualifying gen within required radius of victim's point of death +} + +function CTFGame::testCarrierKill(%game, %victimID, %killerID) +{ + %flag = %victimID.plyrDiedHoldingFlag; + return ((%flag !$= "") && (%flag.team == %killerID.team)); +} + +function CTFGame::testEscortAssist(%game, %victimID, %killerID) +{ + return (%victimID.dmgdFlagCarrier); +} + +function CTFGame::testValidRepair(%game, %obj) +{ + if(!%obj.wasDisabled) + { + //error(%obj SPC "was never disabled"); + return false; + } + else if(%obj.lastDamagedByTeam == %obj.team) + { + //error(%obj SPC "was last damaged by a friendly"); + return false; + } + else if(%obj.team != %obj.repairedBy.team) + { + //error(%obj SPC "was repaired by an enemy"); + return false; + } + else + { + if(%obj.soiledByEnemyRepair) + %obj.soiledByEnemyRepair = false; + return true; + } +} + +function CTFGame::awardScoreFlagCap(%game, %cl, %flag) +{ + %cl.flagCaps++; + $TeamScore[%cl.team] += %game.SCORE_PER_TEAM_FLAG_CAP; + messageAll('MsgTeamScoreIs', "", %cl.team, $TeamScore[%cl.team]); + + %flag.grabber.flagGrabs++; + + if (%game.SCORE_PER_TEAM_FLAG_CAP > 0) + { + %plural = (%game.SCORE_PER_PLYR_FLAG_CAP != 1 ? 's' : ""); + %plural2 = (%game.SCORE_PER_PLYR_FLAG_TOUCH != 1 ? 's' : ""); + + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + if(%cl == %flag.grabber) + { + messageClient(%cl, 'msgCTFFriendCap', '\c0You receive %1 point%2 for stealing and capturing the enemy flag!', %game.SCORE_PER_PLYR_FLAG_CAP+%game.SCORE_PER_PLYR_FLAG_TOUCH, %plural); + messageTeam(%flag.team, 'msgCTFEnemyCap', '\c0Enemy %1 received %2 point%3 for capturing your flag!', %cl.name, %game.SCORE_PER_PLYR_FLAG_CAP+%game.SCORE_PER_PLYR_FLAG_TOUCH, %plural); + //messageTeamExcept(%cl, 'msgCTFFriendCap', '\c0Teammate %1 receives %2 point%3 for capturing the enemy flag!', %cl.name, %game.SCORE_PER_PLYR_FLAG_CAP+%game.SCORE_PER_PLYR_FLAG_TOUCH, %plural); // z0dd - ZOD, 8/15/02. Message is pointless + } + else + { + if(isObject(%flag.grabber)) // is the grabber still here? + { + messageClient(%cl, 'msgCTFFriendCap', '\c0You receive %1 point%2 for capturing the enemy flag! %3 gets %4 point%5 for the steal assist.', %game.SCORE_PER_PLYR_FLAG_CAP, %plural, %flag.grabber.name, %game.SCORE_PER_PLYR_FLAG_TOUCH, %plural2); + messageClient(%flag.grabber, 'msgCTFFriendCap', '\c0You receive %1 point%2 for stealing a flag that was subsequently capped by %3.', %game.SCORE_PER_PLYR_FLAG_TOUCH, %plural2, %cl.name); + } + else + messageClient(%cl, 'msgCTFFriendCap', '\c0You receive %1 point%2 for capturing the enemy flag!', %game.SCORE_PER_PLYR_FLAG_CAP, %plural); + + //messageTeamExcept(%cl, 'msgCTFFriendCap', '\c0Teammate %1 receives %2 point%3 for capturing the enemy flag!', %cl.name, %game.SCORE_PER_PLYR_FLAG_CAP, %plural); // z0dd - ZOD, 8/15/02. Message is pointless + //messageTeam(%flag.team, 'msgCTFEnemyCap', '\c0Enemy %1 received %2 point%3 for capturing your flag!', %cl.name, %game.SCORE_PER_PLYR_FLAG_CAP, %plural); // z0dd - ZOD, 8/15/02. Message is pointless + } + // --------------------------------------------------- + } + + %game.recalcScore(%cl); + + if(isObject(%flag.grabber)) + %game.recalcScore(%flag.grabber); + + %game.checkScoreLimit(%cl.team); +} + + +function CTFGame::awardScoreFlagTouch(%game, %cl, %flag) +{ + + %flag.grabber = %cl; + %team = %cl.team; + if( $DontScoreTimer[%team] ) + return; + + $dontScoreTimer[%team] = true; + //tinman - needed to remove all game calls to "eval" for the PURE server... + %game.schedule(%game.TOUCH_DELAY_MS, resetDontScoreTimer, %team); + //schedule(%game.TOUCH_DELAY_MS, 0, eval, "$dontScoreTimer["@%team@"] = false;"); + schedule(%game.TOUCH_DELAY_MS, 0, eval, "$dontScoreTimer["@%team@"] = false;"); + $TeamScore[%team] += %game.SCORE_PER_TEAM_FLAG_TOUCH; + messageAll('MsgTeamScoreIs', "", %team, $TeamScore[%team]); + + if (%game.SCORE_PER_TEAM_FLAG_TOUCH > 0) + { + %plural = (%game.SCORE_PER_TEAM_FLAG_TOUCH != 1 ? 's' : ""); + messageTeam(%team, 'msgCTFFriendFlagTouch', '\c0Your team receives %1 point%2 for grabbing the enemy flag!', %game.SCORE_PER_TEAM_FLAG_TOUCH, %plural); + messageTeam(%flag.team, 'msgCTFEnemyFlagTouch', '\c0Enemy %1 receives %2 point%3 for grabbing your flag!', %cl.name, %game.SCORE_PER_TEAM_FLAG_TOUCH, %plural); + } + %game.recalcScore(%cl); + %game.checkScoreLimit(%team); +} + +function CTFGame::resetDontScoreTimer(%game, %team) +{ + $dontScoreTimer[%team] = false; +} + +function CTFGame::checkScoreLimit(%game, %team) +{ + %scoreLimit = MissionGroup.CTF_scoreLimit * %game.SCORE_PER_TEAM_FLAG_CAP; + // default of 5 if scoreLimit not defined + if(%scoreLimit $= "") + %scoreLimit = 5 * %game.SCORE_PER_TEAM_FLAG_CAP; + if($TeamScore[%team] >= %scoreLimit) + %game.scoreLimitReached(); +} + +function CTFGame::awardScoreFlagReturn(%game, %cl, %perc) +{ + // --------------------------------------------------- + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + if (%game.SCORE_PER_FLAG_RETURN != 0) + { + %pts = mfloor( %game.SCORE_PER_FLAG_RETURN * (%perc/100) ); + if(%perc == 100) + messageClient(%cl, 'scoreFlaRetMsg', 'Flag return - exceeded capping distance - %1 point bonus.', %pts, %perc); + else if(%perc == 0) + messageClient(%cl, 'scoreFlaRetMsg', 'You gently place the flag back on the stand.', %pts, %perc); + else + messageClient(%cl, 'scoreFlaRetMsg', '\c0Flag return from %2%% of capping distance - %1 point bonus.', %pts, %perc); + %cl.returnPts += %pts; + } + %game.recalcScore(%cl); + return %game.SCORE_PER_FLAG_RETURN; + // --------------------------------------------------- +} + +function CTFGame::awardScoreStalemateReturn(%game, %cl) +{ + if (%game.SCORE_PER_STALEMATE_RETURN != 0) + { + messageClient(%cl, 'scoreStaleRetMsg', '\c0You received a %1 point bonus for a stalemate-breaking, flag return.', %game.SCORE_PER_STALEMATE_RETURN); + %cl.returnPts += %game.SCORE_PER_STALEMATE_RETURN; + } + %game.recalcScore(%cl); + return %game.SCORE_PER_STALEMATE_RETURN; +} + +// Asset Destruction scoring +function CTFGame::awardScoreGenDestroy(%game,%cl) +{ + %cl.genDestroys++; + if (%game.SCORE_PER_DESTROY_GEN != 0) + { + messageClient(%cl, 'msgGenDes', '\c0You received a %1 point bonus for destroying an enemy generator.', %game.SCORE_PER_DESTROY_GEN); + //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); + } + %game.recalcScore(%cl); + return %game.SCORE_PER_DESTROY_GEN; +} + +function CTFGame::awardScoreSensorDestroy(%game,%cl) +{ + %cl.sensorDestroys++; + if (%game.SCORE_PER_DESTROY_SENSOR != 0) + { + messageClient(%cl, 'msgSensorDes', '\c0You received a %1 point bonus for destroying an enemy sensor.', %game.SCORE_PER_DESTROY_SENSOR); + //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); + } + %game.recalcScore(%cl); + return %game.SCORE_PER_DESTROY_SENSOR; +} + +function CTFGame::awardScoreTurretDestroy(%game,%cl) +{ + %cl.turretDestroys++; + if (%game.SCORE_PER_DESTROY_TURRET != 0) + { + messageClient(%cl, 'msgTurretDes', '\c0You received a %1 point bonus for destroying an enemy turret.', %game.SCORE_PER_DESTROY_TURRET); + //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); + } + %game.recalcScore(%cl); + return %game.SCORE_PER_DESTROY_TURRET; +} + +function CTFGame::awardScoreInvDestroy(%game,%cl) +{ + %cl.IStationDestroys++; + if (%game.SCORE_PER_DESTROY_ISTATION != 0) + { + messageClient(%cl, 'msgInvDes', '\c0You received a %1 point bonus for destroying an enemy inventory station.', %game.SCORE_PER_DESTROY_ISTATION); + //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); + } + %game.recalcScore(%cl); + return %game.SCORE_PER_DESTROY_ISTATION; +} + +function CTFGame::awardScoreVehicleStationDestroy(%game,%cl) +{ + %cl.VStationDestroys++; + if (%game.SCORE_PER_DESTROY_VSTATION != 0) + { + messageClient(%cl, 'msgVSDes', '\c0You received a %1 point bonus for destroying an enemy vehicle station.', %game.SCORE_PER_DESTROY_VSTATION); + //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); + } + %game.recalcScore(%cl); + return %game.SCORE_PER_DESTROY_VSTATION; +} + +// --------------------------------------------------------- +// z0dd - ZOD 3/30/02. MBP Teleporter +function CTFGame::awardScoreMPBTeleporterDestroy(%game,%cl) +{ + %cl.mpbtstationDestroys++; + if (%game.SCORE_PER_DESTROY_MPBTSTATION != 0) + { + messageClient(%cl, 'msgMPBTeleDes', '\c0You received a %1 point bonus for destroying an enemy MPB teleport station.', %game.SCORE_PER_DESTROY_MPBTSTATION); + //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); + } + %game.recalcScore(%cl); + return %game.SCORE_PER_DESTROY_MPBTSTATION; +} +// --------------------------------------------------------- + +function CTFGame::awardScoreSolarDestroy(%game,%cl) +{ + %cl.SolarDestroys++; + if (%game.SCORE_PER_DESTROY_SOLAR != 0) + { + messageClient(%cl, 'msgSolarDes', '\c0You received a %1 point bonus for destroying an enemy solar panel.', %game.SCORE_PER_DESTROY_SOLAR); + //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); + } + %game.recalcScore(%cl); + return %game.SCORE_PER_DESTROY_SOLAR; +} + +function CTFGame::awardScoreSentryDestroy(%game,%cl) +{ + %cl.sentryDestroys++; + if (%game.SCORE_PER_DESTROY_SENTRY != 0) + { + messageClient(%cl, 'msgSentryDes', '\c0You received a %1 point bonus for destroying an enemy sentry turret.', %game.SCORE_PER_DESTROY_SENTRY); + //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); + } + %game.recalcScore(%cl); + return %game.SCORE_PER_DESTROY_SENTRY; +} + +function CTFGame::awardScoreDepSensorDestroy(%game,%cl) +{ + %cl.depSensorDestroys++; + if (%game.SCORE_PER_DESTROY_DEP_SENSOR != 0) + { + messageClient(%cl, 'msgDepSensorDes', '\c0You received a %1 point bonus for destroying an enemy deployable sensor.', %game.SCORE_PER_DESTROY_DEP_SENSOR); // z0dd - ZOD, 8/15/02. Added "sensor" + //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); + } + %game.recalcScore(%cl); + return %game.SCORE_PER_DESTROY_DEP_SENSOR; +} + +function CTFGame::awardScoreDepTurretDestroy(%game,%cl) +{ + %cl.depTurretDestroys++; + if (%game.SCORE_PER_DESTROY_DEP_TUR != 0) + { + messageClient(%cl, 'msgDepTurDes', '\c0You received a %1 point bonus for destroying an enemy deployed turret.', %game.SCORE_PER_DESTROY_DEP_TUR); + //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); + } + %game.recalcScore(%cl); + return %game.SCORE_PER_DESTROY_DEP_TUR; +} + +function CTFGame::awardScoreDepStationDestroy(%game,%cl) +{ + %cl.depStationDestroys++; + if (%game.SCORE_PER_DESTROY_DEP_INV != 0) + { + messageClient(%cl, 'msgDepInvDes', '\c0You received a %1 point bonus for destroying an enemy deployed station.', %game.SCORE_PER_DESTROY_DEP_INV); + //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); + } + %game.recalcScore(%cl); + return %game.SCORE_PER_DESTROY_DEP_INV; +} + +// --------------------------------------------------------- +// z0dd - ZOD, 10/03/02. Penalty for TKing equiptment. +function CTFGame::awardScoreTkDestroy(%game, %cl) +{ + %cl.tkDestroys++; + if (%game.SCORE_PER_TK_DESTROY != 0) + { + messageClient(%cl, 'msgTkDes', '\c0You have been penalized %1 points for destroying your teams equiptment.', %game.SCORE_PER_TK_DESTROY); + } + %game.recalcScore(%cl); + return %game.SCORE_PER_TK_DESTROY; +} +// --------------------------------------------------------- + +function CTFGame::awardScoreGenDefend(%game, %killerID) +{ + %killerID.genDefends++; + if (%game.SCORE_PER_GEN_DEFEND != 0) + { + messageClient(%killerID, 'msgGenDef', '\c0You received a %1 point bonus for defending a generator.', %game.SCORE_PER_GEN_DEFEND); + messageTeamExcept(%killerID, 'msgGenDef', '\c2%1 defended our generator from an attack.', %killerID.name); // z0dd - ZOD, 8/15/02. Tell team + //messageTeamExcept(%killerID, 'msgGenDef', '\c0Teammate %1 received a %2 point bonus for defending a generator.', %killerID.name, %game.SCORE_PER_GEN_DEFEND); + } + %game.recalcScore(%cl); + return %game.SCORE_PER_GEN_DEFEND; +} + +function CTFGame::awardScoreCarrierKill(%game, %killerID) +{ + %killerID.carrierKills++; + if (%game.SCORE_PER_CARRIER_KILL != 0) + { + messageClient(%killerID, 'msgCarKill', '\c0You received a %1 point bonus for stopping the enemy flag carrier!', %game.SCORE_PER_CARRIER_KILL); + messageTeamExcept(%killerID, 'msgCarKill', '\c2%1 stopped the enemy flag carrier.', %killerID.name); // z0dd - ZOD, 8/15/02. Tell team + //messageTeamExcept(%killerID, 'msgCarKill', '\c0Teammate %1 received a %2 point bonus for stopping the enemy flag carrier!', %killerID.name, %game.SCORE_PER_CARRIER_KILL); + } + %game.recalcScore(%killerID); + return %game.SCORE_PER_CARRIER_KILL; +} + +function CTFGame::awardScoreFlagDefend(%game, %killerID) +{ + %killerID.flagDefends++; + if (%game.SCORE_PER_FLAG_DEFEND != 0) + { + messageClient(%killerID, 'msgFlagDef', '\c0You received a %1 point bonus for defending your flag!', %game.SCORE_PER_FLAG_DEFEND); + messageTeamExcept(%killerID, 'msgFlagDef', '\c2%1 defended our flag.', %killerID.name); // z0dd - ZOD, 8/15/02. Tell team + //messageTeamExcept(%killerID, 'msgFlagDef', '\c0Teammate %1 received a %2 point bonus for defending your flag!', %killerID.name, %game.SCORE_PER_FLAG_DEFEND); + } + %game.recalcScore(%killerID); + return %game.SCORE_PER_FLAG_DEFEND; +} + +function CTFGame::awardScoreEscortAssist(%game, %killerID) +{ + %killerID.escortAssists++; + if (%game.SCORE_PER_ESCORT_ASSIST != 0) + { + messageClient(%killerID, 'msgEscAsst', '\c0You received a %1 point bonus for protecting the flag carrier!', %game.SCORE_PER_ESCORT_ASSIST); + messageTeamExcept(%killerID, 'msgEscAsst', '\c2%1 protected our flag carrier.', %killerID.name); // z0dd - ZOD, 8/15/02. Tell team + //messageTeamExcept(%killerID, 'msgEscAsst', '\c0Teammate %1 received a %2 point bonus for protecting the flag carrier!', %killerID.name, %game.SCORE_PER_ESCORT_ASSIST); + } + %game.recalcScore(%killerID); + return %game.SCORE_PER_ESCORT_ASSIST; +} + +function CTFGame::resetScore(%game, %client) +{ + %client.offenseScore = 0; + %client.kills = 0; + %client.deaths = 0; + %client.suicides = 0; + %client.escortAssists = 0; + %client.teamKills = 0; + %client.tkDestroys = 0; // z0dd - ZOD, 10/03/02. Penalty for tking equiptment. + %client.flagCaps = 0; + %client.flagGrabs = 0; + %client.genDestroys = 0; + %client.sensorDestroys = 0; + %client.turretDestroys = 0; + %client.iStationDestroys = 0; + %client.vstationDestroys = 0; + %client.mpbtstationDestroys = 0; // z0dd - ZOD 3/30/02. MPB Teleporter + %client.solarDestroys = 0; + %client.sentryDestroys = 0; + %client.depSensorDestroys = 0; + %client.depTurretDestroys = 0; + %client.depStationDestroys = 0; + %client.vehicleScore = 0; + %client.vehicleBonus = 0; + + %client.flagDefends = 0; + %client.defenseScore = 0; + %client.genDefends = 0; + %client.carrierKills = 0; + %client.escortAssists = 0; + %client.turretKills = 0; + %client.mannedTurretKills = 0; + %client.flagReturns = 0; + %client.genRepairs = 0; + %client.SensorRepairs =0; + %client.TurretRepairs =0; + %client.StationRepairs =0; + %client.VStationRepairs =0; + %client.mpbtstationRepairs = 0; // z0dd - ZOD 3/30/02. MPB Teleporter + %client.solarRepairs =0; + %client.sentryRepairs =0; + %client.depInvRepairs =0; + %client.depTurretRepairs=0; + %client.returnPts = 0; + %client.score = 0; +} + +function CTFGame::objectRepaired(%game, %obj, %objName) +{ + %item = %obj.getDataBlock().getName(); + switch$ (%item) + { + case generatorLarge : + %game.genOnRepaired(%obj, %objName); + case sensorMediumPulse : + %game.sensorOnRepaired(%obj, %objName); + case sensorLargePulse : + %game.sensorOnRepaired(%obj, %objName); + case stationInventory : + %game.stationOnRepaired(%obj, %objName); + case turretBaseLarge : + %game.turretOnRepaired(%obj, %objName); + case stationVehicle : + %game.vStationOnRepaired(%obj, %objName); + case MPBTeleporter : // z0dd - ZOD 3/30/02. MPB Teleporter + %game.mpbTStationOnRepaired(%obj, %objName); + case solarPanel : + %game.solarPanelOnRepaired(%obj, %objName); + case sentryTurret : + %game.sentryTurretOnRepaired(%obj, %objName); + case TurretDeployedWallIndoor: + %game.depTurretOnRepaired(%obj, %objName); + case TurretDeployedFloorIndoor: + %game.depTurretOnRepaired(%obj, %objName); + case TurretDeployedCeilingIndoor: + %game.depTurretOnRepaired(%obj, %objName); + case TurretDeployedOutdoor: + %game.depTurretOnRepaired(%obj, %objName); + } + %obj.wasDisabled = false; +} + +function CTFGame::genOnRepaired(%game, %obj, %objName) +{ + + if (%game.testValidRepair(%obj)) + { + %repairman = %obj.repairedBy; + teamRepairMessage(%repairman, 'msgGenRepaired', '\c0%1 repaired a %2 Generator!', %repairman.name, %obj.nameTag); + %game.awardScoreGenRepair(%obj.repairedBy); + } +} + +function CTFGame::stationOnRepaired(%game, %obj, %objName) +{ + if (%game.testValidRepair(%obj)) + { + %repairman = %obj.repairedBy; + teamRepairMessage(%repairman, 'msgStationRepaired', '\c0%1 repaired a %2 Inventory Station!', %repairman.name, %obj.nameTag); + %game.awardScoreStationRepair(%obj.repairedBy); + } +} + +function CTFGame::sensorOnRepaired(%game, %obj, %objName) +{ + if (%game.testValidRepair(%obj)) + { + %repairman = %obj.repairedBy; + teamRepairMessage(%repairman, 'msgSensorRepaired', '\c0%1 repaired a %2 Pulse Sensor!', %repairman.name, %obj.nameTag); + %game.awardScoreSensorRepair(%obj.repairedBy); + } +} + +function CTFGame::turretOnRepaired(%game, %obj, %objName) +{ + if (%game.testValidRepair(%obj)) + { + %repairman = %obj.repairedBy; + teamRepairMessage(%repairman, 'msgTurretRepaired', '\c0%1 repaired a %2 Turret!', %repairman.name, %obj.nameTag); + %game.awardScoreTurretRepair(%obj.repairedBy); + } +} + +function CTFGame::vStationOnRepaired(%game, %obj, %objName) +{ + if (%game.testValidRepair(%obj)) + { + %repairman = %obj.repairedBy; + teamRepairMessage(%repairman, 'msgvstationRepaired', '\c0%1 repaired a Vehicle Station!', %repairman.name); + %game.awardScoreVStationRepair(%obj.repairedBy); + } +} + +// z0dd - ZOD 3/17/02. Score for repairing MPB Teleporter station. +function CTFGame::mpbTStationOnRepaired(%game, %obj, %objName) +{ + if (%game.testValidRepair(%obj)) + { + %repairman = %obj.repairedBy; + teamRepairMessage(%repairman, 'msgTeleporterRepaired', '\c0%1 repaired a MPB Teleport Station!', %repairman.name); + %game.awardScoreMpbTStationRepair(%obj.repairedBy); + } +} + +function CTFGame::solarPanelOnRepaired(%game, %obj, %objName) +{ + if (%game.testValidRepair(%obj)) + { + %repairman = %obj.repairedBy; + teamRepairMessage(%repairman, 'msgsolarRepaired', '\c0%1 repaired a %2 Solar Panel!', %repairman.name, %obj.nameTag); + %game.awardScoreSolarRepair(%obj.repairedBy); + } +} + +function CTFGame::sentryTurretOnRepaired(%game, %obj, %objName) +{ + if (%game.testValidRepair(%obj)) + { + %repairman = %obj.repairedBy; + teamRepairMessage(%repairman, 'msgsentryTurretRepaired', '\c0%1 repaired a %2 Sentry Turret!', %repairman.name, %obj.nameTag); + %game.awardScoreSentryRepair(%obj.repairedBy); + } +} + +function CTFGame::depTurretOnRepaired(%game, %obj, %objName) +{ + if (%game.testValidRepair(%obj)) + { + %repairman = %obj.repairedBy; + teamRepairMessage(%repairman, 'msgdepTurretRepaired', '\c0%1 repaired a %2 Deployable Turret!', %repairman.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Added this line + %game.awardScoreDepTurretRepair(%obj.repairedBy); + } +} + +function CTFGame::depInvOnRepaired(%game, %obj, %objName) +{ + if (%game.testValidRepair(%obj)) + { + teamRepairMessage(%repairman, 'msgdepInvRepaired', '\c0%1 repaired a %2 Deployable Inventory!', %repairman.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Added this line + %repairman = %obj.repairedBy; + %game.awardScoreDepInvRepair(%obj.repairedBy); + } +} + +function CTFGame::awardScoreGenRepair(%game, %cl) +{ + %cl.genRepairs++; + if (%game.SCORE_PER_REPAIR_GEN != 0) + { + messageClient(%cl, 'msgGenRep', '\c0You received a %1 point bonus for repairing a generator.', %game.SCORE_PER_REPAIR_GEN); + } + %game.recalcScore(%cl); +} + +function CTFGame::awardScoreStationRepair(%game, %cl) +{ + %cl.stationRepairs++; + if (%game.SCORE_PER_REPAIR_ISTATION != 0) + { + messageClient(%cl, 'msgIStationRep', '\c0You received a %1 point bonus for repairing a inventory station.', %game.SCORE_PER_REPAIR_ISTATION); + } + %game.recalcScore(%cl); +} + +function CTFGame::awardScoreSensorRepair(%game, %cl) +{ + %cl.sensorRepairs++; + if (%game.SCORE_PER_REPAIR_SENSOR != 0) + { + messageClient(%cl, 'msgSensorRep', '\c0You received a %1 point bonus for repairing a sensor.', %game.SCORE_PER_REPAIR_SENSOR); + } + %game.recalcScore(%cl); +} + +function CTFGame::awardScoreTurretRepair(%game, %cl) +{ + %cl.TurretRepairs++; + if (%game.SCORE_PER_REPAIR_TURRET != 0) + { + messageClient(%cl, 'msgTurretRep', '\c0You received a %1 point bonus for repairing a base turret.', %game.SCORE_PER_REPAIR_TURRET); + } + %game.recalcScore(%cl); +} + +function CTFGame::awardScoreVStationRepair(%game, %cl) +{ + %cl.VStationRepairs++; + if (%game.SCORE_PER_REPAIR_VSTATION != 0) + { + messageClient(%cl, 'msgVStationRep', '\c0You received a %1 point bonus for repairing a vehicle station.', %game.SCORE_PER_REPAIR_VSTATION); + } + %game.recalcScore(%cl); +} + +// z0dd - ZOD 3/17/02. Score for repairing MPB Teleporter station. +function CTFGame::awardScoreMpbTStationRepair(%game, %cl) +{ + %cl.mpbtstationRepairs++; + if (%game.SCORE_PER_REPAIR_MPBTSTATION != 0) + { + messageClient(%cl, 'msgVStationRep', '\c0You received a %1 point bonus for repairing a MPB teleporter station.', %game.SCORE_PER_REPAIR_TSTATION); + } + %game.recalcScore(%cl); +} + +function CTFGame::awardScoreSolarRepair(%game, %cl) +{ + %cl.solarRepairs++; + if (%game.SCORE_PER_REPAIR_SOLAR != 0) + { + messageClient(%cl, 'msgsolarRep', '\c0You received a %1 point bonus for repairing a solar panel.', %game.SCORE_PER_REPAIR_SOLAR); + } + %game.recalcScore(%cl); +} + +function CTFGame::awardScoreSentryRepair(%game, %cl) +{ + %cl.sentryRepairs++; + if (%game.SCORE_PER_REPAIR_SENTRY != 0) + { + messageClient(%cl, 'msgSentryRep', '\c0You received a %1 point bonus for repairing a sentry turret.', %game.SCORE_PER_REPAIR_SENTRY); + } + %game.recalcScore(%cl); +} + +function CTFGame::awardScoreDepTurretRepair(%game, %cl) +{ + %cl.depTurretRepairs++; + if (%game.SCORE_PER_REPAIR_DEP_TUR != 0) + { + messageClient(%cl, 'msgDepTurretRep', '\c0You received a %1 point bonus for repairing a deployed turret.', %game.SCORE_PER_REPAIR_DEP_TUR); + } + %game.recalcScore(%cl); +} + +function CTFGame::awardScoreDepInvRepair(%game, %cl) +{ + %cl.depInvRepairs++; + if (%game.SCORE_PER_REPAIR_DEP_INV != 0) + { + messageClient(%cl, 'msgDepInvRep', '\c0You received a %1 point bonus for repairing a deployed station.', %game.SCORE_PER_REPAIR_DEP_INV); + } + %game.recalcScore(%cl); +} + +function CTFGame::enterMissionArea(%game, %playerData, %player) +{ + if(%player.getState() $= "Dead") + return; + %player.client.outOfBounds = false; + messageClient(%player.client, 'EnterMissionArea', '\c1You are back in the mission area.'); + logEcho(%player.client.nameBase@" (pl "@%player@"/cl "@%player.client@") entered mission area"); + + //the instant a player leaves the mission boundary, the flag is dropped, and the return is scheduled... + if (%player.holdingFlag > 0) + { + cancel($FlagReturnTimer[%player.holdingFlag]); + $FlagReturnTimer[%player.holdingFlag] = ""; + } +} + +function CTFGame::leaveMissionArea(%game, %playerData, %player) +{ + if(%player.getState() $= "Dead") + return; + // maybe we'll do this just in case + %player.client.outOfBounds = true; + // if the player is holding a flag, strip it and throw it back into the mission area + // otherwise, just print a message + if(%player.holdingFlag > 0) + %game.boundaryLoseFlag(%player); + else + messageClient(%player.client, 'MsgLeaveMissionArea', '\c1You have left the mission area.~wfx/misc/warning_beep.wav'); + logEcho(%player.client.nameBase@" (pl "@%player@"/cl "@%player.client@") left mission area"); +} + +function CTFGame::boundaryLoseFlag(%game, %player) +{ + // this is called when a player goes out of the mission area while holding + // the enemy flag. - make sure the player is still out of bounds + if (!%player.client.outOfBounds || !isObject(%player.holdingFlag)) + return; + + // ------------------------------------------------------------------------------ + // z0dd - ZOD - SquirrelOfDeath, 9/27/02. Delay on grabbing flag after tossing it + %player.flagTossWait = true; + %player.schedule(1000, resetFlagTossWait); + // ------------------------------------------------------------------------------ + + %client = %player.client; + %flag = %player.holdingFlag; + %flag.setVelocity("0 0 0"); + %flag.setTransform(%player.getWorldBoxCenter()); + %flag.setCollisionTimeout(%player); + + %held = %game.formatTime(getSimTime() - %game.flagHeldTime[%flag], false); // z0dd - ZOD, 8/15/02. How long did player hold flag? + + %game.playerDroppedFlag(%player); + + // now for the tricky part -- throwing the flag back into the mission area + // let's try throwing it back towards its "home" + %home = %flag.originalPosition; + %vecx = firstWord(%home) - firstWord(%player.getWorldBoxCenter()); + %vecy = getWord(%home, 1) - getWord(%player.getWorldBoxCenter(), 1); + %vecz = getWord(%home, 2) - getWord(%player.getWorldBoxCenter(), 2); + %vec = %vecx SPC %vecy SPC %vecz; + + // normalize the vector, scale it, and add an extra "upwards" component + %vecNorm = VectorNormalize(%vec); + %vec = VectorScale(%vecNorm, 1500); + %vec = vectorAdd(%vec, "0 0 500"); + + // z0dd - ZOD, 6/09/02. Remove anti-hover so flag can be thrown properly + %flag.static = false; + + // z0dd - ZOD, 10/02/02. Hack for flag collision bug. + %flag.searchSchedule = %game.schedule(10, "startFlagCollisionSearch", %flag); + + // apply the impulse to the flag object + %flag.applyImpulse(%player.getWorldBoxCenter(), %vec); + + //don't forget to send the message + //messageClient(%player.client, 'MsgCTFFlagDropped', '\c1You have left the mission area and lost the flag.~wfx/misc/flag_drop.wav', 0, 0, %player.holdingFlag.team); + + // z0dd - ZOD 3/30/02. Above message was sending the wrong varible to objective hud. + messageClient(%player.client, 'MsgCTFFlagDropped', '\c1You have left the mission area and lost the flag. (Held: %4)~wfx/misc/flag_drop.wav', %client.name, 0, %flag.team, %held); // Yogi, 8/18/02. 3rd param changed 0 -> %client.name + logEcho(%player.client.nameBase@" (pl "@%player@"/cl "@%player.client@") lost flag (out of bounds)"@" (Held: "@%held@")"); +} + +function CTFGame::dropFlag(%game, %player) +{ + if(%player.holdingFlag > 0) + { + if (!%player.client.outOfBounds) + %player.throwObject(%player.holdingFlag); + else + %game.boundaryLoseFlag(%player); + } +} + +function CTFGame::applyConcussion(%game, %player) +{ + %game.dropFlag( %player ); +} + +function CTFGame::vehicleDestroyed(%game, %vehicle, %destroyer) +{ + //vehicle name + %data = %vehicle.getDataBlock(); + //%vehicleType = getTaggedString(%data.targetNameTag) SPC getTaggedString(%data.targetTypeTag); + %vehicleType = getTaggedString(%data.targetTypeTag); + if(%vehicleType !$= "MPB") + %vehicleType = strlwr(%vehicleType); + + %enemyTeam = ( %destroyer.team == 1 ) ? 2 : 1; + + %scorer = 0; + %multiplier = 1; + + %passengers = 0; + for(%i = 0; %i < %data.numMountPoints; %i++) + if(%vehicle.getMountNodeObject(%i)) + %passengers++; + + //what destroyed this vehicle + if(%destroyer.client) + { + //it was a player, or his mine, satchel, whatever... + %destroyer = %destroyer.client; + %scorer = %destroyer; + + // determine if the object used was a mine + if(%vehicle.lastDamageType == $DamageType::Mine) + %multiplier = 2; + } + else if(%destroyer.getClassName() $= "Turret") + { + if(%destroyer.getControllingClient()) + { + //manned turret + %destroyer = %destroyer.getControllingClient(); + %scorer = %destroyer; + } + else + { + %destroyerName = "A turret"; + %multiplier = 0; + } + } + else if(%destroyer.getDataBlock().catagory $= "Vehicles") + { + // Vehicle vs vehicle kill! + if(%name $= "BomberFlyer" || %name $= "AssaultVehicle") + %gunnerNode = 1; + else + %gunnerNode = 0; + + if(%destroyer.getMountNodeObject(%gunnerNode)) + { + %destroyer = %destroyer.getMountNodeObject(%gunnerNode).client; + %scorer = %destroyer; + } + %multiplier = 3; + } + else // Is there anything else we care about? + return; + + + if(%destroyerName $= "") + %destroyerName = %destroyer.name; + + if(%vehicle.team == %destroyer.team) // team kill + { + %pref = (%vehicleType $= "Assault Tank") ? "an" : "a"; + messageAll( 'msgVehicleTeamDestroy', '\c0%1 TEAMKILLED %3 %2!', %destroyerName, %vehicleType, %pref); + } + + else // legit kill + { + //messageTeamExcept(%destroyer, 'msgVehicleDestroy', '\c0%1 destroyed an enemy %2.', %destroyerName, %vehicleType); // z0dd - ZOD, 8/20/02. not needed with new messenger on line below + teamDestroyMessage(%destroyer, 'msgVehDestroyed', '\c5%1 destroyed an enemy %2!', %destroyerName, %vehicleType); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + messageTeam(%enemyTeam, 'msgVehicleDestroy', '\c0%1 destroyed your team\'s %2.', %destroyerName, %vehicleType); + //messageClient(%destroyer, 'msgVehicleDestroy', '\c0You destroyed an enemy %1.', %vehicleType); + + if(%scorer) + { + %value = %game.awardScoreVehicleDestroyed(%scorer, %vehicleType, %multiplier, %passengers); + %game.shareScore(%value); + } + } +} + +function CTFGame::awardScoreVehicleDestroyed(%game, %client, %vehicleType, %mult, %passengers) +{ + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + + if(%vehicleType $= "Grav Cycle") + %base = %game.SCORE_PER_DESTROY_WILDCAT; + else if(%vehicleType $= "Assault Tank") + %base = %game.SCORE_PER_DESTROY_TANK; + else if(%vehicleType $= "MPB") + %base = %game.SCORE_PER_DESTROY_MPB; + else if(%vehicleType $= "Turbograv") + %base = %game.SCORE_PER_DESTROY_SHRIKE; + else if(%vehicleType $= "Bomber") + %base = %game.SCORE_PER_DESTROY_BOMBER; + else if(%vehicleType $= "Heavy Transport") + %base = %game.SCORE_PER_DESTROY_TRANSPORT; + + %total = ( %base * %mult ) + ( %passengers * %game.SCORE_PER_PASSENGER ); + + %client.vehicleScore += %total; + + messageClient(%client, 'msgVehicleScore', '\c0You received a %1 point bonus for destroying an enemy %2.', %total, %vehicleType); + %game.recalcScore(%client); + return %total; +} + +function CTFGame::shareScore(%game, %client, %amount) +{ + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + + //error("share score of"SPC %amount SPC "from client:" SPC %client); + // all of the player in the bomber and tank share the points + // gained from any of the others + %vehicle = %client.vehicleMounted; + if(!%vehicle) + return 0; + %vehicleType = getTaggedString(%vehicle.getDataBlock().targetTypeTag); + if(%vehicleType $= "Bomber" || %vehicleType $= "Assault Tank") + { + for(%i = 0; %i < %vehicle.getDataBlock().numMountPoints; %i++) + { + %occupant = %vehicle.getMountNodeObject(%i); + if(%occupant) + { + %occCl = %occupant.client; + if(%occCl != %client && %occCl.team == %client.team) + { + // the vehicle has a valid teammate at this node + // share the score with them + %occCl.vehicleBonus += %amount; + %game.recalcScore(%occCl); + } + } + } + + } +} + +function CTFGame::awardScoreTurretKill(%game, %victimID, %implement) +{ + if ((%killer = %implement.getControllingClient()) != 0) //award whoever might be controlling the turret + { + if (%killer == %victimID) + %game.awardScoreSuicide(%victimID); + else if (%killer.team == %victimID.team) //player controlling a turret killed a teammate + { + %killer.teamKills++; + %game.awardScoreTurretTeamKill(%victimID, %killer); + %game.awardScoreDeath(%victimID); + } + else + { + %killer.mannedturretKills++; + %game.recalcScore(%killer); + %game.awardScoreDeath(%victimID); + } + } + else if ((%killer = %implement.owner) != 0) //if it isn't controlled, award score to whoever deployed it + { + if (%killer.team == %victimID.team) + { + %game.awardScoreDeath(%victimID); + } + else + { + %killer.turretKills++; + %game.recalcScore(%killer); + %game.awardScoreDeath(%victimID); + } + } + //default is, no one was controlling it, no one owned it. No score given. +} + +function CTFGame::testKill(%game, %victimID, %killerID) +{ + return ((%killerID !=0) && (%victimID.team != %killerID.team)); +} + +function CTFGame::awardScoreKill(%game, %killerID) +{ + %killerID.kills++; + %game.recalcScore(%killerID); + return %game.SCORE_PER_KILL; +} + + +function checkVehicleCamping( %team ) +{ + %position = $flagPos[%team]; + %radius = 5; + InitContainerRadiusSearch(%position, %radius, $TypeMasks::VehicleObjectType ); + + while ((%vehicle = containerSearchNext()) != 0) + { + %dist = containerSearchCurrRadDamageDist(); + + if (%dist > %radius) + continue; + else + { + //if( %vehicle.team == %team ) + applyVehicleCampDamage( %vehicle ); + } + } + + if( %team == 1 ) + Game.campThread_1 = schedule( 1000, 0, "checkVehicleCamping", 1 ); + else + Game.campThread_2 = schedule( 1000, 0, "checkVehicleCamping", 2 ); +} + +function applyVehicleCampDamage( %vehicle ) +{ + if( !isObject( %vehicle ) ) + return; + + if( %vehicle.getDamageState() $= "Destroyed" ) + return; + + %client = %vehicle.getMountNodeObject(0).client; // grab the pilot + + messageClient( %client, 'serverMessage', "Can't park vehicles in flag zones!" ); + %vehicle.getDataBlock().damageObject( %vehicle, 0, "0 0 0", 0.5, 0); +} + +// z0dd - ZOD, 10/02/02. Hack for flag collision bug. +function CTFGame::startFlagCollisionSearch(%game, %flag) +{ + %flag.searchSchedule = %game.schedule(10, "startFlagCollisionSearch", %flag); // SquirrelOfDeath, 10/02/02. Moved from after the while loop + %pos = %flag.getWorldBoxCenter(); + InitContainerRadiusSearch( %pos, 1.0, $TypeMasks::VehicleObjectType | $TypeMasks::CorpseObjectType | $TypeMasks::PlayerObjectType ); + while((%found = containerSearchNext()) != 0) + { + %flag.getDataBlock().onCollision(%flag, %found); + // SquirrelOfDeath, 10/02/02. Removed break to catch all players possibly intersecting with flag + } +} + + + diff --git a/scripts/CnHGame.cs b/scripts/CnHGame.cs index d1e21d3..45b8704 100644 --- a/scripts/CnHGame.cs +++ b/scripts/CnHGame.cs @@ -1,468 +1,468 @@ -// DisplayName = Capture and Hold - -//--- GAME RULES BEGIN --- -//Teams try to capture marked objectives -//Capturing player gets a point 12 seconds after a capture -//Hold objectives in order to score -//A team scores 2 points per second it holds an objective -//Turrets and inventory stations convert when their switch is taken -//--- GAME RULES END --- - -//exec the AI scripts -exec("scripts/aiCnH.cs"); - -$InvBanList[CnH, "MiningTool"] = 1; - -package CnHGame { - -function FlipFlop::playerTouch(%data, %flipflop, %player) -{ - if(%flipflop.team != %player.client.team) - { - Parent::playerTouch(%data, %flipflop, %player); - Game.startTimerPlayerFFCap(%player.client, %flipflop); - } -} - -function Flipflop::objectiveInit(%data, %flipflop) -{ - %flipflop.tCapThread = ""; - %flipflop.tHoldThread = ""; - %flipflop.pCapThread = ""; - Parent::objectiveInit(%data, %flipflop); -} - -}; - - -//--------- CnH SCORING INIT ------------------ -function CnHGame::initGameVars(%game) -{ - %game.SCORE_PER_SUICIDE = -1; - %game.SCORE_PER_TEAMKILL = -1; - %game.SCORE_PER_DEATH = -1; - - %game.SCORE_PER_KILL = 1; - %game.SCORE_PER_PLYR_FLIPFLOP_CAP = 1; - %game.SCORE_PER_TEAM_FLIPFLOP_CAP = 1; - %game.SCORE_PER_TEAM_FLIPFLOP_HOLD = 1; - - %game.SCORE_PER_TURRET_KILL = 1; - %game.SCORE_PER_FLIPFLOP_DEFEND = 1; - %game.SCORE_LIMIT_PER_TOWER = 1200; //default of 1200 points per tower required to win @ 1 pt per %game.TIME_REQ_TEAM_HOLD_BONUS milliseconds - - %game.TIME_REQ_PLYR_CAP_BONUS = 12 * 1000; //player must hold a switch 12 seconds to get a point for it. - %game.TIME_REQ_TEAM_CAP_BONUS = 12 * 1000; //time after touching it takes for team to get a point - %game.TIME_REQ_TEAM_HOLD_BONUS = 0.5 * 1000; //recurring time it takes team to earn a point when flipflop held - %game.RADIUS_FLIPFLOP_DEFENSE = 20; //meters -} - -function CnHGame::setUpTeams(%game) -{ - DefaultGame::setUpTeams(%game); - - // reset the visibility of team 0 (team is still defaulted as friendly) - setSensorGroupAlwaysVisMask(0, 0); -} - -//-- tracking --- -// .deaths .kills .suicides .teamKills .turretKills -// .flipFlopDefends .flipFlopsCapped - -function CnHGame::startMatch(%game) -{ - for(%i = 0; %i <= %game.numTeams; %i++) - $TeamScore[%i] = 0; - - DefaultGame::startMatch(%game); -} - -function CnHGame::checkScoreLimit(%game, %team) -{ - %scoreLimit = %game.getScoreLimit(); - if($TeamScore[%team] >= %scoreLimit) - %game.scoreLimitReached(); -} - -function CnHGame::getScoreLimit(%game) -{ - %scoreLimit = MissionGroup.CnH_scoreLimit; - if(%scoreLimit $= "") - %scoreLimit = %game.getNumFlipFlops() * %game.SCORE_LIMIT_PER_TOWER; - - return %scoreLimit; -} - -function CnHGame::scoreLimitReached(%game) -{ - logEcho("game over (scorelimit)"); - %game.gameOver(); - cycleMissions(); -} - -function CnHGame::timeLimitReached(%game) -{ - logEcho("game over (timelimit)"); - %game.gameOver(); - cycleMissions(); -} - -function CnHGame::gameOver(%game) -{ - //call the default - DefaultGame::gameOver(%game); - - // stop all bonus timers - %game.stopScoreTimers(); - - //send the winner message - %winner = ""; - if ($teamScore[1] > $teamScore[2]) - %winner = $teamName[1]; - else if ($teamScore[2] > $teamScore[1]) - %winner = $teamName[2]; - - if (%winner $= 'Storm') - messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.stowins.wav" ); - else if (%winner $= 'Inferno') - messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.infwins.wav" ); - else - messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.gameover.wav" ); - - messageAll('MsgClearObjHud', ""); - for(%i = 0; %i < ClientGroup.getCount(); %i ++) - { - %client = ClientGroup.getObject(%i); - %game.resetScore(%client); - } - for ( %team = 1; %team <= %game.numTeams; %team++ ) - { - $TeamScore[%team] = 0; - messageAll('MsgCnHTeamCap', "", -1, -1, -1, %team, $TeamScore[%team], %game.getScoreLimit()); - } -} - -function CnHGame::stopScoreTimers(%game) -{ - // find all switches and cancel any timers associated with them - %ffGroup = nameToId("MissionCleanup/FlipFlops"); - if(%ffGroup <= 0) - return; - - for(%i = 0; %i < %ffGroup.getCount(); %i++) - { - %curFF = %ffGroup.getObject(%i); - cancel(%curFF.tHoldThread); - cancel(%curFF.pCapThread); - cancel(%curFF.tCapThread); - } -} - -function CnHGame::clientMissionDropReady(%game, %client) -{ - messageClient(%client, 'MsgClientReady',"", %game.class); - %scoreLimit = %game.getScoreLimit(); - - for(%i = 1; %i <= %game.numTeams; %i++) - { - %teamHeld = %game.countFlipsHeld(%i); - messageClient(%client, 'MsgCnHAddTeam', "", %i, $TeamName[%i], $TeamScore[%i], %scoreLimit, %teamHeld); - } - - //%game.populateTeamRankArray(%client); - //messageClient(%client, 'MsgYourRankIs', "", -1); - - messageClient(%client, 'MsgMissionDropInfo', '\c0You are in mission %1 (%2).', $MissionDisplayName, $MissionTypeDisplayName, $ServerName ); - - DefaultGame::clientMissionDropReady(%game, %client); -} - -function CnHGame::assignClientTeam(%game, %client, %respawn) -{ - DefaultGame::assignClientTeam(%game, %client, %respawn); - // if player's team is not on top of objective hud, switch lines - messageClient(%client, 'MsgCheckTeamLines', "", %client.team); -} - -function CnHGame::getNumFlipFlops() -{ - %ffGroup = nameToID("MissionCleanup/FlipFlops"); - return %ffGroup.getCount(); -} - -function CnHGame::countFlipsHeld(%game, %team) -{ - %teamHeld = 0; - // count how many flipflops each team holds - %ffSet = nameToID("MissionCleanup/FlipFlops"); - if(%ffSet > 0) - { - %numFF = %ffSet.getCount(); - for(%j = 0; %j < %numFF; %j++) - { - %curFF = %ffSet.getObject(%j); - if(%curFF.team == %team) - %teamHeld++; - } - } - - return %teamHeld; -} - -function CnHGame::countFlips(%game) -{ - return true; -} - -function CnHGame::equip(%game, %player) -{ - for(%i =0; %i<$InventoryHudCount; %i++) - %player.client.setInventoryHudItem($InventoryHudData[%i, itemDataName], 0, 1); - %player.client.clearBackpackIcon(); - - //%player.setArmor("Light"); - %player.setInventory(Blaster,1); - %player.setInventory(Chaingun, 1); - %player.setInventory(ChaingunAmmo, 100); - %player.setInventory(Disc,1); - %player.setInventory(DiscAmmo, 20); - %player.setInventory(TargetingLaser, 1); - %player.setInventory(Grenade,6); - %player.setInventory(Beacon, 3); - %player.setInventory(RepairKit,1); - %player.weaponCount = 3; - - %player.use("Blaster"); -} - -//--------------- Scoring functions ----------------- -function CnHGame::recalcScore(%game, %cl) -{ - %killValue = %cl.kills * %game.SCORE_PER_KILL; - %deathValue = %cl.deaths * %game.SCORE_PER_DEATH; - - if (%killValue - %deathValue == 0) - %killPoints = 0; - else - %killPoints = (%killValue * %killValue) / (%killValue - %deathValue); - - %cl.offenseScore = %killPoints; - %cl.offenseScore += %cl.suicides * %game.SCORE_PER_SUICIDE; //-1 - %cl.offenseScore += %cl.teamKills * %game.SCORE_PER_TEAMKILL; // -1 - %cl.offenseScore += %cl.flipFlopsCapped * %game.SCORE_PER_PLYR_FLIPFLOP_CAP; - - %cl.defenseScore = %cl.turretKills * %game.SCORE_PER_TURRET_KILL; // 1 - %cl.defenseScore += %cl.flipFlopDefends * %game.SCORE_PER_FLIPFLOP_DEFEND; - - %cl.score = mFloor(%cl.offenseScore + %cl.defenseScore); - //track switches held (not touched), switches defended, kills, deaths, suicides, tks - - %game.recalcTeamRanks(%cl); -} - -function CnHGame::updateKillScores(%game, %clVictim, %clKiller, %damageType, %implement) -{ - if(%game.testTurretKill(%implement)) //check for turretkill before awarded a non client points for a kill - { - %game.awardScoreTurretKill(%clVictim, %implement); - } - else if (%game.testKill(%clVictim, %clKiller)) //verify victim was an enemy - { - %game.awardScoreKill(%clKiller); - %game.awardScoreDeath(%clVictim); - - //see if we were defending a flip flop - %flipflop = %game.testPlayerFFDefend(%clVictim, %clKiller); - if (isObject(%flipflop)) - %game.awardScorePlayerFFDefend(%clKiller, %flipflop); - } - else - { - if (%game.testSuicide(%clVictim, %clKiller, %damageType)) //otherwise test for suicide - { - %game.awardScoreSuicide(%clVictim); - } - else - { - if (%game.testTeamKill(%clVictim, %clKiller)) //otherwise test for a teamkill - %game.awardScoreTeamKill(%clVictim, %clKiller); - } - } -} - -function CnHGame::testPlayerFFDefend(%game, %victimID, %killerID) -{ - if (!isObject(%victimId) || !isObject(%killerId) || %killerId.team <= 0) - return -1; - - //loop through the flipflops looking for one within range that belongs to the killer... - %ffGroup = nameToID("MissionCleanup/FlipFlops"); - for (%i = 0; %i < %ffGroup.getCount(); %i++) - { - %ffObj = %ffGroup.getObject(%i); - if (VectorDist(%ffObj.position, %victimID.plyrPointOfDeath) < %game.RADIUS_FLIPFLOP_DEFENSE) - { - if (%ffObj.team == %killerID.team) - return %ffObj; - } - } - - //none were found - return -1; -} - -function CnHGame::awardScorePlayerFFDefend(%game, %cl, %flipflop) -{ - %cl.flipFlopDefends++; - if (%game.SCORE_PER_FLIPFLOP_DEFEND != 0) - { - messageClient(%cl, 'msgFFDef', '\c0You received a %1 point bonus for defending %2.', %game.SCORE_PER_FLIPFLOP_DEFEND, %game.cleanWord(%flipflop.name)); -// messageTeamExcept(%cl, 'msgFFDef', '\c0Teammate %1 received a %2 point bonus for defending %3', %cl.name, %game.SCORE_PER_FLIPFLOP_DEFEND, %game.cleanWord(%flipflop.name)); - } - %game.recalcScore(%cl); -} - -function CnHGame::awardScorePlayerFFCap(%game, %cl, %this) -{ - if(!($missionRunning)) - return; - - %cl.flipFlopsCapped++; - if (%game.SCORE_PER_PLYR_FLIPFLOP_CAP != 0) - { - messageClient(%cl, 'msgFFDef', '\c0You received a %1 point bonus for holding the %2.', %game.SCORE_PER_PLYR_FLIPFLOP_CAP, %game.cleanWord(%this.name)); -// messageTeamExcept(%cl, 'msgFFDef', '\c0Teammate %1 received a %2 point bonus for holding the %3', %cl.name, %game.SCORE_PER_PLYR_FLIPFLOP_CAP, %game.cleanWord(%this.name)); - } - %game.recalcScore(%cl); -} - -function CnHGame::awardScoreTeamFFCap(%game, %team, %this) -{ - cancel(%this.tCapThread); - - if(!($missionRunning)) - return; - - $TeamScore[%team] +=%game.SCORE_PER_TEAM_FLIPFLOP_CAP; - %sLimit = %game.getScoreLimit(); - if (%game.SCORE_PER_TEAM_FLIPFLOP_CAP) - messageAll('MsgCnHTeamCap', "", -1, -1, -1, %team, $teamScore[%team], %sLimit); - if (%game.SCORE_PER_TEAM_FLIPFLOP_HOLD != 0) - %this.tHoldThread = %game.schedule(%game.TIME_REQ_TEAM_HOLD_BONUS, "awardScoreTeamFFHold", %team, %this); - - %game.checkScoreLimit(%team); -} - -function CnHGame::awardScoreTeamFFHold(%game, %team, %this) -{ - cancel(%this.tHoldThread); - - if(!($missionRunning)) - return; - - $TeamScore[%team] +=%game.SCORE_PER_TEAM_FLIPFLOP_HOLD; - %sLimit = %game.getScoreLimit(); - if (%game.SCORE_PER_TEAM_FLIPFLOP_HOLD) - messageAll('MsgCnHTeamCap', "", $TeamName[%team], %game.SCORE_PER_TEAM_FLIPFLOP_HOLD, %game.cleanWord(%this.name), %team, $teamScore[%team], %sLimit); - - // if either team's score is divisible by 100, send a console log message - if(($TeamScore[%team] / 100) == (mFloor($TeamScore[%team] / 100))) - for(%i = 1; %i <= %game.numTeams; %i++) - logEcho("team "@%i@" score "@$TeamScore[%i]); - - %game.checkScoreLimit(%team); - - %this.tHoldThread = %game.schedule(%game.TIME_REQ_TEAM_HOLD_BONUS, "awardScoreTeamFFHold", %team, %this); -} - -function CnHGame::testValidRepair(%game, %obj) -{ - return ((%obj.lastDamagedByTeam != %obj.team) && (%obj.repairedBy.team == %obj.team)); -} - -function CnHGame::genOnRepaired(%game, %obj, %objName) -{ - - if (%game.testValidRepair(%obj)) - { - %repairman = %obj.repairedBy; - messageTeam(%repairman.team, 'msgGenRepaired', '\c0%1 repaired the %2 Generator!', %repairman.name, %obj.nameTag); - } -} - -function CnHGame::stationOnRepaired(%game, %obj, %objName) -{ - if (%game.testValidRepair(%obj)) - { - %repairman = %obj.repairedBy; - messageTeam(%repairman.team, 'msgStationRepaired', '\c0%1 repaired the %2 Inventory Station!', %repairman.name, %obj.nameTag); - } -} - -function CnHGame::sensorOnRepaired(%game, %obj, %objName) -{ - if (%game.testValidRepair(%obj)) - { - %repairman = %obj.repairedBy; - messageTeam(%repairman.team, 'msgSensorRepaired', '\c0%1 repaired the %2 Pulse Sensor!', %repairman.name, %obj.nameTag); - } -} - -function CnHGame::turretOnRepaired(%game, %obj, %objName) -{ - if (%game.testValidRepair(%obj)) - { - %repairman = %obj.repairedBy; - messageTeam(%repairman.team, 'msgTurretRepaired', '\c0%1 repaired the %2 Turret!', %repairman.name, %obj.nameTag); - } -} - -function CnHGame::vStationOnRepaired(%game, %obj, %objName) -{ - if (%game.testValidRepair(%obj)) - { - %repairman = %obj.repairedBy; - messageTeam(%repairman.team, 'msgTurretRepaired', '\c0%1 repaired the %2 Vehicle Station!', %repairman.name, %obj.nameTag); - } -} - -function CnHGame::startTimerPlayerFFCap(%game, %cl, %this) -{ - cancel(%this.pCapThread); //stop the last owner from collecting a cap bonus - %this.pCapThread = %game.schedule(%game.TIME_REQ_PLYR_CAP_BONUS, "awardScorePlayerFFCap", %cl, %this); - cancel(%this.tCapThread); //stop the old owners from collecting any cap bonus - cancel(%this.tHoldThread); //stop the old owners from collecting any hold bonus - %this.tCapThread = %game.schedule(%game.TIME_REQ_TEAM_CAP_BONUS, "awardScoreTeamFFCap", %cl.team, %this); -} - -function CnHGame::startTimerTeamFFCap(%game, %team, %this, %time) -{ - %this.tCapThread = %game.schedule(%time, "awardScoreTeamFFCap", %team, %this); -} - -//------------------------------------------------------------------------ - -function CnHGame::resetScore(%game, %client) -{ - %client.offenseScore = 0; - %client.kills = 0; - %client.deaths = 0; - %client.suicides = 0; - %client.teamKills = 0; - %client.flipFlopsCapped = 0; - - - %client.defenseScore = 0; - %client.turretKills = 0; - %client.flipFlopDefends = 0; - - %client.score = 0; - - for ( %team = 1; %team <= %game.numTeams; %team++ ) - if($TeamScore[%team] != 0) - $TeamScore[%team] = 0; -} - -function CnHGame::applyConcussion(%game, %player) -{ -} +// DisplayName = Capture and Hold + +//--- GAME RULES BEGIN --- +//Teams try to capture marked objectives +//Capturing player gets a point 12 seconds after a capture +//Hold objectives in order to score +//A team scores 2 points per second it holds an objective +//Turrets and inventory stations convert when their switch is taken +//--- GAME RULES END --- + +//exec the AI scripts +exec("scripts/aiCnH.cs"); + +$InvBanList[CnH, "MiningTool"] = 1; + +package CnHGame { + +function FlipFlop::playerTouch(%data, %flipflop, %player) +{ + if(%flipflop.team != %player.client.team) + { + Parent::playerTouch(%data, %flipflop, %player); + Game.startTimerPlayerFFCap(%player.client, %flipflop); + } +} + +function Flipflop::objectiveInit(%data, %flipflop) +{ + %flipflop.tCapThread = ""; + %flipflop.tHoldThread = ""; + %flipflop.pCapThread = ""; + Parent::objectiveInit(%data, %flipflop); +} + +}; + + +//--------- CnH SCORING INIT ------------------ +function CnHGame::initGameVars(%game) +{ + %game.SCORE_PER_SUICIDE = -1; + %game.SCORE_PER_TEAMKILL = -1; + %game.SCORE_PER_DEATH = -1; + + %game.SCORE_PER_KILL = 1; + %game.SCORE_PER_PLYR_FLIPFLOP_CAP = 1; + %game.SCORE_PER_TEAM_FLIPFLOP_CAP = 1; + %game.SCORE_PER_TEAM_FLIPFLOP_HOLD = 1; + + %game.SCORE_PER_TURRET_KILL = 1; + %game.SCORE_PER_FLIPFLOP_DEFEND = 1; + %game.SCORE_LIMIT_PER_TOWER = 1200; //default of 1200 points per tower required to win @ 1 pt per %game.TIME_REQ_TEAM_HOLD_BONUS milliseconds + + %game.TIME_REQ_PLYR_CAP_BONUS = 12 * 1000; //player must hold a switch 12 seconds to get a point for it. + %game.TIME_REQ_TEAM_CAP_BONUS = 12 * 1000; //time after touching it takes for team to get a point + %game.TIME_REQ_TEAM_HOLD_BONUS = 0.5 * 1000; //recurring time it takes team to earn a point when flipflop held + %game.RADIUS_FLIPFLOP_DEFENSE = 20; //meters +} + +function CnHGame::setUpTeams(%game) +{ + DefaultGame::setUpTeams(%game); + + // reset the visibility of team 0 (team is still defaulted as friendly) + setSensorGroupAlwaysVisMask(0, 0); +} + +//-- tracking --- +// .deaths .kills .suicides .teamKills .turretKills +// .flipFlopDefends .flipFlopsCapped + +function CnHGame::startMatch(%game) +{ + for(%i = 0; %i <= %game.numTeams; %i++) + $TeamScore[%i] = 0; + + DefaultGame::startMatch(%game); +} + +function CnHGame::checkScoreLimit(%game, %team) +{ + %scoreLimit = %game.getScoreLimit(); + if($TeamScore[%team] >= %scoreLimit) + %game.scoreLimitReached(); +} + +function CnHGame::getScoreLimit(%game) +{ + %scoreLimit = MissionGroup.CnH_scoreLimit; + if(%scoreLimit $= "") + %scoreLimit = %game.getNumFlipFlops() * %game.SCORE_LIMIT_PER_TOWER; + + return %scoreLimit; +} + +function CnHGame::scoreLimitReached(%game) +{ + logEcho("game over (scorelimit)"); + %game.gameOver(); + cycleMissions(); +} + +function CnHGame::timeLimitReached(%game) +{ + logEcho("game over (timelimit)"); + %game.gameOver(); + cycleMissions(); +} + +function CnHGame::gameOver(%game) +{ + //call the default + DefaultGame::gameOver(%game); + + // stop all bonus timers + %game.stopScoreTimers(); + + //send the winner message + %winner = ""; + if ($teamScore[1] > $teamScore[2]) + %winner = $teamName[1]; + else if ($teamScore[2] > $teamScore[1]) + %winner = $teamName[2]; + + if (%winner $= 'Storm') + messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.stowins.wav" ); + else if (%winner $= 'Inferno') + messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.infwins.wav" ); + else + messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.gameover.wav" ); + + messageAll('MsgClearObjHud', ""); + for(%i = 0; %i < ClientGroup.getCount(); %i ++) + { + %client = ClientGroup.getObject(%i); + %game.resetScore(%client); + } + for ( %team = 1; %team <= %game.numTeams; %team++ ) + { + $TeamScore[%team] = 0; + messageAll('MsgCnHTeamCap', "", -1, -1, -1, %team, $TeamScore[%team], %game.getScoreLimit()); + } +} + +function CnHGame::stopScoreTimers(%game) +{ + // find all switches and cancel any timers associated with them + %ffGroup = nameToId("MissionCleanup/FlipFlops"); + if(%ffGroup <= 0) + return; + + for(%i = 0; %i < %ffGroup.getCount(); %i++) + { + %curFF = %ffGroup.getObject(%i); + cancel(%curFF.tHoldThread); + cancel(%curFF.pCapThread); + cancel(%curFF.tCapThread); + } +} + +function CnHGame::clientMissionDropReady(%game, %client) +{ + messageClient(%client, 'MsgClientReady',"", %game.class); + %scoreLimit = %game.getScoreLimit(); + + for(%i = 1; %i <= %game.numTeams; %i++) + { + %teamHeld = %game.countFlipsHeld(%i); + messageClient(%client, 'MsgCnHAddTeam', "", %i, $TeamName[%i], $TeamScore[%i], %scoreLimit, %teamHeld); + } + + //%game.populateTeamRankArray(%client); + //messageClient(%client, 'MsgYourRankIs', "", -1); + + messageClient(%client, 'MsgMissionDropInfo', '\c0You are in mission %1 (%2).', $MissionDisplayName, $MissionTypeDisplayName, $ServerName ); + + DefaultGame::clientMissionDropReady(%game, %client); +} + +function CnHGame::assignClientTeam(%game, %client, %respawn) +{ + DefaultGame::assignClientTeam(%game, %client, %respawn); + // if player's team is not on top of objective hud, switch lines + messageClient(%client, 'MsgCheckTeamLines', "", %client.team); +} + +function CnHGame::getNumFlipFlops() +{ + %ffGroup = nameToID("MissionCleanup/FlipFlops"); + return %ffGroup.getCount(); +} + +function CnHGame::countFlipsHeld(%game, %team) +{ + %teamHeld = 0; + // count how many flipflops each team holds + %ffSet = nameToID("MissionCleanup/FlipFlops"); + if(%ffSet > 0) + { + %numFF = %ffSet.getCount(); + for(%j = 0; %j < %numFF; %j++) + { + %curFF = %ffSet.getObject(%j); + if(%curFF.team == %team) + %teamHeld++; + } + } + + return %teamHeld; +} + +function CnHGame::countFlips(%game) +{ + return true; +} + +function CnHGame::equip(%game, %player) +{ + for(%i =0; %i<$InventoryHudCount; %i++) + %player.client.setInventoryHudItem($InventoryHudData[%i, itemDataName], 0, 1); + %player.client.clearBackpackIcon(); + + //%player.setArmor("Light"); + %player.setInventory(Blaster,1); + %player.setInventory(Chaingun, 1); + %player.setInventory(ChaingunAmmo, 100); + %player.setInventory(Disc,1); + %player.setInventory(DiscAmmo, 20); + %player.setInventory(TargetingLaser, 1); + %player.setInventory(Grenade,6); + %player.setInventory(Beacon, 3); + %player.setInventory(RepairKit,1); + %player.weaponCount = 3; + + %player.use("Blaster"); +} + +//--------------- Scoring functions ----------------- +function CnHGame::recalcScore(%game, %cl) +{ + %killValue = %cl.kills * %game.SCORE_PER_KILL; + %deathValue = %cl.deaths * %game.SCORE_PER_DEATH; + + if (%killValue - %deathValue == 0) + %killPoints = 0; + else + %killPoints = (%killValue * %killValue) / (%killValue - %deathValue); + + %cl.offenseScore = %killPoints; + %cl.offenseScore += %cl.suicides * %game.SCORE_PER_SUICIDE; //-1 + %cl.offenseScore += %cl.teamKills * %game.SCORE_PER_TEAMKILL; // -1 + %cl.offenseScore += %cl.flipFlopsCapped * %game.SCORE_PER_PLYR_FLIPFLOP_CAP; + + %cl.defenseScore = %cl.turretKills * %game.SCORE_PER_TURRET_KILL; // 1 + %cl.defenseScore += %cl.flipFlopDefends * %game.SCORE_PER_FLIPFLOP_DEFEND; + + %cl.score = mFloor(%cl.offenseScore + %cl.defenseScore); + //track switches held (not touched), switches defended, kills, deaths, suicides, tks + + %game.recalcTeamRanks(%cl); +} + +function CnHGame::updateKillScores(%game, %clVictim, %clKiller, %damageType, %implement) +{ + if(%game.testTurretKill(%implement)) //check for turretkill before awarded a non client points for a kill + { + %game.awardScoreTurretKill(%clVictim, %implement); + } + else if (%game.testKill(%clVictim, %clKiller)) //verify victim was an enemy + { + %game.awardScoreKill(%clKiller); + %game.awardScoreDeath(%clVictim); + + //see if we were defending a flip flop + %flipflop = %game.testPlayerFFDefend(%clVictim, %clKiller); + if (isObject(%flipflop)) + %game.awardScorePlayerFFDefend(%clKiller, %flipflop); + } + else + { + if (%game.testSuicide(%clVictim, %clKiller, %damageType)) //otherwise test for suicide + { + %game.awardScoreSuicide(%clVictim); + } + else + { + if (%game.testTeamKill(%clVictim, %clKiller)) //otherwise test for a teamkill + %game.awardScoreTeamKill(%clVictim, %clKiller); + } + } +} + +function CnHGame::testPlayerFFDefend(%game, %victimID, %killerID) +{ + if (!isObject(%victimId) || !isObject(%killerId) || %killerId.team <= 0) + return -1; + + //loop through the flipflops looking for one within range that belongs to the killer... + %ffGroup = nameToID("MissionCleanup/FlipFlops"); + for (%i = 0; %i < %ffGroup.getCount(); %i++) + { + %ffObj = %ffGroup.getObject(%i); + if (VectorDist(%ffObj.position, %victimID.plyrPointOfDeath) < %game.RADIUS_FLIPFLOP_DEFENSE) + { + if (%ffObj.team == %killerID.team) + return %ffObj; + } + } + + //none were found + return -1; +} + +function CnHGame::awardScorePlayerFFDefend(%game, %cl, %flipflop) +{ + %cl.flipFlopDefends++; + if (%game.SCORE_PER_FLIPFLOP_DEFEND != 0) + { + messageClient(%cl, 'msgFFDef', '\c0You received a %1 point bonus for defending %2.', %game.SCORE_PER_FLIPFLOP_DEFEND, %game.cleanWord(%flipflop.name)); +// messageTeamExcept(%cl, 'msgFFDef', '\c0Teammate %1 received a %2 point bonus for defending %3', %cl.name, %game.SCORE_PER_FLIPFLOP_DEFEND, %game.cleanWord(%flipflop.name)); + } + %game.recalcScore(%cl); +} + +function CnHGame::awardScorePlayerFFCap(%game, %cl, %this) +{ + if(!($missionRunning)) + return; + + %cl.flipFlopsCapped++; + if (%game.SCORE_PER_PLYR_FLIPFLOP_CAP != 0) + { + messageClient(%cl, 'msgFFDef', '\c0You received a %1 point bonus for holding the %2.', %game.SCORE_PER_PLYR_FLIPFLOP_CAP, %game.cleanWord(%this.name)); +// messageTeamExcept(%cl, 'msgFFDef', '\c0Teammate %1 received a %2 point bonus for holding the %3', %cl.name, %game.SCORE_PER_PLYR_FLIPFLOP_CAP, %game.cleanWord(%this.name)); + } + %game.recalcScore(%cl); +} + +function CnHGame::awardScoreTeamFFCap(%game, %team, %this) +{ + cancel(%this.tCapThread); + + if(!($missionRunning)) + return; + + $TeamScore[%team] +=%game.SCORE_PER_TEAM_FLIPFLOP_CAP; + %sLimit = %game.getScoreLimit(); + if (%game.SCORE_PER_TEAM_FLIPFLOP_CAP) + messageAll('MsgCnHTeamCap', "", -1, -1, -1, %team, $teamScore[%team], %sLimit); + if (%game.SCORE_PER_TEAM_FLIPFLOP_HOLD != 0) + %this.tHoldThread = %game.schedule(%game.TIME_REQ_TEAM_HOLD_BONUS, "awardScoreTeamFFHold", %team, %this); + + %game.checkScoreLimit(%team); +} + +function CnHGame::awardScoreTeamFFHold(%game, %team, %this) +{ + cancel(%this.tHoldThread); + + if(!($missionRunning)) + return; + + $TeamScore[%team] +=%game.SCORE_PER_TEAM_FLIPFLOP_HOLD; + %sLimit = %game.getScoreLimit(); + if (%game.SCORE_PER_TEAM_FLIPFLOP_HOLD) + messageAll('MsgCnHTeamCap', "", $TeamName[%team], %game.SCORE_PER_TEAM_FLIPFLOP_HOLD, %game.cleanWord(%this.name), %team, $teamScore[%team], %sLimit); + + // if either team's score is divisible by 100, send a console log message + if(($TeamScore[%team] / 100) == (mFloor($TeamScore[%team] / 100))) + for(%i = 1; %i <= %game.numTeams; %i++) + logEcho("team "@%i@" score "@$TeamScore[%i]); + + %game.checkScoreLimit(%team); + + %this.tHoldThread = %game.schedule(%game.TIME_REQ_TEAM_HOLD_BONUS, "awardScoreTeamFFHold", %team, %this); +} + +function CnHGame::testValidRepair(%game, %obj) +{ + return ((%obj.lastDamagedByTeam != %obj.team) && (%obj.repairedBy.team == %obj.team)); +} + +function CnHGame::genOnRepaired(%game, %obj, %objName) +{ + + if (%game.testValidRepair(%obj)) + { + %repairman = %obj.repairedBy; + messageTeam(%repairman.team, 'msgGenRepaired', '\c0%1 repaired the %2 Generator!', %repairman.name, %obj.nameTag); + } +} + +function CnHGame::stationOnRepaired(%game, %obj, %objName) +{ + if (%game.testValidRepair(%obj)) + { + %repairman = %obj.repairedBy; + messageTeam(%repairman.team, 'msgStationRepaired', '\c0%1 repaired the %2 Inventory Station!', %repairman.name, %obj.nameTag); + } +} + +function CnHGame::sensorOnRepaired(%game, %obj, %objName) +{ + if (%game.testValidRepair(%obj)) + { + %repairman = %obj.repairedBy; + messageTeam(%repairman.team, 'msgSensorRepaired', '\c0%1 repaired the %2 Pulse Sensor!', %repairman.name, %obj.nameTag); + } +} + +function CnHGame::turretOnRepaired(%game, %obj, %objName) +{ + if (%game.testValidRepair(%obj)) + { + %repairman = %obj.repairedBy; + messageTeam(%repairman.team, 'msgTurretRepaired', '\c0%1 repaired the %2 Turret!', %repairman.name, %obj.nameTag); + } +} + +function CnHGame::vStationOnRepaired(%game, %obj, %objName) +{ + if (%game.testValidRepair(%obj)) + { + %repairman = %obj.repairedBy; + messageTeam(%repairman.team, 'msgTurretRepaired', '\c0%1 repaired the %2 Vehicle Station!', %repairman.name, %obj.nameTag); + } +} + +function CnHGame::startTimerPlayerFFCap(%game, %cl, %this) +{ + cancel(%this.pCapThread); //stop the last owner from collecting a cap bonus + %this.pCapThread = %game.schedule(%game.TIME_REQ_PLYR_CAP_BONUS, "awardScorePlayerFFCap", %cl, %this); + cancel(%this.tCapThread); //stop the old owners from collecting any cap bonus + cancel(%this.tHoldThread); //stop the old owners from collecting any hold bonus + %this.tCapThread = %game.schedule(%game.TIME_REQ_TEAM_CAP_BONUS, "awardScoreTeamFFCap", %cl.team, %this); +} + +function CnHGame::startTimerTeamFFCap(%game, %team, %this, %time) +{ + %this.tCapThread = %game.schedule(%time, "awardScoreTeamFFCap", %team, %this); +} + +//------------------------------------------------------------------------ + +function CnHGame::resetScore(%game, %client) +{ + %client.offenseScore = 0; + %client.kills = 0; + %client.deaths = 0; + %client.suicides = 0; + %client.teamKills = 0; + %client.flipFlopsCapped = 0; + + + %client.defenseScore = 0; + %client.turretKills = 0; + %client.flipFlopDefends = 0; + + %client.score = 0; + + for ( %team = 1; %team <= %game.numTeams; %team++ ) + if($TeamScore[%team] != 0) + $TeamScore[%team] = 0; +} + +function CnHGame::applyConcussion(%game, %player) +{ +} diff --git a/scripts/DMGame.cs b/scripts/DMGame.cs index b0edca1..31f832b 100644 --- a/scripts/DMGame.cs +++ b/scripts/DMGame.cs @@ -1,380 +1,380 @@ -// -------------------------------------------------------- -// Deathmatch mission type -// -------------------------------------------------------- - -// DisplayName = Deathmatch - -//--- GAME RULES BEGIN --- -//There aren't many rules... -//Kill -//Don't get killed -//Points are scored for each kill you make and subtracted each time you die -//--- GAME RULES END --- - -$InvBanList[DM, "TurretOutdoorDeployable"] = 1; -$InvBanList[DM, "TurretIndoorDeployable"] = 1; -$InvBanList[DM, "ElfBarrelPack"] = 1; -$InvBanList[DM, "MortarBarrelPack"] = 1; -$InvBanList[DM, "PlasmaBarrelPack"] = 1; -$InvBanList[DM, "AABarrelPack"] = 1; -$InvBanList[DM, "MissileBarrelPack"] = 1; -$InvBanList[DM, "Mine"] = 1; -$InvBanList[DM, "MiningTool"] = 1; - -function DMGame::setUpTeams(%game) -{ - %group = nameToID("MissionGroup/Teams"); - if(%group == -1) - return; - - // create a team0 if it does not exist - %team = nameToID("MissionGroup/Teams/team0"); - if(%team == -1) - { - %team = new SimGroup("team0"); - %group.add(%team); - } - - // 'team0' is not counted as a team here - %game.numTeams = 0; - while(%team != -1) - { - // create drop set and add all spawnsphere objects into it - %dropSet = new SimSet("TeamDrops" @ %game.numTeams); - MissionCleanup.add(%dropSet); - - %spawns = nameToID("MissionGroup/Teams/team" @ %game.numTeams @ "/SpawnSpheres"); - if(%spawns != -1) - { - %count = %spawns.getCount(); - for(%i = 0; %i < %count; %i++) - %dropSet.add(%spawns.getObject(%i)); - } - - // set the 'team' field for all the objects in this team - %team.setTeam(0); - - clearVehicleCount(%team+1); - // get next group - %team = nameToID("MissionGroup/Teams/team" @ %game.numTeams + 1); - if (%team != -1) - %game.numTeams++; - } - - // set the number of sensor groups (including team0) that are processed - setSensorGroupCount(%game.numTeams + 1); - %game.numTeams = 1; - - // allow teams 1->31 to listen to each other (team 0 can only listen to self) - for(%i = 1; %i < 32; %i++) - setSensorGroupListenMask(%i, 0xfffffffe); -} - -function DMGame::initGameVars(%game) -{ - %game.SCORE_PER_KILL = 1; - %game.SCORE_PER_DEATH = -1; - %game.SCORE_PER_SUICIDE = -1; -} - -exec("scripts/aiDeathMatch.cs"); - -function DMGame::allowsProtectedStatics(%game) -{ - return true; -} - -function DMGame::equip(%game, %player) -{ - for(%i =0; %i<$InventoryHudCount; %i++) - %player.client.setInventoryHudItem($InventoryHudData[%i, itemDataName], 0, 1); - %player.client.clearBackpackIcon(); - - //%player.setArmor("Light"); - %player.setInventory(RepairKit, 1); - %player.setInventory("Disc", 1); - %player.setInventory("DiscAmmo", 15); - %player.setInventory("TargetingLaser", 1); - %player.weaponCount = 1; - - if (%player.client.race $= "Draakan") //Also defined in DefaultGame.cs, but this overrides it. - %player.setInventory(Flamer,1); - - // do we want to give players a disc launcher instead? GJL: Yes we do! - %player.use("Disc"); -} - -function DMGame::pickPlayerSpawn(%game, %client, %respawn) -{ - // all spawns come from team 1 - return %game.pickTeamSpawn(1); -} - -function DMGame::clientJoinTeam( %game, %client, %team, %respawn ) -{ - %game.assignClientTeam( %client ); - - // Spawn the player: - %game.spawnPlayer( %client, %respawn ); -} - -function DMGame::assignClientTeam(%game, %client) -{ - for(%i = 1; %i < 32; %i++) - $DMTeamArray[%i] = false; - - %maxSensorGroup = 0; - %count = ClientGroup.getCount(); - for(%i = 0; %i < %count; %i++) - { - %cl = ClientGroup.getObject(%i); - if(%cl != %client) - { - $DMTeamArray[%cl.team] = true; - if (%cl.team > %maxSensorGroup) - %maxSensorGroup = %cl.team; - } - } - - //now loop through the team array, looking for an empty team - for(%i = 1; %i < 32; %i++) - { - if (! $DMTeamArray[%i]) - { - %client.team = %i; - if (%client.team > %maxSensorGroup) - %maxSensorGroup = %client.team; - break; - } - } - - // set player's skin pref here - setTargetSkin(%client.target, %client.skin); - - // Let everybody know you are no longer an observer: - messageAll( 'MsgClientJoinTeam', '\c1%1 has joined the fray.', %client.name, "", %client, 1 ); - updateCanListenState( %client ); - - //now set the max number of sensor groups... - setSensorGroupCount(%maxSensorGroup + 1); -} - -function DMGame::clientMissionDropReady(%game, %client) -{ - messageClient(%client, 'MsgClientReady',"", %game.class); - messageClient(%client, 'MsgYourScoreIs', "", 0); - messageClient(%client, 'MsgDMPlayerDies', "", 0); - messageClient(%client, 'MsgDMKill', "", 0); - %game.resetScore(%client); - - messageClient(%client, 'MsgMissionDropInfo', '\c0You are in mission %1 (%2).', $MissionDisplayName, $MissionTypeDisplayName, $ServerName ); - - DefaultGame::clientMissionDropReady(%game, %client); -} - -function DMGame::AIHasJoined(%game, %client) -{ - //let everyone know the player has joined the game - //messageAllExcept(%client, -1, 'MsgClientJoinTeam', '%1 has joined the fray.', %client.name, "", %client, 1 ); -} - -function DMGame::checkScoreLimit(%game, %client) -{ - //there's no score limit in DM -} - -function DMGame::createPlayer(%game, %client, %spawnLoc, %respawn) -{ - DefaultGame::createPlayer(%game, %client, %spawnLoc, %respawn); - %client.setSensorGroup(%client.team); -} - -function DMGame::resetScore(%game, %client) -{ - %client.deaths = 0; - %client.kills = 0; - %client.score = 0; - %client.efficiency = 0.0; - %client.suicides = 0; -} - -function DMGame::onClientKilled(%game, %clVictim, %clKiller, %damageType, %implement, %damageLoc) -{ - cancel(%clVictim.player.alertThread); - DefaultGame::onClientKilled(%game, %clVictim, %clKiller, %damageType, %implement, %damageLoc); -} - -function DMGame::updateKillScores(%game, %clVictim, %clKiller, %damageType, %implement) -{ - if (%game.testKill(%clVictim, %clKiller)) //verify victim was an enemy - { - %game.awardScoreKill(%clKiller); - messageClient(%clKiller, 'MsgDMKill', "", %clKiller.kills); - %game.awardScoreDeath(%clVictim); - } - else if (%game.testSuicide(%clVictim, %clKiller, %damageType)) //otherwise test for suicide - %game.awardScoreSuicide(%clVictim); - - messageClient(%clVictim, 'MsgDMPlayerDies', "", %clVictim.deaths + %clVictim.suicides); -} - -function DMGame::recalcScore(%game, %client) -{ - %killValue = %client.kills * %game.SCORE_PER_KILL; - %deathValue = %client.deaths * %game.SCORE_PER_DEATH; - %suicideValue = %client.suicides * %game.SCORE_PER_SUICIDE; - - if (%killValue - %deathValue == 0) - %client.efficiency = %suicideValue; - else - %client.efficiency = ((%killValue * %killValue) / (%killValue - %deathValue)) + %suicideValue; - - %client.score = mFloatLength(%client.efficiency, 1); - messageClient(%client, 'MsgYourScoreIs', "", %client.score); - %game.recalcTeamRanks(%client); - %game.checkScoreLimit(%client); -} - -function DMGame::timeLimitReached(%game) -{ - logEcho("game over (timelimit)"); - %game.gameOver(); - cycleMissions(); -} - -function DMGame::scoreLimitReached(%game) -{ - logEcho("game over (scorelimit)"); - %game.gameOver(); - cycleMissions(); -} - -function DMGame::gameOver(%game) -{ - //call the default - DefaultGame::gameOver(%game); - - messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.gameover.wav" ); - - cancel(%game.timeThread); - messageAll('MsgClearObjHud', ""); - for(%i = 0; %i < ClientGroup.getCount(); %i ++) { - %client = ClientGroup.getObject(%i); - %game.resetScore(%client); - } -} - -function DMGame::enterMissionArea(%game, %playerData, %player) -{ - %player.client.outOfBounds = false; - messageClient(%player.client, 'EnterMissionArea', '\c1You are back in the mission area.'); - logEcho(%player.client.nameBase@" (pl "@%player@"/cl "@%player.client@") entered mission area"); - cancel(%player.alertThread); -} - -function DMGame::leaveMissionArea(%game, %playerData, %player) -{ - if(%player.getState() $= "Dead") - return; - - %player.client.outOfBounds = true; - messageClient(%player.client, 'LeaveMissionArea', '\c1You have left the mission area. Return or take damage.~wfx/misc/warning_beep.wav'); - logEcho(%player.client.nameBase@" (pl "@%player@"/cl "@%player.client@") left mission area"); - %player.alertThread = %game.schedule(1000, "DMAlertPlayer", 3, %player); -} - -function DMGame::DMAlertPlayer(%game, %count, %player) -{ - // MES - I commented below line out because it prints a blank line to chat window - //messageClient(%player.client, 'MsgDMLeftMisAreaWarn', '~wfx/misc/red_alert.wav'); - if(%count > 1) - %player.alertThread = %game.schedule(1000, "DMAlertPlayer", %count - 1, %player); - else - %player.alertThread = %game.schedule(1000, "MissionAreaDamage", %player); -} - -function DMGame::MissionAreaDamage(%game, %player) -{ - if(%player.getState() !$= "Dead") { - %player.setDamageFlash(0.1); - %prevHurt = %player.getDamageLevel(); - %player.setDamageLevel(%prevHurt + 0.05); - %player.alertThread = %game.schedule(1000, "MissionAreaDamage", %player); - } - else - %game.onClientKilled(%player.client, 0, $DamageType::OutOfBounds); -} - -function DMGame::updateScoreHud(%game, %client, %tag) -{ - // Clear the header: - messageClient( %client, 'SetScoreHudHeader', "", "" ); - - // Send the subheader: - messageClient(%client, 'SetScoreHudSubheader', "", '\tPLAYER\tRATING\tKILLS\tDEATHS'); - - for (%index = 0; %index < $TeamRank[0, count]; %index++) - { - //get the client info - %cl = $TeamRank[0, %index]; - - //get the score - %clScore = mFloatLength( %cl.efficiency, 1 ); - - %clKills = mFloatLength( %cl.kills, 0 ); - %clDeaths = mFloatLength( %cl.deaths + %cl.suicides, 0 ); - %clStyle = %cl == %client ? "" : ""; - - //if the client is not an observer, send the message - if (%client.team != 0) - { - messageClient( %client, 'SetLineHud', "", %tag, %index, '%5\t%1%2%3%4', - %cl.name, %clScore, %clKills, %clDeaths, %clStyle ); - } - //else for observers, create an anchor around the player name so they can be observed - else - { - messageClient( %client, 'SetLineHud', "", %tag, %index, '%5\t%1%2%3%4', - %cl.name, %clScore, %clKills, %clDeaths, %clStyle, %cl ); - } - } - - // Tack on the list of observers: - %observerCount = 0; - for (%i = 0; %i < ClientGroup.getCount(); %i++) - { - %cl = ClientGroup.getObject(%i); - if (%cl.team == 0) - %observerCount++; - } - - if (%observerCount > 0) - { - messageClient( %client, 'SetLineHud', "", %tag, %index, ""); - %index++; - messageClient(%client, 'SetLineHud', "", %tag, %index, '\tOBSERVERS (%1)TIME', %observerCount); - %index++; - for (%i = 0; %i < ClientGroup.getCount(); %i++) - { - %cl = ClientGroup.getObject(%i); - //if this is an observer - if (%cl.team == 0) - { - %obsTime = getSimTime() - %cl.observerStartTime; - %obsTimeStr = %game.formatTime(%obsTime, false); - messageClient( %client, 'SetLineHud', "", %tag, %index, '\t%1%2', - %cl.name, %obsTimeStr ); - %index++; - } - } - } - - //clear the rest of Hud so we don't get old lines hanging around... - messageClient( %client, 'ClearHud', "", %tag, %index ); -} - -function DMGame::applyConcussion(%game, %player) -{ -} - - +// -------------------------------------------------------- +// Deathmatch mission type +// -------------------------------------------------------- + +// DisplayName = Deathmatch + +//--- GAME RULES BEGIN --- +//There aren't many rules... +//Kill +//Don't get killed +//Points are scored for each kill you make and subtracted each time you die +//--- GAME RULES END --- + +$InvBanList[DM, "TurretOutdoorDeployable"] = 1; +$InvBanList[DM, "TurretIndoorDeployable"] = 1; +$InvBanList[DM, "ElfBarrelPack"] = 1; +$InvBanList[DM, "MortarBarrelPack"] = 1; +$InvBanList[DM, "PlasmaBarrelPack"] = 1; +$InvBanList[DM, "AABarrelPack"] = 1; +$InvBanList[DM, "MissileBarrelPack"] = 1; +$InvBanList[DM, "Mine"] = 1; +$InvBanList[DM, "MiningTool"] = 1; + +function DMGame::setUpTeams(%game) +{ + %group = nameToID("MissionGroup/Teams"); + if(%group == -1) + return; + + // create a team0 if it does not exist + %team = nameToID("MissionGroup/Teams/team0"); + if(%team == -1) + { + %team = new SimGroup("team0"); + %group.add(%team); + } + + // 'team0' is not counted as a team here + %game.numTeams = 0; + while(%team != -1) + { + // create drop set and add all spawnsphere objects into it + %dropSet = new SimSet("TeamDrops" @ %game.numTeams); + MissionCleanup.add(%dropSet); + + %spawns = nameToID("MissionGroup/Teams/team" @ %game.numTeams @ "/SpawnSpheres"); + if(%spawns != -1) + { + %count = %spawns.getCount(); + for(%i = 0; %i < %count; %i++) + %dropSet.add(%spawns.getObject(%i)); + } + + // set the 'team' field for all the objects in this team + %team.setTeam(0); + + clearVehicleCount(%team+1); + // get next group + %team = nameToID("MissionGroup/Teams/team" @ %game.numTeams + 1); + if (%team != -1) + %game.numTeams++; + } + + // set the number of sensor groups (including team0) that are processed + setSensorGroupCount(%game.numTeams + 1); + %game.numTeams = 1; + + // allow teams 1->31 to listen to each other (team 0 can only listen to self) + for(%i = 1; %i < 32; %i++) + setSensorGroupListenMask(%i, 0xfffffffe); +} + +function DMGame::initGameVars(%game) +{ + %game.SCORE_PER_KILL = 1; + %game.SCORE_PER_DEATH = -1; + %game.SCORE_PER_SUICIDE = -1; +} + +exec("scripts/aiDeathMatch.cs"); + +function DMGame::allowsProtectedStatics(%game) +{ + return true; +} + +function DMGame::equip(%game, %player) +{ + for(%i =0; %i<$InventoryHudCount; %i++) + %player.client.setInventoryHudItem($InventoryHudData[%i, itemDataName], 0, 1); + %player.client.clearBackpackIcon(); + + //%player.setArmor("Light"); + %player.setInventory(RepairKit, 1); + %player.setInventory("Disc", 1); + %player.setInventory("DiscAmmo", 15); + %player.setInventory("TargetingLaser", 1); + %player.weaponCount = 1; + + if (%player.client.race $= "Draakan") //Also defined in DefaultGame.cs, but this overrides it. + %player.setInventory(Flamer,1); + + // do we want to give players a disc launcher instead? GJL: Yes we do! + %player.use("Disc"); +} + +function DMGame::pickPlayerSpawn(%game, %client, %respawn) +{ + // all spawns come from team 1 + return %game.pickTeamSpawn(1); +} + +function DMGame::clientJoinTeam( %game, %client, %team, %respawn ) +{ + %game.assignClientTeam( %client ); + + // Spawn the player: + %game.spawnPlayer( %client, %respawn ); +} + +function DMGame::assignClientTeam(%game, %client) +{ + for(%i = 1; %i < 32; %i++) + $DMTeamArray[%i] = false; + + %maxSensorGroup = 0; + %count = ClientGroup.getCount(); + for(%i = 0; %i < %count; %i++) + { + %cl = ClientGroup.getObject(%i); + if(%cl != %client) + { + $DMTeamArray[%cl.team] = true; + if (%cl.team > %maxSensorGroup) + %maxSensorGroup = %cl.team; + } + } + + //now loop through the team array, looking for an empty team + for(%i = 1; %i < 32; %i++) + { + if (! $DMTeamArray[%i]) + { + %client.team = %i; + if (%client.team > %maxSensorGroup) + %maxSensorGroup = %client.team; + break; + } + } + + // set player's skin pref here + setTargetSkin(%client.target, %client.skin); + + // Let everybody know you are no longer an observer: + messageAll( 'MsgClientJoinTeam', '\c1%1 has joined the fray.', %client.name, "", %client, 1 ); + updateCanListenState( %client ); + + //now set the max number of sensor groups... + setSensorGroupCount(%maxSensorGroup + 1); +} + +function DMGame::clientMissionDropReady(%game, %client) +{ + messageClient(%client, 'MsgClientReady',"", %game.class); + messageClient(%client, 'MsgYourScoreIs', "", 0); + messageClient(%client, 'MsgDMPlayerDies', "", 0); + messageClient(%client, 'MsgDMKill', "", 0); + %game.resetScore(%client); + + messageClient(%client, 'MsgMissionDropInfo', '\c0You are in mission %1 (%2).', $MissionDisplayName, $MissionTypeDisplayName, $ServerName ); + + DefaultGame::clientMissionDropReady(%game, %client); +} + +function DMGame::AIHasJoined(%game, %client) +{ + //let everyone know the player has joined the game + //messageAllExcept(%client, -1, 'MsgClientJoinTeam', '%1 has joined the fray.', %client.name, "", %client, 1 ); +} + +function DMGame::checkScoreLimit(%game, %client) +{ + //there's no score limit in DM +} + +function DMGame::createPlayer(%game, %client, %spawnLoc, %respawn) +{ + DefaultGame::createPlayer(%game, %client, %spawnLoc, %respawn); + %client.setSensorGroup(%client.team); +} + +function DMGame::resetScore(%game, %client) +{ + %client.deaths = 0; + %client.kills = 0; + %client.score = 0; + %client.efficiency = 0.0; + %client.suicides = 0; +} + +function DMGame::onClientKilled(%game, %clVictim, %clKiller, %damageType, %implement, %damageLoc) +{ + cancel(%clVictim.player.alertThread); + DefaultGame::onClientKilled(%game, %clVictim, %clKiller, %damageType, %implement, %damageLoc); +} + +function DMGame::updateKillScores(%game, %clVictim, %clKiller, %damageType, %implement) +{ + if (%game.testKill(%clVictim, %clKiller)) //verify victim was an enemy + { + %game.awardScoreKill(%clKiller); + messageClient(%clKiller, 'MsgDMKill', "", %clKiller.kills); + %game.awardScoreDeath(%clVictim); + } + else if (%game.testSuicide(%clVictim, %clKiller, %damageType)) //otherwise test for suicide + %game.awardScoreSuicide(%clVictim); + + messageClient(%clVictim, 'MsgDMPlayerDies', "", %clVictim.deaths + %clVictim.suicides); +} + +function DMGame::recalcScore(%game, %client) +{ + %killValue = %client.kills * %game.SCORE_PER_KILL; + %deathValue = %client.deaths * %game.SCORE_PER_DEATH; + %suicideValue = %client.suicides * %game.SCORE_PER_SUICIDE; + + if (%killValue - %deathValue == 0) + %client.efficiency = %suicideValue; + else + %client.efficiency = ((%killValue * %killValue) / (%killValue - %deathValue)) + %suicideValue; + + %client.score = mFloatLength(%client.efficiency, 1); + messageClient(%client, 'MsgYourScoreIs', "", %client.score); + %game.recalcTeamRanks(%client); + %game.checkScoreLimit(%client); +} + +function DMGame::timeLimitReached(%game) +{ + logEcho("game over (timelimit)"); + %game.gameOver(); + cycleMissions(); +} + +function DMGame::scoreLimitReached(%game) +{ + logEcho("game over (scorelimit)"); + %game.gameOver(); + cycleMissions(); +} + +function DMGame::gameOver(%game) +{ + //call the default + DefaultGame::gameOver(%game); + + messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.gameover.wav" ); + + cancel(%game.timeThread); + messageAll('MsgClearObjHud', ""); + for(%i = 0; %i < ClientGroup.getCount(); %i ++) { + %client = ClientGroup.getObject(%i); + %game.resetScore(%client); + } +} + +function DMGame::enterMissionArea(%game, %playerData, %player) +{ + %player.client.outOfBounds = false; + messageClient(%player.client, 'EnterMissionArea', '\c1You are back in the mission area.'); + logEcho(%player.client.nameBase@" (pl "@%player@"/cl "@%player.client@") entered mission area"); + cancel(%player.alertThread); +} + +function DMGame::leaveMissionArea(%game, %playerData, %player) +{ + if(%player.getState() $= "Dead") + return; + + %player.client.outOfBounds = true; + messageClient(%player.client, 'LeaveMissionArea', '\c1You have left the mission area. Return or take damage.~wfx/misc/warning_beep.wav'); + logEcho(%player.client.nameBase@" (pl "@%player@"/cl "@%player.client@") left mission area"); + %player.alertThread = %game.schedule(1000, "DMAlertPlayer", 3, %player); +} + +function DMGame::DMAlertPlayer(%game, %count, %player) +{ + // MES - I commented below line out because it prints a blank line to chat window + //messageClient(%player.client, 'MsgDMLeftMisAreaWarn', '~wfx/misc/red_alert.wav'); + if(%count > 1) + %player.alertThread = %game.schedule(1000, "DMAlertPlayer", %count - 1, %player); + else + %player.alertThread = %game.schedule(1000, "MissionAreaDamage", %player); +} + +function DMGame::MissionAreaDamage(%game, %player) +{ + if(%player.getState() !$= "Dead") { + %player.setDamageFlash(0.1); + %prevHurt = %player.getDamageLevel(); + %player.setDamageLevel(%prevHurt + 0.05); + %player.alertThread = %game.schedule(1000, "MissionAreaDamage", %player); + } + else + %game.onClientKilled(%player.client, 0, $DamageType::OutOfBounds); +} + +function DMGame::updateScoreHud(%game, %client, %tag) +{ + // Clear the header: + messageClient( %client, 'SetScoreHudHeader', "", "" ); + + // Send the subheader: + messageClient(%client, 'SetScoreHudSubheader', "", '\tPLAYER\tRATING\tKILLS\tDEATHS'); + + for (%index = 0; %index < $TeamRank[0, count]; %index++) + { + //get the client info + %cl = $TeamRank[0, %index]; + + //get the score + %clScore = mFloatLength( %cl.efficiency, 1 ); + + %clKills = mFloatLength( %cl.kills, 0 ); + %clDeaths = mFloatLength( %cl.deaths + %cl.suicides, 0 ); + %clStyle = %cl == %client ? "" : ""; + + //if the client is not an observer, send the message + if (%client.team != 0) + { + messageClient( %client, 'SetLineHud', "", %tag, %index, '%5\t%1%2%3%4', + %cl.name, %clScore, %clKills, %clDeaths, %clStyle ); + } + //else for observers, create an anchor around the player name so they can be observed + else + { + messageClient( %client, 'SetLineHud', "", %tag, %index, '%5\t%1%2%3%4', + %cl.name, %clScore, %clKills, %clDeaths, %clStyle, %cl ); + } + } + + // Tack on the list of observers: + %observerCount = 0; + for (%i = 0; %i < ClientGroup.getCount(); %i++) + { + %cl = ClientGroup.getObject(%i); + if (%cl.team == 0) + %observerCount++; + } + + if (%observerCount > 0) + { + messageClient( %client, 'SetLineHud', "", %tag, %index, ""); + %index++; + messageClient(%client, 'SetLineHud', "", %tag, %index, '\tOBSERVERS (%1)TIME', %observerCount); + %index++; + for (%i = 0; %i < ClientGroup.getCount(); %i++) + { + %cl = ClientGroup.getObject(%i); + //if this is an observer + if (%cl.team == 0) + { + %obsTime = getSimTime() - %cl.observerStartTime; + %obsTimeStr = %game.formatTime(%obsTime, false); + messageClient( %client, 'SetLineHud', "", %tag, %index, '\t%1%2', + %cl.name, %obsTimeStr ); + %index++; + } + } + } + + //clear the rest of Hud so we don't get old lines hanging around... + messageClient( %client, 'ClearHud', "", %tag, %index ); +} + +function DMGame::applyConcussion(%game, %player) +{ +} + + diff --git a/scripts/DnDGame.cs b/scripts/DnDGame.cs index 9204342..de6994e 100644 --- a/scripts/DnDGame.cs +++ b/scripts/DnDGame.cs @@ -1,1333 +1,1333 @@ -// DisplayName = Defend and Destroy - -//--- GAME RULES BEGIN --- -//Destroy objectives and hold switches. -//Teams score 1 point for each switch held, and each Large Turret, Sensor, Generator, and Vehicle Station destroyed. -//The map ends when one team destroys all the enemy objectives and holds all switches, or the timelimit expires. -//--- GAME RULES END --- - -//-------------------------------------------------------------------------------- -// <> Defend and Destroy <> -// -// Version: 1.1.25026 -// Date: October 23, 2002 -// By: ZOD -// http://www.planettribes.com/syrinx/ -// -// SCORING: -// -// Teams get 1 point each time they destroy and enemy objective or hold a -// flip flop switch. -// -// Objectives consist of vehicle stations, large and medium pulse sensors, -// solar panels, generators and base turrets. -//-------------------------------------------------------------------------------- - -//exec the AI scripts -exec("scripts/aiDnD.cs"); - -$InvBanList[DnD, "MiningTool"] = 1; - -$DnDVer = "1.1.25026"; -if($Host::MarkDnDObjectives $= "") - $Host::MarkDnDObjectives = 1; - -function DnDGame::initGameVars(%game) -{ - %game.SCORE_PER_SUICIDE = 0; // z0dd - ZOD, 8/19/02. No penalty for suicide! Was -10 - %game.SCORE_PER_TEAMKILL = -5; - %game.SCORE_PER_DEATH = 0; - - %game.SCORE_PER_KILL = 5; - %game.SCORE_PER_HEADSHOT = 1; - %game.SCORE_PER_TURRET_KILL = 5; - %game.SCORE_PER_TURRET_KILL_AUTO = 1; - - %game.SCORE_PER_OBJECT_DEFEND = 5; // Score for defending an objective - - %game.SCORE_PER_DESTROY_GEN = 10; - %game.SCORE_PER_DESTROY_SOLAR = 8; - %game.SCORE_PER_DESTROY_SENSOR = 4; - %game.SCORE_PER_DESTROY_TURRET = 6; - %game.SCORE_PER_DESTROY_ISTATION = 4; - %game.SCORE_PER_DESTROY_ASTATION = 4; - %game.SCORE_PER_DESTROY_VSTATION = 8; - %game.SCORE_PER_DESTROY_TSTATION = 4; - %game.SCORE_PER_DESTROY_SENTRY = 4; - %game.SCORE_PER_DESTROY_DEP_SENSOR = 1; - %game.SCORE_PER_DESTROY_DEP_INV = 2; - %game.SCORE_PER_DESTROY_DEP_TUR = 3; - %game.SCORE_PER_TK_DESTROY = -10; // Penalty for TKing equiptment, needs to be harsh. - - %game.SCORE_PER_PLYR_FLIPFLOP_CAP = 8; - - %game.SCORE_PER_DESTROY_SHRIKE = 5; - %game.SCORE_PER_DESTROY_BOMBER = 8; - %game.SCORE_PER_DESTROY_TRANSPORT = 5; - %game.SCORE_PER_DESTROY_WILDCAT = 5; - %game.SCORE_PER_DESTROY_TANK = 8; - %game.SCORE_PER_DESTROY_MPB = 12; - %game.SCORE_PER_PASSENGER = 2; - - %game.SCORE_PER_REPAIR_GEN = 8; - %game.SCORE_PER_REPAIR_SOLAR = 6; - %game.SCORE_PER_REPAIR_SENSOR = 2; - %game.SCORE_PER_REPAIR_TURRET = 4; - %game.SCORE_PER_REPAIR_ASTATION = 2; - %game.SCORE_PER_REPAIR_ISTATION = 2; - %game.SCORE_PER_REPAIR_VSTATION = 4; - %game.SCORE_PER_REPAIR_TSTATION = 4; - %game.SCORE_PER_REPAIR_SENTRY = 2; - %game.SCORE_PER_REPAIR_DEP_SENSOR = 1; - %game.SCORE_PER_REPAIR_DEP_TUR = 3; - %game.SCORE_PER_REPAIR_DEP_INV = 2; - - %game.RADIUS_OBJECT_DEFENSE = 20; - %game.TIME_REQ_PLYR_CAP_BONUS = 12 * 1000; // player must hold a switch 12 seconds to get a point for it. - %game.TIME_REQ_TEAM_CAP_BONUS = 12 * 1000; // time after touching it takes for team to get a point -} - -package DnDGame -{ - // z0dd - ZOD. From Classic MOD, placed here for base and mod compatibility. - function teamDestroyMessage(%client, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) - { - %team = %client.team; - %count = ClientGroup.getCount(); - for(%i = 0; %i < %count; %i++) - { - %recipient = ClientGroup.getObject(%i); - if((%recipient.team == %team) && (%recipient != %client)) - { - commandToClient(%recipient, 'TeamDestroyMessage', %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6); - } - } - } - - function ShapeBaseData::onDestroyed(%data, %obj, %prevstate) - { - %scorer = %obj.lastDamagedBy; - if(!isObject(%scorer)) - return; - - if((%scorer.getType() & $TypeMasks::GameBaseObjectType) && %scorer.getDataBlock().catagory $= "Vehicles") - { - %name = %scorer.getDatablock().getName(); - if(%name $= "BomberFlyer" || %name $= "AssaultVehicle") - %gunnerNode = 1; - else - %gunnerNode = 0; - - if(%scorer.getMountNodeObject(%gunnerNode)) - { - %destroyer = %scorer.getMountNodeObject(%gunnerNode).client; - %scorer = %destroyer; - %damagingTeam = %scorer.team; - } - } - else if(%scorer.getClassName() $= "Turret") - { - if(%scorer.getControllingClient()) - { - // manned turret - %destroyer = %scorer.getControllingClient(); - %scorer = %destroyer; - %damagingTeam = %scorer.team; - } - else - %scorer = %scorer.owner; // unmanned turret - } - if(!%damagingTeam) - %damagingTeam = %scorer.team; - - if(%damagingTeam != %obj.team) - { - if(!%obj.soiledByEnemyRepair) - { - Game.awardScoreStaticShapeDestroy(%scorer, %obj); - } - } - else - { - if(!%obj.getDataBlock().deployedObject) - Game.awardScoreTkDestroy(%scorer, %obj); - } - if(!%obj.objectiveCompleted && %obj.scoreValue) - { - messageAllExcept(%scorer, %damagingTeam, 'MsgDnDObjDisabled', '\c2%1 destroyed your %2 objective!', %scorer.name, Game.cleanWord(%obj.getDataBlock().targetTypeTag)); - %obj.objectiveCompleted = true; - if(isObject(%obj.wayPointMarker)) - %obj.wayPointMarker.schedule(100, "delete"); - - $teamScore[%damagingTeam]++; - Game.checkScoreLimit(%damagingTeam); - } - } - - function ShapeBaseData::onDisabled(%data, %obj) - { - %obj.wasDisabled = true; - Parent::onDisabled(%data, %obj); - } - - function RepairGunImage::onRepair(%this, %obj, %slot) - { - Parent::onRepair(%this, %obj, %slot); - %target = %obj.repairing; - if(%target && %target.team != %obj.team) - { - %target.soiledByEnemyRepair = true; - } - } - - function StaticShapeData::objectiveInit(%data, %obj) - { - if(!%data.deployedObject && %obj.team > 0) - { - %class = %data.className; - if(%class $= "Generator" || %class $= "Sensor" || %class $= "TurretBase") - { - %obj.objectiveCompleted = false; - %obj.scoreValue = true; - $numObjectives[%obj.team]++; - if($Host::MarkDnDObjectives) - Game.setupObjectiveMarker(%obj); - } - } - } - - function StationVehicle::onAdd(%this, %obj) - { - // We use onAdd because objectiveInit is never called on v-stations. - Parent::onAdd(%this, %obj); - if(%obj.team > 0) - { - %obj.objectiveCompleted = false; - %obj.scoreValue = true; - $numObjectives[%obj.team]++; - if($Host::MarkDnDObjectives) - Game.setupObjectiveMarker(%obj); - } - } - - function FlipFlop::objectiveInit(%data, %flipflop) - { - Parent::objectiveInit(%data, %flipflop); - %flipflop.tCapThread = ""; - %flipflop.pCapThread = ""; - %flipflop.scoreValue = true; - for(%i = 1; %i <= Game.numTeams; %i++) - { - $numObjectives[%i]++; - } - %flipFlop.prevTeam = ""; - } - - function FlipFlop::playerTouch(%data, %flipflop, %player) - { - if(%flipflop.team != %player.client.team) - { - Parent::playerTouch(%data, %flipflop, %player); - Game.startTimerPlayerFFCap(%player.client, %flipflop); - } - } -}; - -function DnDGame::setupObjectiveMarker(%game, %obj) -{ - %name = (getTaggedString(%obj.getDataBlock().targetNameTag) SPC getTaggedString(%obj.getDataBlock().targetTypeTag)); - %obj.wayPointMarker = new WayPoint() { - position = %obj.getPosition(); - name = %name; - dataBlock = "WayPointMarker"; - team = %obj.team; - }; - MissionCleanup.add(%obj.wayPointMarker); -} - -function serverCmdsetDnDMarkers(%client, %value) -{ - // USAGE: commandToServer('setDnDMarkers', 1); - %val = deTag(%value); - %adj = %val == 1 ? 1 : 0; - %snd = '~wfx/misc/warning_beep.wav'; - %detail = (%adj ? "enabled" : "disabled"); - %name = %client.name; - if(%client.isAdmin) - { - switch$ ( %adj ) - { - case 0: - %msg = '\c3%5: \c2Objective markers: \c3%4\c2, cycling mission.%1'; - $Host::MarkDnDObjectives = %adj; - export( "$Host::*", "prefs/ServerPrefs.cs", false ); - if( isObject( Game ) ) - Game.gameOver(); - - loadMission($CurrentMission, $CurrentMissionType, false); - - case 1: - %msg = '\c3%5: \c2Objective markers: \c3%4\c2, cycling mission.%1'; - $Host::MarkDnDObjectives = %adj; - export( "$Host::*", "prefs/ServerPrefs.cs", false ); - if( isObject( Game ) ) - Game.gameOver(); - - loadMission($CurrentMission, $CurrentMissionType, false); - - default: - messageClient(%client, 'MsgAdmin', '\c2Incorrect value, 0 disables markers, 1 enables markers.'); - } - messageAll( 'MsgAdmin', %msg, %snd, %val, %adj, %detail, %name, $CurrentMission ); - } - else - messageClient(%client, 'MsgAdmin', '\c2Only Admins can use this command.'); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Team Functions /////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////// - -function DnDGame::setUpTeams(%game) -{ - DefaultGame::setUpTeams(%game); - - // reset the visibility of team 0 (team is still defaulted as friendly) - setSensorGroupAlwaysVisMask(0, 0); -} - -function DnDGame::clientMissionDropReady(%game, %client) -{ - messageClient(%client, 'MsgClientReady', "", %game.class); - for(%i = 1; %i <= %game.numTeams; %i++) - { - messageClient(%client, 'MsgDnDAddTeam', "", %i, %game.getTeamName(%i), $teamScore[%i], %game.getScoreLimit(%i), -1, -1); - } - %game.populateTeamRankArray(%client); - messageClient(%client, 'MsgYourRankIs', "", -1); - - messageClient(%client, 'MsgMissionDropInfo', '\c0You are in mission %1 (%2).', $MissionDisplayName, $MissionTypeDisplayName, $ServerName ); - DefaultGame::clientMissionDropReady(%game, %client); -} - -function DnDGame::assignClientTeam(%game, %client, %respawn) -{ - DefaultGame::assignClientTeam(%game, %client, %respawn); - // if player's team is not on top of objective hud, switch lines - messageClient(%client, 'MsgCheckTeamLines', "", %client.team); -} - -function DnDGame::getTeamSkin(%game, %team) -{ - if($Host::tournamentMode) - return $teamSkin[%team]; - - if(!$Host::useCustomSkins) - { - %terrain = MissionGroup.musicTrack; - switch$(%terrain) - { - case "lush": - if(%team == 1) - %skin = 'beagle'; - else if(%team == 2) - %skin = 'dsword'; - else - %skin = 'base'; - - case "badlands": - if(%team == 1) - %skin = 'swolf'; - else if(%team == 2) - %skin = 'dsword'; - else - %skin = 'base'; - - case "ice": - if(%team == 1) - %skin = 'swolf'; - else if(%team == 2) - %skin = 'beagle'; - else - %skin = 'base'; - - case "desert": - if(%team == 1) - %skin = 'cotp'; - else if(%team == 2) - %skin = 'beagle'; - else %skin = 'base'; - - case "Volcanic": - if(%team == 1) - %skin = 'dsword'; - else if(%team == 2) - %skin = 'cotp'; - else - %skin = 'base'; - - default: - if(%team == 2) - %skin = 'baseb'; - else - %skin = 'base'; - } - if(%skin $= "") - %skin = $teamSkin[%team]; - } - else - %skin = $teamSkin[%team]; - - return %skin; -} - -function DnDGame::getTeamName(%game, %team) -{ - if($Host::tournamentMode) - return $TeamName[%team]; - - if(!$Host::useCustomSkins) - { - %terrain = MissionGroup.musicTrack; - switch$(%terrain) - { - case "lush": - if(%team == 1) - %name = 'Blood Eagle'; - else if(%team == 2) - %name = 'Diamond Sword'; - - case "badlands": - if(%team == 1) - %name = 'Starwolf'; - else if(%team == 2) - %name = 'Diamond Sword'; - - case "ice": - if(%team == 1) - %name = 'Starwolf'; - else if(%team == 2) - %name = 'Blood Eagle'; - - case "desert": - if(%team == 1) - %name = 'Phoenix'; - else if(%team == 2) - %name = 'Blood Eagle'; - - case "Volcanic": - if(%team == 1) - %name = 'Diamond Sword'; - else if(%team == 2) - %name = 'Phoenix'; - - default: - if(%team == 2) - %name = 'Inferno'; - else - %name = 'Storm'; - } - if(%name $= "") - %name = $teamName[%team]; - } - else - %name = $TeamName[%team]; - - return %name; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Flip Flop Functions ////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////// - -function DnDGame::startTimerPlayerFFCap(%game, %cl, %this) -{ - cancel(%this.pCapThread); //stop the last owner from collecting a cap bonus - %this.pCapThread = %game.schedule(%game.TIME_REQ_PLYR_CAP_BONUS, "awardScorePlayerFFCap", %cl, %this); - cancel(%this.tCapThread); //stop the old owners from collecting any cap bonus - %this.tCapThread = %game.schedule(%game.TIME_REQ_TEAM_CAP_BONUS, "awardScoreTeamFFCap", %this.team, %this); -} - -function DnDGame::stopScoreTimers(%game) -{ - // find all switches and cancel any timers associated with them - %ffGroup = nameToId("MissionCleanup/FlipFlops"); - if(%ffGroup <= 0) - return; - - for(%i = 0; %i < %ffGroup.getCount(); %i++) - { - %curFF = %ffGroup.getObject(%i); - cancel(%curFF.pCapThread); - cancel(%curFF.tCapThread); - } -} - -function DnDGame::countFlips(%game) -{ - return false; -} - -function DnDGame::awardScorePlayerFFCap(%game, %cl, %this) -{ - if(!($missionRunning)) - return; - - %cl.flipFlopsCapped++; - messageClient(%cl, 'msgFFDef', '\c0You received a %1 point bonus for holding the %2.', %game.SCORE_PER_PLYR_FLIPFLOP_CAP, %game.cleanWord(%this.name)); - messageTeamExcept(%cl, 'msgFFDef', '\c0Teammate %1 received a %2 point bonus for holding the %3', %cl.name, %game.SCORE_PER_PLYR_FLIPFLOP_CAP, %game.cleanWord(%this.name)); - %game.recalcScore(%cl); -} - -function DnDGame::awardScoreTeamFFCap(%game, %team, %this) -{ - if(!($missionRunning)) - return; - - cancel(%this.tCapThread); - $teamScore[%team]++; - if(%this.prevTeam) - $teamScore[%this.prevTeam]--; - - %this.prevTeam = %team; - %game.checkScoreLimit(%team); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Scoring Functions //////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////// - -function DnDGame::checkScoreLimit(%game, %team) -{ - // Since checkScore limit is called for every score, announce the team. - if ($missionRunning) - { - if (%game.getTeamName(%team) $= 'Inferno') - messageAll("", '~wvoice/announcer/ann.infscores.wav'); - else if (%game.getTeamName(%team) $= 'Storm') - messageAll("", '~wvoice/announcer/ann.stoscores.wav'); - else if (%game.getTeamName(%team) $= 'Phoenix') - messageAll("", '~wvoice/announcer/ann.pxscore.wav'); - else if (%game.getTeamName(%team) $= 'Blood Eagle') - messageAll("", '~wvoice/announcer/ann.bescore.wav'); - else if (%game.getTeamName(%team) $= 'Diamond Sword') - messageAll("", '~wvoice/announcer/ann.dsscore.wav'); - else if (%game.getTeamName(%team) $= 'Starwolf') - messageAll("", '~wvoice/announcer/ann.swscore.wav'); - } - - // Update everyones objective hud. - for(%i = 1; %i <= %game.numTeams; %i++) - messageAll('MsgDnDTeamScores', "", %i, %game.getTeamName(%i), $teamScore[%i], %game.getScoreLimit(%i), -1, -1, -1); - - %scoreLimit = %game.getScoreLimit(%team); - if($teamScore[%team] >= %scoreLimit) - %game.scoreLimitReached(); -} - -function DnDGame::getScoreLimit(%game, %team) -{ - // If we ever have more then two teams this must be changed. - %otherTeam = %team == 1 ? 2 : 1; - return $numObjectives[%otherTeam]; -} - -function DnDGame::timeLimitReached(%game) -{ - logEcho("game over (timelimit)"); - %game.gameOver(); - cycleMissions(); -} - -function DnDGame::scoreLimitReached(%game) -{ - logEcho("game over (scorelimit)"); - %game.gameOver(); - cycleMissions(); -} - -function DnDGame::gameOver(%game) -{ - // call the default - DefaultGame::gameOver(%game); - - // stop all bonus timers - %game.stopScoreTimers(); - - //send the winner message - %winner = ""; - if ($teamScore[1] > $teamScore[2]) - %winner = %game.getTeamName(1); - else if ($teamScore[2] > $teamScore[1]) - %winner = %game.getTeamName(2); - - if (%winner $= 'Storm') - messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.stowins.wav" ); - else if (%winner $= 'Inferno') - messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.infwins.wav" ); - else if (%winner $= 'Starwolf') - messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.swwin.wav" ); - else if (%winner $= 'Blood Eagle') - messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.bewin.wav" ); - else if (%winner $= 'Diamond Sword') - messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.dswin.wav" ); - else if (%winner $= 'Phoenix') - messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.pxwin.wav" ); - else - messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.gameover.wav" ); - - messageAll('MsgClearObjHud', ""); - for(%i = 0; %i < ClientGroup.getCount(); %i++) - { - %client = ClientGroup.getObject(%i); - %game.resetScore(%client); - } - for ( %team = 1; %team <= %game.numTeams; %team++ ) - { - $TeamScore[%team] = 0; - $numObjectives[%team] = 0; - } -} - -function DnDGame::onClientDamaged(%game, %clVictim, %clAttacker, %damageType, %implement, %damageLoc) -{ - if(%clVictim.headshot && %damageType == $DamageType::Laser && %clVictim.team != %clAttacker.team) - { - %clAttacker.scoreHeadshot++; - if (%game.SCORE_PER_HEADSHOT != 0) - { - messageClient(%clAttacker, 'msgHeadshot', '\c0You received a %1 point bonus for a successful headshot.', %game.SCORE_PER_HEADSHOT); - } - %game.recalcScore(%clAttacker); - } - //the DefaultGame will set some vars - DefaultGame::onClientDamaged(%game, %clVictim, %clAttacker, %damageType, %implement, %damageLoc); -} - -function DnDGame::recalcScore(%game, %cl) -{ - %killValue = %cl.kills * %game.SCORE_PER_KILL; - %deathValue = %cl.deaths * %game.SCORE_PER_DEATH; - - if (%killValue - %deathValue == 0) - %killPoints = 0; - else - %killPoints = (%killValue * %killValue) / (%killValue - %deathValue); - - %cl.offenseScore = %killPoints + - %cl.suicides * %game.SCORE_PER_SUICIDE + - %cl.escortAssists * %game.SCORE_PER_ESCORT_ASSIST + - %cl.teamKills * %game.SCORE_PER_TEAMKILL + - %cl.tkDestroys * %game.SCORE_PER_TK_DESTROY + - %cl.scoreHeadshot * %game.SCORE_PER_HEADSHOT + - %cl.flagCaps * %game.SCORE_PER_PLYR_FLAG_CAP + - %cl.flagGrabs * %game.SCORE_PER_PLYR_FLAG_TOUCH + - %cl.genDestroys * %game.SCORE_PER_DESTROY_GEN + - %cl.sensorDestroys * %game.SCORE_PER_DESTROY_SENSOR + - %cl.turretDestroys * %game.SCORE_PER_DESTROY_TURRET + - %cl.IStationDestroys * %game.SCORE_PER_DESTROY_ISTATION + - %cl.AStationDestroys * %game.SCORE_PER_DESTROY_ASTATION + - %cl.vstationDestroys * %game.SCORE_PER_DESTROY_VSTATION + - %cl.TStationDestroys * %game.SCORE_PER_DESTROY_TSTATION + - %cl.solarDestroys * %game.SCORE_PER_DESTROY_SOLAR + - %cl.sentryDestroys * %game.SCORE_PER_DESTROY_SENTRY + - %cl.depSensorDestroys * %game.SCORE_PER_DESTROY_DEP_SENSOR + - %cl.depTurretDestroys * %game.SCORE_PER_DESTROY_DEP_TUR + - %cl.depStationDestroys * %game.SCORE_PER_DESTROY_DEP_INV + - %cl.flipFlopsCapped * %game.SCORE_PER_PLYR_FLIPFLOP_CAP + - %cl.vehicleScore + %cl.vehicleBonus; - - %cl.defenseScore = %cl.genDefends * %game.SCORE_PER_OBJECT_DEFEND + - %cl.turretKills * %game.SCORE_PER_TURRET_KILL_AUTO + - %cl.mannedturretKills * %game.SCORE_PER_TURRET_KILL + - %cl.genRepairs * %game.SCORE_PER_REPAIR_GEN + - %cl.sensorRepairs * %game.SCORE_PER_REPAIR_SENSOR + - %cl.turretRepairs * %game.SCORE_PER_REPAIR_TURRET + - %cl.stationRepairs * %game.SCORE_PER_REPAIR_ISTATION + - %cl.AStationRepairs * %game.SCORE_PER_REPAIR_ASTATION + - %cl.VStationRepairs * %game.SCORE_PER_REPAIR_VSTATION + - %cl.TStationRepairs * %game.SCORE_PER_REPAIR_TSTATION + - %cl.solarRepairs * %game.SCORE_PER_REPAIR_SOLAR + - %cl.sentryRepairs * %game.SCORE_PER_REPAIR_SENTRY + - %cl.depStationRepairs * %game.SCORE_PER_REPAIR_DEP_SENSOR + - %cl.depInvRepairs * %game.SCORE_PER_REPAIR_DEP_INV + - %cl.depTurretRepairs * %game.SCORE_PER_REPAIR_DEP_TUR; - - %cl.score = mFloor(%cl.offenseScore + %cl.defenseScore); - %game.recalcTeamRanks(%cl); -} - -function DnDGame::resetScore(%game, %client) -{ - %client.kills = 0; - %client.deaths = 0; - %client.suicides = 0; - %client.teamKills = 0; - %client.tkDestroys = 0; - %client.genDestroys = 0; - %client.sensorDestroys = 0; - %client.turretDestroys = 0; - %client.IStationDestroys = 0; - %client.AStationDestroys = 0; - %client.vstationDestroys = 0; - %client.TStationDestroys = 0; - %client.solarDestroys = 0; - %client.sentryDestroys = 0; - %client.depSensorDestroys = 0; - %client.depTurretDestroys = 0; - %client.depStationDestroys = 0; - %client.vehicleScore = 0; - %client.vehicleBonus = 0; - %client.flipFlopsCapped = 0; - %client.offenseScore = 0; - - %client.objDefends = 0; - %client.turretKills = 0; - %client.mannedTurretKills = 0; - %client.genRepairs = 0; - %client.sensorRepairs = 0; - %client.turretRepairs = 0; - %client.stationRepairs = 0; - %client.AStationRepairs = 0; - %client.VStationRepairs = 0; - %client.TStationRepairs = 0; - %client.solarRepairs = 0; - %client.sentryRepairs = 0; - %client.sentryRepairs = 0; - %client.depStationRepairs = 0; - %client.depInvRepairs = 0; - %client.defenseScore = 0; - %client.score = 0; - %client.outOfBounds = ""; -} - -function DnDGame::updateKillScores(%game, %clVictim, %clKiller, %damageType, %implement) -{ - // is this a vehicle kill rather than a player kill - // console error message suppression - if( isObject( %implement ) ) - { - if( %implement.getDataBlock().getName() $= "AssaultPlasmaTurret" || %implement.getDataBlock().getName() $= "BomberTurret" ) // gunner - %clKiller = %implement.vehicleMounted.getMountNodeObject(1).client; - else if(%implement.getDataBlock().catagory $= "Vehicles") // pilot - %clKiller = %implement.getMountNodeObject(0).client; - } - - if(%game.testTurretKill(%implement)) // check for turretkill before awarded a non client points for a kill - %game.awardScoreTurretKill(%clVictim, %implement); - else if(%game.testKill(%clVictim, %clKiller)) // verify victim was an enemy - { - %value = %game.awardScoreKill(%clKiller); - %game.shareScore(%clKiller, %value); - %game.awardScoreDeath(%clVictim); - - if(%game.testObjectDefend(%clVictim, %clKiller)) - %game.awardScoreObjectDefend(%clKiller); - } - else - { - if (%game.testSuicide(%clVictim, %clKiller, %damageType)) // otherwise test for suicide - { - %game.awardScoreSuicide(%clVictim); - } - else - { - if (%game.testTeamKill(%clVictim, %clKiller)) // otherwise test for a teamkill - %game.awardScoreTeamKill(%clVictim, %clKiller); - } - } -} - -function DnDGame::vehicleDestroyed(%game, %vehicle, %destroyer) -{ - //vehicle name - %data = %vehicle.getDataBlock(); - //%vehicleType = getTaggedString(%data.targetNameTag) SPC getTaggedString(%data.targetTypeTag); - %vehicleType = getTaggedString(%data.targetTypeTag); - if(%vehicleType !$= "MPB") - %vehicleType = strlwr(%vehicleType); - - %enemyTeam = ( %destroyer.team == 1 ) ? 2 : 1; - %scorer = 0; - %multiplier = 1; - %passengers = 0; - for(%i = 0; %i < %data.numMountPoints; %i++) - if(%vehicle.getMountNodeObject(%i)) - %passengers++; - - //what destroyed this vehicle - if(%destroyer.client) - { - //it was a player, or his mine, satchel, whatever... - %destroyer = %destroyer.client; - %scorer = %destroyer; - - // determine if the object used was a mine - if(%vehicle.lastDamageType == $DamageType::Mine) - %multiplier = 2; - } - else if(%destroyer.getClassName() $= "Turret") - { - if(%destroyer.getControllingClient()) - { - //manned turret - %destroyer = %destroyer.getControllingClient(); - %scorer = %destroyer; - } - else - { - %destroyerName = "A turret"; - %multiplier = 0; - } - } - else if(%destroyer.getDataBlock().catagory $= "Vehicles") - { - // Vehicle vs vehicle kill! - if(%name $= "BomberFlyer" || %name $= "AssaultVehicle") - %gunnerNode = 1; - else - %gunnerNode = 0; - - if(%destroyer.getMountNodeObject(%gunnerNode)) - { - %destroyer = %destroyer.getMountNodeObject(%gunnerNode).client; - %scorer = %destroyer; - } - %multiplier = 3; - } - else // Is there anything else we care about? - return; - - if(%destroyerName $= "") - %destroyerName = %destroyer.name; - - if(%vehicle.team == %destroyer.team) // team kill - { - %pref = (%vehicleType $= "Assault Tank") ? "an" : "a"; - messageAll( 'msgVehicleTeamDestroy', '\c0%1 TEAMKILLED %3 %2!', %destroyerName, %vehicleType, %pref); - } - else // legit kill - { - //messageTeamExcept(%destroyer, 'msgVehicleDestroy', '\c0%1 destroyed an enemy %2.', %destroyerName, %vehicleType); - teamDestroyMessage(%destroyer, 'msgVehDestroyed', '\c5%1 destroyed an enemy %2!', %destroyerName, %vehicleType); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - messageTeam(%enemyTeam, 'msgVehicleDestroy', '\c0%1 destroyed your team\'s %2.', %destroyerName, %vehicleType); - //messageClient(%destroyer, 'msgVehicleDestroy', '\c0You destroyed an enemy %1.', %vehicleType); - - if(%scorer) - { - %value = %game.awardScoreVehicleDestroyed(%scorer, %vehicleType, %multiplier, %passengers); - %game.shareScore(%value); - } - } -} - -function DnDGame::awardScoreVehicleDestroyed(%game, %client, %vehicleType, %mult, %passengers) -{ - if(%vehicleType $= "Grav Cycle") - %base = %game.SCORE_PER_DESTROY_WILDCAT; - else if(%vehicleType $= "Assault Tank") - %base = %game.SCORE_PER_DESTROY_TANK; - else if(%vehicleType $= "MPB") - %base = %game.SCORE_PER_DESTROY_MPB; - else if(%vehicleType $= "Turbograv") - %base = %game.SCORE_PER_DESTROY_SHRIKE; - else if(%vehicleType $= "Bomber") - %base = %game.SCORE_PER_DESTROY_BOMBER; - else if(%vehicleType $= "Heavy Transport") - %base = %game.SCORE_PER_DESTROY_TRANSPORT; - - %total = ( %base * %mult ) + ( %passengers * %game.SCORE_PER_PASSENGER ); - - %client.vehicleScore += %total; - - messageClient(%client, 'msgVehicleScore', '\c0You received a %1 point bonus for destroying an enemy %2.', %total, %vehicleType); - %game.recalcScore(%client); - return %total; -} - -function DnDGame::shareScore(%game, %client, %amount) -{ - //error("share score of"SPC %amount SPC "from client:" SPC %client); - // all of the player in the bomber and tank share the points - // gained from any of the others - %vehicle = %client.vehicleMounted; - if(!%vehicle) - return 0; - - %vehicleType = getTaggedString(%vehicle.getDataBlock().targetTypeTag); - if(%vehicleType $= "Bomber" || %vehicleType $= "Assault Tank") - { - for(%i = 0; %i < %vehicle.getDataBlock().numMountPoints; %i++) - { - %occupant = %vehicle.getMountNodeObject(%i); - if(%occupant) - { - %occCl = %occupant.client; - if(%occCl != %client && %occCl.team == %client.team) - { - // the vehicle has a valid teammate at this node - // share the score with them - %occCl.vehicleBonus += %amount; - %game.recalcScore(%occCl); - } - } - } - } -} - -function DnDGame::testObjectDefend(%game, %victimID, %killerID) -{ - InitContainerRadiusSearch(%victimID.plyrPointOfDeath, %game.RADIUS_OBJECT_DEFENSE, $TypeMasks::StaticShapeObjectType); - %objID = containerSearchNext(); - while(%objID != 0) - { - if((%objID.scoreValue && !%objID.objectiveCompleted) && (%objID.team == %killerID.team)) - return true; //found the(a) killer's objective near the victim's point of death - else - %objID = containerSearchNext(); - } - return false; // didn't find a qualifying objective within required radius of victims point of death -} - -function DnDGame::awardScoreObjectDefend(%game, %killerID) -{ - %killerID.objDefends++; - messageClient(%killerID, 'msgObjDef', '\c0You received a %1 point bonus for defending an objective.', %game.SCORE_PER_OBJECT_DEFEND); - messageTeamExcept(%killerID, 'msgObjDef', '\c0Teammate %1 received a %2 point bonus for defending an objective.', %killerID.name, %game.SCORE_PER_OBJECT_DEFEND); - %game.recalcScore(%killerID); - return %game.SCORE_PER_OBJECT_DEFEND; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Destroy Scoring Functions //////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////// - -function DnDGame::awardScoreTkDestroy(%game, %cl, %obj) -{ - %cl.tkDestroys++; - teamDestroyMessage(%cl, 'msgTkDes', '\c5Teammate %1 destroyed your team\'s %3 objective!', %cl.name, %game.cleanWord(%obj.getDataBlock().targetTypeTag)); - messageClient(%cl, 'msgTkDes', '\c0You have been penalized %1 points for destroying your teams equiptment.', %game.SCORE_PER_TK_DESTROY); - %game.recalcScore(%cl); - %game.shareScore(%cl, %game.SCORE_PER_TK_DESTROY); -} - -function DnDGame::awardScoreStaticShapeDestroy(%game, %cl, %obj) -{ - %dataName = %obj.getDataBlock().getName(); - switch$ ( %dataName ) - { - case "GeneratorLarge": - %cl.genDestroys++; - %value = %game.SCORE_PER_DESTROY_GEN; - %msgType = 'msgGenDes'; - %tMsg = '\c5%1 destroyed a %2 Generator!'; - %clMsg = '\c0You received a %1 point bonus for destroying an enemy generator.'; - - case "SolarPanel": - %cl.solarDestroys++; - %value = %game.SCORE_PER_DESTROY_SOLAR; - %msgType = 'msgSolarDes'; - %tMsg = '\c5%1 destroyed a %2 Solar Panel!'; - %clMsg = '\c0You received a %1 point bonus for destroying an enemy solar panel.'; - - case "SensorLargePulse": - %cl.sensorDestroys++; - %value = %game.SCORE_PER_DESTROY_SENSOR; - %msgType = 'msgSensorDes'; - %tMsg = '\c5%1 destroyed a %2 Sensor!'; - %clMsg = '\c0You received a %1 point bonus for destroying a large enemy pulse sensor.'; - - case "SensorMediumPulse": - %cl.sensorDestroys++; - %value = %game.SCORE_PER_DESTROY_SENSOR; - %msgType = 'msgSensorDes'; - %tMsg = '\c5%1 destroyed a %2 Sensor!'; - %clMsg = '\c0You received a %1 point bonus for destroying a medium enemy pulse sensor.'; - - case "TurretBaseLarge": - %cl.turretDestroys++; - %value = %game.SCORE_PER_DESTROY_TURRET; - %msgType = 'msgTurretDes'; - %tMsg = '\c5%1 destroyed a %2 Turret!'; - %clMsg = '\c0You received a %1 point bonus for destroying an enemy base turret.'; - - case "StationInventory": - %cl.IStationDestroys++; - %value = %game.SCORE_PER_DESTROY_GEN; - %msgType = 'msgInvDes'; - %tMsg = '\c5%1 destroyed a %2 Inventory Station!'; - %clMsg = '\c0You received a %1 point bonus for destroying an enemy inventory station.'; - - case "StationAmmo": - %cl.aStationDestroys++; - %value = %game.SCORE_PER_DESTROY_ASTATION; - %msgType = 'msgAmmoDes'; - %tMsg = '\c5%1 destroyed a % 2 Ammo Station!'; - %clMsg = '\c0You received a %1 point bonus for destroying an enemy ammo station.'; - - case "StationVehicle": - %cl.VStationDestroys++; - %value = %game.SCORE_PER_DESTROY_VSTATION; - %msgType = 'msgVSDes'; - %tMsg = '\c5%1 destroyed a Vehicle Station!'; - %clMsg = '\c0You received a %1 point bonus for destroying an enemy vehicle station.'; - - case "SentryTurret": - %cl.sentryDestroys++; - %value = %game.SCORE_PER_DESTROY_SENTRY; - %msgType = 'msgSentryDes'; - %tMsg = '\c5%1 destroyed a %2 Sentry Turret!'; - %clMsg = '\c0You received a %1 point bonus for destroying an enemy sentry turret.'; - - case "DeployedMotionSensor": - %cl.depSensorDestroys++; - %value = %game.SCORE_PER_DESTROY_DEP_SENSOR; - %msgType = 'msgDepSensorDes'; - %tMsg = '\c5%1 destroyed a Deployable Motion Sensor!'; - %clMsg = '\c0You received a %1 point bonus for destroying an enemy deployable motion sensor.'; - - case "DeployedPulseSensor": - %cl.depSensorDestroys++; - %value = %game.SCORE_PER_DESTROY_DEP_SENSOR; - %msgType = 'msgDepSensorDes'; - %tMsg = '\c5%1 destroyed a Deployable Pulse Sensor!'; - %clMsg = '\c0You received a %1 point bonus for destroying an enemy deployable pulse sensor.'; - - case "TurretDeployedWallIndoor": - %cl.depTurretDestroys++; - %value = %game.SCORE_PER_DESTROY_DEP_TUR; - %msgType = 'msgDepTurDes'; - %tMsg = '\c5%1 destroyed a Deployable Spider Clamp Turret!'; - %clMsg = '\c0You received a %1 point bonus for destroying an enemy deployable spider clamp turret.'; - - case "TurretDeployedFloorIndoor": - %cl.depTurretDestroys++; - %value = %game.SCORE_PER_DESTROY_DEP_TUR; - %msgType = 'msgDepTurDes'; - %tMsg = '\c5%1 destroyed a Deployable Spider Clamp Turret!'; - %clMsg = '\c0You received a %1 point bonus for destroying an enemy deployable spider clamp turret.'; - - case "TurretDeployedCeilingIndoor": - %cl.depTurretDestroys++; - %value = %game.SCORE_PER_DESTROY_DEP_TUR; - %msgType = 'msgDepTurDes'; - %tMsg = '\c5%1 destroyed a Deployable Spider Clamp Turret!'; - %clMsg = '\c0You received a %1 point bonus for destroying an enemy deployable spider clamp turret.'; - - case "TurretDeployedOutdoor": - %cl.depTurretDestroys++; - %value = %game.SCORE_PER_DESTROY_DEP_TUR; - %msgType = 'msgDepTurDes'; - %tMsg = '\c5%1 destroyed a Deployable Landspike Turret!'; - %clMsg = '\c0You received a %1 point bonus for destroying an enemy deployable landspike turret.'; - - case "DeployedStationInventory": - %cl.depStationDestroys++; - %value = %game.SCORE_PER_DESTROY_DEP_INV; - %msgType = 'msgDepInvDes'; - %tMsg = '\c5%1 destroyed a Deployable Inventory!'; - %clMsg = '\c0You received a %1 point bonus for destroying an enemy deployable inventory station.'; - - case "MPBTeleporter": - %cl.TStationDestroys++; - %value = %game.SCORE_PER_DESTROY_TSTATION; - %msgType = 'msgMPBTeleDes'; - %tMsg = '\c5%1 destroyed a MPB Teleport Station!'; - %clMsg = '\c0You received a %1 point bonus for destroying an enemy MPB teleport station.'; - - default: - return; - } - teamDestroyMessage(%cl, 'msgDestroyed', %tMsg, %cl.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - messageClient(%cl, %msgType, %clMsg, %value, %dataName); - %game.recalcScore(%cl); - %game.shareScore(%scorer, %value); -} - -function DnDGame::awardScoreTurretKill(%game, %victimID, %implement) -{ - if ((%killer = %implement.getControllingClient()) != 0) //award whoever might be controlling the turret - { - if (%killer == %victimID) - %game.awardScoreSuicide(%victimID); - else if (%killer.team == %victimID.team) //player controlling a turret killed a teammate - { - %killer.teamKills++; - %game.awardScoreTurretTeamKill(%victimID, %killer); - %game.awardScoreDeath(%victimID); - } - else - { - %killer.mannedturretKills++; - %game.recalcScore(%killer); - %game.awardScoreDeath(%victimID); - } - } - else if ((%killer = %implement.owner) != 0) //if it isn't controlled, award score to whoever deployed it - { - if (%killer.team == %victimID.team) - { - %game.awardScoreDeath(%victimID); - } - else - { - %killer.turretKills++; - %game.recalcScore(%killer); - %game.awardScoreDeath(%victimID); - } - } - //default is, no one was controlling it, no one owned it. No score given. -} - -function DnDGame::testKill(%game, %victimID, %killerID) -{ - return ((%killerID != 0) && (%victimID.team != %killerID.team)); -} - -function DnDGame::awardScoreKill(%game, %killerID) -{ - %killerID.kills++; - %game.recalcScore(%killerID); - return %game.SCORE_PER_KILL; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Repair Scoring Functions ///////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////// - -function DnDGame::testValidRepair(%game, %obj) -{ - if(!%obj.wasDisabled) - return false; - else if(%obj.lastDamagedByTeam == %obj.team) - return false; - else if(%obj.team != %obj.repairedBy.team) - return false; - else - { - if(%obj.soiledByEnemyRepair) - %obj.soiledByEnemyRepair = false; - return true; - } -} - -function DnDGame::objectRepaired(%game, %obj, %objName) -{ - %game.staticShapeOnRepaired(%obj, %objName); - %obj.wasDisabled = false; -} - -function DnDGame::staticShapeOnRepaired(%game, %obj, %objName) -{ - if (%game.testValidRepair(%obj)) - { - %repairman = %obj.repairedBy; - %dataName = %obj.getDataBlock().getName(); - switch$ (%dataName) - { - case "GeneratorLarge": - %repairman.genRepairs++; - %score = %game.SCORE_PER_REPAIR_GEN; - %tMsgType = 'msgGenRepaired'; - %msgType = 'msgGenRep'; - %tMsg = '\c0%1 repaired the %2 Generator!'; - %clMsg = '\c0You received a %1 point bonus for repairing a generator.'; - - case "SolarPanel": - %repairman.solarRepairs++; - %score = %game.SCORE_PER_REPAIR_SOLAR; - %tMsgType = 'msgsolarRepaired'; - %msgType = 'msgsolarRep'; - %tMsg = '\c0%1 repaired the %2 Solar Panel!'; - %clMsg = '\c0You received a %1 point bonus for repairing a solar panel.'; - - case "SensorLargePulse": - %repairman.sensorRepairs++; - %score = %game.SCORE_PER_REPAIR_SENSOR; - %tMsgType = 'msgSensorRepaired'; - %msgType = 'msgSensorRep'; - %tMsg = '\c0%1 repaired the %2 Large Pulse Sensor!'; - %clMsg = '\c0You received a %1 point bonus for repairing a large pulse sensor.'; - - case "SensorMediumPulse": - %repairman.sensorRepairs++; - %score = %game.SCORE_PER_REPAIR_SENSOR; - %tMsgType = 'msgSensorRepaired'; - %msgType = 'msgSensorRep'; - %tMsg = '\c0%1 repaired the %2 Medium Pulse Sensor!'; - %clMsg = '\c0You received a %1 point bonus for repairing a medium pulse sensor.'; - - case "DeployedMotionSensor": - %repairman.depSensorRepairs++; - %tMsgType = 'msgDepSensorRepaired'; - %msgType = 'msgDepSensorRep'; - %score = %game.SCORE_PER_REPAIR_DEP_SENSOR; - %tMsg = '\c0%1 repaired a Deployed Motion Sensor!'; - %clMsg = '\c0You received a %1 point bonus for repairing a deployed motion sensor.'; - - case "DeployedPulseSensor": - %repairman.depSensorRepairs++; - %score = %game.SCORE_PER_REPAIR_DEP_SENSOR; - %tMsgType = 'msgDepSensorRepaired'; - %msgType = 'msgDepSensorRep'; - %tMsg = '\c0%1 repaired a Deployed Pulse Sensor!'; - %clMsg = '\c0You received a %1 point bonus for repairing a deployed pulse sensor.'; - - case "StationInventory": - %repairman.stationRepairs++; - %score = %game.SCORE_PER_REPAIR_ISTATION; - %tMsgType = 'msgStationRepaired'; - %msgType = 'msgIStationRep'; - %tMsg = '\c0%1 repaired the %2 Inventory Station!'; - %clMsg = '\c0You received a %1 point bonus for repairing a inventory station.'; - - case "StationAmmo": - %repairman.stationRepairs++; - %score = %game.SCORE_PER_REPAIR_ASTATION; - %tMsgType = 'msgStationRepaired'; - %msgType = 'msgAStationRep'; - %tMsg = '\c0%1 repaired the %2 Ammo Station!'; - %clMsg = '\c0You received a %1 point bonus for repairing a ammo station.'; - - case "StationVehicle": - %repairman.VStationRepairs++; - %score = %game.SCORE_PER_REPAIR_VSTATION; - %tMsgType = 'msgvstationRepaired'; - %msgType = 'msgVStationRep'; - %tMsg = '\c0%1 repaired the Vehicle Station!'; - %clMsg = '\c0You received a %1 point bonus for repairing a vehicle station.'; - - case "TurretBaseLarge": - %repairman.TurretRepairs++; - %score = %game.SCORE_PER_REPAIR_TURRET; - %tMsgType = 'msgTurretRepaired'; - %msgType = 'msgTurretRep'; - %tMsg = '\c0%1 repaired the %2 Turret!'; - %clMsg = '\c0You received a %1 point bonus for repairing a base turret.'; - - case "SentryTurret": - %repairman.sentryRepairs++; - %score = %game.SCORE_PER_REPAIR_SENTRY; - %tMsgType = 'msgsentryTurretRepaired'; - %msgType = 'msgSentryRep'; - %tMsg = '\c0%1 repaired the %2 Sentry Turret!'; - %clMsg = '\c0You received a %1 point bonus for repairing a sentry turret.'; - - case "TurretDeployedWallIndoor": - %repairman.depTurretRepairs++; - %score = %game.SCORE_PER_REPAIR_DEP_TUR; - %tMsgType = 'msgDepTurretRepaired'; - %msgType = 'msgDepTurretRep'; - %tMsg = '\c0%1 repaired a Spider Clamp Turret!'; - %clMsg = '\c0You received a %1 point bonus for repairing a deployable spider clamp turret.'; - - case "TurretDeployedFloorIndoor": - %repairman.depTurretRepairs++; - %score = %game.SCORE_PER_REPAIR_DEP_TUR; - %tMsgType = 'msgDepTurretRepaired'; - %msgType = 'msgDepTurretRep'; - %tMsg = '\c0%1 repaired a Spider Clamp Turret!'; - %clMsg = '\c0You received a %1 point bonus for repairing a deployable spider clamp turret.'; - - case "TurretDeployedCeilingIndoor": - %repairman.depTurretRepairs++; - %score = %game.SCORE_PER_REPAIR_DEP_TUR; - %tMsgType = 'msgDepTurretRepaired'; - %msgType = 'msgDepTurretRep'; - %tMsg = '\c0%1 repaired a Spider Clamp Turret!'; - %clMsg = '\c0You received a %1 point bonus for repairing a deployable spider clamp turret.'; - - case "TurretDeployedOutdoor": - %repairman.depTurretRepairs++; - %score = %game.SCORE_PER_REPAIR_DEP_TUR; - %tMsgType = 'msgDepTurretRepaired'; - %msgType = 'msgDepTurretRep'; - %tMsg = '\c0%1 repaired a Landspike Turret!'; - %clMsg = '\c0You received a %1 point bonus for repairing a deployable landspike turret.'; - - case "DeployedStationInventory": - %repairman.depInvRepairs++; - %score = %game.SCORE_PER_REPAIR_DEP_INV; - %tMsgType = 'msgDepInvRepaired'; - %msgType = 'msgDepInvRep'; - %tMsg = '\c0%1 repaired a Deployable Inventory!'; - %clMsg = '\c0You received a %1 point bonus for repairing a deployed inventory station.'; - - case "MPBTeleporter": - %repairman.TStationRepairs++; - %score = %game.SCORE_PER_REPAIR_TSTATION; - %tMsgType = 'msgMPBTeleRepaired'; - %msgType = 'msgMPBTeleRep'; - %tMsg = '\c0%1 repaired the MPB Teleporter Station!'; - %clMsg = '\c0You received a %1 point bonus for repairing a mpb teleporter station.'; - - default: - return; - } - teamRepairMessage(%repairman, %tMsgType, %tMsg, %repairman.name, %obj.nameTag); - messageClient(%repairman, %msgType, %clMsg, %score, %dataName); - %game.recalcScore(%repairman); - } -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Misc Functions ////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////// - -function DnDGame::enterMissionArea(%game, %playerData, %player) -{ - %player.client.outOfBounds = false; - messageClient(%player.client, 'EnterMissionArea', '\c1You are back in the mission area.'); - logEcho(%player.client.nameBase @ " (pl " @ %player @ "/cl "@%player.client @ ") entered mission area"); - cancel(%player.alertThread); -} - -function DnDGame::leaveMissionArea(%game, %playerData, %player) -{ - if(%player.getState() $= "Dead") - return; - - %player.client.outOfBounds = true; - messageClient(%player.client, 'LeaveMissionArea', '\c1You have left the mission area. Return or take damage.~wfx/misc/warning_beep.wav'); - logEcho(%player.client.nameBase @ " (pl " @ %player @ "/cl " @ %player.client @ ") left mission area"); - %player.alertThread = %game.schedule(1000, "DMAlertPlayer", 3, %player); -} - -function DnDGame::DMAlertPlayer(%game, %count, %player) -{ - // MES - I commented below line out because it prints a blank line to chat window - //messageClient(%player.client, 'MsgDMLeftMisAreaWarn', '~wfx/misc/red_alert.wav'); - if(%count > 1) - %player.alertThread = %game.schedule(1000, "DMAlertPlayer", %count - 1, %player); - else - %player.alertThread = %game.schedule(1000, "MissionAreaDamage", %player); -} - -function DnDGame::MissionAreaDamage(%game, %player) -{ - if(%player.getState() !$= "Dead") - { - %player.setDamageFlash(0.1); - %prevHurt = %player.getDamageLevel(); - %player.setDamageLevel(%prevHurt + 0.05); - %player.alertThread = %game.schedule(1000, "MissionAreaDamage", %player); - } - else - { - if(%player.alertThread !$= "") - { - cancel(%player.alertThread); - %player.alertThread = ""; - } - if(%player.client.team != 0) - { - %game.onClientKilled(%player.client, 0, $DamageType::OutOfBounds); - } - } -} - -function DnDGame::applyConcussion(%game, %player) -{ - %player.throwPack(); - %player.throwWeapon(); -} +// DisplayName = Defend and Destroy + +//--- GAME RULES BEGIN --- +//Destroy objectives and hold switches. +//Teams score 1 point for each switch held, and each Large Turret, Sensor, Generator, and Vehicle Station destroyed. +//The map ends when one team destroys all the enemy objectives and holds all switches, or the timelimit expires. +//--- GAME RULES END --- + +//-------------------------------------------------------------------------------- +// <> Defend and Destroy <> +// +// Version: 1.1.25026 +// Date: October 23, 2002 +// By: ZOD +// http://www.planettribes.com/syrinx/ +// +// SCORING: +// +// Teams get 1 point each time they destroy and enemy objective or hold a +// flip flop switch. +// +// Objectives consist of vehicle stations, large and medium pulse sensors, +// solar panels, generators and base turrets. +//-------------------------------------------------------------------------------- + +//exec the AI scripts +exec("scripts/aiDnD.cs"); + +$InvBanList[DnD, "MiningTool"] = 1; + +$DnDVer = "1.1.25026"; +if($Host::MarkDnDObjectives $= "") + $Host::MarkDnDObjectives = 1; + +function DnDGame::initGameVars(%game) +{ + %game.SCORE_PER_SUICIDE = 0; // z0dd - ZOD, 8/19/02. No penalty for suicide! Was -10 + %game.SCORE_PER_TEAMKILL = -5; + %game.SCORE_PER_DEATH = 0; + + %game.SCORE_PER_KILL = 5; + %game.SCORE_PER_HEADSHOT = 1; + %game.SCORE_PER_TURRET_KILL = 5; + %game.SCORE_PER_TURRET_KILL_AUTO = 1; + + %game.SCORE_PER_OBJECT_DEFEND = 5; // Score for defending an objective + + %game.SCORE_PER_DESTROY_GEN = 10; + %game.SCORE_PER_DESTROY_SOLAR = 8; + %game.SCORE_PER_DESTROY_SENSOR = 4; + %game.SCORE_PER_DESTROY_TURRET = 6; + %game.SCORE_PER_DESTROY_ISTATION = 4; + %game.SCORE_PER_DESTROY_ASTATION = 4; + %game.SCORE_PER_DESTROY_VSTATION = 8; + %game.SCORE_PER_DESTROY_TSTATION = 4; + %game.SCORE_PER_DESTROY_SENTRY = 4; + %game.SCORE_PER_DESTROY_DEP_SENSOR = 1; + %game.SCORE_PER_DESTROY_DEP_INV = 2; + %game.SCORE_PER_DESTROY_DEP_TUR = 3; + %game.SCORE_PER_TK_DESTROY = -10; // Penalty for TKing equiptment, needs to be harsh. + + %game.SCORE_PER_PLYR_FLIPFLOP_CAP = 8; + + %game.SCORE_PER_DESTROY_SHRIKE = 5; + %game.SCORE_PER_DESTROY_BOMBER = 8; + %game.SCORE_PER_DESTROY_TRANSPORT = 5; + %game.SCORE_PER_DESTROY_WILDCAT = 5; + %game.SCORE_PER_DESTROY_TANK = 8; + %game.SCORE_PER_DESTROY_MPB = 12; + %game.SCORE_PER_PASSENGER = 2; + + %game.SCORE_PER_REPAIR_GEN = 8; + %game.SCORE_PER_REPAIR_SOLAR = 6; + %game.SCORE_PER_REPAIR_SENSOR = 2; + %game.SCORE_PER_REPAIR_TURRET = 4; + %game.SCORE_PER_REPAIR_ASTATION = 2; + %game.SCORE_PER_REPAIR_ISTATION = 2; + %game.SCORE_PER_REPAIR_VSTATION = 4; + %game.SCORE_PER_REPAIR_TSTATION = 4; + %game.SCORE_PER_REPAIR_SENTRY = 2; + %game.SCORE_PER_REPAIR_DEP_SENSOR = 1; + %game.SCORE_PER_REPAIR_DEP_TUR = 3; + %game.SCORE_PER_REPAIR_DEP_INV = 2; + + %game.RADIUS_OBJECT_DEFENSE = 20; + %game.TIME_REQ_PLYR_CAP_BONUS = 12 * 1000; // player must hold a switch 12 seconds to get a point for it. + %game.TIME_REQ_TEAM_CAP_BONUS = 12 * 1000; // time after touching it takes for team to get a point +} + +package DnDGame +{ + // z0dd - ZOD. From Classic MOD, placed here for base and mod compatibility. + function teamDestroyMessage(%client, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) + { + %team = %client.team; + %count = ClientGroup.getCount(); + for(%i = 0; %i < %count; %i++) + { + %recipient = ClientGroup.getObject(%i); + if((%recipient.team == %team) && (%recipient != %client)) + { + commandToClient(%recipient, 'TeamDestroyMessage', %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6); + } + } + } + + function ShapeBaseData::onDestroyed(%data, %obj, %prevstate) + { + %scorer = %obj.lastDamagedBy; + if(!isObject(%scorer)) + return; + + if((%scorer.getType() & $TypeMasks::GameBaseObjectType) && %scorer.getDataBlock().catagory $= "Vehicles") + { + %name = %scorer.getDatablock().getName(); + if(%name $= "BomberFlyer" || %name $= "AssaultVehicle") + %gunnerNode = 1; + else + %gunnerNode = 0; + + if(%scorer.getMountNodeObject(%gunnerNode)) + { + %destroyer = %scorer.getMountNodeObject(%gunnerNode).client; + %scorer = %destroyer; + %damagingTeam = %scorer.team; + } + } + else if(%scorer.getClassName() $= "Turret") + { + if(%scorer.getControllingClient()) + { + // manned turret + %destroyer = %scorer.getControllingClient(); + %scorer = %destroyer; + %damagingTeam = %scorer.team; + } + else + %scorer = %scorer.owner; // unmanned turret + } + if(!%damagingTeam) + %damagingTeam = %scorer.team; + + if(%damagingTeam != %obj.team) + { + if(!%obj.soiledByEnemyRepair) + { + Game.awardScoreStaticShapeDestroy(%scorer, %obj); + } + } + else + { + if(!%obj.getDataBlock().deployedObject) + Game.awardScoreTkDestroy(%scorer, %obj); + } + if(!%obj.objectiveCompleted && %obj.scoreValue) + { + messageAllExcept(%scorer, %damagingTeam, 'MsgDnDObjDisabled', '\c2%1 destroyed your %2 objective!', %scorer.name, Game.cleanWord(%obj.getDataBlock().targetTypeTag)); + %obj.objectiveCompleted = true; + if(isObject(%obj.wayPointMarker)) + %obj.wayPointMarker.schedule(100, "delete"); + + $teamScore[%damagingTeam]++; + Game.checkScoreLimit(%damagingTeam); + } + } + + function ShapeBaseData::onDisabled(%data, %obj) + { + %obj.wasDisabled = true; + Parent::onDisabled(%data, %obj); + } + + function RepairGunImage::onRepair(%this, %obj, %slot) + { + Parent::onRepair(%this, %obj, %slot); + %target = %obj.repairing; + if(%target && %target.team != %obj.team) + { + %target.soiledByEnemyRepair = true; + } + } + + function StaticShapeData::objectiveInit(%data, %obj) + { + if(!%data.deployedObject && %obj.team > 0) + { + %class = %data.className; + if(%class $= "Generator" || %class $= "Sensor" || %class $= "TurretBase") + { + %obj.objectiveCompleted = false; + %obj.scoreValue = true; + $numObjectives[%obj.team]++; + if($Host::MarkDnDObjectives) + Game.setupObjectiveMarker(%obj); + } + } + } + + function StationVehicle::onAdd(%this, %obj) + { + // We use onAdd because objectiveInit is never called on v-stations. + Parent::onAdd(%this, %obj); + if(%obj.team > 0) + { + %obj.objectiveCompleted = false; + %obj.scoreValue = true; + $numObjectives[%obj.team]++; + if($Host::MarkDnDObjectives) + Game.setupObjectiveMarker(%obj); + } + } + + function FlipFlop::objectiveInit(%data, %flipflop) + { + Parent::objectiveInit(%data, %flipflop); + %flipflop.tCapThread = ""; + %flipflop.pCapThread = ""; + %flipflop.scoreValue = true; + for(%i = 1; %i <= Game.numTeams; %i++) + { + $numObjectives[%i]++; + } + %flipFlop.prevTeam = ""; + } + + function FlipFlop::playerTouch(%data, %flipflop, %player) + { + if(%flipflop.team != %player.client.team) + { + Parent::playerTouch(%data, %flipflop, %player); + Game.startTimerPlayerFFCap(%player.client, %flipflop); + } + } +}; + +function DnDGame::setupObjectiveMarker(%game, %obj) +{ + %name = (getTaggedString(%obj.getDataBlock().targetNameTag) SPC getTaggedString(%obj.getDataBlock().targetTypeTag)); + %obj.wayPointMarker = new WayPoint() { + position = %obj.getPosition(); + name = %name; + dataBlock = "WayPointMarker"; + team = %obj.team; + }; + MissionCleanup.add(%obj.wayPointMarker); +} + +function serverCmdsetDnDMarkers(%client, %value) +{ + // USAGE: commandToServer('setDnDMarkers', 1); + %val = deTag(%value); + %adj = %val == 1 ? 1 : 0; + %snd = '~wfx/misc/warning_beep.wav'; + %detail = (%adj ? "enabled" : "disabled"); + %name = %client.name; + if(%client.isAdmin) + { + switch$ ( %adj ) + { + case 0: + %msg = '\c3%5: \c2Objective markers: \c3%4\c2, cycling mission.%1'; + $Host::MarkDnDObjectives = %adj; + export( "$Host::*", "prefs/ServerPrefs.cs", false ); + if( isObject( Game ) ) + Game.gameOver(); + + loadMission($CurrentMission, $CurrentMissionType, false); + + case 1: + %msg = '\c3%5: \c2Objective markers: \c3%4\c2, cycling mission.%1'; + $Host::MarkDnDObjectives = %adj; + export( "$Host::*", "prefs/ServerPrefs.cs", false ); + if( isObject( Game ) ) + Game.gameOver(); + + loadMission($CurrentMission, $CurrentMissionType, false); + + default: + messageClient(%client, 'MsgAdmin', '\c2Incorrect value, 0 disables markers, 1 enables markers.'); + } + messageAll( 'MsgAdmin', %msg, %snd, %val, %adj, %detail, %name, $CurrentMission ); + } + else + messageClient(%client, 'MsgAdmin', '\c2Only Admins can use this command.'); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Team Functions /////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// + +function DnDGame::setUpTeams(%game) +{ + DefaultGame::setUpTeams(%game); + + // reset the visibility of team 0 (team is still defaulted as friendly) + setSensorGroupAlwaysVisMask(0, 0); +} + +function DnDGame::clientMissionDropReady(%game, %client) +{ + messageClient(%client, 'MsgClientReady', "", %game.class); + for(%i = 1; %i <= %game.numTeams; %i++) + { + messageClient(%client, 'MsgDnDAddTeam', "", %i, %game.getTeamName(%i), $teamScore[%i], %game.getScoreLimit(%i), -1, -1); + } + %game.populateTeamRankArray(%client); + messageClient(%client, 'MsgYourRankIs', "", -1); + + messageClient(%client, 'MsgMissionDropInfo', '\c0You are in mission %1 (%2).', $MissionDisplayName, $MissionTypeDisplayName, $ServerName ); + DefaultGame::clientMissionDropReady(%game, %client); +} + +function DnDGame::assignClientTeam(%game, %client, %respawn) +{ + DefaultGame::assignClientTeam(%game, %client, %respawn); + // if player's team is not on top of objective hud, switch lines + messageClient(%client, 'MsgCheckTeamLines', "", %client.team); +} + +function DnDGame::getTeamSkin(%game, %team) +{ + if($Host::tournamentMode) + return $teamSkin[%team]; + + if(!$Host::useCustomSkins) + { + %terrain = MissionGroup.musicTrack; + switch$(%terrain) + { + case "lush": + if(%team == 1) + %skin = 'beagle'; + else if(%team == 2) + %skin = 'dsword'; + else + %skin = 'base'; + + case "badlands": + if(%team == 1) + %skin = 'swolf'; + else if(%team == 2) + %skin = 'dsword'; + else + %skin = 'base'; + + case "ice": + if(%team == 1) + %skin = 'swolf'; + else if(%team == 2) + %skin = 'beagle'; + else + %skin = 'base'; + + case "desert": + if(%team == 1) + %skin = 'cotp'; + else if(%team == 2) + %skin = 'beagle'; + else %skin = 'base'; + + case "Volcanic": + if(%team == 1) + %skin = 'dsword'; + else if(%team == 2) + %skin = 'cotp'; + else + %skin = 'base'; + + default: + if(%team == 2) + %skin = 'baseb'; + else + %skin = 'base'; + } + if(%skin $= "") + %skin = $teamSkin[%team]; + } + else + %skin = $teamSkin[%team]; + + return %skin; +} + +function DnDGame::getTeamName(%game, %team) +{ + if($Host::tournamentMode) + return $TeamName[%team]; + + if(!$Host::useCustomSkins) + { + %terrain = MissionGroup.musicTrack; + switch$(%terrain) + { + case "lush": + if(%team == 1) + %name = 'Blood Eagle'; + else if(%team == 2) + %name = 'Diamond Sword'; + + case "badlands": + if(%team == 1) + %name = 'Starwolf'; + else if(%team == 2) + %name = 'Diamond Sword'; + + case "ice": + if(%team == 1) + %name = 'Starwolf'; + else if(%team == 2) + %name = 'Blood Eagle'; + + case "desert": + if(%team == 1) + %name = 'Phoenix'; + else if(%team == 2) + %name = 'Blood Eagle'; + + case "Volcanic": + if(%team == 1) + %name = 'Diamond Sword'; + else if(%team == 2) + %name = 'Phoenix'; + + default: + if(%team == 2) + %name = 'Inferno'; + else + %name = 'Storm'; + } + if(%name $= "") + %name = $teamName[%team]; + } + else + %name = $TeamName[%team]; + + return %name; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Flip Flop Functions ////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// + +function DnDGame::startTimerPlayerFFCap(%game, %cl, %this) +{ + cancel(%this.pCapThread); //stop the last owner from collecting a cap bonus + %this.pCapThread = %game.schedule(%game.TIME_REQ_PLYR_CAP_BONUS, "awardScorePlayerFFCap", %cl, %this); + cancel(%this.tCapThread); //stop the old owners from collecting any cap bonus + %this.tCapThread = %game.schedule(%game.TIME_REQ_TEAM_CAP_BONUS, "awardScoreTeamFFCap", %this.team, %this); +} + +function DnDGame::stopScoreTimers(%game) +{ + // find all switches and cancel any timers associated with them + %ffGroup = nameToId("MissionCleanup/FlipFlops"); + if(%ffGroup <= 0) + return; + + for(%i = 0; %i < %ffGroup.getCount(); %i++) + { + %curFF = %ffGroup.getObject(%i); + cancel(%curFF.pCapThread); + cancel(%curFF.tCapThread); + } +} + +function DnDGame::countFlips(%game) +{ + return false; +} + +function DnDGame::awardScorePlayerFFCap(%game, %cl, %this) +{ + if(!($missionRunning)) + return; + + %cl.flipFlopsCapped++; + messageClient(%cl, 'msgFFDef', '\c0You received a %1 point bonus for holding the %2.', %game.SCORE_PER_PLYR_FLIPFLOP_CAP, %game.cleanWord(%this.name)); + messageTeamExcept(%cl, 'msgFFDef', '\c0Teammate %1 received a %2 point bonus for holding the %3', %cl.name, %game.SCORE_PER_PLYR_FLIPFLOP_CAP, %game.cleanWord(%this.name)); + %game.recalcScore(%cl); +} + +function DnDGame::awardScoreTeamFFCap(%game, %team, %this) +{ + if(!($missionRunning)) + return; + + cancel(%this.tCapThread); + $teamScore[%team]++; + if(%this.prevTeam) + $teamScore[%this.prevTeam]--; + + %this.prevTeam = %team; + %game.checkScoreLimit(%team); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Scoring Functions //////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// + +function DnDGame::checkScoreLimit(%game, %team) +{ + // Since checkScore limit is called for every score, announce the team. + if ($missionRunning) + { + if (%game.getTeamName(%team) $= 'Inferno') + messageAll("", '~wvoice/announcer/ann.infscores.wav'); + else if (%game.getTeamName(%team) $= 'Storm') + messageAll("", '~wvoice/announcer/ann.stoscores.wav'); + else if (%game.getTeamName(%team) $= 'Phoenix') + messageAll("", '~wvoice/announcer/ann.pxscore.wav'); + else if (%game.getTeamName(%team) $= 'Blood Eagle') + messageAll("", '~wvoice/announcer/ann.bescore.wav'); + else if (%game.getTeamName(%team) $= 'Diamond Sword') + messageAll("", '~wvoice/announcer/ann.dsscore.wav'); + else if (%game.getTeamName(%team) $= 'Starwolf') + messageAll("", '~wvoice/announcer/ann.swscore.wav'); + } + + // Update everyones objective hud. + for(%i = 1; %i <= %game.numTeams; %i++) + messageAll('MsgDnDTeamScores', "", %i, %game.getTeamName(%i), $teamScore[%i], %game.getScoreLimit(%i), -1, -1, -1); + + %scoreLimit = %game.getScoreLimit(%team); + if($teamScore[%team] >= %scoreLimit) + %game.scoreLimitReached(); +} + +function DnDGame::getScoreLimit(%game, %team) +{ + // If we ever have more then two teams this must be changed. + %otherTeam = %team == 1 ? 2 : 1; + return $numObjectives[%otherTeam]; +} + +function DnDGame::timeLimitReached(%game) +{ + logEcho("game over (timelimit)"); + %game.gameOver(); + cycleMissions(); +} + +function DnDGame::scoreLimitReached(%game) +{ + logEcho("game over (scorelimit)"); + %game.gameOver(); + cycleMissions(); +} + +function DnDGame::gameOver(%game) +{ + // call the default + DefaultGame::gameOver(%game); + + // stop all bonus timers + %game.stopScoreTimers(); + + //send the winner message + %winner = ""; + if ($teamScore[1] > $teamScore[2]) + %winner = %game.getTeamName(1); + else if ($teamScore[2] > $teamScore[1]) + %winner = %game.getTeamName(2); + + if (%winner $= 'Storm') + messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.stowins.wav" ); + else if (%winner $= 'Inferno') + messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.infwins.wav" ); + else if (%winner $= 'Starwolf') + messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.swwin.wav" ); + else if (%winner $= 'Blood Eagle') + messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.bewin.wav" ); + else if (%winner $= 'Diamond Sword') + messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.dswin.wav" ); + else if (%winner $= 'Phoenix') + messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.pxwin.wav" ); + else + messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.gameover.wav" ); + + messageAll('MsgClearObjHud', ""); + for(%i = 0; %i < ClientGroup.getCount(); %i++) + { + %client = ClientGroup.getObject(%i); + %game.resetScore(%client); + } + for ( %team = 1; %team <= %game.numTeams; %team++ ) + { + $TeamScore[%team] = 0; + $numObjectives[%team] = 0; + } +} + +function DnDGame::onClientDamaged(%game, %clVictim, %clAttacker, %damageType, %implement, %damageLoc) +{ + if(%clVictim.headshot && %damageType == $DamageType::Laser && %clVictim.team != %clAttacker.team) + { + %clAttacker.scoreHeadshot++; + if (%game.SCORE_PER_HEADSHOT != 0) + { + messageClient(%clAttacker, 'msgHeadshot', '\c0You received a %1 point bonus for a successful headshot.', %game.SCORE_PER_HEADSHOT); + } + %game.recalcScore(%clAttacker); + } + //the DefaultGame will set some vars + DefaultGame::onClientDamaged(%game, %clVictim, %clAttacker, %damageType, %implement, %damageLoc); +} + +function DnDGame::recalcScore(%game, %cl) +{ + %killValue = %cl.kills * %game.SCORE_PER_KILL; + %deathValue = %cl.deaths * %game.SCORE_PER_DEATH; + + if (%killValue - %deathValue == 0) + %killPoints = 0; + else + %killPoints = (%killValue * %killValue) / (%killValue - %deathValue); + + %cl.offenseScore = %killPoints + + %cl.suicides * %game.SCORE_PER_SUICIDE + + %cl.escortAssists * %game.SCORE_PER_ESCORT_ASSIST + + %cl.teamKills * %game.SCORE_PER_TEAMKILL + + %cl.tkDestroys * %game.SCORE_PER_TK_DESTROY + + %cl.scoreHeadshot * %game.SCORE_PER_HEADSHOT + + %cl.flagCaps * %game.SCORE_PER_PLYR_FLAG_CAP + + %cl.flagGrabs * %game.SCORE_PER_PLYR_FLAG_TOUCH + + %cl.genDestroys * %game.SCORE_PER_DESTROY_GEN + + %cl.sensorDestroys * %game.SCORE_PER_DESTROY_SENSOR + + %cl.turretDestroys * %game.SCORE_PER_DESTROY_TURRET + + %cl.IStationDestroys * %game.SCORE_PER_DESTROY_ISTATION + + %cl.AStationDestroys * %game.SCORE_PER_DESTROY_ASTATION + + %cl.vstationDestroys * %game.SCORE_PER_DESTROY_VSTATION + + %cl.TStationDestroys * %game.SCORE_PER_DESTROY_TSTATION + + %cl.solarDestroys * %game.SCORE_PER_DESTROY_SOLAR + + %cl.sentryDestroys * %game.SCORE_PER_DESTROY_SENTRY + + %cl.depSensorDestroys * %game.SCORE_PER_DESTROY_DEP_SENSOR + + %cl.depTurretDestroys * %game.SCORE_PER_DESTROY_DEP_TUR + + %cl.depStationDestroys * %game.SCORE_PER_DESTROY_DEP_INV + + %cl.flipFlopsCapped * %game.SCORE_PER_PLYR_FLIPFLOP_CAP + + %cl.vehicleScore + %cl.vehicleBonus; + + %cl.defenseScore = %cl.genDefends * %game.SCORE_PER_OBJECT_DEFEND + + %cl.turretKills * %game.SCORE_PER_TURRET_KILL_AUTO + + %cl.mannedturretKills * %game.SCORE_PER_TURRET_KILL + + %cl.genRepairs * %game.SCORE_PER_REPAIR_GEN + + %cl.sensorRepairs * %game.SCORE_PER_REPAIR_SENSOR + + %cl.turretRepairs * %game.SCORE_PER_REPAIR_TURRET + + %cl.stationRepairs * %game.SCORE_PER_REPAIR_ISTATION + + %cl.AStationRepairs * %game.SCORE_PER_REPAIR_ASTATION + + %cl.VStationRepairs * %game.SCORE_PER_REPAIR_VSTATION + + %cl.TStationRepairs * %game.SCORE_PER_REPAIR_TSTATION + + %cl.solarRepairs * %game.SCORE_PER_REPAIR_SOLAR + + %cl.sentryRepairs * %game.SCORE_PER_REPAIR_SENTRY + + %cl.depStationRepairs * %game.SCORE_PER_REPAIR_DEP_SENSOR + + %cl.depInvRepairs * %game.SCORE_PER_REPAIR_DEP_INV + + %cl.depTurretRepairs * %game.SCORE_PER_REPAIR_DEP_TUR; + + %cl.score = mFloor(%cl.offenseScore + %cl.defenseScore); + %game.recalcTeamRanks(%cl); +} + +function DnDGame::resetScore(%game, %client) +{ + %client.kills = 0; + %client.deaths = 0; + %client.suicides = 0; + %client.teamKills = 0; + %client.tkDestroys = 0; + %client.genDestroys = 0; + %client.sensorDestroys = 0; + %client.turretDestroys = 0; + %client.IStationDestroys = 0; + %client.AStationDestroys = 0; + %client.vstationDestroys = 0; + %client.TStationDestroys = 0; + %client.solarDestroys = 0; + %client.sentryDestroys = 0; + %client.depSensorDestroys = 0; + %client.depTurretDestroys = 0; + %client.depStationDestroys = 0; + %client.vehicleScore = 0; + %client.vehicleBonus = 0; + %client.flipFlopsCapped = 0; + %client.offenseScore = 0; + + %client.objDefends = 0; + %client.turretKills = 0; + %client.mannedTurretKills = 0; + %client.genRepairs = 0; + %client.sensorRepairs = 0; + %client.turretRepairs = 0; + %client.stationRepairs = 0; + %client.AStationRepairs = 0; + %client.VStationRepairs = 0; + %client.TStationRepairs = 0; + %client.solarRepairs = 0; + %client.sentryRepairs = 0; + %client.sentryRepairs = 0; + %client.depStationRepairs = 0; + %client.depInvRepairs = 0; + %client.defenseScore = 0; + %client.score = 0; + %client.outOfBounds = ""; +} + +function DnDGame::updateKillScores(%game, %clVictim, %clKiller, %damageType, %implement) +{ + // is this a vehicle kill rather than a player kill + // console error message suppression + if( isObject( %implement ) ) + { + if( %implement.getDataBlock().getName() $= "AssaultPlasmaTurret" || %implement.getDataBlock().getName() $= "BomberTurret" ) // gunner + %clKiller = %implement.vehicleMounted.getMountNodeObject(1).client; + else if(%implement.getDataBlock().catagory $= "Vehicles") // pilot + %clKiller = %implement.getMountNodeObject(0).client; + } + + if(%game.testTurretKill(%implement)) // check for turretkill before awarded a non client points for a kill + %game.awardScoreTurretKill(%clVictim, %implement); + else if(%game.testKill(%clVictim, %clKiller)) // verify victim was an enemy + { + %value = %game.awardScoreKill(%clKiller); + %game.shareScore(%clKiller, %value); + %game.awardScoreDeath(%clVictim); + + if(%game.testObjectDefend(%clVictim, %clKiller)) + %game.awardScoreObjectDefend(%clKiller); + } + else + { + if (%game.testSuicide(%clVictim, %clKiller, %damageType)) // otherwise test for suicide + { + %game.awardScoreSuicide(%clVictim); + } + else + { + if (%game.testTeamKill(%clVictim, %clKiller)) // otherwise test for a teamkill + %game.awardScoreTeamKill(%clVictim, %clKiller); + } + } +} + +function DnDGame::vehicleDestroyed(%game, %vehicle, %destroyer) +{ + //vehicle name + %data = %vehicle.getDataBlock(); + //%vehicleType = getTaggedString(%data.targetNameTag) SPC getTaggedString(%data.targetTypeTag); + %vehicleType = getTaggedString(%data.targetTypeTag); + if(%vehicleType !$= "MPB") + %vehicleType = strlwr(%vehicleType); + + %enemyTeam = ( %destroyer.team == 1 ) ? 2 : 1; + %scorer = 0; + %multiplier = 1; + %passengers = 0; + for(%i = 0; %i < %data.numMountPoints; %i++) + if(%vehicle.getMountNodeObject(%i)) + %passengers++; + + //what destroyed this vehicle + if(%destroyer.client) + { + //it was a player, or his mine, satchel, whatever... + %destroyer = %destroyer.client; + %scorer = %destroyer; + + // determine if the object used was a mine + if(%vehicle.lastDamageType == $DamageType::Mine) + %multiplier = 2; + } + else if(%destroyer.getClassName() $= "Turret") + { + if(%destroyer.getControllingClient()) + { + //manned turret + %destroyer = %destroyer.getControllingClient(); + %scorer = %destroyer; + } + else + { + %destroyerName = "A turret"; + %multiplier = 0; + } + } + else if(%destroyer.getDataBlock().catagory $= "Vehicles") + { + // Vehicle vs vehicle kill! + if(%name $= "BomberFlyer" || %name $= "AssaultVehicle") + %gunnerNode = 1; + else + %gunnerNode = 0; + + if(%destroyer.getMountNodeObject(%gunnerNode)) + { + %destroyer = %destroyer.getMountNodeObject(%gunnerNode).client; + %scorer = %destroyer; + } + %multiplier = 3; + } + else // Is there anything else we care about? + return; + + if(%destroyerName $= "") + %destroyerName = %destroyer.name; + + if(%vehicle.team == %destroyer.team) // team kill + { + %pref = (%vehicleType $= "Assault Tank") ? "an" : "a"; + messageAll( 'msgVehicleTeamDestroy', '\c0%1 TEAMKILLED %3 %2!', %destroyerName, %vehicleType, %pref); + } + else // legit kill + { + //messageTeamExcept(%destroyer, 'msgVehicleDestroy', '\c0%1 destroyed an enemy %2.', %destroyerName, %vehicleType); + teamDestroyMessage(%destroyer, 'msgVehDestroyed', '\c5%1 destroyed an enemy %2!', %destroyerName, %vehicleType); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + messageTeam(%enemyTeam, 'msgVehicleDestroy', '\c0%1 destroyed your team\'s %2.', %destroyerName, %vehicleType); + //messageClient(%destroyer, 'msgVehicleDestroy', '\c0You destroyed an enemy %1.', %vehicleType); + + if(%scorer) + { + %value = %game.awardScoreVehicleDestroyed(%scorer, %vehicleType, %multiplier, %passengers); + %game.shareScore(%value); + } + } +} + +function DnDGame::awardScoreVehicleDestroyed(%game, %client, %vehicleType, %mult, %passengers) +{ + if(%vehicleType $= "Grav Cycle") + %base = %game.SCORE_PER_DESTROY_WILDCAT; + else if(%vehicleType $= "Assault Tank") + %base = %game.SCORE_PER_DESTROY_TANK; + else if(%vehicleType $= "MPB") + %base = %game.SCORE_PER_DESTROY_MPB; + else if(%vehicleType $= "Turbograv") + %base = %game.SCORE_PER_DESTROY_SHRIKE; + else if(%vehicleType $= "Bomber") + %base = %game.SCORE_PER_DESTROY_BOMBER; + else if(%vehicleType $= "Heavy Transport") + %base = %game.SCORE_PER_DESTROY_TRANSPORT; + + %total = ( %base * %mult ) + ( %passengers * %game.SCORE_PER_PASSENGER ); + + %client.vehicleScore += %total; + + messageClient(%client, 'msgVehicleScore', '\c0You received a %1 point bonus for destroying an enemy %2.', %total, %vehicleType); + %game.recalcScore(%client); + return %total; +} + +function DnDGame::shareScore(%game, %client, %amount) +{ + //error("share score of"SPC %amount SPC "from client:" SPC %client); + // all of the player in the bomber and tank share the points + // gained from any of the others + %vehicle = %client.vehicleMounted; + if(!%vehicle) + return 0; + + %vehicleType = getTaggedString(%vehicle.getDataBlock().targetTypeTag); + if(%vehicleType $= "Bomber" || %vehicleType $= "Assault Tank") + { + for(%i = 0; %i < %vehicle.getDataBlock().numMountPoints; %i++) + { + %occupant = %vehicle.getMountNodeObject(%i); + if(%occupant) + { + %occCl = %occupant.client; + if(%occCl != %client && %occCl.team == %client.team) + { + // the vehicle has a valid teammate at this node + // share the score with them + %occCl.vehicleBonus += %amount; + %game.recalcScore(%occCl); + } + } + } + } +} + +function DnDGame::testObjectDefend(%game, %victimID, %killerID) +{ + InitContainerRadiusSearch(%victimID.plyrPointOfDeath, %game.RADIUS_OBJECT_DEFENSE, $TypeMasks::StaticShapeObjectType); + %objID = containerSearchNext(); + while(%objID != 0) + { + if((%objID.scoreValue && !%objID.objectiveCompleted) && (%objID.team == %killerID.team)) + return true; //found the(a) killer's objective near the victim's point of death + else + %objID = containerSearchNext(); + } + return false; // didn't find a qualifying objective within required radius of victims point of death +} + +function DnDGame::awardScoreObjectDefend(%game, %killerID) +{ + %killerID.objDefends++; + messageClient(%killerID, 'msgObjDef', '\c0You received a %1 point bonus for defending an objective.', %game.SCORE_PER_OBJECT_DEFEND); + messageTeamExcept(%killerID, 'msgObjDef', '\c0Teammate %1 received a %2 point bonus for defending an objective.', %killerID.name, %game.SCORE_PER_OBJECT_DEFEND); + %game.recalcScore(%killerID); + return %game.SCORE_PER_OBJECT_DEFEND; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Destroy Scoring Functions //////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// + +function DnDGame::awardScoreTkDestroy(%game, %cl, %obj) +{ + %cl.tkDestroys++; + teamDestroyMessage(%cl, 'msgTkDes', '\c5Teammate %1 destroyed your team\'s %3 objective!', %cl.name, %game.cleanWord(%obj.getDataBlock().targetTypeTag)); + messageClient(%cl, 'msgTkDes', '\c0You have been penalized %1 points for destroying your teams equiptment.', %game.SCORE_PER_TK_DESTROY); + %game.recalcScore(%cl); + %game.shareScore(%cl, %game.SCORE_PER_TK_DESTROY); +} + +function DnDGame::awardScoreStaticShapeDestroy(%game, %cl, %obj) +{ + %dataName = %obj.getDataBlock().getName(); + switch$ ( %dataName ) + { + case "GeneratorLarge": + %cl.genDestroys++; + %value = %game.SCORE_PER_DESTROY_GEN; + %msgType = 'msgGenDes'; + %tMsg = '\c5%1 destroyed a %2 Generator!'; + %clMsg = '\c0You received a %1 point bonus for destroying an enemy generator.'; + + case "SolarPanel": + %cl.solarDestroys++; + %value = %game.SCORE_PER_DESTROY_SOLAR; + %msgType = 'msgSolarDes'; + %tMsg = '\c5%1 destroyed a %2 Solar Panel!'; + %clMsg = '\c0You received a %1 point bonus for destroying an enemy solar panel.'; + + case "SensorLargePulse": + %cl.sensorDestroys++; + %value = %game.SCORE_PER_DESTROY_SENSOR; + %msgType = 'msgSensorDes'; + %tMsg = '\c5%1 destroyed a %2 Sensor!'; + %clMsg = '\c0You received a %1 point bonus for destroying a large enemy pulse sensor.'; + + case "SensorMediumPulse": + %cl.sensorDestroys++; + %value = %game.SCORE_PER_DESTROY_SENSOR; + %msgType = 'msgSensorDes'; + %tMsg = '\c5%1 destroyed a %2 Sensor!'; + %clMsg = '\c0You received a %1 point bonus for destroying a medium enemy pulse sensor.'; + + case "TurretBaseLarge": + %cl.turretDestroys++; + %value = %game.SCORE_PER_DESTROY_TURRET; + %msgType = 'msgTurretDes'; + %tMsg = '\c5%1 destroyed a %2 Turret!'; + %clMsg = '\c0You received a %1 point bonus for destroying an enemy base turret.'; + + case "StationInventory": + %cl.IStationDestroys++; + %value = %game.SCORE_PER_DESTROY_GEN; + %msgType = 'msgInvDes'; + %tMsg = '\c5%1 destroyed a %2 Inventory Station!'; + %clMsg = '\c0You received a %1 point bonus for destroying an enemy inventory station.'; + + case "StationAmmo": + %cl.aStationDestroys++; + %value = %game.SCORE_PER_DESTROY_ASTATION; + %msgType = 'msgAmmoDes'; + %tMsg = '\c5%1 destroyed a % 2 Ammo Station!'; + %clMsg = '\c0You received a %1 point bonus for destroying an enemy ammo station.'; + + case "StationVehicle": + %cl.VStationDestroys++; + %value = %game.SCORE_PER_DESTROY_VSTATION; + %msgType = 'msgVSDes'; + %tMsg = '\c5%1 destroyed a Vehicle Station!'; + %clMsg = '\c0You received a %1 point bonus for destroying an enemy vehicle station.'; + + case "SentryTurret": + %cl.sentryDestroys++; + %value = %game.SCORE_PER_DESTROY_SENTRY; + %msgType = 'msgSentryDes'; + %tMsg = '\c5%1 destroyed a %2 Sentry Turret!'; + %clMsg = '\c0You received a %1 point bonus for destroying an enemy sentry turret.'; + + case "DeployedMotionSensor": + %cl.depSensorDestroys++; + %value = %game.SCORE_PER_DESTROY_DEP_SENSOR; + %msgType = 'msgDepSensorDes'; + %tMsg = '\c5%1 destroyed a Deployable Motion Sensor!'; + %clMsg = '\c0You received a %1 point bonus for destroying an enemy deployable motion sensor.'; + + case "DeployedPulseSensor": + %cl.depSensorDestroys++; + %value = %game.SCORE_PER_DESTROY_DEP_SENSOR; + %msgType = 'msgDepSensorDes'; + %tMsg = '\c5%1 destroyed a Deployable Pulse Sensor!'; + %clMsg = '\c0You received a %1 point bonus for destroying an enemy deployable pulse sensor.'; + + case "TurretDeployedWallIndoor": + %cl.depTurretDestroys++; + %value = %game.SCORE_PER_DESTROY_DEP_TUR; + %msgType = 'msgDepTurDes'; + %tMsg = '\c5%1 destroyed a Deployable Spider Clamp Turret!'; + %clMsg = '\c0You received a %1 point bonus for destroying an enemy deployable spider clamp turret.'; + + case "TurretDeployedFloorIndoor": + %cl.depTurretDestroys++; + %value = %game.SCORE_PER_DESTROY_DEP_TUR; + %msgType = 'msgDepTurDes'; + %tMsg = '\c5%1 destroyed a Deployable Spider Clamp Turret!'; + %clMsg = '\c0You received a %1 point bonus for destroying an enemy deployable spider clamp turret.'; + + case "TurretDeployedCeilingIndoor": + %cl.depTurretDestroys++; + %value = %game.SCORE_PER_DESTROY_DEP_TUR; + %msgType = 'msgDepTurDes'; + %tMsg = '\c5%1 destroyed a Deployable Spider Clamp Turret!'; + %clMsg = '\c0You received a %1 point bonus for destroying an enemy deployable spider clamp turret.'; + + case "TurretDeployedOutdoor": + %cl.depTurretDestroys++; + %value = %game.SCORE_PER_DESTROY_DEP_TUR; + %msgType = 'msgDepTurDes'; + %tMsg = '\c5%1 destroyed a Deployable Landspike Turret!'; + %clMsg = '\c0You received a %1 point bonus for destroying an enemy deployable landspike turret.'; + + case "DeployedStationInventory": + %cl.depStationDestroys++; + %value = %game.SCORE_PER_DESTROY_DEP_INV; + %msgType = 'msgDepInvDes'; + %tMsg = '\c5%1 destroyed a Deployable Inventory!'; + %clMsg = '\c0You received a %1 point bonus for destroying an enemy deployable inventory station.'; + + case "MPBTeleporter": + %cl.TStationDestroys++; + %value = %game.SCORE_PER_DESTROY_TSTATION; + %msgType = 'msgMPBTeleDes'; + %tMsg = '\c5%1 destroyed a MPB Teleport Station!'; + %clMsg = '\c0You received a %1 point bonus for destroying an enemy MPB teleport station.'; + + default: + return; + } + teamDestroyMessage(%cl, 'msgDestroyed', %tMsg, %cl.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + messageClient(%cl, %msgType, %clMsg, %value, %dataName); + %game.recalcScore(%cl); + %game.shareScore(%scorer, %value); +} + +function DnDGame::awardScoreTurretKill(%game, %victimID, %implement) +{ + if ((%killer = %implement.getControllingClient()) != 0) //award whoever might be controlling the turret + { + if (%killer == %victimID) + %game.awardScoreSuicide(%victimID); + else if (%killer.team == %victimID.team) //player controlling a turret killed a teammate + { + %killer.teamKills++; + %game.awardScoreTurretTeamKill(%victimID, %killer); + %game.awardScoreDeath(%victimID); + } + else + { + %killer.mannedturretKills++; + %game.recalcScore(%killer); + %game.awardScoreDeath(%victimID); + } + } + else if ((%killer = %implement.owner) != 0) //if it isn't controlled, award score to whoever deployed it + { + if (%killer.team == %victimID.team) + { + %game.awardScoreDeath(%victimID); + } + else + { + %killer.turretKills++; + %game.recalcScore(%killer); + %game.awardScoreDeath(%victimID); + } + } + //default is, no one was controlling it, no one owned it. No score given. +} + +function DnDGame::testKill(%game, %victimID, %killerID) +{ + return ((%killerID != 0) && (%victimID.team != %killerID.team)); +} + +function DnDGame::awardScoreKill(%game, %killerID) +{ + %killerID.kills++; + %game.recalcScore(%killerID); + return %game.SCORE_PER_KILL; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Repair Scoring Functions ///////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// + +function DnDGame::testValidRepair(%game, %obj) +{ + if(!%obj.wasDisabled) + return false; + else if(%obj.lastDamagedByTeam == %obj.team) + return false; + else if(%obj.team != %obj.repairedBy.team) + return false; + else + { + if(%obj.soiledByEnemyRepair) + %obj.soiledByEnemyRepair = false; + return true; + } +} + +function DnDGame::objectRepaired(%game, %obj, %objName) +{ + %game.staticShapeOnRepaired(%obj, %objName); + %obj.wasDisabled = false; +} + +function DnDGame::staticShapeOnRepaired(%game, %obj, %objName) +{ + if (%game.testValidRepair(%obj)) + { + %repairman = %obj.repairedBy; + %dataName = %obj.getDataBlock().getName(); + switch$ (%dataName) + { + case "GeneratorLarge": + %repairman.genRepairs++; + %score = %game.SCORE_PER_REPAIR_GEN; + %tMsgType = 'msgGenRepaired'; + %msgType = 'msgGenRep'; + %tMsg = '\c0%1 repaired the %2 Generator!'; + %clMsg = '\c0You received a %1 point bonus for repairing a generator.'; + + case "SolarPanel": + %repairman.solarRepairs++; + %score = %game.SCORE_PER_REPAIR_SOLAR; + %tMsgType = 'msgsolarRepaired'; + %msgType = 'msgsolarRep'; + %tMsg = '\c0%1 repaired the %2 Solar Panel!'; + %clMsg = '\c0You received a %1 point bonus for repairing a solar panel.'; + + case "SensorLargePulse": + %repairman.sensorRepairs++; + %score = %game.SCORE_PER_REPAIR_SENSOR; + %tMsgType = 'msgSensorRepaired'; + %msgType = 'msgSensorRep'; + %tMsg = '\c0%1 repaired the %2 Large Pulse Sensor!'; + %clMsg = '\c0You received a %1 point bonus for repairing a large pulse sensor.'; + + case "SensorMediumPulse": + %repairman.sensorRepairs++; + %score = %game.SCORE_PER_REPAIR_SENSOR; + %tMsgType = 'msgSensorRepaired'; + %msgType = 'msgSensorRep'; + %tMsg = '\c0%1 repaired the %2 Medium Pulse Sensor!'; + %clMsg = '\c0You received a %1 point bonus for repairing a medium pulse sensor.'; + + case "DeployedMotionSensor": + %repairman.depSensorRepairs++; + %tMsgType = 'msgDepSensorRepaired'; + %msgType = 'msgDepSensorRep'; + %score = %game.SCORE_PER_REPAIR_DEP_SENSOR; + %tMsg = '\c0%1 repaired a Deployed Motion Sensor!'; + %clMsg = '\c0You received a %1 point bonus for repairing a deployed motion sensor.'; + + case "DeployedPulseSensor": + %repairman.depSensorRepairs++; + %score = %game.SCORE_PER_REPAIR_DEP_SENSOR; + %tMsgType = 'msgDepSensorRepaired'; + %msgType = 'msgDepSensorRep'; + %tMsg = '\c0%1 repaired a Deployed Pulse Sensor!'; + %clMsg = '\c0You received a %1 point bonus for repairing a deployed pulse sensor.'; + + case "StationInventory": + %repairman.stationRepairs++; + %score = %game.SCORE_PER_REPAIR_ISTATION; + %tMsgType = 'msgStationRepaired'; + %msgType = 'msgIStationRep'; + %tMsg = '\c0%1 repaired the %2 Inventory Station!'; + %clMsg = '\c0You received a %1 point bonus for repairing a inventory station.'; + + case "StationAmmo": + %repairman.stationRepairs++; + %score = %game.SCORE_PER_REPAIR_ASTATION; + %tMsgType = 'msgStationRepaired'; + %msgType = 'msgAStationRep'; + %tMsg = '\c0%1 repaired the %2 Ammo Station!'; + %clMsg = '\c0You received a %1 point bonus for repairing a ammo station.'; + + case "StationVehicle": + %repairman.VStationRepairs++; + %score = %game.SCORE_PER_REPAIR_VSTATION; + %tMsgType = 'msgvstationRepaired'; + %msgType = 'msgVStationRep'; + %tMsg = '\c0%1 repaired the Vehicle Station!'; + %clMsg = '\c0You received a %1 point bonus for repairing a vehicle station.'; + + case "TurretBaseLarge": + %repairman.TurretRepairs++; + %score = %game.SCORE_PER_REPAIR_TURRET; + %tMsgType = 'msgTurretRepaired'; + %msgType = 'msgTurretRep'; + %tMsg = '\c0%1 repaired the %2 Turret!'; + %clMsg = '\c0You received a %1 point bonus for repairing a base turret.'; + + case "SentryTurret": + %repairman.sentryRepairs++; + %score = %game.SCORE_PER_REPAIR_SENTRY; + %tMsgType = 'msgsentryTurretRepaired'; + %msgType = 'msgSentryRep'; + %tMsg = '\c0%1 repaired the %2 Sentry Turret!'; + %clMsg = '\c0You received a %1 point bonus for repairing a sentry turret.'; + + case "TurretDeployedWallIndoor": + %repairman.depTurretRepairs++; + %score = %game.SCORE_PER_REPAIR_DEP_TUR; + %tMsgType = 'msgDepTurretRepaired'; + %msgType = 'msgDepTurretRep'; + %tMsg = '\c0%1 repaired a Spider Clamp Turret!'; + %clMsg = '\c0You received a %1 point bonus for repairing a deployable spider clamp turret.'; + + case "TurretDeployedFloorIndoor": + %repairman.depTurretRepairs++; + %score = %game.SCORE_PER_REPAIR_DEP_TUR; + %tMsgType = 'msgDepTurretRepaired'; + %msgType = 'msgDepTurretRep'; + %tMsg = '\c0%1 repaired a Spider Clamp Turret!'; + %clMsg = '\c0You received a %1 point bonus for repairing a deployable spider clamp turret.'; + + case "TurretDeployedCeilingIndoor": + %repairman.depTurretRepairs++; + %score = %game.SCORE_PER_REPAIR_DEP_TUR; + %tMsgType = 'msgDepTurretRepaired'; + %msgType = 'msgDepTurretRep'; + %tMsg = '\c0%1 repaired a Spider Clamp Turret!'; + %clMsg = '\c0You received a %1 point bonus for repairing a deployable spider clamp turret.'; + + case "TurretDeployedOutdoor": + %repairman.depTurretRepairs++; + %score = %game.SCORE_PER_REPAIR_DEP_TUR; + %tMsgType = 'msgDepTurretRepaired'; + %msgType = 'msgDepTurretRep'; + %tMsg = '\c0%1 repaired a Landspike Turret!'; + %clMsg = '\c0You received a %1 point bonus for repairing a deployable landspike turret.'; + + case "DeployedStationInventory": + %repairman.depInvRepairs++; + %score = %game.SCORE_PER_REPAIR_DEP_INV; + %tMsgType = 'msgDepInvRepaired'; + %msgType = 'msgDepInvRep'; + %tMsg = '\c0%1 repaired a Deployable Inventory!'; + %clMsg = '\c0You received a %1 point bonus for repairing a deployed inventory station.'; + + case "MPBTeleporter": + %repairman.TStationRepairs++; + %score = %game.SCORE_PER_REPAIR_TSTATION; + %tMsgType = 'msgMPBTeleRepaired'; + %msgType = 'msgMPBTeleRep'; + %tMsg = '\c0%1 repaired the MPB Teleporter Station!'; + %clMsg = '\c0You received a %1 point bonus for repairing a mpb teleporter station.'; + + default: + return; + } + teamRepairMessage(%repairman, %tMsgType, %tMsg, %repairman.name, %obj.nameTag); + messageClient(%repairman, %msgType, %clMsg, %score, %dataName); + %game.recalcScore(%repairman); + } +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Misc Functions ////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// + +function DnDGame::enterMissionArea(%game, %playerData, %player) +{ + %player.client.outOfBounds = false; + messageClient(%player.client, 'EnterMissionArea', '\c1You are back in the mission area.'); + logEcho(%player.client.nameBase @ " (pl " @ %player @ "/cl "@%player.client @ ") entered mission area"); + cancel(%player.alertThread); +} + +function DnDGame::leaveMissionArea(%game, %playerData, %player) +{ + if(%player.getState() $= "Dead") + return; + + %player.client.outOfBounds = true; + messageClient(%player.client, 'LeaveMissionArea', '\c1You have left the mission area. Return or take damage.~wfx/misc/warning_beep.wav'); + logEcho(%player.client.nameBase @ " (pl " @ %player @ "/cl " @ %player.client @ ") left mission area"); + %player.alertThread = %game.schedule(1000, "DMAlertPlayer", 3, %player); +} + +function DnDGame::DMAlertPlayer(%game, %count, %player) +{ + // MES - I commented below line out because it prints a blank line to chat window + //messageClient(%player.client, 'MsgDMLeftMisAreaWarn', '~wfx/misc/red_alert.wav'); + if(%count > 1) + %player.alertThread = %game.schedule(1000, "DMAlertPlayer", %count - 1, %player); + else + %player.alertThread = %game.schedule(1000, "MissionAreaDamage", %player); +} + +function DnDGame::MissionAreaDamage(%game, %player) +{ + if(%player.getState() !$= "Dead") + { + %player.setDamageFlash(0.1); + %prevHurt = %player.getDamageLevel(); + %player.setDamageLevel(%prevHurt + 0.05); + %player.alertThread = %game.schedule(1000, "MissionAreaDamage", %player); + } + else + { + if(%player.alertThread !$= "") + { + cancel(%player.alertThread); + %player.alertThread = ""; + } + if(%player.client.team != 0) + { + %game.onClientKilled(%player.client, 0, $DamageType::OutOfBounds); + } + } +} + +function DnDGame::applyConcussion(%game, %player) +{ + %player.throwPack(); + %player.throwWeapon(); +} diff --git a/scripts/GameGui.cs b/scripts/GameGui.cs index 48e07c8..1101ea6 100644 --- a/scripts/GameGui.cs +++ b/scripts/GameGui.cs @@ -1,2157 +1,2151 @@ -//------------------------------------------------------------------------------ -// -// GameGui.cs -// -//------------------------------------------------------------------------------ - -// z0dd - ZOD: Execute the mission and game type skip lists so that -// arrays are put into memory for function buildMissionList. -exec("prefs/MissionSkip.cs", true); -exec("prefs/GameTypeSkip.cs", true); - -//------------------------------------------------------------------------------ -function LaunchGame( %pane ) -{ - if ( %pane !$= "" ) - GameGui.pane = %pane; - - LaunchTabView.viewTab( "GAME", GameGui, 0 ); -} - -//------------------------------------------------------------------------------ -function GameGui::onWake( %this ) -{ - Canvas.pushDialog( LaunchToolbarDlg ); - - if ( $PlayingOnline ) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - GM_Frame.setTitle( "GAME" ); - else - GM_Frame.setTitle( "LAN GAME" ); - - // This is essentially an "isInitialized" flag... - if ( GM_TabView.tabCount() == 0 ) - { - // --------------------------------------------------- - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - GM_TabView.addTab( 1, "JOIN" ); - GM_TabView.addTab( 2, "HOST" ); - GM_TabView.addTab( 3, "WARRIOR SETUP", 1 ); - queryMasterGameTypes(); - // --------------------------------------------------- - } - - switch$ ( %this.pane ) - { - case "Join": - GM_TabView.setSelected( 1 ); - case "Host": - GM_TabView.setSelected( 2 ); - default: // "Warrior" - GM_TabView.setSelected( 3 ); - } -} - -//------------------------------------------------------------------------------ -function GameGui::onSleep( %this ) -{ - %ctrl = "GM_" @ %this.pane @ "Pane"; - if ( isObject( %ctrl ) ) - %ctrl.onDeactivate(); - -// if( isObject( $dummySeq ) ) -// { -// $dummySeq.delete(); -// } - - Canvas.popDialog(LaunchToolbarDlg); -} - -//------------------------------------------------------------------------------ -function GameGui::setKey( %this, %key ) -{ - // To avoid console error -} - -//------------------------------------------------------------------------------ -function GameGui::onClose( %this, %key ) -{ - // To avoid console error -} - -//------------------------------------------------------------------------------ -function GM_TabView::onAdd( %this ) -{ - %this.addSet( 1, "gui/shll_horztabbuttonB", "5 5 5", "50 50 0", "5 5 5" ); -} - -//------------------------------------------------------------------------------ -function GM_TabView::onSelect( %this, %id, %text ) -{ - GM_JoinPane.setVisible( %id == 1 ); - GM_HostPane.setVisible( %id == 2 ); - GM_WarriorPane.setVisible( %id == 3 ); - GM_TabFrame.setAltColor( %this.getTabSet( %id ) != 0 ); - - %ctrl = "GM_" @ GameGui.pane @ "Pane"; - if ( isObject( %ctrl ) ) - %ctrl.onDeactivate(); - - switch ( %id ) - { - case 1: // Join - GM_JoinPane.onActivate(); - case 2: // Host - GM_HostPane.onActivate(); - case 3: // Warrior Setup - GM_WarriorPane.onActivate(); - } -} - -//------------------------------------------------------------------------------ -// Join Game pane: -//------------------------------------------------------------------------------ -function GM_JoinPane::onActivate( %this ) -{ - GameGui.pane = "Join"; - - if ( %this.onceOnly $= "" ) - { - GM_VersionText.setText( "Version" SPC getT2VersionNumber() ); - GMJ_StopBtn.setActive( false ); - - %this.onceOnly = 1; - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - GMJ_Browser.lastQuery = $PlayingOnline ? "Master" : "LanServers"; - GMJ_Browser.runQuery(); - } - - if ( isObject( BrowserMap ) ) - { - BrowserMap.pop(); - BrowserMap.delete(); - } - new ActionMap( BrowserMap ); - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - BrowserMap.bindCmd( keyboard, insert, "GMJ_Browser.insertIPAddress();", "" ); - BrowserMap.bindCmd( keyboard, "ctrl f", "Canvas.pushDialog( FindServerDlg );", "" ); - BrowserMap.bindCmd( keyboard, F3, "GMJ_Browser.findNextServer();", "" ); - BrowserMap.push(); - - GM_VersionText.setVisible( true ); // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - - if ( $pref::ServerBrowser::InfoWindowOpen ) - Canvas.pushDialog( ServerInfoDlg ); -} - -//------------------------------------------------------------------------------ -function GM_JoinPane::onDeactivate( %this ) -{ - if ( isObject( BrowserMap ) ) - { - BrowserMap.pop(); - BrowserMap.delete(); - } - - GM_VersionText.setVisible( false ); - - $pref::ServerBrowser::InfoWindowOpen = GMJ_Browser.infoWindowOpen; - if ( GMJ_Browser.infoWindowOpen ) - Canvas.popDialog( ServerInfoDlg ); -} - -//------------------------------------------------------------------------------ -$BrowserColumnCount = 0; -$BrowserColumnName[0] = "Server Name"; -$BrowserColumnRange[0] = "25 300"; -$BrowserColumnCount++; -$BrowserColumnName[1] = "Status"; -$BrowserColumnRange[1] = "25 75"; -$BrowserColumnCount++; -$BrowserColumnName[2] = "Favorite"; -$BrowserColumnRange[2] = "25 75"; -$BrowserColumnCount++; -$BrowserColumnName[3] = "Ping"; -$BrowserColumnRange[3] = "25 120"; -$BrowserColumnCount++; -$BrowserColumnName[4] = "Game Type"; -$BrowserColumnRange[4] = "25 200"; -$BrowserColumnCount++; -$BrowserColumnName[5] = "Mission Name"; -$BrowserColumnRange[5] = "25 300"; -$BrowserColumnCount++; -// --------------------------------------------------- -// z0dd - ZOD, 9/29/02. Removed T2 demo code from here -$BrowserColumnName[6] = "Rules Set"; -$BrowserColumnRange[6] = "25 300"; -$BrowserColumnCount++; -// --------------------------------------------------- -$BrowserColumnName[7] = "# Players (Bots)"; -$BrowserColumnRange[7] = "25 150"; -$BrowserColumnCount++; -$BrowserColumnName[8] = "CPU"; -$BrowserColumnRange[8] = "25 120"; -$BrowserColumnCount++; -$BrowserColumnName[9] = "IP Address"; -$BrowserColumnRange[9] = "25 200"; -$BrowserColumnCount++; -// --------------------------------------------------- -// z0dd - ZOD, 9/29/02. Removed T2 demo code from here -$BrowserColumnName[10] = "Version"; -$BrowserColumnRange[10] = "25 200"; -$BrowserColumnCount++; -// --------------------------------------------------- -$BrowserColumnName[11] = "Visibility"; -$BrowserColumnRange[11] = "25 120"; -$BrowserColumnCount++; - -//------------------------------------------------------------------------------ -function GMJ_Browser::onAdd( %this ) -{ - // Add the Server Browser columns based on the prefs: - for ( %i = 0; %i < $BrowserColumnCount; %i++ ) - { - %key = firstWord( $pref::ServerBrowser::Column[%i] ); - if ( $BrowserColumnName[%key] !$= "" && $BrowserColumnRange[%key] !$= "" ) - { - %width = getWord( $pref::ServerBrowser::Column[%i], 1 ); - %this.addColumn( %key, $BrowserColumnName[%key], %width, firstWord( $BrowserColumnRange[%key] ), getWord( $BrowserColumnRange[%key], 1 ) ); - } - } - %this.setSortColumn( $pref::ServerBrowser::SortColumnKey ); - %this.setSortIncreasing( $pref::ServerBrowser::SortInc ); -} - -//------------------------------------------------------------------------------ -function updateServerBrowser() -{ - GMJ_Browser.sort(); - if ( GMJ_Browser.infoWindowOpen ) - ServerInfoDlg.update(); -} - -//------------------------------------------------------------------------------ -function updateServerBrowserStatus( %text, %percentage ) -{ - GMJ_StatusText.setValue( %text ); - if ( %percentage >= 0 && %percentage <= 1 ) - { - GMJ_ProgressBar.setValue( %percentage ); - if ( %percentage == 0 ) // Query is over. - GMJ_StopBtn.setActive( false ); - } -} - -//------------------------------------------------------------------------------ -function GMJ_Browser::runQuery( %this ) -{ - GMJ_ProgressBar.setValue( 0 ); - $JoinGameAddress = ""; - GMJ_JoinBtn.setActive( false ); - GMJ_RefreshServerBtn.setActive( false ); - %this.clearList(); - - // Clear the Server Info dialog: - SI_InfoWindow.setText( "No server selected." ); - SI_ContentWindow.setText( "" ); - - if ( %this.lastQuery $= "LanServers" ) - { - GMJ_StatusText.setValue( "Querying LAN servers..." ); - GMJ_FilterBtn.setActive( false ); - GMJ_FilterBtn.setVisible( false ); - GMJ_FilterText.setText( "LAN Servers" ); - queryLanServers( $JoinGamePort ); - GMJ_StopBtn.setActive( true ); - } - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - else - { - GMJ_FilterBtn.setActive( true ); - GMJ_FilterBtn.setVisible( true ); - - if ( $pref::ServerBrowser::activeFilter == 0 ) - { - GMJ_StatusText.setValue( "Querying the master server..." ); - GMJ_FilterText.setText( "All servers" ); - queryMasterServer( $JoinGamePort ); - GMJ_StopBtn.setActive( true ); - } - else if ( $pref::ServerBrowser::activeFilter == 1 ) - { - // Buddy list query: - GMJ_StatusText.setValue( "Fetching buddy list..." ); - GMJ_FilterText.setText( "Buddies" ); - %this.key = LaunchGui.key++; - DatabaseQueryArray( 5, 0, "", %this, %this.key ); - } - else if ( $pref::ServerBrowser::activeFilter == 2 ) - { - // Favorites only: - GMJ_FilterText.setText( "Favorites" ); - if ( $pref::ServerBrowser::FavoriteCount <= 0 || $pref::ServerBrowser::Favorite[0] $= "" ) - { - GMJ_StatusText.setValue( "No favorites found." ); - MessageBoxOK( "INVALID FILTER", "You haven't marked any servers as favorites. Click the Favorites column to mark a server as a favorite." ); - } - else - { - GMJ_StatusText.setValue( "Querying favorites..." ); - queryFavoriteServers(); - GMJ_StopBtn.setActive( true ); - } - } - else - { - GMJ_StatusText.setValue( "Querying the master server..." ); - %filterIndex = $pref::ServerBrowser::activeFilter - 3; - if ( $pref::ServerBrowser::Filter[%filterIndex] !$= "" ) - { - %filter = $pref::ServerBrowser::Filter[%filterIndex]; - GMJ_FilterText.setText( getField( %filter, 0 ) ); - %rulesSet = getField( %filter, 1 ); - if ( %rulesSet $= "" ) - %rulesSet = "any"; - %missionType = getField( %filter, 2 ); - if ( %missionType $= "" ) - %missionType = "any"; - %maxPlayers = getField( %filter, 4 ); - if ( %maxPlayers $= "" ) - %maxPlayers = 255; - %maxBots = getField( %filter, 7 ); - if ( %maxBots $= "" ) - %maxBots = 16; - %regionMask = getField( %filter, 5 ); - if ( %regionMask $= "" ) - %regionMask = 4294967295; - - queryMasterServer( - $JoinGamePort, - 0, // Flags - %rulesSet, // Rules Set - %missionType, // Mission Type - getField( %filter, 3 ), // Min Players - %maxPlayers, // Max Players - %maxBots, // Max Bots - %regionMask, // Region Mask - getField( %filter, 6 ), // Max Ping - getField( %filter, 8 ), // Min CPU Speed - getField( %filter, 9 ) ); // Filter flags - GMJ_StopBtn.setActive( true ); - } - else - { - // Filter is invalid, so fall back to the default: - $pref::ServerBrowser::activeFilter = 0; - GMJ_FilterText.setText( "All servers" ); - queryMasterServer( $JoinGamePort ); - GMJ_StopBtn.setActive( true ); - } - } - } -} - -//------------------------------------------------------------------------------ -function GMJ_Browser::onDatabaseQueryResult( %this, %status, %resultString, %key ) -{ - if ( %this.key != %key ) - return; - - if ( getField( %resultString, 0 ) <= 0 ) - { - GMJ_StatusText.setValue( "No buddies found." ); - MessageBoxOK( "INVALID FILTER", "You have no buddies in your buddy list!" ); - } - else // Prepare for the incoming buddy list: - %this.buddyList = ""; -} - -//------------------------------------------------------------------------------ -function GMJ_Browser::onDatabaseRow( %this, %row, %isLastRow, %key ) -{ - if ( %this.key != %key ) - return; - - %buddyName = getField( %row, 0 ); - %buddyGuid = getField( %row, 3 ); - echo( "Got buddy: \c9\"" @ %buddyName @ "\": " @ %buddyGuid ); - %this.buddyList = %this.buddyList $= "" ? %buddyGuid : %this.buddyList TAB %buddyGuid; - - if ( %isLastRow ) - { - GMJ_StatusText.setValue( "Querying the master server..." ); - queryMasterServer( - $JoinGamePort, // Port - 0, // Flags - "Any", // Rules Set - "Any", // Mission Type - 0, // Min Players - 255, // Max Players - 16, // Max Bots - 0xFFFFFFFF, // Region Mask - 0, // Max Ping - 0, // Min CPU Speed - 0, // Filter flags - %this.buddyList ); - GMJ_StopBtn.setActive( true ); - %this.buddyList = ""; - } -} - -//------------------------------------------------------------------------------ -function GMJ_Browser::onSelect( %this, %address ) -{ - GMJ_JoinBtn.setActive( true ); - if ( !isServerQueryActive() ) - GMJ_RefreshServerBtn.setActive( true ); - $JoinGamePassword = ""; - $JoinGameAddress = %address; - - if ( %this.infoWindowOpen ) - ServerInfoDlg.update(); -} - -//------------------------------------------------------------------------------ -function GMJ_Browser::refreshSelectedServer( %this ) -{ - querySingleServer( $JoinGameAddress ); - if ( %this.infoWindowOpen ) - ServerInfoDlg.update(); -} - -//------------------------------------------------------------------------------ -function GMJ_Browser::onSetSortKey( %this, %sortKey, %isIncreasing ) -{ - $pref::ServerBrowser::SortColumnKey = %sortKey; - $pref::ServerBrowser::SortInc = %isIncreasing; -} - -//------------------------------------------------------------------------------ -function GMJ_Browser::onColumnResize( %this, %column, %newSize, %key ) -{ - $pref::ServerBrowser::Column[%column] = %key SPC %newSize; -} - -//------------------------------------------------------------------------------ -function GMJ_Browser::onColumnRepositioned( %this, %oldColumn, %newColumn ) -{ - // Puke em all... - %count = %this.getNumColumns(); - for ( %col = 0; %col < %count; %col++ ) - $pref::ServerBrowser::Column[%col] = %this.getColumnKey( %col ) SPC %this.getColumnWidth( %col ); -} - -//------------------------------------------------------------------------------ -function GMJ_Browser::addFavorite( %this, %name, %address ) -{ - //error( "** addFavorite( \"" @ %name @ "\", " @ %address @ " ) **" ); - $pref::ServerBrowser::Favorite[$pref::ServerBrowser::FavoriteCount] = %name TAB %address; - $pref::ServerBrowser::FavoriteCount++; -} - -//------------------------------------------------------------------------------ -function GMJ_Browser::removeFavorite( %this, %address ) -{ - //error( "** removeFavorite( " @ %address @ " ) **" ); - %foundIt = false; - for ( %i = 0; %i < $pref::ServerBrowser::FavoriteCount; %i++ ) - { - if ( !%foundIt ) - { - if ( getField( $pref::ServerBrowser::Favorite[%i], 1 ) $= %address ) - %foundIt = true; - } - - if ( %foundIt ) - $pref::ServerBrowser::Favorite[%i] = $pref::ServerBrowser::Favorite[%i + 1]; - } - - if ( %foundIt ) - $pref::ServerBrowser::FavoriteCount--; -} - -//------------------------------------------------------------------------------ -function GMJ_Browser::insertIPAddress( %this ) -{ - if ( isServerQueryActive() ) - { - BrowserMap.pop(); - MessageBoxOK( "ERROR", "Can't insert addresses while a query is running!", "BrowserMap.push();" ); - alxPlay( InputDeniedSound, 0, 0, 0 ); - return; - } - - IPEntry.setText( "IP:" ); - Canvas.pushDialog( EnterIPDlg ); -} - -//------------------------------------------------------------------------------ -function EnterIPDlg::onDone( %this ) -{ - Canvas.popDialog( EnterIPDlg ); - %address = IPEntry.getValue(); - if ( getSubStr( %address, 0, 3 ) !$= "IP:" ) - %address = "IP:" @ %address; - if ( strpos( %address, ":", 3 ) == -1 ) - %address = %address @ ":28000"; - - echo( "Starting ping to server " @ %address @ "..." ); - pushServerAddress( %address ); - GMJ_Browser.selectRowByAddress( %address, true ); -} - -//------------------------------------------------------------------------------ -function FindServerDlg::onWake( %this ) -{ - FS_SearchPattern.validate(); - FS_SearchPattern.selectAll(); -} - -//------------------------------------------------------------------------------ -function FindServerDlg::onGo( %this ) -{ - %pattern = FS_SearchPattern.getValue(); - if ( %pattern !$= "" ) - { - Canvas.popDialog( FindServerDlg ); - if ( !GMJ_Browser.findServer( %pattern ) ) - MessageBoxOK( "NOT FOUND", "No servers with \"" @ %pattern @ "\" in their name were found." ); - } - else - alxPlay( InputDeniedSound, 0, 0, 0 ); -} - -//------------------------------------------------------------------------------ -function FS_SearchPattern::validate( %this ) -{ - FS_GoBtn.setActive( %this.getValue() !$= "" ); -} - -//------------------------------------------------------------------------------ -function ServerInfoDlg::onAdd( %this ) -{ - %this.headerStyle = ""; -} - -//------------------------------------------------------------------------------ -function ServerInfoDlg::onWake( %this ) -{ - GMJ_Browser.infoWindowOpen = true; - - // Get the position and size from the prefs: - %res = getResolution(); - %resW = firstWord( %res ); - %resH = getWord( %res, 1 ); - %w = firstWord( $pref::ServerBrowser::InfoWindowExtent ); - if ( %w > %resW ) - %w = %resW; - %h = getWord( $pref::ServerBrowser::InfoWindowExtent, 1 ); - if ( %h > %resH ) - %h = %resH; - %x = firstWord( $pref::ServerBrowser::InfoWindowPos ); - if ( %x > %resW - %w ) - %x = %resW - %w; - %y = getWord( $pref::ServerBrowser::InfoWindowPos, 1 ); - if ( %y > %resH - %h ) - %y = %resH - %h; - SI_Window.resize( %x, %y, %w, %h ); - - GMJ_InfoBtn.setActive( false ); - SI_RefreshBtn.setActive( false ); - %this.update(); -} - -//------------------------------------------------------------------------------ -function ServerInfoDlg::update( %this ) -{ - %status = GMJ_Browser.getServerStatus(); - if ( %status $= "invalid" ) - { - SI_InfoWindow.setText( "No server selected." ); - return; - } - - %info = GMJ_Browser.getServerInfoString(); - %infoText = "" @ %this.headerStyle @ "NAME:" TAB getRecord( %info, 0 ) - NL "" @ %this.headerStyle @ "ADDRESS:" TAB getRecord( %info, 1 ) @ ""; - - %refreshable = false; - if ( %status $= "responded" ) - { - %temp = getRecord( %info, 2 ); - if ( %temp !$= "" ) - %infoText = %infoText NL "" @ %this.headerStyle @ "RULES SET:" TAB %temp @ ""; - %temp = getRecord( %info, 3 ); - if ( %temp $= "" ) - %temp = "None"; - %infoText = %infoText NL "" @ %this.headerStyle @ "FLAGS:" TAB %temp @ ""; - %temp = getRecord( %info, 4 ); - if ( %temp !$= "" ) - %infoText = %infoText NL "" @ %this.headerStyle @ "GAME TYPE:" TAB %temp @ ""; - %temp = getRecord( %info, 5 ); - if ( %temp !$= "" ) - %infoText = %infoText NL "" @ %this.headerStyle @ "MAP NAME:" TAB %temp @ ""; - %temp = getRecords( %info, 6, 10 ); - if ( %temp !$= "" ) - %infoText = %infoText NL "" @ %this.headerStyle @ "SERVER INFO:" TAB %temp @ ""; - - // Fill in the content window: - %content = GMJ_Browser.getServerContentString(); - SI_ContentWindow.fill( %content ); - %refreshable = !isServerQueryActive(); - } - else - { - switch$ ( %status ) - { - case "new": - %temp = "Not queried yet."; - SI_ContentWindow.setText( "Not available." ); - case "querying": - %temp = "Querying..."; - SI_ContentWindow.setText( "Not available." ); - case "updating": - %temp = "Updating..."; - case "timedOut": - %temp = "Timed out."; - SI_ContentWindow.setText( "Not available." ); - %refreshable = !isServerQueryActive(); - } - %infoText = %infoText NL "" @ %this.headerStyle @ "STATUS: " TAB %temp; - } - - SI_InfoWindow.setText( %infoText ); - SI_InfoScroll.scrollToTop(); - SI_ContentScroll.scrollToTop(); - SI_RefreshBtn.setActive( %refreshable ); -} - -//------------------------------------------------------------------------------ -function SI_ContentWindow::fill( %this, %content ) -{ - if ( getRecordCount( %content ) == 1 ) - { - %this.setText( "" ); - return; - } - - %record = 0; - %teamCount = getRecord( %content, %record ); - %record++; - if ( %teamCount > 1 ) - { - %string = "" @ ServerInfoDlg.headerStyle @ "TEAMSSCORE"; - for ( %i = 0; %i < %teamCount; %i++ ) - { - %teamEntry = getRecord( %content, %record ); - %string = %string NL "" SPC getField( %teamEntry, 0 ) @ "" SPC getField( %teamEntry, 1 ); - %record++; - } - - %playerCount = getRecord( %content, %record ); - %record++; - %string = %string NL "\n" @ ServerInfoDlg.headerStyle @ "PLAYERSTEAMSCORE"; - for ( %i = 0; %i < %playerCount; %i++ ) - { - %playerEntry = getRecord( %content, %record ); - %string = %string NL "" SPC getField( %playerEntry, 0 ) @ "" - SPC getField( %playerEntry, 1 ) @ "" SPC getField( %playerEntry, 2 ) @ ""; - %record++; - } - } - else - { - %record++; - %playerCount = getRecord( %content, %record ); - %record++; - %string = "" @ ServerInfoDlg.headerStyle @ "PLAYERSSCORE"; - for ( %i = 0; %i < %playerCount; %i++ ) - { - %playerEntry = getRecord( %content, %record ); - %string = %string NL "" SPC getField( %playerEntry, 0 ) @ "" SPC getField( %playerEntry, 2 ); - %record++; - } - } - - %this.setText( %string ); -} - -//------------------------------------------------------------------------------ -function ServerInfoDlg::onSleep( %this ) -{ - GMJ_Browser.infoWindowOpen = false; - - // Save off the Server Info Window prefs: - $pref::ServerBrowser::InfoWindowPos = SI_Window.getPosition(); - $pref::ServerBrowser::InfoWindowExtent = SI_Window.getExtent(); - $pref::ServerBrowser::InfoWindowBarPos = getWord( SI_InfoScroll.getExtent(), 1 ); - - GMJ_InfoBtn.setActive( true ); -} - -//------------------------------------------------------------------------------ -function PasswordDlg::onWake( %this ) -{ - $JoinGamePassword = ""; -} - -//------------------------------------------------------------------------------ -function PasswordDlg::accept( %this ) -{ - Canvas.popDialog( PasswordDlg ); - JoinSelectedGame(); -} - -//------------------------------------------------------------------------------ -function JoinSelectedGame() -{ - $ServerInfo = GMJ_Browser.getServerInfoString(); - - JoinGame($JoinGameAddress); -} - -//------------------------------------------------------------------------------ -function JoinGame(%address) -{ - MessagePopup( "JOINING SERVER", "CONNECTING" ); - cancelServerQuery(); - echo("Joining Server " @ %address); - %playerPref = $pref::Player[$pref::Player::Current]; - %playerName = getField( %playerPref, 0 ); - %playerRaceGender = strReplace(getField( %playerPref, 1 ),"Type A","A"); - %playerSkin = getField( %playerPref, 2 ); - %playerVoice = getField( %playerPref, 3 ); - %playerVoicePitch = getField( %playerPref, 4 ); - LoadingGui.gotLoadInfo = ""; - //Make sure the server is T2BOL. If not, join as a derm if we're Draakan or Creole - if (getField(GMJ_Browser.getServerInfoString(),2) !$= "T2BOL") - { - %race = getWord(%playerRaceGender,0); - if (%race $= "Draakan" || %race $= "Criollos" ) - %playerRaceGender = "Bioderm"; - } - connect( %address, $JoinGamePassword, %playerName, %playerRaceGender, %playerSkin, %playerVoice, %playerVoicePitch ); -} - -//------------------------------------------------------------------------------ -// Host Game pane: -//------------------------------------------------------------------------------ -function GM_HostPane::onActivate( %this ) -{ - GameGui.pane = "Host"; - - $HostGameType = $PlayingOnline ? "Online" : "LAN"; - - buildMissionTypePopup( GMH_MissionType ); - // --------------------------------------------------- - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - GMH_BotMinSlider.setValue( $Host::MinBotDifficulty ); - GMH_BotMaxSlider.setValue( $Host::MaxBotDifficulty ); - GMH_BotsEnabledTgl.setValue( $Host::BotsEnabled ); - GMH_BotsEnabledTgl.onAction(); - - //clamp and set the bot count slider - setBotCountSlider(); - // --------------------------------------------------- - - // Select the saved-off prefs: - if ( $Host::MissionType !$= "" ) - { - // Find the last selected type: - for ( %type = 0; %type < $HostTypeCount; %type++ ) - { - if ( $HostTypeName[%type] $= $Host::MissionType ) - break; - } - - if ( %type != $HostTypeCount ) - { - GMH_MissionType.setSelected( %type ); - GMH_MissionType.onSelect( %type, "" ); - - if ($Host::MissionType $= "RPG" || $Host::MissionType $= "SV") - { - GMH_BotsEnabledTgl.setValue(0); - GMH_BotsEnabledTgl.onAction(); - GMH_BotsEnabledTgl.setActive(0); - } - - if ( $Host::Map !$= "" ) - { - // Find the last selected mission: - for ( %index = 0; %index < $HostMissionCount[%type]; %index++ ) - { - if ( $HostMissionFile[$HostMission[%type, %index]] $= $Host::Map ) - break; - } - - if ( %index != $HostMissionCount[%type] ) - GMH_MissionList.setSelectedById( $HostMission[%type, %index] ); - } - } - } - else - { - GMH_MissionType.setSelected( 0 ); - GMH_MissionType.onSelect( 0, "" ); - } - - GMH_StartGameBtn.makeFirstResponder( 1 ); -} - -//------------------------------------------------------------------------------ -function GM_HostPane::onDeactivate( %this ) -{ -} - -//------------------------------------------------------------------------------ -function buildMissionTypePopup( %popup ) -{ - %popup.clear(); - for( %type = 0; %type < $HostTypeCount; %type++ ) - %popup.add( $HostTypeDisplayName[%type], %type ); - %popup.sort( true ); -} - -//------------------------------------------------------------------------------ -function getMissionTypeDisplayNames() -{ - %file = new FileObject(); - for ( %type = 0; %type < $HostTypeCount; %type++ ) - { - $HostTypeDisplayName[%type] = $HostTypeName[%type]; - if ( %file.openForRead( "scripts/" @ $HostTypeName[%type] @ "Game.cs" ) ) - { - while ( !%file.isEOF() ) - { - %line = %file.readLine(); - if ( getSubStr( %line, 0, 17 ) $= "// DisplayName = " ) - { - $HostTypeDisplayName[%type] = getSubStr( %line, 17, 1000 ); - break; - } - } - } - } - - %file.delete(); -} - -//------------------------------------------------------------------------------ -function buildMissionList() -{ - %search = "missions/*.mis"; - %ct = 0; - $HostTypeCount = 0; - $HostMissionCount = 0; - %fobject = new FileObject(); - for( %file = findFirstFile( %search ); %file !$= ""; %file = findNextFile( %search ) ) - { - %name = fileBase( %file ); // get the name - - // --------------------------------------------------------------------- - // z0dd - ZOD: - // If skip list file exists, make sure this mission isn't in skip list. - // If mission is on the skip list then remove it from rotation. - if(isFile("prefs/MissionSkip.cs")) - { - %found = 0; - for( %i = 0; $SkipMission::name[%i] !$= ""; %i++ ) { - if( $SkipMission::name[%i] $= %name ) - { - error("MISSION PULLED FROM ROTATION: " @ %name); - %found = 1; - break; - } - } - if(%found) - continue; - } - // --------------------------------------------------------------------- - - %idx = $HostMissionCount; - $HostMissionCount++; - $HostMissionFile[%idx] = %name; - $HostMissionName[%idx] = %name; - - if ( !%fobject.openForRead( %file ) ) - continue; - - %typeList = "None"; - while ( !%fobject.isEOF() ) - { - %line = %fobject.readLine(); - if ( getSubStr( %line, 0, 17 ) $= "// DisplayName = " ) - { - // Override the mission name: - $HostMissionName[%idx] = getSubStr( %line, 17, 1000 ); - } - else if ( getSubStr( %line, 0, 18 ) $= "// MissionTypes = " ) - { - %typeList = getSubStr( %line, 18, 1000 ); - break; - } - } - %fobject.close(); - - // Don't include single player missions: - if ( strstr( %typeList, "SinglePlayer" ) != -1 ) - continue; - - // Test to see if the mission is bot-enabled: - %navFile = "terrains/" @ %name @ ".nav"; - $BotEnabled[%idx] = isFile( %navFile ); - - for( %word = 0; ( %misType = getWord( %typeList, %word ) ) !$= ""; %word++ ) - { - //--------------------------------------------------------------------------------- - // z0dd - ZOD - Founder(founder@mechina.com): Append Tribe Practice to CTF missions - if(%misType $= "CTF") - %typeList = rtrim(%typeList) @ " PracticeCTF"; - - // z0dd - ZOD: If skip list file exists, make sure this mission type isn't in - // skip list. If mission type is on the skip list then remove it from rotation. - if(isFile("prefs/GameTypeSkip.cs")) - { - %found = 0; - for( %i = 0; $SkipType::name[%i] !$= ""; %i++ ) { - if( $SkipType::name[%i] $= %misType ) - { - error("GAME TYPE REMOVED: " @ %misType); - %found = 1; - break; - } - } - if(%found) - continue; - } - //--------------------------------------------------------------------------------- - for ( %i = 0; %i < $HostTypeCount; %i++ ) - if ( $HostTypeName[%i] $= %misType ) - break; - if ( %i == $HostTypeCount ) - { - $HostTypeCount++; - $HostTypeName[%i] = %misType; - $HostMissionCount[%i] = 0; - } - // add the mission to the type - %ct = $HostMissionCount[%i]; - $HostMission[%i, $HostMissionCount[%i]] = %idx; - $HostMissionCount[%i]++; - } - } - getMissionTypeDisplayNames(); - %fobject.delete(); -} - -// One time only function call: -buildMissionList(); - -///////////////////////////////////////////////////////////////////////////////////////////////////// -// z0dd - ZOD - Founder(founder@mechina.com): -// Functions to add and remove missions from $SkipMission::name (MissionSkip.cs). - -// commandToServer('AddMap', MapFilename); -function serverCmdAddMap(%client, %map) -{ - %map = detag(%map); - if(%client.isSuperAdmin) - AddMapToList(%map, %client); - else - messageClient(%client, 'MsgNotSuperAdmin', '\c2Only Super Admins can use this command.'); -} -// AddMapToList(MapFilename); -function AddMapToList(%map, %client) -{ - if(%map $="") - return; - - %found = 0; - for( %i = 0; $SkipMission::name[%i] !$= ""; %i++ ) { - if($SkipMission::name[%i] $= %map) { - %found = 1; - break; - } - } - if(%found) - { - error( "Mission " @ %map @ " allready exists in skip list!" ); - return; - } - if($MissionSkip::count $= "") - $MissionSkip::count = 0; - - $SkipMission::name[$MissionSkip::count] = %map; - $MissionSkip::count++; - - %val = 'removal from'; - writeMissionSkipList(%map, %val, %client); -} - -// commandToServer('RemoveMap', MapFilename); -function serverCmdRemoveMap(%client, %map) -{ - %map = detag(%map); - if(%client.isSuperAdmin) - RemoveMapFromList(%map, %client); - else - messageClient(%client, 'MsgNotSuperAdmin', '\c2Only Super Admins can use this command.'); -} - -// RemoveMapFromList(MapFilename); -function RemoveMapFromList(%map, %client) -{ - if(%map $="") - return; - - %count = 0; - for( %i = 0; %i < $MissionSkip::count; %i++ ) - { - if($SkipMission::name[%i] !$= %map) - { - %Temp[%count] = $SkipMission::name[%i]; - %count++; - } - } - for( %j = 0; %j < %count; %j++ ) - $SkipMission::name[%j] = %Temp[%j]; - - $MissionSkip::count = %count; - //$MissionSkip::count --; - - %val = 'restoration to'; - writeMissionSkipList(%map, %val, %client); -} - -function writeMissionSkipList(%name, %val, %client) -{ - %newfile = "prefs/MissionSkip.cs"; - if(isFile(%newfile)) - { - deleteFile(%newfile); - if(isFile("prefs/MissionSkip.cs.dso")) - deleteFile("prefs/MissionSkip.cs.dso"); - } - - %listfile = new fileObject(); - %listfile.openForWrite(%newfile); - %listfile.writeLine("// ------------------------- Mission Skip List -------------------------"); - %listfile.writeLine("// ----- Mission file names without file extension. Ex: BeggarsRun -----"); - %listfile.writeLine("// ------------ Missions on list are excluded from rotation ------------"); - %listfile.writeLine(""); - for( %k = 0; %k < $MissionSkip::count; %k++ ) { - %listfile.writeLine("$SkipMission::name[" @ %k @ "] = \"" @ $SkipMission::name[%k] @ "\";"); - } - %listfile.writeLine("$MissionSkip::count = " @ $MissionSkip::count @ ";"); - %listfile.close(); - %listfile.delete(); - - if(%client !$= "") - messageClient(%client, 'MsgAdmin', '\c3\"%1\"\c2 %2 mission rotation successful.', %name, %val); - - echo( "Mission " @ %name @ " " @ %val @ " mission rotation successful." ); -} - -///////////////////////////////////////////////////////////////////////////////////////////////////// -// z0dd - ZOD - Founder(founder@mechina.com): -// Functions to add and remove mission types from $SkipType::name (GameTypeSkip.cs). - -// commandToServer('AddType', Typename); -function serverCmdAddType(%client, %type) -{ - %type = detag(%type); - if(%client.isSuperAdmin) - AddTypeToList(%type, %client); - else - messageClient(%client, 'MsgNotSuperAdmin', '\c2Only Super Admins can use this command.'); -} - -// AddTypeToList(Typename); -function AddTypeToList(%type, %client) -{ - if(%type $="") - return; - - %found = 0; - for( %i = 0; $SkipType::name[%i] !$= ""; %i++ ) { - if($SkipType::name[%i] $= %type) { - %found = 1; - break; - } - } - if(%found) - { - error( "Game type " @ %type @ " allready exists in skip list!" ); - return; - } - if($TypeSkip::count $= "") - $TypeSkip::Count = 0; - - $SkipType::name[$TypeSkip::count] = %type; - $TypeSkip::count++; - - %val = 'removed'; - writeTypeSkipList(%type, %val, %client); -} - -// commandToServer('RemoveType', Typename); -function serverCmdRemoveType(%client, %type) -{ - %type = detag(%type); - if(%client.isSuperAdmin) - RemoveTypeFromList(%type, %client); - else - messageClient(%client, 'MsgNotSuperAdmin', '\c2Only Super Admins can use this command.'); -} - -// RemoveTypeFromList(Typename); -function RemoveTypeFromList(%type, %client) -{ - if(%type $="") - return; - - %count = 0; - for( %i = 0; %i < $TypeSkip::count; %i++ ) - { - if($SkipType::name[%i] !$= %type) - { - %Temp[%count] = $SkipType::name[%i]; - %count++; - } - } - for( %j = 0; %j < %count; %j++ ) - $SkipType::name[%j] = %Temp[%j]; - - $TypeSkip::count = %count; - //$TypeSkip::count --; - - %val = 'restored'; - writeTypeSkipList(%type, %val, %client); -} - -function writeTypeSkipList(%name, %val, %client) -{ - %newfile = "prefs/GameTypeSkip.cs"; - if(isFile(%newfile)) - { - deleteFile(%newfile); - if(isFile("prefs/GameTypeSkip.cs.dso")) - deleteFile("prefs/GameTypeSkip.cs.dso"); - } - %listfile = new fileObject(); - %listfile.openForWrite(%newfile); - %listfile.writeLine("// ------------------------- Game Type Skip List -------------------------"); - %listfile.writeLine("// ----------------------- Game type names. Ex: CnH ----------------------"); - %listfile.writeLine("// ------------ Game types on list are excluded from rotation ------------"); - %listfile.writeLine(""); - for( %k = 0; %k < $TypeSkip::count; %k++ ) { - %listfile.writeLine("$SkipType::name[" @ %k @ "] = \"" @ $SkipType::name[%k] @ "\";"); - } - %listfile.writeLine("$TypeSkip::count = " @ $TypeSkip::count @ ";"); - %listfile.close(); - %listfile.delete(); - - if(%client !$= "") - messageClient(%client, 'MsgAdmin', '\c2Game type \c3\"%1\"\c2 %2 successfully.', %name, %val); - - echo( "Game type " @ %name @ " " @ %val @ " successfully." ); -} - -//------------------------------------------------------------------------------ -function validateMissionAndType(%misName, %misType) -{ - for ( %mis = 0; %mis < $HostMissionCount; %mis++ ) - if( $HostMissionFile[%mis] $= %misName ) - break; - if ( %mis == $HostMissionCount ) - return false; - for ( %type = 0; %type < $HostTypeCount; %type++ ) - if ( $HostTypeName[%type] $= %misType ) - break; - if(%type == $hostTypeCount) - return false; - $Host::Map = $HostMissionFile[%mis]; - $Host::MissionType = $HostTypeName[%type]; - - return true; -} - -//------------------------------------------------------------------------------ -// This function returns the index of the next mission in the mission list. -//------------------------------------------------------------------------------ -function getNextMission( %misName, %misType ) -{ - // First find the index of the mission in the master list: - for ( %mis = 0; %mis < $HostMissionCount; %mis++ ) - if( $HostMissionFile[%mis] $= %misName ) - break; - - if ( %mis == $HostMissionCount ) - return ""; - - // Now find the index of the mission type: - for ( %type = 0; %type < $HostTypeCount; %type++ ) - if ( $HostTypeName[%type] $= %misType ) - break; - - if ( %type == $hostTypeCount ) - return ""; - - // Now find the mission's index in the mission-type specific sub-list: - for ( %i = 0; %i < $HostMissionCount[%type]; %i++ ) - if ( $HostMission[%type, %i] == %mis ) - break; - - // -------------------------------------------------------------------- - // z0dd - ZOD: Enable random mission rotation for current mission type. - if($Host::ClassicRandomMissions) - { - %i = mFloor(getRandom(0, ($HostMissionCount[%type] - 1))); - - // If its same as last map, go back 1 - if($HostMissionFile[$HostMission[%type, %i]] $= %misName) - %i--; - - // If its greater then or equal to count, set to zero - %i = %i >= $HostMissionCount[%type] ? 0 : %i; - } - else - { - // Go BACKWARDS, because the missions are in reverse alphabetical order: - if ( %i == 0 ) - %i = $HostMissionCount[%type] - 1; - else - %i--; - } - // -------------------------------------------------------------------- - - // If there are bots in the game, don't switch to any maps without - // a NAV file: - if ( $HostGameBotCount > 0 ) - { - for ( %j = 0; %j < $HostMissionCount[%type] - 1; %j++ ) - { - if ( $BotEnabled[$HostMission[%type, %i]] ) - break; - - // -------------------------------------------------------------------- - // z0dd - ZOD: Enable random mission rotation for current mission type. - if($Host::ClassicRandomMissions) - { - %i = mFloor(getRandom(0, ($HostMissionCount[%type] - 1))); - - // If its same as last map, go back 1 - if($HostMissionFile[$HostMission[%type, %i]] $= %misName) - %i--; - - // If its greater then or equal to count, set to zero - %i = %i >= $HostMissionCount[%type] ? 0 : %i; - } - else - { - if ( %i == 0 ) - %i = $HostMissionCount[%type] - 1; - else - %i--; - } - // -------------------------------------------------------------------- - } - } - - return $HostMission[%type, %i]; -} - -//------------------------------------------------------------------------------ -function GMH_MissionType::onSelect( %this, %id, %text ) -{ - // Fill the mission list: - GMH_MissionList.clear(); - %lastAdded = 0; - for ( %i = 0; %i < $HostMissionCount[%id];%i++ ) - { - %misId = $HostMission[%id,%i]; - GMH_MissionList.addRow( %misId, $HostMissionName[%misId] ); - %lastAdded = %misId; - } - GMH_MissionList.sort( 0 ); - - // Select the last mission added: - GMH_MissionList.setSelectedById( %lastAdded ); - $Host::MissionType = $HostTypeName[%id]; - - // --------------------------------------------------- - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - - // Disable all non bot-enabled maps if bots are enabled: - if ( GMH_BotsEnabledTgl.getValue() ) - GMH_BotsEnabledTgl.onAction(); - // --------------------------------------------------- - - // --------------------------------------------------- - // Disable the 'enable AI' button if "RPG" is selected.. - if (%text $= "Role Playing" || %text $= "Survival") //Or Survival.. - { - GMH_BotsEnabledTgl.setValue(0); - GMH_BotsEnabledTgl.onAction(); - GMH_BotsEnabledTgl.setActive(0); - } - else - { - GMH_BotsEnabledTgl.setValue($Host::BotsEnabled); - GMH_BotsEnabledTgl.onAction(); - GMH_BotsEnabledTgl.setActive(1); - } -} - -//------------------------------------------------------------------------------ -function GMH_MissionList::onSelect( %this, %id, %text ) -{ - if ( GMH_BotsEnabledTgl.getValue() ) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - GMH_StartGameBtn.setActive( $BotEnabled[%id] ); -} - -//------------------------------------------------------------------------------ -function tryToStartHostedGame() -{ - if ( GMH_BotsEnabledTgl.getValue() ) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - { - %selId = GMH_MissionList.getSelectedId(); - if ( !$BotEnabled[%selId] ) - return; - } - - StartHostedGame(); -} - -//------------------------------------------------------------------------------ -function StartHostedGame() -{ - %selId = GMH_MissionList.getSelectedId(); - %misFile = $HostMissionFile[%selId]; - - if ( $Host::BotsEnabled ) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - { - validateMaxPlayers(); - $HostGameBotCount = $Host::BotCount; - } - else - $HostGameBotCount = 0; - - $ServerName = $Host::GameName; - $Host::Map = %misFile; - - echo( "exporting server prefs..." ); - export( "$Host::*", "prefs/ServerPrefs.cs", false ); - - if ( $Host::Dedicated ) - { - MessageBoxYesNo( "WARNING", - "You are about to launch a dedicated server and quit Tribes 2. Do you want to continue?", - "tryToLaunchDedicatedServer(" @ $Host::PureServer @ ");" ); - return; - } - - //IRCClient::onJoinGame("", ""); - - MessagePopup( "STARTING SERVER", "Initializing..." ); - Canvas.repaint(); - - cancelServerQuery(); - setNetPort( $Host::Port ); - CreateServer( $Host::Map, $Host::MissionType ); - %playerPref = $pref::Player[$pref::Player::Current]; - %playerName = getField( %playerPref, 0 ); - %playerRaceGender = strReplace(getField( %playerPref, 1 ),"Type A","A"); - %playerSkin = getField( %playerPref, 2 ); - %playerVoice = getField( %playerPref, 3 ); - %playerVoicePitch = getField( %playerPref, 4 ); - localConnect( %playerName, %playerRaceGender, %playerSkin, %playerVoice, %playerVoicePitch ); - if(!$RecordDemo) - { - // demos are incompatible with local simulated net params - ServerConnection.setSimulatedNetParams($pref::Net::simPacketLoss, $pref::net::simPing * 0.5); - LocalClientConnection.setSimulatedNetParams($pref::Net::simPacketLoss, $pref::net::simPing * 0.5); - } -} - -//------------------------------------------------------------------------------ -function tryToLaunchDedicatedServer( %pure ) -{ - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - %numBots = $Host::BotsEnabled ? $Host::BotCount : 0; - if ( launchDedicatedServer( $Host::MissionType, $Host::Map, %numBots, %pure ) ) - quit(); - else - { - error( "Failed to launch the dedicated server." ); - schedule( 0, 0, MessageBoxOK, "FAILED", "Tribes 2 failed to launch the dedicated server." ); - } -} - -//------------------------------------------------------------------------------ -function GMH_BotsEnabledTgl::onAction( %this ) -{ - %count = GMH_MissionList.rowCount(); - if ( %this.getValue() ) - { - for ( %i = 0; %i < %count; %i++ ) - { - %id = GMH_MissionList.getRowId( %i ); - GMH_MissionList.setRowActive( %id, $BotEnabled[%id] ); - } - - GMH_EnableBotsGroup.setVisible(true); - %misId = GMH_MissionList.getSelectedId(); - GMH_StartGameBtn.setActive( $BotEnabled[%misId] ); - } - else - { - for ( %i = 0; %i < %count; %i++ ) - { - %id = GMH_MissionList.getRowId( %i ); - GMH_MissionList.setRowActive( %id, true ); - } - - GMH_EnableBotsGroup.setVisible( false ); - GMH_StartGameBtn.setActive( true ); - } -} - -//------------------------------------------------------------------------------ -function updateMinBotDifficulty() -{ - %min = GMH_BotMinSlider.getValue(); - $Host::MinBotDifficulty = %min; - if ( GMH_BotMaxSlider.getValue() < %min ) - GMH_BotMaxSlider.setValue( %min ); -} - -//------------------------------------------------------------------------------ -function updateMaxBotDifficulty() -{ - %max = GMH_BotMaxSlider.getValue(); - $Host::MaxBotDifficulty = %max; - if ( GMH_BotMinSlider.getValue() > %max ) - GMH_BotMinSlider.setValue( %max ); -} - -//------------------------------------------------------------------------------ -function GMH_BotsEnabledTgl::onAction( %this ) -{ - %count = GMH_MissionList.rowCount(); - if ( %this.getValue() ) - { - for ( %i = 0; %i < %count; %i++ ) - { - %id = GMH_MissionList.getRowId( %i ); - GMH_MissionList.setRowActive( %id, $BotEnabled[%id] ); - } - - GMH_EnableBotsGroup.setVisible(true); - %misId = GMH_MissionList.getSelectedId(); - GMH_StartGameBtn.setActive( $BotEnabled[%misId] ); - } - else - { - for ( %i = 0; %i < %count; %i++ ) - { - %id = GMH_MissionList.getRowId( %i ); - GMH_MissionList.setRowActive( %id, true ); - } - - GMH_EnableBotsGroup.setVisible(false); - GMH_StartGameBtn.setActive( true ); - } -} - -//------------------------------------------------------------------------------ -function validateMaxPlayers() -{ - %maxPlayers = GMH_MaxPlayersTE.getValue(); - if (%maxPlayers < 1) - %maxPlayers = 1; - - if (%maxPlayers > 64) - %maxPlayers = 64; - - //reset the value back into the TE - GMH_MaxPlayersTE.setValue(%maxPlayers); - - // --------------------------------------------------- - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - - //and make sure the bot sliders reflect the changes.. - setBotCountSlider(); - // --------------------------------------------------- -} - -function setBotCountSlider() -{ - %maxBots = 15; - if (%maxBots > $Host::MaxPlayers - 2) - %maxBots = $Host::MaxPlayers - 2; - if ($Host::BotCount > %maxBots + 1) - $Host::BotCount = %maxBots + 1; - - if (%maxBots <= 1) - %sliderValue = 0.0; - else - %sliderValue = ($Host::BotCount - 0.95) / %maxBots; - - GMH_MinCombatantSlider.setValue(%sliderValue); -} - -function setMinCombatants() -{ - %maxBots = 16; - if (%maxBots > $Host::MaxPlayers - 1) - %maxBots = $Host::MaxPlayers - 1; - if (%maxBots <= 0) - $Host::BotCount = 0; - else - $Host::BotCount = mFloor( GMH_MinCombatantSlider.getValue() * (%maxBots - 1)) + 1; - GMH_BotCountText.setValue( "(" @ $Host::BotCount @ ")" ); -} - -//------------------------------------------------------------------------------ -function AdvancedHostDlg::onWake( %this ) -{ - // Set all of the controls to the current pref states: - AH_HostPort.setText( $Host::Port ); - if ( $Host::HiVisibility ) - AH_HiVisibilityRdo.setValue( true ); - else - AH_HiFPSRdo.setValue( true ); - AH_DedicatedTgl.setValue( $Host::Dedicated ); - AH_DedicatedTgl.onAction(); - AH_TeamDamageTgl.setValue( $Host::TeamDamageOn ); - AH_TournamentTgl.setValue( $Host::TournamentMode ); - AH_AdminVoteTgl.setValue( $Host::allowAdminPlayerVotes ); - AH_AllowSmurfTgl.setValue( !$Host::NoSmurfs ); - AH_TimeLimit.setText( $Host::TimeLimit ); - AH_AdminPassword.setText( $Host::AdminPassword ); - AH_ServerInfo.setText( $Host::Info ); - AH_VotePassSlider.setValue( $Host::VotePassPercent ); - AH_VoteTimeSlider.setValue( $Host::VoteTime ); - AH_RespawnSlider.setValue( $Host::PlayerRespawnTimeout ); - AH_WarmupSlider.setValue( $Host::WarmupTime ); -} - -//------------------------------------------------------------------------------ -function AdvancedHostDlg::accept( %this ) -{ - // Apply all of the changes: - $Host::Port = AH_HostPort.getValue(); - $Host::HiVisibility = AH_HiVisibilityRdo.getValue(); - $Host::Dedicated = AH_DedicatedTgl.getValue(); - if ( $Host::Dedicated ) - $Host::PureServer = AH_PureServerTgl.getValue(); - $Host::TeamDamageOn = AH_TeamDamageTgl.getValue(); - $Host::TournamentMode = AH_TournamentTgl.getValue(); - $Host::allowAdminPlayerVotes = AH_AdminVoteTgl.getValue(); - $Host::NoSmurfs = !AH_AllowSmurfTgl.getValue(); - $Host::TimeLimit = AH_TimeLimit.getValue(); - $Host::AdminPassword = AH_AdminPassword.getValue(); - $Host::Info = AH_ServerInfo.getText(); - $Host::VotePassPercent = mFloor( AH_VotePassSlider.getValue() ); - $Host::VoteTime = mFloor( AH_VoteTimeSlider.getValue() ); - $Host::PlayerRespawnTimeout = mFloor( AH_RespawnSlider.getValue() ); - $Host::WarmupTime = mFloor( AH_WarmupSlider.getValue() ); - - // Save off the new prefs: - export( "$Host::*", "prefs/ServerPrefs.cs", false ); - - Canvas.popDialog( AdvancedHostDlg ); -} - -//------------------------------------------------------------------------------ -function AH_DedicatedTgl::onAction( %this ) -{ - if ( %this.getValue() ) - { - AH_PureServerTgl.setValue( $Host::PureServer ); - AH_PureServerTgl.setActive( true ); - } - else - { - AH_PureServerTgl.setValue( false ); - AH_PureServerTgl.setActive( false ); - } -} - -//------------------------------------------------------------------------------ -function AH_VotePassText::update( %this ) -{ - %this.setText( mFloor( AH_VotePassSlider.getValue() ) @ "%" ); -} - -//------------------------------------------------------------------------------ -function AH_VoteTimeText::update( %this ) -{ - %this.setText( mFloor( AH_VoteTimeSlider.getValue() ) SPC "seconds" ); -} - -//------------------------------------------------------------------------------ -function AH_RespawnText::update( %this ) -{ - %this.setText( mFloor( AH_RespawnSlider.getValue() ) SPC "seconds" ); -} - -//------------------------------------------------------------------------------ -function AH_WarmupText::update( %this ) -{ - %this.setText( mFloor( AH_WarmupSlider.getValue() ) SPC "seconds" ); -} - -//------------------------------------------------------------------------------ -// Warrior Setup pane: -//------------------------------------------------------------------------------ -function GM_WarriorPane::onActivate( %this ) -{ - GameGui.pane = "Warrior"; - if ( $pref::Player::Count == 0 ) - %this.createNewAlias(); - else - { - // Fill the warrior list: - GMW_WarriorPopup.clear(); - GMW_LightRdo.setValue( true ); - - // First add the warrior corresponding to the player nickname: - %this.warriorIndex = -1; - if ( $PlayingOnline ) - { - %warrior = getField( WONGetAuthInfo(), 0 ); - for ( %i = 0; %i < $pref::Player::Count; %i++ ) - { - %name = getField( $pref::Player[%i], 0 ); - if ( %name $= %warrior ) - { - %this.warriorIndex = %i; - GMW_WarriorPopup.add( %name, %i, 1 ); - break; - } - } - } - - // Add the rest of the aliases: - for ( %count = 0; %count < $pref::Player::Count; %count++ ) - { - if ( $pref::Player[%count] !$= "" && %count != %this.warriorIndex ) - { - %name = stripTrailingSpaces( strToPlayerName( getField( $pref::Player[%count], 0 ) ) ); - GMW_WarriorPopup.add( %name, %count ); - } - } - - // Fill the static menus: - GMW_RaceGenderPopup.fillList(); - GMW_SkinPrefPopup.fillList(); - - // Select the current player: - GMW_WarriorPopup.setSelected( $pref::Player::Current ); - GMW_WarriorPopup.onSelect( $pref::Player::Current, "" ); - - if ( $pref::Player::Count > 1 && $pref::Player::Current != %this.warriorIndex ) - GMW_DeleteWarriorBtn.setActive( true ); - else - GMW_DeleteWarriorBtn.setActive( false ); - - GMW_PlayerPageBtn.setVisible( $PlayingOnline ); - } -} - -//------------------------------------------------------------------------------ -function GM_WarriorPane::onDeactivate( %this ) -{ -} - -//------------------------------------------------------------------------------ -function GM_WarriorPane::createNewAlias( %this ) -{ - NW_NameEdit.setValue( "" ); - NW_DoneBtn.setActive( false ); - NW_CancelBtn.setVisible( $pref::Player::Count > 0 ); - Canvas.pushDialog( NewWarriorDlg ); -} - -//------------------------------------------------------------------------------ -function GM_WarriorPane::deleteWarrior( %this ) -{ - MessageBoxYesNo( "CONFIRM", "Are you sure you want to delete this alias?", "doDeleteWarrior();", "" ); -} - -//------------------------------------------------------------------------------ -function doDeleteWarrior() -{ - // Make sure we aren't trying to delete the default warrior (should never get this): - if ( $pref::Player::Current == GM_WarriorPane.warriorIndex ) - return; - - for ( %i = $pref::Player::Current; %i < $pref::Player::Count - 1; %i++ ) - $pref::Player[%i] = $pref::Player[%i + 1]; - $pref::Player[%i] = ""; - - if ( GM_WarriorPane.warriorIndex > $pref::Player::Current ) - GM_WarriorPane.warriorIndex--; - - $pref::Player::Count--; - if ( GM_WarriorPane.warriorIndex != -1 ) - $pref::Player::Current = GM_WarriorPane.warriorIndex; - else - $pref::Player::Current = 0; - - // Update the interface: - GM_WarriorPane::onActivate(); -} - -//------------------------------------------------------------------------------ -function GM_WarriorPane::gotoPlayerPage( %this ) -{ - %warrior = getField( WONGetAuthInfo(), 0 ); - LaunchBrowser( %warrior, "Warrior" ); -} - -//------------------------------------------------------------------------------ -function GMW_PlayerModel::update( %this ) -{ - // Get the shape names: - if ( GMW_HeavyRdo.getValue() ) - %armor = "heavy"; - else if ( GMW_MediumRdo.getValue() ) - %armor = "medium"; - else - %armor = "light"; - - switch ( GMW_RaceGenderPopup.getSelected() ) - { - case 1: - if ( %armor $= "heavy" ) - %shape = %armor @ "_male"; - else - %shape = %armor @ "_female"; - case 2 or 3 or 4 or 5 or 6: %shape = "bioderm_" @ %armor; - default: %shape = %armor @ "_male"; - } - - %skin = getField( $pref::Player[$pref::Player::Current], 2 ); - -// if( isObject( $dummySeq ) ) -// { -// $dummySeq.delete(); -// } -// -// $dummySeq = new TSShapeConstructor() -// { -// baseShape = %shape @ ".dts"; -// sequence0 = %shape @ "_forward.dsq dummyRun"; -// }; - - %this.setModel( %shape, %skin ); -} - -//------------------------------------------------------------------------------ -function GMW_WarriorPopup::onAdd( %this ) -{ - %this.addScheme( 1, "255 255 0", "255 255 128", "128 128 0" ); -} - -//------------------------------------------------------------------------------ -function GMW_WarriorPopup::onSelect( %this, %id, %text ) -{ - // Set this as the currently selected player: - $pref::Player::Current = %id; - - // Select the race/gender: - %raceGender = getField( $pref::Player[%id], 1 ); - %selId = GMW_RaceGenderPopup.findText( %raceGender ); - if ( %selId == -1 ) - %selId = 0; - - GMW_RaceGenderPopup.setSelected( %selId ); - GMW_VoicePopup.fillList( %selId ); - - // Select the skin: - %skin = getField( $pref::Player[%id], 2 ); - %baseSkin = isDynamixSkin( %skin ); - GMW_SkinPrefPopup.setSelected( !%baseSkin ); - GMW_SkinPopup.fillList( %selId ); - - %selId = -1; - for ( %i = 0; %i < GMW_SkinPopup.size(); %i++ ) - { - if ( GMW_SkinPopup.realSkin[%i] !$= "" ) - { - if ( %skin $= GMW_SkinPopup.realSkin[%i] ) - { - %selId = %i; - break; - } - } - else if ( %skin $= GMW_SkinPopup.getTextById( %i ) ) - { - %selId = %i; - break; - } - } - if ( %selId == -1 ) - %selId = 0; - GMW_SkinPopup.setSelected( %selId ); - GMW_SkinPopup.onSelect( %selId, GMW_SkinPopup.getTextById( %selId ) ); - - // Select the voice: - %voice = getField( $pref::Player[%id], 3 ); - %voiceId = getSubStr( %voice, strlen( %voice ) -1, 1000 ) - 1; - GMW_VoicePopup.setSelected( %voiceId ); - GMW_VoicePopup.voiceIndex = 0; - - GMW_DeleteWarriorBtn.setActive( $pref::Player::Count > 1 && %id != GM_WarriorPane.warriorIndex ); -} - -//------------------------------------------------------------------------------ -function GMW_RaceGenderPopup::fillList( %this ) -{ - if ( %this.size() ) - return; - - %this.add( "Human Male", 0 ); - %this.add( "Human Female", 1 ); - %this.add( "Bioderm", 2 ); - %this.add( "Draakan Type A", 3 ); - %this.add( "Draakan Type B", 4 ); - %this.add( "Draakan Type C", 5 ); - %this.add( "Criollos", 6 ); -} - -//------------------------------------------------------------------------------ -function GMW_RaceGenderPopup::onSelect( %this, %id, %text ) -{ - // Update the player pref: - $pref::Player[$pref::Player::Current] = setField( $pref::Player[$pref::Player::Current], 1, %this.getText() ); - - // Fill the skin list: - %prevSkin = GMW_SkinPopup.getText(); - GMW_SkinPopup.fillList( %id ); - %selId = GMW_SkinPopup.findText( %prevSkin ); - if ( %selId == -1 ) - %selId = 0; - GMW_SkinPopup.setSelected( %selId ); - GMW_SkinPopup.onSelect( %selId, GMW_SkinPopup.getTextById( %selId ) ); - - // Fill the voice list: - %prevVoice = GMW_VoicePopup.getText(); - GMW_VoicePopup.fillList( %id ); - %selId = GMW_VoicePopup.findText( %prevVoice ); - if ( %selId == -1 ) - %selId = 0; - - GMW_VoicePopup.setSelected( %selId ); - GMW_VoicePopup.onSelect( %selId, "" ); -} - -//------------------------------------------------------------------------------ -function GMW_SkinPrefPopup::fillList( %this ) -{ - if ( %this.size() ) - return; - - %this.add( "Dynamix Skins", 0 ); - %this.add( "Custom Skins", 1 ); -} - -//------------------------------------------------------------------------------ -function GMW_SkinPrefPopup::onSelect( %this, %id, %text ) -{ - %curSkin = GMW_SkinPopup.getText(); - GMW_SkinPopup.fillList( GMW_RaceGenderPopup.getSelected() ); - %selId = GMW_SkinPopup.findText( %curSkin ); - if ( %selId == -1 ) - %selId = 0; - - if ( GMW_SkinPopup.size() ) - { - GMW_SkinPopup.setSelected( %selId ); - GMW_SkinPopup.onSelect( %selId, GMW_SkinPopup.getTextById( %selId ) ); - } -} - -//------------------------------------------------------------------------------ -$SkinCount = 0; -$Skin[$SkinCount, name] = "Blood Eagle"; -$Skin[$SkinCount, code] = "beagle"; -$SkinCount++; -$Skin[$SkinCount, name] = "Diamond Sword"; -$Skin[$SkinCount, code] = "dsword"; -$SkinCount++; -$Skin[$SkinCount, name] = "Starwolf"; -$Skin[$SkinCount, code] = "swolf"; -$SkinCount++; -$Skin[$SkinCount, name] = "Phoenix"; -$Skin[$SkinCount, code] = "cotp"; -$SkinCount++; -$Skin[$SkinCount, name] = "Storm"; -$Skin[$SkinCount, code] = "base"; -$SkinCount++; -$Skin[$SkinCount, name] = "Inferno"; -$Skin[$SkinCount, code] = "baseb"; -$SkinCount++; -$Skin[$SkinCount, name] = "Horde"; -$Skin[$SkinCount, code] = "horde"; -$SkinCount++; - -//------------------------------------------------------------------------------ -function isDynamixSkin( %skin ) -{ - for ( %i = 0; %i < $SkinCount; %i++ ) - { - if ( %skin $= $Skin[%i, code] ) - return( true ); - } - - return( false ); -} - -//------------------------------------------------------------------------------ -function GMW_SkinPopup::fillList( %this, %raceGender ) -{ - for ( %i = 0; %i < %this.size(); %i++ ) - %this.realSkin[%i] = ""; - - - %this.clear(); - %path = "textures/skins/"; - switch ( %raceGender ) - { - case 0: // Human Male - %pattern = ".lmale.png"; - case 1: // Human Female - %pattern = ".lfemale.png"; - case 2: // Bioderm - %pattern = ".lbioderm.png"; - case 3 or 4 or 5 or 6: //Draakan & Criollos - %pattern = ".lbioderm.png"; - } - - %customSkins = GMW_SkinPrefPopup.getSelected(); - %count = 0; - for ( %file = findFirstFile( %path @ "*" @ %pattern ); %file !$= ""; %file = findNextFile( %path @ "*" @ %pattern ) ) - { - %skin = getSubStr( %file, strlen( %path ), strlen( %file ) - strlen( %path ) - strlen( %pattern ) ); // strip off the path and postfix - // Make sure this is not a bot skin: - if ( %skin !$= "basebot" && %skin !$= "basebbot" ) - { - // See if this skin has an alias: - %baseSkin = false; - for ( %i = 0; %i < $SkinCount; %i++ ) - { - if ( %skin $= $Skin[%i, code] ) - { - %baseSkin = true; - %skin = $Skin[%i, name]; - break; - } - } - - if ( %customSkins != %baseSkin && !%loaded[%skin] ) //Avoid Duplicate skins cluttering up your selection ^.^ - { - if ( %baseSkin ) - %this.realSkin[%count] = $Skin[%i, code]; - %this.add( %skin, %count ); - %loaded[%skin] = true; - %count++; - } - } - } - - %this.sort( true ); -} - -//------------------------------------------------------------------------------ -function GMW_SkinPopup::onSelect( %this, %id, %text ) -{ - // Update the player pref: - if ( %this.realSkin[%id] !$= "" ) - $pref::Player[$pref::Player::Current] = setField( $pref::Player[$pref::Player::Current], 2, %this.realSkin[%id] ); - else - $pref::Player[$pref::Player::Current] = setField( $pref::Player[$pref::Player::Current], 2, %text ); - - // Update the player model: - GMW_PlayerModel.update(); -} - -//------------------------------------------------------------------------------ -// TRANSLATE these voice set display names: -$MaleVoiceCount = 0; -$MaleVoiceName[$MaleVoiceCount] = "Hero"; -$MaleVoiceCount++; -$MaleVoiceName[$MaleVoiceCount] = "Iceman"; -$MaleVoiceCount++; -$MaleVoiceName[$MaleVoiceCount] = "Rogue"; -$MaleVoiceCount++; -$MaleVoiceName[$MaleVoiceCount] = "Hardcase"; -$MaleVoiceCount++; -$MaleVoiceName[$MaleVoiceCount] = "Psycho"; -$MaleVoiceCount++; - -$FemaleVoiceCount = 0; -$FemaleVoiceName[$FemaleVoiceCount] = "Heroine"; -$FemaleVoiceCount++; -$FemaleVoiceName[$FemaleVoiceCount] = "Professional"; -$FemaleVoiceCount++; -$FemaleVoiceName[$FemaleVoiceCount] = "Cadet"; -$FemaleVoiceCount++; -$FemaleVoiceName[$FemaleVoiceCount] = "Veteran"; -$FemaleVoiceCount++; -$FemaleVoiceName[$FemaleVoiceCount] = "Amazon"; -$FemaleVoiceCount++; - -$DermVoiceCount = 0; -$DermVoiceName[$DermVoiceCount] = "Warrior"; -$DermVoiceCount++; -$DermVoiceName[$DermVoiceCount] = "Monster"; -$DermVoiceCount++; -$DermVoiceName[$DermVoiceCount] = "Predator"; -$DermVoiceCount++; - -//------------------------------------------------------------------------------ -function GMW_VoicePopup::fillList( %this, %raceGender ) -{ - %this.clear(); - - switch ( %raceGender ) - { - case 0: // Human Male - for ( %i = 0; %i < $MaleVoiceCount; %i++ ) - %this.add( $MaleVoiceName[%i], %i ); - - case 1: // Human Female - for ( %i = 0; %i < $FemaleVoiceCount; %i++ ) - %this.add( $FemaleVoiceName[%i], %i ); - - case 2: // Bioderm - for ( %i = 0; %i < $DermVoiceCount; %i++ ) - %this.add( $DermVoiceName[%i], %i ); - - case 3: // Draakan Type A - for ( %i = 0; %i < $DermVoiceCount; %i++ ) - %this.add( $DermVoiceName[%i], %i ); - - case 4: // Draakan Type B - for ( %i = 0; %i < $DermVoiceCount; %i++ ) - %this.add( $DermVoiceName[%i], %i ); - - case 5: // Draakan Type C - for ( %i = 0; %i < $DermVoiceCount; %i++ ) - %this.add( $DermVoiceName[%i], %i ); - - case 6: // Criollos - for ( %i = 0; %i < $DermVoiceCount; %i++ ) - %this.add( $DermVoiceName[%i], %i ); - } -} - -//------------------------------------------------------------------------------ -function GMW_VoicePopup::onSelect( %this, %id, %text ) -{ - // Update the player pref: - switch ( GMW_RaceGenderPopup.getSelected() ) - { - case 0: %base = "Male"; - case 1: %base = "Fem"; - case 2: %base = "Derm"; - case 3: %base = "Derm"; - case 4: %base = "Derm"; - case 5: %base = "Derm"; - case 6: %base = "Derm"; - } - - $pref::Player[$pref::Player::Current] = setField( $pref::Player[$pref::Player::Current], 3, %base @ ( %id + 1 ) ); - - %this.voiceIndex = 0; -} - -//------------------------------------------------------------------------------ -function GMW_VoicePitchSlider::setPitch(%this) -{ -} - -function GMW_VoicePopup::test( %this ) -{ - switch ( %this.voiceIndex ) - { - case 0: %file = "gbl.hi"; - case 1: %file = "gbl.brag"; - case 2: %file = "gbl.woohoo"; - case 3: %file = "gbl.rock"; - case 4: %file = "gbl.obnoxious"; - case 5: %file = "gbl.shazbot"; - } - - switch ( GMW_RaceGenderPopup.getSelected() ) - { - case 0: %base = "Male"; - case 1: %base = "Fem"; - case 2: %base = "Derm"; - case 3: %base = "Derm"; - case 4: %base = "Derm"; - case 5: %base = "Derm"; - case 6: %base = "Derm"; - } - - GMW_VoiceTestBtn.setActive( false ); - %voiceId = %this.getSelected() + 1; - %wav = "voice/" @ %base @ %voiceId @ "/" @ %file @ ".wav"; - %handle = alxCreateSource( AudioGui, %wav ); - - //pitch the voice - //%pitchSliderVal = GMW_VoicePitchSlider.getValue(); - //%pitch = getValidVoicePitch(%voiceId, %pitchSliderVal); - //if (%pitch != 1.0) - // alxSourcef(%handle, "AL_PITCH", %pitch); - - alxPlay( %handle ); - - %delay = alxGetWaveLen( %wav ); - schedule( %delay, 0, "restoreVoiceTestButton" ); - - if ( %this.voiceIndex == 5 ) - %this.voiceIndex = 0; - else - %this.voiceIndex++; -} - -//------------------------------------------------------------------------------ -function restoreVoiceTestButton() -{ - GMW_VoiceTestBtn.setActive( true ); -} - -//------------------------------------------------------------------------------ -function NewWarriorDlg::createPlayer( %this ) -{ - %name = stripTrailingSpaces( NW_NameEdit.getValue() ); - $pref::Player[$pref::Player::Count] = %name @ "\tHuman Male\tbeagle\tMale1"; - $pref::Player::Current = $pref::Player::Count; - $pref::Player::Count++; - Canvas.popDialog( NewWarriorDlg ); - GM_WarriorPane.onActivate(); // Refresh the warrior gui -} - -//------------------------------------------------------------------------------ -function NW_NameEdit::checkValidPlayerName( %this ) -{ - %name = %this.getValue(); - %test = strToPlayerName( %name ); - if ( %name !$= %test ) - %this.setValue( %test ); - - NW_DoneBtn.setActive( strlen( stripTrailingSpaces( %test ) ) > 2 ); -} - -//------------------------------------------------------------------------------ -function NW_NameEdit::processEnter( %this ) -{ - %this.checkValidPlayerName(); - if ( NW_DoneBtn.isActive() ) - NewWarriorDlg.createPlayer(); -} +//------------------------------------------------------------------------------ +// +// GameGui.cs +// +//------------------------------------------------------------------------------ + +// z0dd - ZOD: Execute the mission and game type skip lists so that +// arrays are put into memory for function buildMissionList. +exec("prefs/MissionSkip.cs", true); +exec("prefs/GameTypeSkip.cs", true); + +//------------------------------------------------------------------------------ +function LaunchGame( %pane ) +{ + if ( %pane !$= "" ) + GameGui.pane = %pane; + + LaunchTabView.viewTab( "GAME", GameGui, 0 ); +} + +//------------------------------------------------------------------------------ +function GameGui::onWake( %this ) +{ + Canvas.pushDialog( LaunchToolbarDlg ); + + if ( $PlayingOnline ) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + GM_Frame.setTitle( "GAME" ); + else + GM_Frame.setTitle( "LAN GAME" ); + + // This is essentially an "isInitialized" flag... + if ( GM_TabView.tabCount() == 0 ) + { + // --------------------------------------------------- + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + GM_TabView.addTab( 1, "JOIN" ); + GM_TabView.addTab( 2, "HOST" ); + GM_TabView.addTab( 3, "WARRIOR SETUP", 1 ); + queryMasterGameTypes(); + // --------------------------------------------------- + } + + switch$ ( %this.pane ) + { + case "Join": + GM_TabView.setSelected( 1 ); + case "Host": + GM_TabView.setSelected( 2 ); + default: // "Warrior" + GM_TabView.setSelected( 3 ); + } +} + +//------------------------------------------------------------------------------ +function GameGui::onSleep( %this ) +{ + %ctrl = "GM_" @ %this.pane @ "Pane"; + if ( isObject( %ctrl ) ) + %ctrl.onDeactivate(); + +// if( isObject( $dummySeq ) ) +// { +// $dummySeq.delete(); +// } + + Canvas.popDialog(LaunchToolbarDlg); +} + +//------------------------------------------------------------------------------ +function GameGui::setKey( %this, %key ) +{ + // To avoid console error +} + +//------------------------------------------------------------------------------ +function GameGui::onClose( %this, %key ) +{ + // To avoid console error +} + +//------------------------------------------------------------------------------ +function GM_TabView::onAdd( %this ) +{ + %this.addSet( 1, "gui/shll_horztabbuttonB", "5 5 5", "50 50 0", "5 5 5" ); +} + +//------------------------------------------------------------------------------ +function GM_TabView::onSelect( %this, %id, %text ) +{ + GM_JoinPane.setVisible( %id == 1 ); + GM_HostPane.setVisible( %id == 2 ); + GM_WarriorPane.setVisible( %id == 3 ); + GM_TabFrame.setAltColor( %this.getTabSet( %id ) != 0 ); + + %ctrl = "GM_" @ GameGui.pane @ "Pane"; + if ( isObject( %ctrl ) ) + %ctrl.onDeactivate(); + + switch ( %id ) + { + case 1: // Join + GM_JoinPane.onActivate(); + case 2: // Host + GM_HostPane.onActivate(); + case 3: // Warrior Setup + GM_WarriorPane.onActivate(); + } +} + +//------------------------------------------------------------------------------ +// Join Game pane: +//------------------------------------------------------------------------------ +function GM_JoinPane::onActivate( %this ) +{ + GameGui.pane = "Join"; + + if ( %this.onceOnly $= "" ) + { + GM_VersionText.setText( "Version" SPC getT2VersionNumber() ); + GMJ_StopBtn.setActive( false ); + + %this.onceOnly = 1; + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + GMJ_Browser.lastQuery = $PlayingOnline ? "Master" : "LanServers"; + GMJ_Browser.runQuery(); + } + + if ( isObject( BrowserMap ) ) + { + BrowserMap.pop(); + BrowserMap.delete(); + } + new ActionMap( BrowserMap ); + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + BrowserMap.bindCmd( keyboard, insert, "GMJ_Browser.insertIPAddress();", "" ); + BrowserMap.bindCmd( keyboard, "ctrl f", "Canvas.pushDialog( FindServerDlg );", "" ); + BrowserMap.bindCmd( keyboard, F3, "GMJ_Browser.findNextServer();", "" ); + BrowserMap.push(); + + GM_VersionText.setVisible( true ); // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + + if ( $pref::ServerBrowser::InfoWindowOpen ) + Canvas.pushDialog( ServerInfoDlg ); +} + +//------------------------------------------------------------------------------ +function GM_JoinPane::onDeactivate( %this ) +{ + if ( isObject( BrowserMap ) ) + { + BrowserMap.pop(); + BrowserMap.delete(); + } + + GM_VersionText.setVisible( false ); + + $pref::ServerBrowser::InfoWindowOpen = GMJ_Browser.infoWindowOpen; + if ( GMJ_Browser.infoWindowOpen ) + Canvas.popDialog( ServerInfoDlg ); +} + +//------------------------------------------------------------------------------ +$BrowserColumnCount = 0; +$BrowserColumnName[0] = "Server Name"; +$BrowserColumnRange[0] = "25 300"; +$BrowserColumnCount++; +$BrowserColumnName[1] = "Status"; +$BrowserColumnRange[1] = "25 75"; +$BrowserColumnCount++; +$BrowserColumnName[2] = "Favorite"; +$BrowserColumnRange[2] = "25 75"; +$BrowserColumnCount++; +$BrowserColumnName[3] = "Ping"; +$BrowserColumnRange[3] = "25 120"; +$BrowserColumnCount++; +$BrowserColumnName[4] = "Game Type"; +$BrowserColumnRange[4] = "25 200"; +$BrowserColumnCount++; +$BrowserColumnName[5] = "Mission Name"; +$BrowserColumnRange[5] = "25 300"; +$BrowserColumnCount++; +// --------------------------------------------------- +// z0dd - ZOD, 9/29/02. Removed T2 demo code from here +$BrowserColumnName[6] = "Rules Set"; +$BrowserColumnRange[6] = "25 300"; +$BrowserColumnCount++; +// --------------------------------------------------- +$BrowserColumnName[7] = "# Players (Bots)"; +$BrowserColumnRange[7] = "25 150"; +$BrowserColumnCount++; +$BrowserColumnName[8] = "CPU"; +$BrowserColumnRange[8] = "25 120"; +$BrowserColumnCount++; +$BrowserColumnName[9] = "IP Address"; +$BrowserColumnRange[9] = "25 200"; +$BrowserColumnCount++; +// --------------------------------------------------- +// z0dd - ZOD, 9/29/02. Removed T2 demo code from here +$BrowserColumnName[10] = "Version"; +$BrowserColumnRange[10] = "25 200"; +$BrowserColumnCount++; +// --------------------------------------------------- +$BrowserColumnName[11] = "Visibility"; +$BrowserColumnRange[11] = "25 120"; +$BrowserColumnCount++; + +//------------------------------------------------------------------------------ +function GMJ_Browser::onAdd( %this ) +{ + // Add the Server Browser columns based on the prefs: + for ( %i = 0; %i < $BrowserColumnCount; %i++ ) + { + %key = firstWord( $pref::ServerBrowser::Column[%i] ); + if ( $BrowserColumnName[%key] !$= "" && $BrowserColumnRange[%key] !$= "" ) + { + %width = getWord( $pref::ServerBrowser::Column[%i], 1 ); + %this.addColumn( %key, $BrowserColumnName[%key], %width, firstWord( $BrowserColumnRange[%key] ), getWord( $BrowserColumnRange[%key], 1 ) ); + } + } + %this.setSortColumn( $pref::ServerBrowser::SortColumnKey ); + %this.setSortIncreasing( $pref::ServerBrowser::SortInc ); +} + +//------------------------------------------------------------------------------ +function updateServerBrowser() +{ + GMJ_Browser.sort(); + if ( GMJ_Browser.infoWindowOpen ) + ServerInfoDlg.update(); +} + +//------------------------------------------------------------------------------ +function updateServerBrowserStatus( %text, %percentage ) +{ + GMJ_StatusText.setValue( %text ); + if ( %percentage >= 0 && %percentage <= 1 ) + { + GMJ_ProgressBar.setValue( %percentage ); + if ( %percentage == 0 ) // Query is over. + GMJ_StopBtn.setActive( false ); + } +} + +//------------------------------------------------------------------------------ +function GMJ_Browser::runQuery( %this ) +{ + GMJ_ProgressBar.setValue( 0 ); + $JoinGameAddress = ""; + GMJ_JoinBtn.setActive( false ); + GMJ_RefreshServerBtn.setActive( false ); + %this.clearList(); + + // Clear the Server Info dialog: + SI_InfoWindow.setText( "No server selected." ); + SI_ContentWindow.setText( "" ); + + if ( %this.lastQuery $= "LanServers" ) + { + GMJ_StatusText.setValue( "Querying LAN servers..." ); + GMJ_FilterBtn.setActive( false ); + GMJ_FilterBtn.setVisible( false ); + GMJ_FilterText.setText( "LAN Servers" ); + queryLanServers( $JoinGamePort ); + GMJ_StopBtn.setActive( true ); + } + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + else + { + GMJ_FilterBtn.setActive( true ); + GMJ_FilterBtn.setVisible( true ); + + if ( $pref::ServerBrowser::activeFilter == 0 ) + { + GMJ_StatusText.setValue( "Querying the master server..." ); + GMJ_FilterText.setText( "All servers" ); + queryMasterServer( $JoinGamePort ); + GMJ_StopBtn.setActive( true ); + } + else if ( $pref::ServerBrowser::activeFilter == 1 ) + { + // Buddy list query: + GMJ_StatusText.setValue( "Fetching buddy list..." ); + GMJ_FilterText.setText( "Buddies" ); + %this.key = LaunchGui.key++; + DatabaseQueryArray( 5, 0, "", %this, %this.key ); + } + else if ( $pref::ServerBrowser::activeFilter == 2 ) + { + // Favorites only: + GMJ_FilterText.setText( "Favorites" ); + if ( $pref::ServerBrowser::FavoriteCount <= 0 || $pref::ServerBrowser::Favorite[0] $= "" ) + { + GMJ_StatusText.setValue( "No favorites found." ); + MessageBoxOK( "INVALID FILTER", "You haven't marked any servers as favorites. Click the Favorites column to mark a server as a favorite." ); + } + else + { + GMJ_StatusText.setValue( "Querying favorites..." ); + queryFavoriteServers(); + GMJ_StopBtn.setActive( true ); + } + } + else + { + GMJ_StatusText.setValue( "Querying the master server..." ); + %filterIndex = $pref::ServerBrowser::activeFilter - 3; + if ( $pref::ServerBrowser::Filter[%filterIndex] !$= "" ) + { + %filter = $pref::ServerBrowser::Filter[%filterIndex]; + GMJ_FilterText.setText( getField( %filter, 0 ) ); + %rulesSet = getField( %filter, 1 ); + if ( %rulesSet $= "" ) + %rulesSet = "any"; + %missionType = getField( %filter, 2 ); + if ( %missionType $= "" ) + %missionType = "any"; + %maxPlayers = getField( %filter, 4 ); + if ( %maxPlayers $= "" ) + %maxPlayers = 255; + %maxBots = getField( %filter, 7 ); + if ( %maxBots $= "" ) + %maxBots = 16; + %regionMask = getField( %filter, 5 ); + if ( %regionMask $= "" ) + %regionMask = 4294967295; + + queryMasterServer( + $JoinGamePort, + 0, // Flags + %rulesSet, // Rules Set + %missionType, // Mission Type + getField( %filter, 3 ), // Min Players + %maxPlayers, // Max Players + %maxBots, // Max Bots + %regionMask, // Region Mask + getField( %filter, 6 ), // Max Ping + getField( %filter, 8 ), // Min CPU Speed + getField( %filter, 9 ) ); // Filter flags + GMJ_StopBtn.setActive( true ); + } + else + { + // Filter is invalid, so fall back to the default: + $pref::ServerBrowser::activeFilter = 0; + GMJ_FilterText.setText( "All servers" ); + queryMasterServer( $JoinGamePort ); + GMJ_StopBtn.setActive( true ); + } + } + } +} + +//------------------------------------------------------------------------------ +function GMJ_Browser::onDatabaseQueryResult( %this, %status, %resultString, %key ) +{ + if ( %this.key != %key ) + return; + + if ( getField( %resultString, 0 ) <= 0 ) + { + GMJ_StatusText.setValue( "No buddies found." ); + MessageBoxOK( "INVALID FILTER", "You have no buddies in your buddy list!" ); + } + else // Prepare for the incoming buddy list: + %this.buddyList = ""; +} + +//------------------------------------------------------------------------------ +function GMJ_Browser::onDatabaseRow( %this, %row, %isLastRow, %key ) +{ + if ( %this.key != %key ) + return; + + %buddyName = getField( %row, 0 ); + %buddyGuid = getField( %row, 3 ); + echo( "Got buddy: \c9\"" @ %buddyName @ "\": " @ %buddyGuid ); + %this.buddyList = %this.buddyList $= "" ? %buddyGuid : %this.buddyList TAB %buddyGuid; + + if ( %isLastRow ) + { + GMJ_StatusText.setValue( "Querying the master server..." ); + queryMasterServer( + $JoinGamePort, // Port + 0, // Flags + "Any", // Rules Set + "Any", // Mission Type + 0, // Min Players + 255, // Max Players + 16, // Max Bots + 0xFFFFFFFF, // Region Mask + 0, // Max Ping + 0, // Min CPU Speed + 0, // Filter flags + %this.buddyList ); + GMJ_StopBtn.setActive( true ); + %this.buddyList = ""; + } +} + +//------------------------------------------------------------------------------ +function GMJ_Browser::onSelect( %this, %address ) +{ + GMJ_JoinBtn.setActive( true ); + if ( !isServerQueryActive() ) + GMJ_RefreshServerBtn.setActive( true ); + $JoinGamePassword = ""; + $JoinGameAddress = %address; + + if ( %this.infoWindowOpen ) + ServerInfoDlg.update(); +} + +//------------------------------------------------------------------------------ +function GMJ_Browser::refreshSelectedServer( %this ) +{ + querySingleServer( $JoinGameAddress ); + if ( %this.infoWindowOpen ) + ServerInfoDlg.update(); +} + +//------------------------------------------------------------------------------ +function GMJ_Browser::onSetSortKey( %this, %sortKey, %isIncreasing ) +{ + $pref::ServerBrowser::SortColumnKey = %sortKey; + $pref::ServerBrowser::SortInc = %isIncreasing; +} + +//------------------------------------------------------------------------------ +function GMJ_Browser::onColumnResize( %this, %column, %newSize, %key ) +{ + $pref::ServerBrowser::Column[%column] = %key SPC %newSize; +} + +//------------------------------------------------------------------------------ +function GMJ_Browser::onColumnRepositioned( %this, %oldColumn, %newColumn ) +{ + // Puke em all... + %count = %this.getNumColumns(); + for ( %col = 0; %col < %count; %col++ ) + $pref::ServerBrowser::Column[%col] = %this.getColumnKey( %col ) SPC %this.getColumnWidth( %col ); +} + +//------------------------------------------------------------------------------ +function GMJ_Browser::addFavorite( %this, %name, %address ) +{ + //error( "** addFavorite( \"" @ %name @ "\", " @ %address @ " ) **" ); + $pref::ServerBrowser::Favorite[$pref::ServerBrowser::FavoriteCount] = %name TAB %address; + $pref::ServerBrowser::FavoriteCount++; +} + +//------------------------------------------------------------------------------ +function GMJ_Browser::removeFavorite( %this, %address ) +{ + //error( "** removeFavorite( " @ %address @ " ) **" ); + %foundIt = false; + for ( %i = 0; %i < $pref::ServerBrowser::FavoriteCount; %i++ ) + { + if ( !%foundIt ) + { + if ( getField( $pref::ServerBrowser::Favorite[%i], 1 ) $= %address ) + %foundIt = true; + } + + if ( %foundIt ) + $pref::ServerBrowser::Favorite[%i] = $pref::ServerBrowser::Favorite[%i + 1]; + } + + if ( %foundIt ) + $pref::ServerBrowser::FavoriteCount--; +} + +//------------------------------------------------------------------------------ +function GMJ_Browser::insertIPAddress( %this ) +{ + if ( isServerQueryActive() ) + { + BrowserMap.pop(); + MessageBoxOK( "ERROR", "Can't insert addresses while a query is running!", "BrowserMap.push();" ); + alxPlay( InputDeniedSound, 0, 0, 0 ); + return; + } + + IPEntry.setText( "IP:" ); + Canvas.pushDialog( EnterIPDlg ); +} + +//------------------------------------------------------------------------------ +function EnterIPDlg::onDone( %this ) +{ + Canvas.popDialog( EnterIPDlg ); + %address = IPEntry.getValue(); + if ( getSubStr( %address, 0, 3 ) !$= "IP:" ) + %address = "IP:" @ %address; + if ( strpos( %address, ":", 3 ) == -1 ) + %address = %address @ ":28000"; + + echo( "Starting ping to server " @ %address @ "..." ); + pushServerAddress( %address ); + GMJ_Browser.selectRowByAddress( %address, true ); +} + +//------------------------------------------------------------------------------ +function FindServerDlg::onWake( %this ) +{ + FS_SearchPattern.validate(); + FS_SearchPattern.selectAll(); +} + +//------------------------------------------------------------------------------ +function FindServerDlg::onGo( %this ) +{ + %pattern = FS_SearchPattern.getValue(); + if ( %pattern !$= "" ) + { + Canvas.popDialog( FindServerDlg ); + if ( !GMJ_Browser.findServer( %pattern ) ) + MessageBoxOK( "NOT FOUND", "No servers with \"" @ %pattern @ "\" in their name were found." ); + } + else + alxPlay( InputDeniedSound, 0, 0, 0 ); +} + +//------------------------------------------------------------------------------ +function FS_SearchPattern::validate( %this ) +{ + FS_GoBtn.setActive( %this.getValue() !$= "" ); +} + +//------------------------------------------------------------------------------ +function ServerInfoDlg::onAdd( %this ) +{ + %this.headerStyle = ""; +} + +//------------------------------------------------------------------------------ +function ServerInfoDlg::onWake( %this ) +{ + GMJ_Browser.infoWindowOpen = true; + + // Get the position and size from the prefs: + %res = getResolution(); + %resW = firstWord( %res ); + %resH = getWord( %res, 1 ); + %w = firstWord( $pref::ServerBrowser::InfoWindowExtent ); + if ( %w > %resW ) + %w = %resW; + %h = getWord( $pref::ServerBrowser::InfoWindowExtent, 1 ); + if ( %h > %resH ) + %h = %resH; + %x = firstWord( $pref::ServerBrowser::InfoWindowPos ); + if ( %x > %resW - %w ) + %x = %resW - %w; + %y = getWord( $pref::ServerBrowser::InfoWindowPos, 1 ); + if ( %y > %resH - %h ) + %y = %resH - %h; + SI_Window.resize( %x, %y, %w, %h ); + + GMJ_InfoBtn.setActive( false ); + SI_RefreshBtn.setActive( false ); + %this.update(); +} + +//------------------------------------------------------------------------------ +function ServerInfoDlg::update( %this ) +{ + %status = GMJ_Browser.getServerStatus(); + if ( %status $= "invalid" ) + { + SI_InfoWindow.setText( "No server selected." ); + return; + } + + %info = GMJ_Browser.getServerInfoString(); + %infoText = "" @ %this.headerStyle @ "NAME:" TAB getRecord( %info, 0 ) + NL "" @ %this.headerStyle @ "ADDRESS:" TAB getRecord( %info, 1 ) @ ""; + + %refreshable = false; + if ( %status $= "responded" ) + { + %temp = getRecord( %info, 2 ); + if ( %temp !$= "" ) + %infoText = %infoText NL "" @ %this.headerStyle @ "RULES SET:" TAB %temp @ ""; + %temp = getRecord( %info, 3 ); + if ( %temp $= "" ) + %temp = "None"; + %infoText = %infoText NL "" @ %this.headerStyle @ "FLAGS:" TAB %temp @ ""; + %temp = getRecord( %info, 4 ); + if ( %temp !$= "" ) + %infoText = %infoText NL "" @ %this.headerStyle @ "GAME TYPE:" TAB %temp @ ""; + %temp = getRecord( %info, 5 ); + if ( %temp !$= "" ) + %infoText = %infoText NL "" @ %this.headerStyle @ "MAP NAME:" TAB %temp @ ""; + %temp = getRecords( %info, 6, 10 ); + if ( %temp !$= "" ) + %infoText = %infoText NL "" @ %this.headerStyle @ "SERVER INFO:" TAB %temp @ ""; + + // Fill in the content window: + %content = GMJ_Browser.getServerContentString(); + SI_ContentWindow.fill( %content ); + %refreshable = !isServerQueryActive(); + } + else + { + switch$ ( %status ) + { + case "new": + %temp = "Not queried yet."; + SI_ContentWindow.setText( "Not available." ); + case "querying": + %temp = "Querying..."; + SI_ContentWindow.setText( "Not available." ); + case "updating": + %temp = "Updating..."; + case "timedOut": + %temp = "Timed out."; + SI_ContentWindow.setText( "Not available." ); + %refreshable = !isServerQueryActive(); + } + %infoText = %infoText NL "" @ %this.headerStyle @ "STATUS: " TAB %temp; + } + + SI_InfoWindow.setText( %infoText ); + SI_InfoScroll.scrollToTop(); + SI_ContentScroll.scrollToTop(); + SI_RefreshBtn.setActive( %refreshable ); +} + +//------------------------------------------------------------------------------ +function SI_ContentWindow::fill( %this, %content ) +{ + if ( getRecordCount( %content ) == 1 ) + { + %this.setText( "" ); + return; + } + + %record = 0; + %teamCount = getRecord( %content, %record ); + %record++; + if ( %teamCount > 1 ) + { + %string = "" @ ServerInfoDlg.headerStyle @ "TEAMSSCORE"; + for ( %i = 0; %i < %teamCount; %i++ ) + { + %teamEntry = getRecord( %content, %record ); + %string = %string NL "" SPC getField( %teamEntry, 0 ) @ "" SPC getField( %teamEntry, 1 ); + %record++; + } + + %playerCount = getRecord( %content, %record ); + %record++; + %string = %string NL "\n" @ ServerInfoDlg.headerStyle @ "PLAYERSTEAMSCORE"; + for ( %i = 0; %i < %playerCount; %i++ ) + { + %playerEntry = getRecord( %content, %record ); + %string = %string NL "" SPC getField( %playerEntry, 0 ) @ "" + SPC getField( %playerEntry, 1 ) @ "" SPC getField( %playerEntry, 2 ) @ ""; + %record++; + } + } + else + { + %record++; + %playerCount = getRecord( %content, %record ); + %record++; + %string = "" @ ServerInfoDlg.headerStyle @ "PLAYERSSCORE"; + for ( %i = 0; %i < %playerCount; %i++ ) + { + %playerEntry = getRecord( %content, %record ); + %string = %string NL "" SPC getField( %playerEntry, 0 ) @ "" SPC getField( %playerEntry, 2 ); + %record++; + } + } + + %this.setText( %string ); +} + +//------------------------------------------------------------------------------ +function ServerInfoDlg::onSleep( %this ) +{ + GMJ_Browser.infoWindowOpen = false; + + // Save off the Server Info Window prefs: + $pref::ServerBrowser::InfoWindowPos = SI_Window.getPosition(); + $pref::ServerBrowser::InfoWindowExtent = SI_Window.getExtent(); + $pref::ServerBrowser::InfoWindowBarPos = getWord( SI_InfoScroll.getExtent(), 1 ); + + GMJ_InfoBtn.setActive( true ); +} + +//------------------------------------------------------------------------------ +function PasswordDlg::onWake( %this ) +{ + $JoinGamePassword = ""; +} + +//------------------------------------------------------------------------------ +function PasswordDlg::accept( %this ) +{ + Canvas.popDialog( PasswordDlg ); + JoinSelectedGame(); +} + +//------------------------------------------------------------------------------ +function JoinSelectedGame() +{ + $ServerInfo = GMJ_Browser.getServerInfoString(); + + JoinGame($JoinGameAddress); +} + +//------------------------------------------------------------------------------ +function JoinGame(%address) +{ + MessagePopup( "JOINING SERVER", "CONNECTING" ); + cancelServerQuery(); + echo("Joining Server " @ %address); + %playerPref = $pref::Player[$pref::Player::Current]; + %playerName = getField( %playerPref, 0 ); + %playerRaceGender = getField( %playerPref, 1 ); + error(%playerPref, 1); + %playerSkin = getField( %playerPref, 2 ); + %playerVoice = getField( %playerPref, 3 ); + %playerVoicePitch = getField( %playerPref, 4 ); + LoadingGui.gotLoadInfo = ""; + //Make sure the server is T2BOL. If not, join as a derm if we're Draakan or Creole + if (getField(GMJ_Browser.getServerInfoString(),2) !$= "T2BOL") + { + %race = getWord(%playerRaceGender,0); + if (%race $= "Draakan" || %race $= "Criollos" ) + %playerRaceGender = "Bioderm"; + } + connect( %address, $JoinGamePassword, %playerName, %playerRaceGender, %playerSkin, %playerVoice, %playerVoicePitch ); +} + +//------------------------------------------------------------------------------ +// Host Game pane: +//------------------------------------------------------------------------------ +function GM_HostPane::onActivate( %this ) +{ + GameGui.pane = "Host"; + + $HostGameType = $PlayingOnline ? "Online" : "LAN"; + + buildMissionTypePopup( GMH_MissionType ); + // --------------------------------------------------- + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + GMH_BotMinSlider.setValue( $Host::MinBotDifficulty ); + GMH_BotMaxSlider.setValue( $Host::MaxBotDifficulty ); + GMH_BotsEnabledTgl.setValue( $Host::BotsEnabled ); + GMH_BotsEnabledTgl.onAction(); + + //clamp and set the bot count slider + setBotCountSlider(); + // --------------------------------------------------- + + // Select the saved-off prefs: + if ( $Host::MissionType !$= "" ) + { + // Find the last selected type: + for ( %type = 0; %type < $HostTypeCount; %type++ ) + { + if ( $HostTypeName[%type] $= $Host::MissionType ) + break; + } + + if ( %type != $HostTypeCount ) + { + GMH_MissionType.setSelected( %type ); + GMH_MissionType.onSelect( %type, "" ); + + if ($Host::MissionType $= "RPG" || $Host::MissionType $= "SV") + { + GMH_BotsEnabledTgl.setValue(0); + GMH_BotsEnabledTgl.onAction(); + GMH_BotsEnabledTgl.setActive(0); + } + + if ( $Host::Map !$= "" ) + { + // Find the last selected mission: + for ( %index = 0; %index < $HostMissionCount[%type]; %index++ ) + { + if ( $HostMissionFile[$HostMission[%type, %index]] $= $Host::Map ) + break; + } + + if ( %index != $HostMissionCount[%type] ) + GMH_MissionList.setSelectedById( $HostMission[%type, %index] ); + } + } + } + else + { + GMH_MissionType.setSelected( 0 ); + GMH_MissionType.onSelect( 0, "" ); + } + + GMH_StartGameBtn.makeFirstResponder( 1 ); +} + +//------------------------------------------------------------------------------ +function GM_HostPane::onDeactivate( %this ) +{ +} + +//------------------------------------------------------------------------------ +function buildMissionTypePopup( %popup ) +{ + %popup.clear(); + for( %type = 0; %type < $HostTypeCount; %type++ ) + %popup.add( $HostTypeDisplayName[%type], %type ); + %popup.sort( true ); +} + +//------------------------------------------------------------------------------ +function getMissionTypeDisplayNames() +{ + %file = new FileObject(); + for ( %type = 0; %type < $HostTypeCount; %type++ ) + { + $HostTypeDisplayName[%type] = $HostTypeName[%type]; + if ( %file.openForRead( "scripts/" @ $HostTypeName[%type] @ "Game.cs" ) ) + { + while ( !%file.isEOF() ) + { + %line = %file.readLine(); + if ( getSubStr( %line, 0, 17 ) $= "// DisplayName = " ) + { + $HostTypeDisplayName[%type] = getSubStr( %line, 17, 1000 ); + break; + } + } + } + } + + %file.delete(); +} + +//------------------------------------------------------------------------------ +function buildMissionList() +{ + %search = "missions/*.mis"; + %ct = 0; + $HostTypeCount = 0; + $HostMissionCount = 0; + %fobject = new FileObject(); + for( %file = findFirstFile( %search ); %file !$= ""; %file = findNextFile( %search ) ) + { + %name = fileBase( %file ); // get the name + + // --------------------------------------------------------------------- + // z0dd - ZOD: + // If skip list file exists, make sure this mission isn't in skip list. + // If mission is on the skip list then remove it from rotation. + if(isFile("prefs/MissionSkip.cs")) + { + %found = 0; + for( %i = 0; $SkipMission::name[%i] !$= ""; %i++ ) { + if( $SkipMission::name[%i] $= %name ) + { + error("MISSION PULLED FROM ROTATION: " @ %name); + %found = 1; + break; + } + } + if(%found) + continue; + } + // --------------------------------------------------------------------- + + %idx = $HostMissionCount; + $HostMissionCount++; + $HostMissionFile[%idx] = %name; + $HostMissionName[%idx] = %name; + + if ( !%fobject.openForRead( %file ) ) + continue; + + %typeList = "None"; + while ( !%fobject.isEOF() ) + { + %line = %fobject.readLine(); + if ( getSubStr( %line, 0, 17 ) $= "// DisplayName = " ) + { + // Override the mission name: + $HostMissionName[%idx] = getSubStr( %line, 17, 1000 ); + } + else if ( getSubStr( %line, 0, 18 ) $= "// MissionTypes = " ) + { + %typeList = getSubStr( %line, 18, 1000 ); + break; + } + } + %fobject.close(); + + // Don't include single player missions: + if ( strstr( %typeList, "SinglePlayer" ) != -1 ) + continue; + + // Test to see if the mission is bot-enabled: + %navFile = "terrains/" @ %name @ ".nav"; + $BotEnabled[%idx] = isFile( %navFile ); + + for( %word = 0; ( %misType = getWord( %typeList, %word ) ) !$= ""; %word++ ) + { + //--------------------------------------------------------------------------------- + // z0dd - ZOD - Founder(founder@mechina.com): Append Tribe Practice to CTF missions + if(%misType $= "CTF") + %typeList = rtrim(%typeList) @ " PracticeCTF"; + + // z0dd - ZOD: If skip list file exists, make sure this mission type isn't in + // skip list. If mission type is on the skip list then remove it from rotation. + if(isFile("prefs/GameTypeSkip.cs")) + { + %found = 0; + for( %i = 0; $SkipType::name[%i] !$= ""; %i++ ) { + if( $SkipType::name[%i] $= %misType ) + { + error("GAME TYPE REMOVED: " @ %misType); + %found = 1; + break; + } + } + if(%found) + continue; + } + //--------------------------------------------------------------------------------- + for ( %i = 0; %i < $HostTypeCount; %i++ ) + if ( $HostTypeName[%i] $= %misType ) + break; + if ( %i == $HostTypeCount ) + { + $HostTypeCount++; + $HostTypeName[%i] = %misType; + $HostMissionCount[%i] = 0; + } + // add the mission to the type + %ct = $HostMissionCount[%i]; + $HostMission[%i, $HostMissionCount[%i]] = %idx; + $HostMissionCount[%i]++; + } + } + getMissionTypeDisplayNames(); + %fobject.delete(); +} + +// One time only function call: +buildMissionList(); + +///////////////////////////////////////////////////////////////////////////////////////////////////// +// z0dd - ZOD - Founder(founder@mechina.com): +// Functions to add and remove missions from $SkipMission::name (MissionSkip.cs). + +// commandToServer('AddMap', MapFilename); +function serverCmdAddMap(%client, %map) +{ + %map = detag(%map); + if(%client.isSuperAdmin) + AddMapToList(%map, %client); + else + messageClient(%client, 'MsgNotSuperAdmin', '\c2Only Super Admins can use this command.'); +} +// AddMapToList(MapFilename); +function AddMapToList(%map, %client) +{ + if(%map $="") + return; + + %found = 0; + for( %i = 0; $SkipMission::name[%i] !$= ""; %i++ ) { + if($SkipMission::name[%i] $= %map) { + %found = 1; + break; + } + } + if(%found) + { + error( "Mission " @ %map @ " allready exists in skip list!" ); + return; + } + if($MissionSkip::count $= "") + $MissionSkip::count = 0; + + $SkipMission::name[$MissionSkip::count] = %map; + $MissionSkip::count++; + + %val = 'removal from'; + writeMissionSkipList(%map, %val, %client); +} + +// commandToServer('RemoveMap', MapFilename); +function serverCmdRemoveMap(%client, %map) +{ + %map = detag(%map); + if(%client.isSuperAdmin) + RemoveMapFromList(%map, %client); + else + messageClient(%client, 'MsgNotSuperAdmin', '\c2Only Super Admins can use this command.'); +} + +// RemoveMapFromList(MapFilename); +function RemoveMapFromList(%map, %client) +{ + if(%map $="") + return; + + %count = 0; + for( %i = 0; %i < $MissionSkip::count; %i++ ) + { + if($SkipMission::name[%i] !$= %map) + { + %Temp[%count] = $SkipMission::name[%i]; + %count++; + } + } + for( %j = 0; %j < %count; %j++ ) + $SkipMission::name[%j] = %Temp[%j]; + + $MissionSkip::count = %count; + //$MissionSkip::count --; + + %val = 'restoration to'; + writeMissionSkipList(%map, %val, %client); +} + +function writeMissionSkipList(%name, %val, %client) +{ + %newfile = "prefs/MissionSkip.cs"; + if(isFile(%newfile)) + { + deleteFile(%newfile); + if(isFile("prefs/MissionSkip.cs.dso")) + deleteFile("prefs/MissionSkip.cs.dso"); + } + + %listfile = new fileObject(); + %listfile.openForWrite(%newfile); + %listfile.writeLine("// ------------------------- Mission Skip List -------------------------"); + %listfile.writeLine("// ----- Mission file names without file extension. Ex: BeggarsRun -----"); + %listfile.writeLine("// ------------ Missions on list are excluded from rotation ------------"); + %listfile.writeLine(""); + for( %k = 0; %k < $MissionSkip::count; %k++ ) { + %listfile.writeLine("$SkipMission::name[" @ %k @ "] = \"" @ $SkipMission::name[%k] @ "\";"); + } + %listfile.writeLine("$MissionSkip::count = " @ $MissionSkip::count @ ";"); + %listfile.close(); + %listfile.delete(); + + if(%client !$= "") + messageClient(%client, 'MsgAdmin', '\c3\"%1\"\c2 %2 mission rotation successful.', %name, %val); + + echo( "Mission " @ %name @ " " @ %val @ " mission rotation successful." ); +} + +///////////////////////////////////////////////////////////////////////////////////////////////////// +// z0dd - ZOD - Founder(founder@mechina.com): +// Functions to add and remove mission types from $SkipType::name (GameTypeSkip.cs). + +// commandToServer('AddType', Typename); +function serverCmdAddType(%client, %type) +{ + %type = detag(%type); + if(%client.isSuperAdmin) + AddTypeToList(%type, %client); + else + messageClient(%client, 'MsgNotSuperAdmin', '\c2Only Super Admins can use this command.'); +} + +// AddTypeToList(Typename); +function AddTypeToList(%type, %client) +{ + if(%type $="") + return; + + %found = 0; + for( %i = 0; $SkipType::name[%i] !$= ""; %i++ ) { + if($SkipType::name[%i] $= %type) { + %found = 1; + break; + } + } + if(%found) + { + error( "Game type " @ %type @ " allready exists in skip list!" ); + return; + } + if($TypeSkip::count $= "") + $TypeSkip::Count = 0; + + $SkipType::name[$TypeSkip::count] = %type; + $TypeSkip::count++; + + %val = 'removed'; + writeTypeSkipList(%type, %val, %client); +} + +// commandToServer('RemoveType', Typename); +function serverCmdRemoveType(%client, %type) +{ + %type = detag(%type); + if(%client.isSuperAdmin) + RemoveTypeFromList(%type, %client); + else + messageClient(%client, 'MsgNotSuperAdmin', '\c2Only Super Admins can use this command.'); +} + +// RemoveTypeFromList(Typename); +function RemoveTypeFromList(%type, %client) +{ + if(%type $="") + return; + + %count = 0; + for( %i = 0; %i < $TypeSkip::count; %i++ ) + { + if($SkipType::name[%i] !$= %type) + { + %Temp[%count] = $SkipType::name[%i]; + %count++; + } + } + for( %j = 0; %j < %count; %j++ ) + $SkipType::name[%j] = %Temp[%j]; + + $TypeSkip::count = %count; + //$TypeSkip::count --; + + %val = 'restored'; + writeTypeSkipList(%type, %val, %client); +} + +function writeTypeSkipList(%name, %val, %client) +{ + %newfile = "prefs/GameTypeSkip.cs"; + if(isFile(%newfile)) + { + deleteFile(%newfile); + if(isFile("prefs/GameTypeSkip.cs.dso")) + deleteFile("prefs/GameTypeSkip.cs.dso"); + } + %listfile = new fileObject(); + %listfile.openForWrite(%newfile); + %listfile.writeLine("// ------------------------- Game Type Skip List -------------------------"); + %listfile.writeLine("// ----------------------- Game type names. Ex: CnH ----------------------"); + %listfile.writeLine("// ------------ Game types on list are excluded from rotation ------------"); + %listfile.writeLine(""); + for( %k = 0; %k < $TypeSkip::count; %k++ ) { + %listfile.writeLine("$SkipType::name[" @ %k @ "] = \"" @ $SkipType::name[%k] @ "\";"); + } + %listfile.writeLine("$TypeSkip::count = " @ $TypeSkip::count @ ";"); + %listfile.close(); + %listfile.delete(); + + if(%client !$= "") + messageClient(%client, 'MsgAdmin', '\c2Game type \c3\"%1\"\c2 %2 successfully.', %name, %val); + + echo( "Game type " @ %name @ " " @ %val @ " successfully." ); +} + +//------------------------------------------------------------------------------ +function validateMissionAndType(%misName, %misType) +{ + for ( %mis = 0; %mis < $HostMissionCount; %mis++ ) + if( $HostMissionFile[%mis] $= %misName ) + break; + if ( %mis == $HostMissionCount ) + return false; + for ( %type = 0; %type < $HostTypeCount; %type++ ) + if ( $HostTypeName[%type] $= %misType ) + break; + if(%type == $hostTypeCount) + return false; + $Host::Map = $HostMissionFile[%mis]; + $Host::MissionType = $HostTypeName[%type]; + + return true; +} + +//------------------------------------------------------------------------------ +// This function returns the index of the next mission in the mission list. +//------------------------------------------------------------------------------ +function getNextMission( %misName, %misType ) +{ + // First find the index of the mission in the master list: + for ( %mis = 0; %mis < $HostMissionCount; %mis++ ) + if( $HostMissionFile[%mis] $= %misName ) + break; + + if ( %mis == $HostMissionCount ) + return ""; + + // Now find the index of the mission type: + for ( %type = 0; %type < $HostTypeCount; %type++ ) + if ( $HostTypeName[%type] $= %misType ) + break; + + if ( %type == $hostTypeCount ) + return ""; + + // Now find the mission's index in the mission-type specific sub-list: + for ( %i = 0; %i < $HostMissionCount[%type]; %i++ ) + if ( $HostMission[%type, %i] == %mis ) + break; + + // -------------------------------------------------------------------- + // z0dd - ZOD: Enable random mission rotation for current mission type. + if($Host::ClassicRandomMissions) + { + %i = mFloor(getRandom(0, ($HostMissionCount[%type] - 1))); + + // If its same as last map, go back 1 + if($HostMissionFile[$HostMission[%type, %i]] $= %misName) + %i--; + + // If its greater then or equal to count, set to zero + %i = %i >= $HostMissionCount[%type] ? 0 : %i; + } + else + { + // Go BACKWARDS, because the missions are in reverse alphabetical order: + if ( %i == 0 ) + %i = $HostMissionCount[%type] - 1; + else + %i--; + } + // -------------------------------------------------------------------- + + // If there are bots in the game, don't switch to any maps without + // a NAV file: + if ( $HostGameBotCount > 0 ) + { + for ( %j = 0; %j < $HostMissionCount[%type] - 1; %j++ ) + { + if ( $BotEnabled[$HostMission[%type, %i]] ) + break; + + // -------------------------------------------------------------------- + // z0dd - ZOD: Enable random mission rotation for current mission type. + if($Host::ClassicRandomMissions) + { + %i = mFloor(getRandom(0, ($HostMissionCount[%type] - 1))); + + // If its same as last map, go back 1 + if($HostMissionFile[$HostMission[%type, %i]] $= %misName) + %i--; + + // If its greater then or equal to count, set to zero + %i = %i >= $HostMissionCount[%type] ? 0 : %i; + } + else + { + if ( %i == 0 ) + %i = $HostMissionCount[%type] - 1; + else + %i--; + } + // -------------------------------------------------------------------- + } + } + + return $HostMission[%type, %i]; +} + +//------------------------------------------------------------------------------ +function GMH_MissionType::onSelect( %this, %id, %text ) +{ + // Fill the mission list: + GMH_MissionList.clear(); + %lastAdded = 0; + for ( %i = 0; %i < $HostMissionCount[%id];%i++ ) + { + %misId = $HostMission[%id,%i]; + GMH_MissionList.addRow( %misId, $HostMissionName[%misId] ); + %lastAdded = %misId; + } + GMH_MissionList.sort( 0 ); + + // Select the last mission added: + GMH_MissionList.setSelectedById( %lastAdded ); + $Host::MissionType = $HostTypeName[%id]; + + // --------------------------------------------------- + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + + // Disable all non bot-enabled maps if bots are enabled: + if ( GMH_BotsEnabledTgl.getValue() ) + GMH_BotsEnabledTgl.onAction(); + // --------------------------------------------------- + + // --------------------------------------------------- + // Disable the 'enable AI' button if "RPG" is selected.. + if (%text $= "Role Playing" || %text $= "Survival") //Or Survival.. + { + GMH_BotsEnabledTgl.setValue(0); + GMH_BotsEnabledTgl.onAction(); + GMH_BotsEnabledTgl.setActive(0); + } + else + { + GMH_BotsEnabledTgl.setValue($Host::BotsEnabled); + GMH_BotsEnabledTgl.onAction(); + GMH_BotsEnabledTgl.setActive(1); + } +} + +//------------------------------------------------------------------------------ +function GMH_MissionList::onSelect( %this, %id, %text ) +{ + if ( GMH_BotsEnabledTgl.getValue() ) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + GMH_StartGameBtn.setActive( $BotEnabled[%id] ); +} + +//------------------------------------------------------------------------------ +function tryToStartHostedGame() +{ + if ( GMH_BotsEnabledTgl.getValue() ) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + { + %selId = GMH_MissionList.getSelectedId(); + if ( !$BotEnabled[%selId] ) + return; + } + + StartHostedGame(); +} + +//------------------------------------------------------------------------------ +function StartHostedGame() +{ + %selId = GMH_MissionList.getSelectedId(); + %misFile = $HostMissionFile[%selId]; + + if ( $Host::BotsEnabled ) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + { + validateMaxPlayers(); + $HostGameBotCount = $Host::BotCount; + } + else + $HostGameBotCount = 0; + + $ServerName = $Host::GameName; + $Host::Map = %misFile; + + echo( "exporting server prefs..." ); + export( "$Host::*", "prefs/ServerPrefs.cs", false ); + + if ( $Host::Dedicated ) + { + MessageBoxYesNo( "WARNING", + "You are about to launch a dedicated server and quit Tribes 2. Do you want to continue?", + "tryToLaunchDedicatedServer(" @ $Host::PureServer @ ");" ); + return; + } + + //IRCClient::onJoinGame("", ""); + + MessagePopup( "STARTING SERVER", "Initializing..." ); + Canvas.repaint(); + + cancelServerQuery(); + setNetPort( $Host::Port ); + CreateServer( $Host::Map, $Host::MissionType ); + %playerPref = $pref::Player[$pref::Player::Current]; + %playerName = getField( %playerPref, 0 ); + %playerRaceGender = strReplace(getField( %playerPref, 1 ),"Type A","A"); + %playerSkin = getField( %playerPref, 2 ); + %playerVoice = getField( %playerPref, 3 ); + %playerVoicePitch = getField( %playerPref, 4 ); + localConnect( %playerName, %playerRaceGender, %playerSkin, %playerVoice, %playerVoicePitch ); + if(!$RecordDemo) + { + // demos are incompatible with local simulated net params + ServerConnection.setSimulatedNetParams($pref::Net::simPacketLoss, $pref::net::simPing * 0.5); + LocalClientConnection.setSimulatedNetParams($pref::Net::simPacketLoss, $pref::net::simPing * 0.5); + } +} + +//------------------------------------------------------------------------------ +function tryToLaunchDedicatedServer( %pure ) +{ + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + %numBots = $Host::BotsEnabled ? $Host::BotCount : 0; + if ( launchDedicatedServer( $Host::MissionType, $Host::Map, %numBots, %pure ) ) + quit(); + else + { + error( "Failed to launch the dedicated server." ); + schedule( 0, 0, MessageBoxOK, "FAILED", "Tribes 2 failed to launch the dedicated server." ); + } +} + +//------------------------------------------------------------------------------ +function GMH_BotsEnabledTgl::onAction( %this ) +{ + %count = GMH_MissionList.rowCount(); + if ( %this.getValue() ) + { + for ( %i = 0; %i < %count; %i++ ) + { + %id = GMH_MissionList.getRowId( %i ); + GMH_MissionList.setRowActive( %id, $BotEnabled[%id] ); + } + + GMH_EnableBotsGroup.setVisible(true); + %misId = GMH_MissionList.getSelectedId(); + GMH_StartGameBtn.setActive( $BotEnabled[%misId] ); + } + else + { + for ( %i = 0; %i < %count; %i++ ) + { + %id = GMH_MissionList.getRowId( %i ); + GMH_MissionList.setRowActive( %id, true ); + } + + GMH_EnableBotsGroup.setVisible( false ); + GMH_StartGameBtn.setActive( true ); + } +} + +//------------------------------------------------------------------------------ +function updateMinBotDifficulty() +{ + %min = GMH_BotMinSlider.getValue(); + $Host::MinBotDifficulty = %min; + if ( GMH_BotMaxSlider.getValue() < %min ) + GMH_BotMaxSlider.setValue( %min ); +} + +//------------------------------------------------------------------------------ +function updateMaxBotDifficulty() +{ + %max = GMH_BotMaxSlider.getValue(); + $Host::MaxBotDifficulty = %max; + if ( GMH_BotMinSlider.getValue() > %max ) + GMH_BotMinSlider.setValue( %max ); +} + +//------------------------------------------------------------------------------ +function GMH_BotsEnabledTgl::onAction( %this ) +{ + %count = GMH_MissionList.rowCount(); + if ( %this.getValue() ) + { + for ( %i = 0; %i < %count; %i++ ) + { + %id = GMH_MissionList.getRowId( %i ); + GMH_MissionList.setRowActive( %id, $BotEnabled[%id] ); + } + + GMH_EnableBotsGroup.setVisible(true); + %misId = GMH_MissionList.getSelectedId(); + GMH_StartGameBtn.setActive( $BotEnabled[%misId] ); + } + else + { + for ( %i = 0; %i < %count; %i++ ) + { + %id = GMH_MissionList.getRowId( %i ); + GMH_MissionList.setRowActive( %id, true ); + } + + GMH_EnableBotsGroup.setVisible(false); + GMH_StartGameBtn.setActive( true ); + } +} + +//------------------------------------------------------------------------------ +function validateMaxPlayers() +{ + %maxPlayers = GMH_MaxPlayersTE.getValue(); + if (%maxPlayers < 1) + %maxPlayers = 1; + + if (%maxPlayers > 64) + %maxPlayers = 64; + + //reset the value back into the TE + GMH_MaxPlayersTE.setValue(%maxPlayers); + + // --------------------------------------------------- + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + + //and make sure the bot sliders reflect the changes.. + setBotCountSlider(); + // --------------------------------------------------- +} + +function setBotCountSlider() +{ + %maxBots = 15; + if (%maxBots > $Host::MaxPlayers - 2) + %maxBots = $Host::MaxPlayers - 2; + if ($Host::BotCount > %maxBots + 1) + $Host::BotCount = %maxBots + 1; + + if (%maxBots <= 1) + %sliderValue = 0.0; + else + %sliderValue = ($Host::BotCount - 0.95) / %maxBots; + + GMH_MinCombatantSlider.setValue(%sliderValue); +} + +function setMinCombatants() +{ + %maxBots = 16; + if (%maxBots > $Host::MaxPlayers - 1) + %maxBots = $Host::MaxPlayers - 1; + if (%maxBots <= 0) + $Host::BotCount = 0; + else + $Host::BotCount = mFloor( GMH_MinCombatantSlider.getValue() * (%maxBots - 1)) + 1; + GMH_BotCountText.setValue( "(" @ $Host::BotCount @ ")" ); +} + +//------------------------------------------------------------------------------ +function AdvancedHostDlg::onWake( %this ) +{ + // Set all of the controls to the current pref states: + AH_HostPort.setText( $Host::Port ); + if ( $Host::HiVisibility ) + AH_HiVisibilityRdo.setValue( true ); + else + AH_HiFPSRdo.setValue( true ); + AH_DedicatedTgl.setValue( $Host::Dedicated ); + AH_DedicatedTgl.onAction(); + AH_TeamDamageTgl.setValue( $Host::TeamDamageOn ); + AH_TournamentTgl.setValue( $Host::TournamentMode ); + AH_AdminVoteTgl.setValue( $Host::allowAdminPlayerVotes ); + AH_AllowSmurfTgl.setValue( !$Host::NoSmurfs ); + AH_TimeLimit.setText( $Host::TimeLimit ); + AH_AdminPassword.setText( $Host::AdminPassword ); + AH_ServerInfo.setText( $Host::Info ); + AH_VotePassSlider.setValue( $Host::VotePassPercent ); + AH_VoteTimeSlider.setValue( $Host::VoteTime ); + AH_RespawnSlider.setValue( $Host::PlayerRespawnTimeout ); + AH_WarmupSlider.setValue( $Host::WarmupTime ); +} + +//------------------------------------------------------------------------------ +function AdvancedHostDlg::accept( %this ) +{ + // Apply all of the changes: + $Host::Port = AH_HostPort.getValue(); + $Host::HiVisibility = AH_HiVisibilityRdo.getValue(); + $Host::Dedicated = AH_DedicatedTgl.getValue(); + if ( $Host::Dedicated ) + $Host::PureServer = AH_PureServerTgl.getValue(); + $Host::TeamDamageOn = AH_TeamDamageTgl.getValue(); + $Host::TournamentMode = AH_TournamentTgl.getValue(); + $Host::allowAdminPlayerVotes = AH_AdminVoteTgl.getValue(); + $Host::NoSmurfs = !AH_AllowSmurfTgl.getValue(); + $Host::TimeLimit = AH_TimeLimit.getValue(); + $Host::AdminPassword = AH_AdminPassword.getValue(); + $Host::Info = AH_ServerInfo.getText(); + $Host::VotePassPercent = mFloor( AH_VotePassSlider.getValue() ); + $Host::VoteTime = mFloor( AH_VoteTimeSlider.getValue() ); + $Host::PlayerRespawnTimeout = mFloor( AH_RespawnSlider.getValue() ); + $Host::WarmupTime = mFloor( AH_WarmupSlider.getValue() ); + + // Save off the new prefs: + export( "$Host::*", "prefs/ServerPrefs.cs", false ); + + Canvas.popDialog( AdvancedHostDlg ); +} + +//------------------------------------------------------------------------------ +function AH_DedicatedTgl::onAction( %this ) +{ + if ( %this.getValue() ) + { + AH_PureServerTgl.setValue( $Host::PureServer ); + AH_PureServerTgl.setActive( true ); + } + else + { + AH_PureServerTgl.setValue( false ); + AH_PureServerTgl.setActive( false ); + } +} + +//------------------------------------------------------------------------------ +function AH_VotePassText::update( %this ) +{ + %this.setText( mFloor( AH_VotePassSlider.getValue() ) @ "%" ); +} + +//------------------------------------------------------------------------------ +function AH_VoteTimeText::update( %this ) +{ + %this.setText( mFloor( AH_VoteTimeSlider.getValue() ) SPC "seconds" ); +} + +//------------------------------------------------------------------------------ +function AH_RespawnText::update( %this ) +{ + %this.setText( mFloor( AH_RespawnSlider.getValue() ) SPC "seconds" ); +} + +//------------------------------------------------------------------------------ +function AH_WarmupText::update( %this ) +{ + %this.setText( mFloor( AH_WarmupSlider.getValue() ) SPC "seconds" ); +} + +//------------------------------------------------------------------------------ +// Warrior Setup pane: +//------------------------------------------------------------------------------ +function GM_WarriorPane::onActivate( %this ) +{ + GameGui.pane = "Warrior"; + if ( $pref::Player::Count == 0 ) + %this.createNewAlias(); + else + { + // Fill the warrior list: + GMW_WarriorPopup.clear(); + GMW_LightRdo.setValue( true ); + + // First add the warrior corresponding to the player nickname: + %this.warriorIndex = -1; + if ( $PlayingOnline ) + { + %warrior = getField( WONGetAuthInfo(), 0 ); + for ( %i = 0; %i < $pref::Player::Count; %i++ ) + { + %name = getField( $pref::Player[%i], 0 ); + if ( %name $= %warrior ) + { + %this.warriorIndex = %i; + GMW_WarriorPopup.add( %name, %i, 1 ); + break; + } + } + } + + // Add the rest of the aliases: + for ( %count = 0; %count < $pref::Player::Count; %count++ ) + { + if ( $pref::Player[%count] !$= "" && %count != %this.warriorIndex ) + { + %name = stripTrailingSpaces( strToPlayerName( getField( $pref::Player[%count], 0 ) ) ); + GMW_WarriorPopup.add( %name, %count ); + } + } + + // Fill the static menus: + GMW_RaceGenderPopup.fillList(); + GMW_SkinPrefPopup.fillList(); + + // Select the current player: + GMW_WarriorPopup.setSelected( $pref::Player::Current ); + GMW_WarriorPopup.onSelect( $pref::Player::Current, "" ); + + if ( $pref::Player::Count > 1 && $pref::Player::Current != %this.warriorIndex ) + GMW_DeleteWarriorBtn.setActive( true ); + else + GMW_DeleteWarriorBtn.setActive( false ); + + GMW_PlayerPageBtn.setVisible( $PlayingOnline ); + } +} + +//------------------------------------------------------------------------------ +function GM_WarriorPane::onDeactivate( %this ) +{ +} + +//------------------------------------------------------------------------------ +function GM_WarriorPane::createNewAlias( %this ) +{ + NW_NameEdit.setValue( "" ); + NW_DoneBtn.setActive( false ); + NW_CancelBtn.setVisible( $pref::Player::Count > 0 ); + Canvas.pushDialog( NewWarriorDlg ); +} + +//------------------------------------------------------------------------------ +function GM_WarriorPane::deleteWarrior( %this ) +{ + MessageBoxYesNo( "CONFIRM", "Are you sure you want to delete this alias?", "doDeleteWarrior();", "" ); +} + +//------------------------------------------------------------------------------ +function doDeleteWarrior() +{ + // Make sure we aren't trying to delete the default warrior (should never get this): + if ( $pref::Player::Current == GM_WarriorPane.warriorIndex ) + return; + + for ( %i = $pref::Player::Current; %i < $pref::Player::Count - 1; %i++ ) + $pref::Player[%i] = $pref::Player[%i + 1]; + $pref::Player[%i] = ""; + + if ( GM_WarriorPane.warriorIndex > $pref::Player::Current ) + GM_WarriorPane.warriorIndex--; + + $pref::Player::Count--; + if ( GM_WarriorPane.warriorIndex != -1 ) + $pref::Player::Current = GM_WarriorPane.warriorIndex; + else + $pref::Player::Current = 0; + + // Update the interface: + GM_WarriorPane::onActivate(); +} + +//------------------------------------------------------------------------------ +function GM_WarriorPane::gotoPlayerPage( %this ) +{ + %warrior = getField( WONGetAuthInfo(), 0 ); + LaunchBrowser( %warrior, "Warrior" ); +} + +//------------------------------------------------------------------------------ +function GMW_PlayerModel::update( %this ) +{ + // Get the shape names: + if ( GMW_HeavyRdo.getValue() ) + %armor = "heavy"; + else if ( GMW_MediumRdo.getValue() ) + %armor = "medium"; + else + %armor = "light"; + + switch ( GMW_RaceGenderPopup.getSelected() ) + { + case 1: + if ( %armor $= "heavy" ) + %shape = %armor @ "_male"; + else + %shape = %armor @ "_female"; + case 2 or 3 or 4 or 5 or 6: %shape = "bioderm_" @ %armor; + default: %shape = %armor @ "_male"; + } + + %skin = getField( $pref::Player[$pref::Player::Current], 2 ); + +// if( isObject( $dummySeq ) ) +// { +// $dummySeq.delete(); +// } +// +// $dummySeq = new TSShapeConstructor() +// { +// baseShape = %shape @ ".dts"; +// sequence0 = %shape @ "_forward.dsq dummyRun"; +// }; + + %this.setModel( %shape, %skin ); +} + +//------------------------------------------------------------------------------ +function GMW_WarriorPopup::onAdd( %this ) +{ + %this.addScheme( 1, "255 255 0", "255 255 128", "128 128 0" ); +} + +//------------------------------------------------------------------------------ +function GMW_WarriorPopup::onSelect( %this, %id, %text ) +{ + // Set this as the currently selected player: + $pref::Player::Current = %id; + + // Select the race/gender: + %raceGender = getField( $pref::Player[%id], 1 ); + %selId = GMW_RaceGenderPopup.findText( %raceGender ); + if ( %selId == -1 ) + %selId = 0; + + GMW_RaceGenderPopup.setSelected( %selId ); + GMW_VoicePopup.fillList( %selId ); + + // Select the skin: + %skin = getField( $pref::Player[%id], 2 ); + %baseSkin = isDynamixSkin( %skin ); + GMW_SkinPrefPopup.setSelected( !%baseSkin ); + GMW_SkinPopup.fillList( %selId ); + + %selId = -1; + for ( %i = 0; %i < GMW_SkinPopup.size(); %i++ ) + { + if ( GMW_SkinPopup.realSkin[%i] !$= "" ) + { + if ( %skin $= GMW_SkinPopup.realSkin[%i] ) + { + %selId = %i; + break; + } + } + else if ( %skin $= GMW_SkinPopup.getTextById( %i ) ) + { + %selId = %i; + break; + } + } + if ( %selId == -1 ) + %selId = 0; + GMW_SkinPopup.setSelected( %selId ); + GMW_SkinPopup.onSelect( %selId, GMW_SkinPopup.getTextById( %selId ) ); + + // Select the voice: + %voice = getField( $pref::Player[%id], 3 ); + %voiceId = getSubStr( %voice, strlen( %voice ) -1, 1000 ) - 1; + GMW_VoicePopup.setSelected( %voiceId ); + GMW_VoicePopup.voiceIndex = 0; + + GMW_DeleteWarriorBtn.setActive( $pref::Player::Count > 1 && %id != GM_WarriorPane.warriorIndex ); +} + +//------------------------------------------------------------------------------ +function GMW_RaceGenderPopup::fillList( %this ) +{ + if ( %this.size() ) + return; + + %this.add( "Human Male", 0 ); + %this.add( "Human Female", 1 ); + %this.add( "Bioderm", 2 ); + %this.add( "Draakan Male", 3 ); + %this.add( "Draakan Female", 4 ); + %this.add( "Criollos", 5 ); +} + +//------------------------------------------------------------------------------ +function GMW_RaceGenderPopup::onSelect( %this, %id, %text ) +{ + // Update the player pref: + $pref::Player[$pref::Player::Current] = setField( $pref::Player[$pref::Player::Current], 1, %this.getText() ); + + // Fill the skin list: + %prevSkin = GMW_SkinPopup.getText(); + GMW_SkinPopup.fillList( %id ); + %selId = GMW_SkinPopup.findText( %prevSkin ); + if ( %selId == -1 ) + %selId = 0; + GMW_SkinPopup.setSelected( %selId ); + GMW_SkinPopup.onSelect( %selId, GMW_SkinPopup.getTextById( %selId ) ); + + // Fill the voice list: + %prevVoice = GMW_VoicePopup.getText(); + GMW_VoicePopup.fillList( %id ); + %selId = GMW_VoicePopup.findText( %prevVoice ); + if ( %selId == -1 ) + %selId = 0; + + GMW_VoicePopup.setSelected( %selId ); + GMW_VoicePopup.onSelect( %selId, "" ); +} + +//------------------------------------------------------------------------------ +function GMW_SkinPrefPopup::fillList( %this ) +{ + if ( %this.size() ) + return; + + %this.add( "Dynamix Skins", 0 ); + %this.add( "Custom Skins", 1 ); +} + +//------------------------------------------------------------------------------ +function GMW_SkinPrefPopup::onSelect( %this, %id, %text ) +{ + %curSkin = GMW_SkinPopup.getText(); + GMW_SkinPopup.fillList( GMW_RaceGenderPopup.getSelected() ); + %selId = GMW_SkinPopup.findText( %curSkin ); + if ( %selId == -1 ) + %selId = 0; + + if ( GMW_SkinPopup.size() ) + { + GMW_SkinPopup.setSelected( %selId ); + GMW_SkinPopup.onSelect( %selId, GMW_SkinPopup.getTextById( %selId ) ); + } +} + +//------------------------------------------------------------------------------ +$SkinCount = 0; +$Skin[$SkinCount, name] = "Blood Eagle"; +$Skin[$SkinCount, code] = "beagle"; +$SkinCount++; +$Skin[$SkinCount, name] = "Diamond Sword"; +$Skin[$SkinCount, code] = "dsword"; +$SkinCount++; +$Skin[$SkinCount, name] = "Starwolf"; +$Skin[$SkinCount, code] = "swolf"; +$SkinCount++; +$Skin[$SkinCount, name] = "Phoenix"; +$Skin[$SkinCount, code] = "cotp"; +$SkinCount++; +$Skin[$SkinCount, name] = "Storm"; +$Skin[$SkinCount, code] = "base"; +$SkinCount++; +$Skin[$SkinCount, name] = "Inferno"; +$Skin[$SkinCount, code] = "baseb"; +$SkinCount++; +$Skin[$SkinCount, name] = "Horde"; +$Skin[$SkinCount, code] = "horde"; +$SkinCount++; + +//------------------------------------------------------------------------------ +function isDynamixSkin( %skin ) +{ + for ( %i = 0; %i < $SkinCount; %i++ ) + { + if ( %skin $= $Skin[%i, code] ) + return( true ); + } + + return( false ); +} + +//------------------------------------------------------------------------------ +function GMW_SkinPopup::fillList( %this, %raceGender ) +{ + for ( %i = 0; %i < %this.size(); %i++ ) + %this.realSkin[%i] = ""; + + + %this.clear(); + %path = "textures/skins/"; + switch ( %raceGender ) + { + case 0: // Human Male + %pattern = ".lmale.png"; + case 1: // Human Female + %pattern = ".lfemale.png"; + case 2: // Bioderm + %pattern = ".lbioderm.png"; + case 3 or 4 or 5: //Draakan & Criollos + %pattern = ".lbioderm.png"; + } + + %customSkins = GMW_SkinPrefPopup.getSelected(); + %count = 0; + for ( %file = findFirstFile( %path @ "*" @ %pattern ); %file !$= ""; %file = findNextFile( %path @ "*" @ %pattern ) ) + { + %skin = getSubStr( %file, strlen( %path ), strlen( %file ) - strlen( %path ) - strlen( %pattern ) ); // strip off the path and postfix + // Make sure this is not a bot skin: + if ( %skin !$= "basebot" && %skin !$= "basebbot" ) + { + // See if this skin has an alias: + %baseSkin = false; + for ( %i = 0; %i < $SkinCount; %i++ ) + { + if ( %skin $= $Skin[%i, code] ) + { + %baseSkin = true; + %skin = $Skin[%i, name]; + break; + } + } + + if ( %customSkins != %baseSkin && !%loaded[%skin] ) //Avoid Duplicate skins cluttering up your selection ^.^ + { + if ( %baseSkin ) + %this.realSkin[%count] = $Skin[%i, code]; + %this.add( %skin, %count ); + %loaded[%skin] = true; + %count++; + } + } + } + + %this.sort( true ); +} + +//------------------------------------------------------------------------------ +function GMW_SkinPopup::onSelect( %this, %id, %text ) +{ + // Update the player pref: + if ( %this.realSkin[%id] !$= "" ) + $pref::Player[$pref::Player::Current] = setField( $pref::Player[$pref::Player::Current], 2, %this.realSkin[%id] ); + else + $pref::Player[$pref::Player::Current] = setField( $pref::Player[$pref::Player::Current], 2, %text ); + + // Update the player model: + GMW_PlayerModel.update(); +} + +//------------------------------------------------------------------------------ +// TRANSLATE these voice set display names: +$MaleVoiceCount = 0; +$MaleVoiceName[$MaleVoiceCount] = "Hero"; +$MaleVoiceCount++; +$MaleVoiceName[$MaleVoiceCount] = "Iceman"; +$MaleVoiceCount++; +$MaleVoiceName[$MaleVoiceCount] = "Rogue"; +$MaleVoiceCount++; +$MaleVoiceName[$MaleVoiceCount] = "Hardcase"; +$MaleVoiceCount++; +$MaleVoiceName[$MaleVoiceCount] = "Psycho"; +$MaleVoiceCount++; + +$FemaleVoiceCount = 0; +$FemaleVoiceName[$FemaleVoiceCount] = "Heroine"; +$FemaleVoiceCount++; +$FemaleVoiceName[$FemaleVoiceCount] = "Professional"; +$FemaleVoiceCount++; +$FemaleVoiceName[$FemaleVoiceCount] = "Cadet"; +$FemaleVoiceCount++; +$FemaleVoiceName[$FemaleVoiceCount] = "Veteran"; +$FemaleVoiceCount++; +$FemaleVoiceName[$FemaleVoiceCount] = "Amazon"; +$FemaleVoiceCount++; + +$DermVoiceCount = 0; +$DermVoiceName[$DermVoiceCount] = "Warrior"; +$DermVoiceCount++; +$DermVoiceName[$DermVoiceCount] = "Monster"; +$DermVoiceCount++; +$DermVoiceName[$DermVoiceCount] = "Predator"; +$DermVoiceCount++; + +//------------------------------------------------------------------------------ +function GMW_VoicePopup::fillList( %this, %raceGender ) +{ + %this.clear(); + + switch ( %raceGender ) + { + case 0: // Human Male + for ( %i = 0; %i < $MaleVoiceCount; %i++ ) + %this.add( $MaleVoiceName[%i], %i ); + + case 1: // Human Female + for ( %i = 0; %i < $FemaleVoiceCount; %i++ ) + %this.add( $FemaleVoiceName[%i], %i ); + + case 2: // Bioderm + for ( %i = 0; %i < $DermVoiceCount; %i++ ) + %this.add( $DermVoiceName[%i], %i ); + + case 3: // Male Draakan + for ( %i = 0; %i < $DermVoiceCount; %i++ ) + %this.add( $DermVoiceName[%i], %i ); + + case 4: // Female Draakan + for ( %i = 0; %i < $DermVoiceCount; %i++ ) + %this.add( $DermVoiceName[%i], %i ); + + case 5: // Criollos + for ( %i = 0; %i < $DermVoiceCount; %i++ ) + %this.add( $DermVoiceName[%i], %i ); + } +} + +//------------------------------------------------------------------------------ +function GMW_VoicePopup::onSelect( %this, %id, %text ) +{ + // Update the player pref: + switch ( GMW_RaceGenderPopup.getSelected() ) + { + case 0: %base = "Male"; + case 1: %base = "Fem"; + case 2: %base = "Derm"; + case 3: %base = "Derm"; + case 4: %base = "Derm"; + case 5: %base = "Derm"; + } + + $pref::Player[$pref::Player::Current] = setField( $pref::Player[$pref::Player::Current], 3, %base @ ( %id + 1 ) ); + + %this.voiceIndex = 0; +} + +//------------------------------------------------------------------------------ +function GMW_VoicePitchSlider::setPitch(%this) +{ +} + +function GMW_VoicePopup::test( %this ) +{ + switch ( %this.voiceIndex ) + { + case 0: %file = "gbl.hi"; + case 1: %file = "gbl.brag"; + case 2: %file = "gbl.woohoo"; + case 3: %file = "gbl.rock"; + case 4: %file = "gbl.obnoxious"; + case 5: %file = "gbl.shazbot"; + } + + switch ( GMW_RaceGenderPopup.getSelected() ) + { + case 0: %base = "Male"; + case 1: %base = "Fem"; + case 2: %base = "Derm"; + case 3: %base = "Derm"; + case 4: %base = "Derm"; + case 5: %base = "Derm"; + } + + GMW_VoiceTestBtn.setActive( false ); + %voiceId = %this.getSelected() + 1; + %wav = "voice/" @ %base @ %voiceId @ "/" @ %file @ ".wav"; + %handle = alxCreateSource( AudioGui, %wav ); + + //pitch the voice + //%pitchSliderVal = GMW_VoicePitchSlider.getValue(); + //%pitch = getValidVoicePitch(%voiceId, %pitchSliderVal); + //if (%pitch != 1.0) + // alxSourcef(%handle, "AL_PITCH", %pitch); + + alxPlay( %handle ); + + %delay = alxGetWaveLen( %wav ); + schedule( %delay, 0, "restoreVoiceTestButton" ); + + if ( %this.voiceIndex == 5 ) + %this.voiceIndex = 0; + else + %this.voiceIndex++; +} + +//------------------------------------------------------------------------------ +function restoreVoiceTestButton() +{ + GMW_VoiceTestBtn.setActive( true ); +} + +//------------------------------------------------------------------------------ +function NewWarriorDlg::createPlayer( %this ) +{ + %name = stripTrailingSpaces( NW_NameEdit.getValue() ); + $pref::Player[$pref::Player::Count] = %name @ "\tHuman Male\tbeagle\tMale1"; + $pref::Player::Current = $pref::Player::Count; + $pref::Player::Count++; + Canvas.popDialog( NewWarriorDlg ); + GM_WarriorPane.onActivate(); // Refresh the warrior gui +} + +//------------------------------------------------------------------------------ +function NW_NameEdit::checkValidPlayerName( %this ) +{ + %name = %this.getValue(); + %test = strToPlayerName( %name ); + if ( %name !$= %test ) + %this.setValue( %test ); + + NW_DoneBtn.setActive( strlen( stripTrailingSpaces( %test ) ) > 2 ); +} + +//------------------------------------------------------------------------------ +function NW_NameEdit::processEnter( %this ) +{ + %this.checkValidPlayerName(); + if ( NW_DoneBtn.isActive() ) + NewWarriorDlg.createPlayer(); +} diff --git a/scripts/HuntersGame.cs b/scripts/HuntersGame.cs index e26059b..3307b64 100644 --- a/scripts/HuntersGame.cs +++ b/scripts/HuntersGame.cs @@ -1,1746 +1,1746 @@ -//--------------------------------------// -// HuntersGame.cs // -//--------------------------------------// - -//--- GAME RULES BEGIN --- -//Kill other players to make them drop flags -//Return flags to the Nexus for points -//The more flags brought to Nexus at one time, the more each flag scores -//GREED mode: you must return 8 or more flags at once to score -//HOARD mode: no returns between 5 and 2 min. left in game -//Flag Colors: Red = 1pt, Blue = 2pts, Yellow = 4pts, Green = 8pts -//--- GAME RULES END --- - -package HuntersGame { - -function Nexus::objectiveInit(%data, %object) -{ - Game.Nexus = %object; - Game.Nexus.playThread(0, "ambient"); - Game.Nexus.setThreadDir(0, true); - //The flash animation plays forwards, then back automatically, so we have to alternate the thread direcction... - Game.Nexus.flashThreadDir = true; - -} - -function NexusBase::objectiveInit(%data, %object) -{ - Game.NexusBase = %object; - Game.NexusBase.playthread(0, "ambient"); - Game.NexusBase.setThreadDir(0, true); -} - -function NexusCap::objectiveInit(%data, %object) -{ - Game.NexusCap = %object; - Game.NexusCap.playthread(0, "ambient"); - Game.NexusCap.setThreadDir(0, true); -} - -}; - -$InvBanList[Hunters, "TurretOutdoorDeployable"] = 1; -$InvBanList[Hunters, "TurretIndoorDeployable"] = 1; -$InvBanList[Hunters, "ElfBarrelPack"] = 1; -$InvBanList[Hunters, "MortarBarrelPack"] = 1; -$InvBanList[Hunters, "PlasmaBarrelPack"] = 1; -$InvBanList[Hunters, "AABarrelPack"] = 1; -$InvBanList[Hunters, "MissileBarrelPack"] = 1; -$InvBanList[Hunters, "Mine"] = 1; -$InvBanList[Hunters, "MiningTool"] = 1; - -datablock EffectProfile(HuntersFlagPickupEffect) -{ - effectname = "misc/hunters_flag_snatch"; - minDistance = 2.5; - maxDistance = 5.0; -}; - -datablock AudioProfile(HuntersFlagPickupSound) -{ - filename = "fx/misc/hunters_flag_snatch.wav"; - description = AudioClose3d; - effect = HuntersFlagPickupEffect; - preload = true; -}; - - -//exec the AI script -exec("scripts/aiHunters.cs"); - -//exec the records script -if (isFile("prefs/HuntersRecords.cs")) - exec("prefs/HuntersRecords.cs"); - -//----------------------------------------------------------------------------- -//Game initialization functions - -function HuntersGame::setUpTeams(%game) -{ - // Force the numTeams variable to one: - DefaultGame::setUpTeams(%game); - %game.numTeams = 1; - - // allow teams 1->31 to listen to each other (team 0 can only listen to self) - for(%i = 1; %i < 32; %i++) - setSensorGroupListenMask(%i, 0xfffffffe); -} - -function HuntersGame::initGameVars(%game) -{ - %game.SCORE_PER_SUICIDE = -1; - %game.SCORE_PER_DEATH = 0; - %game.SCORE_PER_KILL = 1; - - %game.teamMode = false; - - if (!isDemo()) - %game.greedMode = $Host::HuntersGreedMode; - else - %game.greedMode = false; - %game.greedMinFlags = 8; //min number of flags you must have before you can cap - - if (!isDemo()) - %game.hoardMode = $Host::HuntersHoardMode; - else - %game.hoardMode = false; - %game.HoardStartTime = 5; //time left in the game at which hoard mode will start - %game.HoardDuration = 3; //duration of the hoard period - %game.HoardEndTime = %game.HoardStartTime - %game.HoardDuration; - - %game.yardSaleMin = 10; - - //make sure there is enough time in the match to actually have a hoard mode... - if ($host::timeLimit < %game.hoardStartTime + 1) - %game.hoardMode = false; - - %game.maxSensorGroup = 0; - - %game.highestFlagReturnCount = 10; //initialize to 10 - don't bother recording less than that... - %game.highestFlagReturnName = ""; - %game.greedFlagCount = 10; //initialize to 10 - don't bother recording greed less than that... - %game.greedFlagName = ""; - - //this is how many humans have to be playing in order to set a record - %game.numHumansForRecord = 4; - - //this is how many milliseconds before a warning is issued for camping near the Nexus - %game.nexusCampingTime = 10000; - - %game.flagHoarder = ""; - %game.flagHoarderMin = 15; - - //vars for how long before the flag is deleted, and the fade transition time... - %game.flagLifeTimeMS = 120000; - %game.fadeTimeMS = 2000; - - %game.flagMsgDelayMS = 3000; - %game.oobThrowFlagsDelayMS = 3000; - - // targets for each of the flag types (except for base which is properly skinned already) - HuntersFlag1.target = -1; // red - HuntersFlag2.target = allocTarget("", 'Blue', "", "", 0, "", ""); - HuntersFlag4.target = allocTarget("", 'Yellow', "", "", 0, "", ""); - HuntersFlag8.target = allocTarget("", 'Green', "", "", 0, "", ""); -} - -function HuntersGame::allowsProtectedStatics(%game) -{ - return true; -} - -function HuntersGame::missionLoadDone(%game) -{ - //default version sets up teams - must be called first... - DefaultGame::missionLoadDone(%game); - - //initialize the score and flag count for all the players - %count = ClientGroup.getCount(); - for(%i = 0; %i < %count; %i++) - { - %client = ClientGroup.getObject(%i); - %game.resetScore(%client); - %client.flagCount = 1; - %client.trackWaypoint = ""; - %client.playerTrackLine = -1; - } - $TopClient = -1; - $TopClientScore = 0; - - //create the Flag group - $FlagGroup = nameToID("MissionCleanup/FlagGroup"); - if ($FlagGroup <= 0) - { - $FlagGroup = new SimGroup("FlagGroup"); - MissionCleanup.add($FlagGroup); - } - - //create the "yard sale waypoint set" - if(nameToId("HuntersYardSaleSet") <= 0) - { - $HuntersYardSaleSet = new SimSet("HuntersYardSaleSet"); - MissionCleanup.add($HuntersYardSaleSet); - } -} - - -function HuntersGame::startMatch(%game) -{ - //call the default - DefaultGame::startMatch(%game); - - //schedule the hoard countdowns - %game.setupHoardCountdown(); -} - -function HuntersGame::setupHoardCountdown(%game) -{ - //delete all previous scheduled calls... - cancel(%game.hoardStart30); - cancel(%game.hoardStart10); - cancel(%game.hoardStart5); - cancel(%game.hoardStart4); - cancel(%game.hoardStart3); - cancel(%game.hoardStart2); - cancel(%game.hoardStart1); - cancel(%game.hoardStart0); - - cancel(%game.hoardEnd30); - cancel(%game.hoardEnd10); - cancel(%game.hoardEnd5); - cancel(%game.hoardEnd4); - cancel(%game.hoardEnd3); - cancel(%game.hoardEnd2); - cancel(%game.hoardEnd1); - cancel(%game.hoardEnd0); - - //schedule hoard mode start notify calls - %curTimeLeftMS = ($Host::TimeLimit * 60 * 1000) + $missionStartTime - getSimTime(); - %hoardStartTimeMS = %game.HoardStartTime * 60 * 1000; - - if (%curTimeLeftMS >= %hoardStartTimeMS + 30000) - %game.hoardStart30 = %game.schedule(%curTimeLeftMS - (%hoardStartTimeMS + 30000), "notifyHoardStart", 30); - - if (%curTimeLeftMS >= %hoardStartTimeMS + 10000) - %game.hoardStart10 = %game.schedule(%curTimeLeftMS - (%hoardStartTimeMS + 10000), "notifyHoardStart", 10); - - if (%curTimeLeftMS >= %hoardStartTimeMS + 5000) - %game.hoardStart5 = %game.schedule(%curTimeLeftMS - (%hoardStartTimeMS + 5000), "notifyHoardStart", 5); - - if (%curTimeLeftMS >= %hoardStartTimeMS + 4000) - %game.hoardStart4 = %game.schedule(%curTimeLeftMS - (%hoardStartTimeMS + 4000), "notifyHoardStart", 4); - - if (%curTimeLeftMS >= %hoardStartTimeMS + 3000) - %game.hoardStart3 = %game.schedule(%curTimeLeftMS - (%hoardStartTimeMS + 3000), "notifyHoardStart", 3); - - if (%curTimeLeftMS >= %hoardStartTimeMS + 2000) - %game.hoardStart2 = %game.schedule(%curTimeLeftMS - (%hoardStartTimeMS + 2000), "notifyHoardStart", 2); - - if (%curTimeLeftMS >= %hoardStartTimeMS + 1000) - %game.hoardStart1 = %game.schedule(%curTimeLeftMS - (%hoardStartTimeMS + 1000), "notifyHoardStart", 1); - - if (%curTimeLeftMS >= %hoardStartTimeMS) - %game.hoardStart0 = %game.schedule(%curTimeLeftMS - %hoardStartTimeMS, "notifyHoardStart", 0); - - - //schedule hoard mode end notify calls - %hoardEndTimeMS = %game.HoardEndTime * 60 * 1000; - - if (%curTimeLeftMS >= %hoardEndTimeMS + 30000) - %game.hoardEnd30 = %game.schedule(%curTimeLeftMS - (%hoardEndTimeMS + 30000), "notifyHoardEnd", 30); - - if (%curTimeLeftMS >= %hoardEndTimeMS + 10000) - %game.hoardEnd10 = %game.schedule(%curTimeLeftMS - (%hoardEndTimeMS + 10000), "notifyHoardEnd", 10); - - if (%curTimeLeftMS >= %hoardEndTimeMS + 5000) - %game.hoardEnd5 = %game.schedule(%curTimeLeftMS - (%hoardEndTimeMS + 5000), "notifyHoardEnd", 5); - - if (%curTimeLeftMS >= %hoardEndTimeMS + 4000) - %game.hoardEnd4 = %game.schedule(%curTimeLeftMS - (%hoardEndTimeMS + 4000), "notifyHoardEnd", 4); - - if (%curTimeLeftMS >= %hoardEndTimeMS + 3000) - %game.hoardEnd3 = %game.schedule(%curTimeLeftMS - (%hoardEndTimeMS + 3000), "notifyHoardEnd", 3); - - if (%curTimeLeftMS >= %hoardEndTimeMS + 2000) - %game.hoardEnd2 = %game.schedule(%curTimeLeftMS - (%hoardEndTimeMS + 2000), "notifyHoardEnd", 2); - - if (%curTimeLeftMS >= %hoardEndTimeMS + 1000) - %game.hoardEnd1 = %game.schedule(%curTimeLeftMS - (%hoardEndTimeMS + 1000), "notifyHoardEnd", 1); - - if (%curTimeLeftMS >= %hoardEndTimeMS) - %game.hoardEnd0 = %game.schedule(%curTimeLeftMS - %hoardEndTimeMS, "notifyHoardEnd", 0); -} - -function HuntersGame::notifyHoardStart(%game, %seconds) -{ - if (%game.HoardMode) - { - if (%seconds > 1) - messageAll('MsgHuntersHoardNotifyStart', '\c2%1 seconds left until the HOARD period begins.~wfx/misc/hunters_%1.wav', %seconds); - else if (%seconds == 1) - messageAll('MsgHuntersHoardNotifyStart', '\c21 second left until the HOARD period begins.~wfx/misc/hunters_1.wav'); - else - { - messageAll('MsgHuntHoardNotifyStarted', '\c2The HOARD period has begun.~wfx/misc/hunters_horde.wav'); - logEcho("hoard mode start"); - %game.setNexusDisabled(); - cancel(%game.greedNexusFlash); - } - } -} - -function HuntersGame::notifyHoardEnd(%game, %seconds) -{ - if (%game.HoardMode) - { - if (%seconds > 1) - messageAll('MsgHuntersHoardNotifyEnd', '\c2%1 seconds left until the HOARD period ends.~wfx/misc/hunters_%1.wav', %seconds); - else if (%seconds == 1) - messageAll('MsgHuntersHoardNotifyEnd', '\c21 second left until the HOARD period ends.~wfx/misc/hunters_1.wav'); - else - { - messageAll('MsgHuntersHoardNotifyEnded', '\c2The HOARD period has ended!~wfx/misc/hunters_greed.wav'); - logEcho("hoard mode end"); - %game.setNexusEnabled(); - cancel(%game.greedNexusFlash); - } - } -} - -function HuntersGame::clientJoinTeam( %game, %client, %team, %respawn ) -{ - %game.assignClientTeam( %client ); - - // Spawn the player: - %game.spawnPlayer( %client, %respawn ); -} - -//----------------------------------------------------------------------------- -//Player spawn/death functions - -function HuntersGame::assignClientTeam(%game, %client) -{ - %client.team = 0; - - //initialize the team array - for (%i = 1; %i < 32; %i++) - $HuntersTeamArray[%i] = false; - - %game.maxSensorGroup = 0; - %count = ClientGroup.getCount(); - for (%i = 0; %i < %count; %i++) - { - %cl = ClientGroup.getObject(%i); - if (%cl.team != 0) - $HuntersTeamArray[%cl.team] = true; - - //need to set the number of sensor groups to the max... - if (%cl.team > %game.maxSensorGroup) - %game.maxSensorGroup = %cl.team; - } - - //now loop through the team array, looking for an empty team - for (%i = 1; %i < 32; %i++) - { - if (! $HuntersTeamArray[%i]) - { - %client.team = %i; - - if (%client.team > %game.maxSensorGroup) - %game.maxSensorGroup = %client.team; - - break; - } - } - - // set player's skin pref here - setTargetSkin(%client.target, %client.skin); - - // Let everybody know you are no longer an observer: - messageAll( 'MsgClientJoinTeam', '\c1%1 has joined the hunt.', %client.name, "", %client, 1 ); - updateCanListenState( %client ); - - //now set the max number of sensor groups... - setSensorGroupCount(%game.maxSensorGroup + 1); -} - -function HuntersGame::createPlayer(%game, %client, %spawnLoc, %respawn) -{ - //first call the default - DefaultGame::createPlayer(%game, %client, %spawnLoc, %respawn); - - //now set the sensor group - %client.setSensorGroup(%client.team); -} - -function HuntersGame::pickPlayerSpawn(%game, %client, %respawn) -{ - return %game.pickTeamSpawn(1); -} - -function HuntersGame::playerSpawned(%game, %player, %armor) -{ - //intialize - %client = %player.client; - %client.flagCount = 1; - %client.isDead = false; - - //make sure they're not still taking camping damage... - cancel(%client.campingThread); - - - //continue with the default - DefaultGame::playerSpawned(%game, %player, %armor); -} - -function HuntersGame::onClientKilled(%game, %clVictim, %clKiller, %damageType, %implement, %damageLoc) -{ - //set the flag - %clVictim.isDead = true; - - //set the greed variable if required - if (!%game.teamMode && $missionRunning) - { - if (%clVictim.flagCount - 1 > %game.greedFlagCount) - { - %game.greedFlagCount = %clVictim.flagCount - 1; - %game.greedFlagName = getTaggedString(%clVictim.name); - } - } - - //first, drop all the flags - HuntersGame::dropFlag(%game, %clVictim.player); - - //now call the default game stuff - DefaultGame::onClientKilled(%game, %clVictim, %clKiller, %damageType, %implement, %damageLoc); - - messageClient(%clVictim, 'MsgHuntYouHaveFlags', "", 0); -} - -function HuntersGame::updateKillScores(%game, %clVictim, %clKiller, %damageType, %implement) -{ - if (%game.testKill(%clVictim, %clKiller)) //verify victim was an enemy - { - %game.awardScoreKill(%clKiller); - %game.awardScoreDeath(%clVictim); - } - else if (%game.testSuicide(%clVictim, %clKiller, %damageType)) //otherwise test for suicide - %game.awardScoreSuicide(%clVictim); -} - -function Huntersgame::awardScoreKill(%game, %client) -{ - //call the default - DefaultGame::awardScoreKill(%game, %client); - - //check if we have a new leader - if (!%game.teamMode && (%client.score > $TopClientScore)) - { - $TopClientScore = %client.score; - //this message is annoying! - //if (%client != $TopClient) - // messageAll('MsgHuntNewTopScore', '\c0%1 has taken the lead with a score of %2!~wfx/misc/flag_capture.wav', %client.name, %client.score); - $TopClient = %client; - } -} - -function Huntersgame::awardScoreSuicide(%game, %client) -{ - //call the default - DefaultGame::awardScoreSuicide(%game, %client); - - //check if we have a new leader - if (!%game.teamMode && %client == $TopClient && (%client.score < $TopClientScore)) - { - //first lower the topClientScore var - $TopClientScore = %client.score; - - //see if there's a new leader... - %highestScore = %client.score; - %highestScoreClient = -1; - for (%i = 0; %i < ClientGroup.getCount(); %i++) - { - %cl = ClientGroup.getObject(%i); - if (%cl.score > %highestScore) - { - %highestScore = %cl.score; - %highestScoreClient = %cl; - } - } - - //did we find someone? - if (%highestScoreClient > 0) - { - $TopClientScore = %highestScoreClient.score; - $TopClient = %highestScoreClient; - //this message is annoying... - //messageAll('MsgHuntNewTopScore', '\c0%1 is now in the lead with a score of %2!~wfx/misc/flag_capture.wav', %highestScoreClient.name, %highestScoreClient.score); - } - } -} - -function HuntersGame::equip(%game, %player) -{ - for(%i =0; %i<$InventoryHudCount; %i++) - %player.client.setInventoryHudItem($InventoryHudData[%i, itemDataName], 0, 1); - %player.client.clearBackpackIcon(); - - //%player.setArmor("Light"); - %player.setInventory(RepairKit,1); - %player.setInventory(Grenade,6); - %player.setInventory(Blaster,1); - %player.setInventory(Chaingun,1); - %player.setInventory(ChaingunAmmo, 100); - %player.setInventory(Disc,1); - %player.setInventory(DiscAmmo, 20); - %player.setInventory(EnergyPack,1); - %player.setInventory(TargetingLaser, 1); - %player.weaponCount = 3; - - %player.use("Disc"); -} - -//----------------------------------------------------------------------------- -//flag functions -function HuntersGame::playerDroppedFlag(%game, %player) -{ - // this stuff has all been moved to HuntersGame::dropFlag - // we really don't want something to happen for *every* flag a player drops anyway -} - -function HuntersStartFlagTimeOut(%flag) -{ - // start the fade out... - %flag.startFade(Game.fadeTimeMS, 0, true); - schedule(Game.fadeTimeMS, %flag, "HuntersEndFlagTimeOut", %flag); -} - -function HuntersEndFlagTimeOut(%flag) -{ - %flag.delete(); -} - -function HuntersYardSaleTimeOut(%waypoint) -{ - %waypoint.delete(); -} - -function HuntersGame::updateFlagHoarder(%game, %eventClient) -{ - %hoarder = -1; - %maxFlags = -1; - %count = ClientGroup.getCount(); - for (%i = 0; %i < %count; %i++) - { - %client = ClientGroup.getObject(%i); - if (%client.flagCount > %game.flagHoarderMin && %client.flagCount > %maxFlags) - { - %maxflags = %client.flagCount; - %hoarder = %client; - } - } - - //if we found our hoarder, set the waypoint, otherwise, delete it - if (%hoarder > 0) - { - //only update if the event (capping, picking up flag, etc...) was the actual hoarder - if (!isObject(%game.flagHoarder) || %game.flagHoarder == %eventClient) - { - if (!isObject(%game.hoarderWaypoint)) - { - //create a waypoint at player's location... - %game.hoarderWaypoint = new WayPoint() - { - position = %hoarder.player.position; - rotation = "1 0 0 0"; - scale = "1 1 1"; - name = "Flag Hoarder Was Here"; - dataBlock = "WayPointMarker"; - lockCount = "0"; - homingCount = "0"; - team = 0; - }; - - //add the waypoint to the cleanup group - MissionCleanup.add(%game.hoarderWaypoint); - } - - //set the position - %game.flagHoarder = %hoarder; - %game.hoarderWaypoint.setTransform(%hoarder.player.getWorldBoxCenter() SPC "0 0 1 0"); - } - } - else if (isObject(%game.hoarderWaypoint)) - { - %game.flaghoarder = ""; - %game.hoarderWaypoint.delete(); - } -} - -function HuntersGame::sendFlagCountMessage(%game, %client) -{ - //send the messages - if (%client.flagCount - 1 == 1) - { - messageAllExcept(%client, -1, 'MsgHuntPlayerHasFlags', '\c2%1 now has 1 flag.', %client.name, 1); - messageClient(%client, 'MsgHuntYouHaveFlags', '\c2You now have 1 flag.', %client.flagCount - 1); - } - else if (%client.flagCount - 1 > 1) - { - messageAllExcept(%client, -1, 'MsgHuntPlayerHasFlags', '\c2%1 now has %2 flags.', %client.name, %client.flagCount - 1); - messageClient(%client, 'MsgHuntYouHaveFlags', '\c2You now have %1 flags.', %client.flagCount - 1); - } -} - -function HuntersGame::playerTouchFlag(%game, %player, %flag) -{ - //make sure the player is still alive - %client = %player.client; - if (%player.getState() !$= "Dead") - { - //increase the count bye the flag value - %flagValue = %flag.value; - %client.flagCount += %flagValue; - - //delete the flag - %flag.delete(); - - //if the client has 5 or more flags, mount an image - if (%client.flagCount >= 5) - %player.mountImage(HuntersFlagImage, $FlagSlot); - - //schedule an update message - cancel(%client.flagMsgPending); - %client.flagMsgPending = %game.schedule(%game.flagMsgDelayMS, "sendFlagCountMessage", %client); - messageClient(%client, 'MsgHuntYouHaveFlags', "", %client.flagCount - 1); - - //update the log... - logEcho(%client.nameBase@" (pl "@%player@"/cl "@%client@") has "@%client.flagCount-1@" flags"); - - //play the sound pickup in 3D - %player.playAudio(0, HuntersFlagPickupSound); - - //see if the client could set the record - if (!%game.teamMode && !%client.couldSetRecord) - { - %numFlags = %client.flagCount - 1; - if (%numFlags > 10 && %numFlags > $Host::HuntersRecords::Count[$currentMission]) - { - //see if we have at least 4 non-AI players - %humanCount = 0; - %count = ClientGroup.getCount(); - for (%i = 0; %i < %count; %i++) - { - %cl = ClientGroup.getObject(%i); - if (!%cl.isAIControlled()) - %humanCount++; - if (%humanCount >= %game.numHumansForRecord) - break; - } - - if (%humanCount >= %game.numHumansForRecord) - { - %client.couldSetRecord = true; - - //send a message right away... - if (isEventPending(%client.flagMsgPending)) - { - cancel(%client.flagMsgPending); - %game.sendFlagCountMessage(%client); - } - - //send a message to everyone - messageAllExcept(%client, -1, 'MsgHuntPlayerCouldSetRecord', '\c2%1 has enough flags to set the record for this mission!~wfx/misc/flag_return.wav'); - messageClient(%client, 'MsgHuntYouCouldSetRecord', '\c2You have enough flags to set the record for this mission!~wfx/misc/flag_return.wav'); - } - } - } - - //new tracking - *everyone* automatically tracks the "flag hoarder" if they have at least 15 flags - %game.updateFlagHoarder(%client); - } -} - -function HuntersGame::checkTimeLimit(%game) -{ - DefaultGame::checkTimeLimit(%game); - - //make sure the hoard counter is also up to date - %curTimeLeftMS = ($Host::TimeLimit * 60 * 1000) + $missionStartTime - getSimTime(); - messageAll('MsgHuntHoardStatus', "", %game.HoardMode, $Host::TimeLimit, %curTimeLeftMS, %game.HoardStartTime, %game.HoardDuration); -} - -function HuntersGame::timeLimitReached(%game) -{ - logEcho("game over (timelimit)"); - %game.gameOver(); - cycleMissions(); -} - -function HuntersGame::scoreLimitReached(%game) -{ - //no such thing as a score limit in Hunters... -} - -function HuntersGame::gameOver(%game) -{ - //call the default - DefaultGame::gameOver(%game); - - messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.gameover.wav" ); - - messageAll('MsgClearObjHud', ""); - for(%i = 0; %i < ClientGroup.getCount(); %i ++) - { - %client = ClientGroup.getObject(%i); - Game.resetScore(%client); - cancel(%client.oobSched); - } -} - -function HuntersGame::checkScoreLimit(%game, %client) -{ - //no such thing as a score limit in Hunters... -} - -//----------------------------------------------------------------------------- -//Nexus functions - -function HuntersGame::setNexusDisabled(%game) -{ - //set the animations - Game.Nexus.playThread(1, "transition"); - Game.NexusCap.playthread(1, "transition"); - Game.NexusBase.playthread(1, "transition"); - Game.Nexus.setThreadDir(1, true); - Game.NexusCap.setThreadDir(1, true); - Game.NexusBase.setThreadDir(1, true); -} - -function HuntersGame::setNexusEnabled(%game) -{ - //set the animations - Game.Nexus.playThread(1, "transition"); - Game.NexusCap.playthread(1, "transition"); - Game.NexusBase.playthread(1, "transition"); - Game.Nexus.setThreadDir(1, false); - Game.NexusCap.setThreadDir(1, false); - Game.NexusBase.setThreadDir(1, false); -} - -function HuntersGame::flashNexus(%game) -{ - //set the animations - Game.Nexus.playThread(1, "flash"); - Game.NexusCap.playthread(1, "flash"); - Game.NexusBase.playthread(1, "flash"); - Game.Nexus.setThreadDir(1, Game.Nexus.flashThreadDir); - Game.NexusCap.setThreadDir(1, Game.Nexus.flashThreadDir); - Game.NexusBase.setThreadDir(1, Game.Nexus.flashThreadDir); - Game.Nexus.flashThreadDir = !Game.Nexus.flashThreadDir; -} - -function HuntersGame::NexusSparkEmitter(%game, %client, %cap, %numToScore) -{ - if (isObject(%client.nexusEmitter)) - %client.nexusEmitter.delete(); - - %client.nexusEmitter = new ParticleEmissionDummy() - { - //position = getWord(%client.player.position, 0) SPC getWord(%client.player.position, 1) SPC getWord(%client.player.position, 2) + 3; - position = (%cap ? Game.nexus.getWorldBoxCenter() : %client.player.getWorldBoxCenter()); - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = defaultEmissionDummy; - emitter = (%cap ? NexusParticleCapEmitter : NexusParticleDeniedEmitter); - velocity = "1"; - }; - MissionCleanup.add(%client.nexusEmitter); - - //the effect should only last a few seconds - if (%cap) - { - %timeMS = (%numToScore < 10 ? 200 : %numToScore * 20); - %client.nexusEmitter.schedule(%timeMS, "delete"); - } - else - %client.nexusEmitter.schedule(200, "delete"); -} - -function HuntersGame::hoardModeActive(%game, %wouldBeActive) -{ - if (%wouldBeActive $= "") - %wouldBeActive = false; - - //see if hoard mode is on and active - if (%game.HoardMode || %wouldBeActive) - { - %missionEndTime = ($Host::TimeLimit * 60 * 1000) + $missionStartTime; - %timeLeftMS = %missionEndTime - getSimTime(); - - %hoardStartTime = %game.HoardStartTime * 60 * 1000; - %hoardEndTime = %hoardStartTime - (%game.HoardDuration * 60 * 1000); - if (%timeLeftMS <= %hoardStartTime && %timeLeftMS > %hoardEndTime) - return true; - } - return false; -} - -function Nexus::onCollision(%data, %obj, %colObj) -{ - //make sure it was a player that entered the trigger - if((%colObj.getDataBlock().className $= Armor) && (%colObj.getState() !$= "Dead")) - { - %player = %colObj; - %client = %player.client; - - // if player has been to the nexus within last 5 seconds, don't keep spamming messages - if((getSimTime() - %player.lastNexusTime) < 5000) - return; - - %player.lastNexusTime = getSimTime(); - - if(Game.hoardModeActive()) - { - messageClient(%client, 'MsgHuntHoardNoCap', '\c2Hoard mode is in effect! You cannot return any flags right now.~wfx/powered/nexus_deny.wav'); - - //apply a "bounce" impulse to the player - %velocity = %player.getVelocity(); - if (VectorDist("0 0 0", %velocity) < 2) - %velocityNorm = "0 20 0"; - else - %velocityNorm = VectorScale(VectorNormalize(%velocity), 20); - %vector = VectorScale(%velocityNorm, -200); - %player.applyImpulse(%player.position, %vector); - - Game.NexusSparkEmitter(%client, false); - return; - } - - // you can't cap your own flag - %numToScore = %client.flagCount - 1; - if (Game.greedMode && (%numToScore < Game.GreedMinFlags) && (%numToScore >= 1)) - { - messageClient(%client, 'MsgHuntNeedGreed', '\c2Greed mode is ON! You must have %1 flags before you can return them.~wfx/powered/nexus_deny.wav', Game.GreedMinFlags); - - //transition the Nexus to the "off" animation and back again - Game.flashNexus(); - - //apply a "bounce" impuse to the player - %velocity = %player.getVelocity(); - if (VectorDist("0 0 0", %velocity) < 2) - %velocityNorm = "0 20 0"; - else - %velocityNorm = VectorScale(VectorNormalize(%velocity), 20); - %vector = VectorScale(%velocityNorm, -200); - %player.applyImpulse(%player.position, %vector); - - Game.NexusSparkEmitter(%client, false); - return; - } - - //send the flags message right away... - if (isEventPending(%client.flagMsgPending)) - { - cancel(%client.flagMsgPending); - %game.sendFlagCountMessage(%client); - } - - //unless the nexus is very near the mission boundary, there should be no oobSched to cancel, but... - cancel(%client.oobSched); - - //score the flags - %totalScore = (%numToScore * (%numToScore + 1)) / 2; - if (Game.teamMode) - { - $teamScore[%client.team] += %totalScore; - logEcho(%client.nameBase@" (pl "@%player@"/cl "@%client@") score "@%numToScore@" flags worth "@%totalScore@" pts for team "@%client.team); - messageAll('MsgTeamScoreIs', "", %client.team, $teamScore[%client.team]); - Game.recalcTeamRanks(%client.team); - } - else - { - %client.flagPoints += %totalScore; - logEcho(%client.nameBase@" (pl "@%player@"/cl "@%client@") score "@%numToScore@" flags worth "@%totalScore@" pts"); - Game.recalcScore(%client); - - //see if we should set the highest for the mission here - if (%numToScore > Game.highestFlagReturnCount) - { - Game.highestFlagReturnCount = %numToScore; - Game.highestFlagReturnName = getTaggedString(%client.name); - } - } - - //reset the flags - %client.flagCount = 1; - %client.couldSetRecord = false; - %player.unMountImage($FlagSlot); - messageClient(%client, 'MsgHuntYouHaveFlags', "", 0); - - //see if it's the top score - if (!Game.teamMode && (%client.score > $TopClientScore)) - %topScore = true; - else - %topScore = false; - - //send the messages - if (%numToScore <= 0) - { - messageClient(%client, 'MsgHuntYouNeedHelp', '\c2Pick up flags and bring them here to score points.~wfx/misc/nexus_idle.wav'); - } - else if (%numToScore == 1) - { - if(Game.teamMode) - messageAllExcept(%client, -1, 'MsgHuntPlayerScored', '\c2%1 returned 1 flag (1 point) for %2.~wfx/misc/nexus_cap.wav', %client.name, $TeamName[%client.team], 1); - else - { - messageAllExcept(%client, -1, 'MsgHuntPlayerScored', '\c2%1 returned 1 flag for 1 point.~wfx/misc/nexus_cap.wav', %client.name, 1); - - //new tracking - *everyone* automatically tracks the "flag hoarder" if they have at least 15 flags - Game.updateFlagHoarder(%client); - } - - //add the nexus effect - Game.NexusSparkEmitter(%client, true, %numToScore); - - messageClient(%client, 'MsgHuntYouScored', '\c2You returned 1 flag for 1 point.~wfx/misc/nexus_cap.wav', 1); - } - else if (%numToScore < 5) - { - if(Game.teamMode) - messageAllExcept(%client, -1, 'MsgHuntPlayerScored', '\c2%1 returned %2 flags (%3 points) for %4.~wfx/misc/nexus_cap.wav', %client.name, %numToScore, %totalScore, $TeamName[%client.team]); - else - { - messageAllExcept(%client, -1, 'MsgHuntPlayerScored', '\c2%1 returned %2 flags for %3 points.~wfx/misc/nexus_cap.wav', %client.name, %numToScore, %totalScore); - - //new tracking - *everyone* automatically tracks the "flag hoarder" if they have at least 15 flags - Game.updateFlagHoarder(%client); - } - - //add the nexus effect - Game.NexusSparkEmitter(%client, true, %numToScore); - - messageClient(%client, 'MsgHuntYouScored', '\c2You returned %1 flags for %2 points.~wfx/misc/nexus_cap.wav', %numToScore, %totalScore); - } - else - { - if(Game.teamMode) - messageAllExcept(%client, -1, 'MsgHuntPlayerScored', '\c2%1 returned %2 flags (%3 points) for %4.~wfx/misc/nexus_cap.wav', %client.name, %numToScore, %totalScore, $TeamName[%client.team]); - else - { - messageAllExcept(%client, -1, 'MsgHuntPlayerScored', '\c2%1 returned %2 flags for %3 points.~wfx/misc/nexus_cap.wav', %client.name, %numToScore, %totalScore); - - //new tracking - *everyone* automatically tracks the "flag hoarder" if they have at least 15 flags - Game.updateFlagHoarder(%client); - } - - //add the nexus effect - Game.NexusSparkEmitter(%client, true, %numToScore); - - messageClient(%client, 'MsgHuntYouScored', '\c2You returned %1 flags for %2 points.~wfx/misc/nexus_cap.wav', %numToScore, %totalScore); - } - - //see if it's the top score - if (%topScore) - { - $TopClientScore = %client.score; - if (%client == $TopClient) - { - if (%numToScore >= 5) - messageAll('MsgHuntTopScore', '\c0%1 is leading with a score of %2!~wfx/misc/flag_capture.wav', %client.name, %client.score); - else - messageAll('MsgHuntTopScore', '\c0%1 is leading with a score of %2!', %client.name, %client.score); - } - else - messageAll('MsgHuntNewTopScore', '\c0%1 has taken the lead with a score of %2!~wfx/misc/flag_capture.wav', %client.name, %client.score); - $TopClient = %client; - } - - //see if it's a record - if (%numToScore > 10 && %numToScore > $Host::HuntersRecords::Count[$currentMission]) - { - //see if we have at least 4 non-AI players - %humanCount = 0; - %count = ClientGroup.getCount(); - for (%i = 0; %i < %count; %i++) - { - %cl = ClientGroup.getObject(%i); - if (!%cl.isAIControlled()) - %humanCount++; - if (%humanCount >= Game.numHumansForRecord) - break; - } - - if (%humanCount >= Game.numHumansForRecord) - { - $Host::HuntersRecords::Count[$currentMission] = %numToScore; - $Host::HuntersRecords::Name[$currentMission] = getTaggedString(%client.name); - - //send a message to everyone - messageAllExcept(%client, -1, 'MsgHuntPlayerSetRecord', '\c2%1 set the record for this mission with a return of %2 flags!~wfx/misc/flag_return.wav', %client.name, %numToScore); - messageClient(%client, 'MsgHuntYouSetRecord', '\c2You set the record for this mission with a return of %1 flags!~wfx/misc/flag_return.wav', %numToScore); - - //update the records file... - export( "$Host::HuntersRecords::*", "prefs/HuntersRecords.cs", false ); - - //once the record has been set, reset everyone's tag - for (%i = 0; %i < %count; %i++) - { - %cl = ClientGroup.getObject(%count); - %cl.couldSetRecord = false; - } - } - } - - if(Game.teamMode) - Game.checkScoreLimit(%team); - else - Game.checkScoreLimit(%client); - } -} - -function HuntersGame::clientMissionDropReady(%game, %client) -{ - //%client.rank = ClientGroup.getCount(); - messageClient(%client, 'MsgClientReady',"", %game.class); - //messageClient(%client, 'MsgHuntGreedStatus', "", %game.greedMode, %game.GreedMinFlags); - //%curTimeLeftMS = ($Host::TimeLimit * 60 * 1000) + $missionStartTime - getSimTime(); - //messageClient(%client, 'MsgHuntHoardStatus', "", %game.HoardMode, $Host::TimeLimit, %curTimeLeftMS, %game.HoardStartTime, %game.HoardDuration); - messageClient(%client, 'MsgHuntYouHaveFlags', "", 0); - messageClient(%client, 'MsgYourScoreIs', "", 0); - // MES function below does not exist - //%game.populateRankArray(%client); - //messageClient(%client, 'MsgYourRankIs', "", -1); - - messageClient(%client, 'MsgMissionDropInfo', '\c0You are in mission %1 (%2).', $MissionDisplayName, $MissionTypeDisplayName, $ServerName ); - - DefaultGame::clientMissionDropReady(%game, %client); -} - -function HuntersGame::AIHasJoined(%game, %client) -{ - //let everyone know the player has joined the game - //messageAllExcept(%client, -1, 'MsgClientJoin', '%1 joined the game.', %client.name, "", %client, 1); -} - -function HuntersGame::resetScore(%game, %client) -{ - %client.score = 0; - %client.suicides = 0; - %client.kills = 0; - %client.teamKills = 0; - %client.deaths = 0; - %client.flagPoints = 0; -} - -function HuntersGame::recalcScore(%game, %cl) -{ - if (%cl <= 0) - return; - - %killValue = %cl.kills * %game.SCORE_PER_KILL; - %deathValue = %cl.deaths * %game.SCORE_PER_DEATH; - - if (%killValue - %deathValue == 0) - %killPoints = 0; - else - %killPoints = (%killValue * %killValue) / (%killValue - %deathValue); - - %cl.score = %killPoints; - %cl.score += %cl.flagPoints; - %cl.score += %cl.suicides * %game.SCORE_PER_SUICIDE; - //%cl.score = mFloatLength(%cl.score, 1); - %cl.score = mFloor(%cl.score); - - //must send the message to update the HUD - messageClient(%cl, 'MsgYourScoreIs', "", %cl.score); - - %game.recalcTeamRanks(%cl); -} - -function HuntersGame::sendGameVoteMenu( %game, %client, %key ) -{ - // Don't send any options if a vote is already running: - if ( %game.scheduleVote $= "" ) - { - // First send the common options: - DefaultGame::sendGameVoteMenu( %game, %client, %key ); - - if (!isDemo()) - { - if(!%client.isAdmin) - { - // Now send the Hunters-specific options: - if ( %game.greedMode ) - messageClient( %client, 'MsgVoteItem', "", %key, 'VoteGreedMode', 'disable greed mode', 'Vote Disable GREED Mode' ); - else - messageClient( %client, 'MsgVoteItem', "", %key, 'VoteGreedMode', 'enable greed mode', 'Vote Enable GREED Mode' ); - - if ( %game.HoardMode ) - messageClient( %client, 'MsgVoteItem', "", %key, 'VoteHoardMode', 'disable hoard mode', 'Vote Disable HOARD Mode' ); - else - messageClient( %client, 'MsgVoteItem', "", %key, 'VoteHoardMode', 'enable hoard mode', 'Vote Enable HOARD Mode' ); - } - else - { - if ( %game.greedMode ) - messageClient( %client, 'MsgVoteItem', "", %key, 'VoteGreedMode', 'disable greed mode', 'Disable GREED Mode' ); - else - messageClient( %client, 'MsgVoteItem', "", %key, 'VoteGreedMode', 'enable greed mode', 'Enable GREED Mode' ); - - if ( %game.HoardMode ) - messageClient( %client, 'MsgVoteItem', "", %key, 'VoteHoardMode', 'disable hoard mode', 'Disable HOARD Mode' ); - else - messageClient( %client, 'MsgVoteItem', "", %key, 'VoteHoardMode', 'enable hoard mode', 'Enable HOARD Mode' ); - } - } - } -} - -function HuntersGame::voteGreedMode( %game, %admin, %player ) -{ - %cause = ""; - %setto = ""; - if ( %admin ) - { - if ( %game.greedMode ) - { - messageAll( 'AdminDisableGreedMode', '\c2The Admin has disabled GREED mode.~wfx/misc/hunters_greed.wav' ); - %game.greedMode = false; - %setto = "disabled"; - } - else - { - messageAll( 'AdminEnableGreedMode', '\c2The Admin has enabled GREED mode.~wfx/misc/hunters_greed.wav' ); - %game.greedMode = true; - %setto = "enabled"; - } - %cause = "(admin)"; - } - else - { - %totalVotes = %game.totalVotesFor + %game.totalVotesAgainst; - if ( %totalVotes > 0 && ( %game.totalVotesFor / %totalVotes ) > 0.7 ) - { - if ( %game.greedMode ) - { - messageAll( 'MsgVotePassed', '\c2GREED mode was disabled by vote.~wfx/misc/hunters_greed.wav' ); - %game.greedMode = false; - %setto = "disabled"; - } - else - { - messageAll( 'MsgVotePassed', '\c2GREED mode was enabled by vote.~wfx/misc/hunters_greed.wav' ); - %game.greedMode = true; - %setto = "enabled"; - } - %cause = "(vote)"; -// alxPlay(VotePassSound, 0, 0, 0); - } - else - { - if ( %game.greedMode ) - messageAll( 'MsgVoteFailed', '\c2Disable GREED mode vote did not pass, %1 to %2.', %game.totalVotesFor, %game.totalVotesAgainst ); - else - messageAll( 'MsgVoteFailed', '\c2Enable GREED mode vote did not pass, %1 to %2.', %game.totalVotesFor, %game.totalVotesAgainst ); -// alxPlay(VoteNotPassSound, 0, 0, 0); - } - } - - //send the global message - messageAll('MsgHuntGreedStatus', "", %game.greedMode, %game.GreedMinFlags); - if(%setto !$= "") - logEcho("greed mode "@%setto SPC %cause); - - //store the result - if (%game.teamMode) - $Host::TeamHuntersGreedMode = %game.greedMode; - else - $Host::HuntersGreedMode = %game.greedMode; -} - -function HuntersGame::voteHoardMode( %game, %admin, %player ) -{ - %cause = ""; - %setto = ""; - - if ( %admin ) - { - if ( %game.HoardMode ) - { - messageAll( 'AdminDisableHoardMode', '\c2The Admin has disabled HOARD mode.' ); - %game.HoardMode = false; - %setto = "disabled"; - } - else - { - messageAll( 'AdminEnableHoardMode', '\c2The Admin has enabled HOARD mode.' ); - %game.HoardMode = true; - %setto = "enabled"; - } - %cause = "(admin)"; - } - else - { - %totalVotes = %game.totalVotesFor + %game.totalVotesAgainst; - if ( %totalVotes > 0 && ( %game.totalVotesFor / %totalVotes ) > 0.7 ) - { - if ( %game.HoardMode ) - { - messageAll( 'MsgVotePassed', '\c2HOARD mode was disabled by vote.' ); - %game.HoardMode = false; - %setto = "disabled"; - } - else - { - messageAll( 'MsgVotePassed', '\c2HOARD mode was enabled by vote.' ); - %game.HoardMode = true; - %setto = "enabled"; - } - %cause = "(vote)"; -// alxPlay(VotePassSound, 0, 0, 0); - } - else - { - if ( %game.HoardMode ) - messageAll( 'MsgVoteFailed', '\c2Disable HOARD mode vote did not pass, %1 to %2.', %game.totalVotesFor, %game.totalVotesAgainst ); - else - messageAll( 'MsgVoteFailed', '\c2Enable HOARD mode vote did not pass, %1 to %2.', %game.totalVotesFor, %game.totalVotesAgainst ); -// alxPlay(VoteNotPassSound, 0, 0, 0); - } - } - - //send the global message - %curTimeLeftMS = ($Host::TimeLimit * 60 * 1000) + $missionStartTime - getSimTime(); - messageAll('MsgHuntHoardStatus', "", %game.HoardMode, $Host::TimeLimit, %curTimeLeftMS, %game.HoardStartTime, %game.HoardDuration); - if(%setto !$= "") - logEcho("hoard mode "@%setto SPC %cause); - - //store the result - if (%game.teamMode) - $Host::TeamHuntersHoardMode = %game.HoardMode; - else - $Host::HuntersHoardMode = %game.HoardMode; -} - -function HuntersGame::voteChangeTimeLimit( %game, %admin, %newLimit ) -{ - %oldTimeLimit = $Host::TimeLimit; - DefaultGame::voteChangeTimeLimit(%game, %admin, %newLimit); - - //if the time limit changed, this will affect hoard mode: - if ($Host::TimeLimit != %oldTimeLimit) - { - %game.setupHoardCountdown(); - } -} - -function createDroppedFlag(%data, %value, %player, %game) -{ - %client = %player.client; - %playerPos = %player.getWorldBoxCenter(); - - // create a flag and throw it - %droppedflag = new Item() { - position = %playerPos; - rotation = "0 0 1 " @ (getRandom() * 360); - scale = "1 1 1"; - dataBlock = %data; - collideable = "0"; - static = "0"; - rotate = "0"; - team = "0"; - }; - $FlagGroup.add(%droppedflag); - %droppedFlag.value = %value; - - // set the flags target (for proper skin) - %droppedFlag.setTarget(%data.target); - - //throw the flag randomly away from the body - if (%client.isDead) - { - %vec = (-1.0 + getRandom() * 2.0) SPC (-1.0 + getRandom() * 2.0) SPC getRandom(); - %vec = VectorScale(%vec, 1000 + (getRandom() * 500)); - - // Add player's velocity - %vec = vectorAdd(%vec, %player.getVelocity()); - } - - //else if the player is Out of bounds, throw them in the direction of the nexus - else if (%client.outOfBounds) - { - %towardsNexusVec = VectorSub(%game.nexus.position, %player.position); - %towardsNexusVec = getWord(%towardsNexusVec, 0) SPC getWord(%towardsNexusVec, 1) SPC "0"; - %towardsNexusVec = VectorNormalize(%towardsNexusVec); - - //add a little noise - %vec = getWord(%towardsNexusVec, 0) + (-0.3 + getRandom() * 0.6) SPC - getWord(%towardsNexusVec, 1) + (-0.3 + getRandom() * 0.6) SPC - getWord(%towardsNexusVec, 2); - %vec = VectorScale(%vec, 1000 + (getRandom() * 500)); - } - - //else throw them more or less in the direction the player was facing... - else - { - %playerFacingVec = MatrixMulVector("0 0 0 " @ getWords(%client.player.getTransform(), 3, 6), "0 1 0"); - %playerFacingVec = VectorNormalize(%playerFacingVec); - - //add a little noise - %vec = getWord(%playerFacingVec, 0) + (-0.3 + getRandom() * 0.6) SPC - getWord(%playerFacingVec, 1) + (-0.3 + getRandom() * 0.6) SPC - getWord(%playerFacingVec, 2); - %vec = VectorScale(%vec, 1000 + (getRandom() * 500)); - - // Add player's velocity - %vec = vectorAdd(%vec, %player.getVelocity()); - } - - %droppedflag.applyImpulse(%playerPos, %vec); - %droppedflag.setCollisionTimeout(%player); - schedule(%game.flagLifeTimeMS, %droppedflag, "HuntersStartFlagTimeOut", %droppedflag); -} - -function HuntersGame::throwFlags(%game, %player) -{ - %client = %player.client; - - //find out how many flags to drop - if (%client.isDead) - %numFlags = %client.flagCount; - else - %numFlags = %client.flagCount - 1; - - if (%numFlags <= 0) - return; - //send the flags message right away... - if (isEventPending(%client.flagMsgPending)) - { - cancel(%client.flagMsgPending); - %game.sendFlagCountMessage(%client); - } - - %numFlagsToDrop = %numFlags; - - //reset the count (which doesn't matter if player is dead) - %client.flagCount = 1; - %client.couldSetRecord = false; - - //drop the flags - %flagIncrement = 1; - %db[1] = HuntersFlag1; - %db[2] = HuntersFlag2; - %db[4] = HuntersFlag4; - %db[8] = HuntersFlag8; - - %i = 0; - while (%i < %numFlagsToDrop) - { - for (%j = 0; %j < 5; %j++) - { - %numFlagsLeft = %numFlagsToDrop - %i; - if (%numFlagsLeft >= %flagIncrement) - { - createDroppedFlag(%db[%flagIncrement], %flagIncrement, %player, %game); - %i += %flagIncrement; - } - else - { - // cleanup - if (%numFlagsLeft >= 8) - { - createDroppedFlag(%db[8], 8, %player, %game); - %i += 8; - %numFlagsLeft -= 8; - } - if (%numFlagsLeft >= 4) - { - createDroppedFlag(%db[4], 4, %player, %game); - %i += 4; - %numFlagsLeft -= 4; - } - if (%numFlagsLeft >= 2) - { - createDroppedFlag(%db[2], 2, %player, %game); - %i += 2; - %numFlagsLeft -= 2; - } - if (%numFlagsLeft >= 1) - { - createDroppedFlag(%db[1], 1, %player, %game); - %i += 1; - %numFlagsLeft -= 1; - } - - if (%i != %numFlagsToDrop || %numFlagsLeft != 0) - { - error("Error, missing a flag!"); - } - break; - } - } - - if (%flagIncrement < 8) - %flagIncrement = %flagIncrement * 2; - } - - //yard sale! - if (%numFlags >= %game.yardSaleMin) - { - messageAll('MsgHuntYardSale', '\c2YARD SALE!!!~wfx/misc/yardsale.wav'); - - //create a waypoint at player's location... - %yardWaypoint = new WayPoint() - { - position = %player.position; - rotation = "1 0 0 0"; - scale = "1 1 1"; - name = "YARD SALE!"; - dataBlock = "WayPointMarker"; - lockCount = "0"; - homingCount = "0"; - team = "0"; - }; - - //add the waypoint to the cleanup group - MissionCleanup.add(%yardWaypoint); - $HuntersYardSaleSet.add(%yardWaypoint); - schedule(30000, %yardWaypoint, "HuntersYardSaleTimeOut", %yardWaypoint); - } - - //remove any mounted flag from the player - %player.unMountImage($FlagSlot); - - //update the client's hud - messageClient(%client, 'MsgHuntYouHaveFlags', "", 0); - - //new tracking - *everyone* automatically tracks the "flag hoarder" if they have at least 15 flags - %game.updateFlagHoarder(%client); -} - -function HuntersGame::dropFlag(%game, %player) -{ - //first throw the flags - %game.throwFlags(%player); - - //send the messages - if (%numFlags == 1) - { - messageAllExcept(%client, -1, 'MsgHuntPlayerDroppedFlags', '\c0%1 dropped 1 flag.', %client.name, 1); - messageClient(%client, 'MsgHuntYouDroppedFlags', '\c0You dropped 1 flag.', 1); - } - else if (%numFlags > 1) - { - messageAllExcept(%client, -1, 'MsgHuntPlayerDroppedFlags', '\c0%1 dropped %2 flags.', %client.name, %numFlags); - messageClient(%client, 'MsgHuntYouDroppedFlags', '\c0You dropped %1 flags.', %numFlags); - } - logEcho(%client.nameBase@" (pl "@%player@"/cl "@%client@") dropped "@%numFlags@" flags"); -} - -function HuntersGame::enterMissionArea(%game, %playerData, %player) -{ - if(%player.getState() $= "Dead") - return; - - %client = %player.client; - %client.outOfBounds = false; - cancel(%client.oobSched); - messageClient(%player.client, 'MsgEnterMissionArea', '\c1You are back in the mission area.'); - logEcho(%player.client.nameBase@" (pl "@%player@"/cl "@%player.client@") entered mission area"); - cancel(%player.alertThread); -} - -function HuntersGame::leaveMissionArea(%game, %playerData, %player) -{ - if(%player.getState() $= "Dead") - return; - - // strip flags and throw them back into the mission area - %client = %player.client; - %client.outOfBounds = true; - if (%player.client.flagCount > 1) - messageClient(%player.client, 'MsgLeaveMissionArea', '\c1You have left the mission area and will lose your flags!~wfx/misc/warning_beep.wav'); - else - messageClient(%player.client, 'MsgLeaveMissionArea', '\c1You have left the mission area.~wfx/misc/warning_beep.wav'); - - %client.oobSched = %game.schedule(%game.oobThrowFlagsDelayMS, "outOfBoundsThrowFlags", %client); - logEcho(%player.client.nameBase@" (pl "@%player@"/cl "@%player.client@") left mission area"); -} - -function HuntersGame::outOfBoundsThrowFlags(%game, %client) -{ - %player = %client.player; - if (!%client.outOfBounds) - return; - - if (%client.flagCount > 1) - { - %game.throwFlags(%player); - messageClient(%player.client, 'MsgLeaveMissionArea', '\c1You are out of the mission area and have lost your flags!~wfx/misc/flag_taken.wav'); - } - - //set the next schedule check - %client.oobSched = %game.schedule(%game.oobThrowFlagsDelayMS, "outOfBoundsThrowFlags", %client); -} - -function HuntersGame::onEnterTrigger(%game, %triggerName, %data, %obj, %colobj) -{ - //schedule a warning in 10 seconds - %client = %colobj.client; - %client.campingThread = %game.schedule(game.nexusCampingTime, "CampingDamage", %client, true); -} - -function HuntersGame::onLeaveTrigger(%game, %triggerName, %data, %obj, %colobj) -{ - %client = %colobj.client; - cancel(%client.campingThread); -} - -function HuntersGame::CampingDamage(%game, %client, %firstWarning) -{ - //make sure we're still alive... - %player = %client.player; - if (!isObject(%player) || %player.getState() $= "Dead") - return; - - //if the match hasn't yet started, don't warn or apply damage yet... - if (!$MatchStarted) - { - %client.campingThread = %game.schedule(game.nexusCampingTime / 2, "CampingDamage", %client, true); - } - else if (%firstWarning) - { - messageClient(%client, 'MsgHuntersNoCampZone', '\c2No camping near the Nexus.', 1); - %client.campingThread = %game.schedule(game.nexusCampingTime / 2, "CampingDamage", %client, false); - } - else - { - %player.setDamageFlash(0.1); - %player.damage(0, %player.position, 0.05, $DamageType::NexusCamping); - %client.campingThread = %game.schedule(1000, "CampingDamage", %client, false); - } - -} - -function HuntersGame::updateScoreHud(%game, %client, %tag) -{ - //tricky stuff here... use two columns if we have more than 15 clients... - %numClients = $TeamRank[0, count]; - if (%numClients > $ScoreHudMaxVisible) - %numColumns = 2; - - // Clear the header: - messageClient( %client, 'SetScoreHudHeader', "", "" ); - - // Send header: - if ( %numColumns == 2 ) - messageClient( %client, 'SetScoreHudSubheader', "", '\tPLAYER\tSCORE\tFLAGS\tPLAYER\tSCORE\tFLAGS' ); - else - messageClient( %client, 'SetScoreHudSubheader', "", '\tPLAYER\tSCORE\tFLAGS' ); - - //find out who has the most flags - %maxFlagsClient = -1; - %maxFlags = -1; - for (%i = 0; %i < %numClients; %i++) - { - %cl = $TeamRank[0, %i]; - if (%cl.flagCount > %maxFlags) - { - %maxFlags = %cl.flagCount - 1; - %maxFlagsClient = %cl; - } - } - - //if no one has any flags, don't hilite anyone... - if (%maxFlags <= 0) - %maxFlagsClient = -1; - - %countMax = %numClients; - if ( %countMax > ( 2 * $ScoreHudMaxVisible ) ) - { - if ( %countMax & 1 ) - %countMax++; - %countMax = %countMax / 2; - } - else if ( %countMax > $ScoreHudMaxVisible ) - %countMax = $ScoreHudMaxVisible; - - for (%index = 0; %index < %countMax; %index++) - { - //get the client info - %col1Client = $TeamRank[0, %index]; - %col1ClientScore = %col1Client.score $= "" ? 0 : %col1Client.score; - %col1ClientFlags = %col1Client.flagCount - 1; - if (%col1ClientFlags <= 0) - %col1ClientFlags = ""; - %col1Style = ""; - if ( %col1Client == %maxFlagsClient ) - %col1Style = ""; - else if ( %col1Client == %client ) - %col1Style = ""; - - //see if we have two columns - if (%numColumns == 2) - { - %col2Client = ""; - %col2ClientScore = ""; - %col2ClientFlags = ""; - %col2Style = ""; - - //get the column 2 client info - %col2Index = %index + %countMax; - if (%col2Index < %numClients) - { - %col2Client = $TeamRank[0, %col2Index]; - %col2ClientScore = %col2Client.score $= "" ? 0 : %col2Client.score; - %col2ClientFlags = %col2Client.flagCount - 1; - if (%col2ClientFlags <= 0) - %col2ClientFlags = ""; - if ( %col2Client == %maxFlagsClient ) - %col2Style = ""; - else if ( %col2Client == %client ) - %col2Style = ""; - } - } - - //if the client is not an observer, send the message - if (%client.team != 0) - { - if ( %numColumns == 2 ) - messageClient( %client, 'SetLineHud', "", %tag, %index, '%7\t%1%2%3%8%4%5%6', - %col1Client.name, %col1ClientScore, %col1ClientFlags, %col2Client.name, %col2ClientScore, %col2ClientFlags, %col1Style, %col2Style ); - else - messageClient( %client, 'SetLineHud', "", %tag, %index, '%4\t%1%2%3', - %col1Client.name, %col1ClientScore, %col1ClientFlags, %col1Style ); - } - - //else for observers, create an anchor around the player name so they can be observed - else - { - if ( %numColumns == 2 ) - { - - //this is lame, but we can only have up to %9 args - if ( %col2Client == %maxFlagsClient ) - { - messageClient( %client, 'SetLineHud', "", %tag, %index, '%7\t%1%2%3%4%5%6', - %col1Client.name, %col1ClientScore, %col1ClientFlags, - %col2Client.name, %col2ClientScore, %col2ClientFlags, - %col1Style, %col1Client, %col2Client); - } - else if ( %col2Client == %client ) - { - messageClient( %client, 'SetLineHud', "", %tag, %index, '%7\t%1%2%3%4%5%6', - %col1Client.name, %col1ClientScore, %col1ClientFlags, - %col2Client.name, %col2ClientScore, %col2ClientFlags, - %col1Style, %col1Client, %col2Client); - } - else - { - messageClient( %client, 'SetLineHud', "", %tag, %index, '%7\t%1%2%3%4%5%6', - %col1Client.name, %col1ClientScore, %col1ClientFlags, - %col2Client.name, %col2ClientScore, %col2ClientFlags, - %col1Style, %col1Client, %col2Client); - } - } - else - messageClient( %client, 'SetLineHud', "", %tag, %index, '%4\t%1%2%3', - %col1Client.name, %col1ClientScore, %col1ClientFlags, %col1Style, %col1Client ); - } - } - - // Tack on the list of observers: - %observerCount = 0; - for (%i = 0; %i < ClientGroup.getCount(); %i++) - { - %cl = ClientGroup.getObject(%i); - if (%cl.team == 0) - %observerCount++; - } - - if (%observerCount > 0) - { - messageClient( %client, 'SetLineHud', "", %tag, %index, ""); - %index++; - messageClient(%client, 'SetLineHud', "", %tag, %index, '\tOBSERVERS (%1)TIME', %observerCount); - %index++; - for (%i = 0; %i < ClientGroup.getCount(); %i++) - { - %cl = ClientGroup.getObject(%i); - //if this is an observer - if (%cl.team == 0) - { - %obsTime = getSimTime() - %cl.observerStartTime; - %obsTimeStr = %game.formatTime(%obsTime, false); - messageClient( %client, 'SetLineHud', "", %tag, %index, '\t%1%2', - %cl.name, %obsTimeStr ); - %index++; - } - } - } - - //clear the rest of Hud so we don't get old lines hanging around... - messageClient( %client, 'ClearHud', "", %tag, %index ); -} - -function HuntersGame::sendDebriefing( %game, %client ) -{ - // Mission result: - if ( $TeamRank[0, 0].score > 0 ) - messageClient( %client, 'MsgDebriefResult', "", '%1 wins with a score of %2!', $TeamRank[0, 0].name, $TeamRank[0, 0].score ); - else - messageClient( %client, 'MsgDebriefResult', "", 'Nobody wins!' ); - - - if ( %game.highestFlagReturnName !$= "" ) - messageClient( %client, 'MsgDebriefResult', "", '%1 had the highest return count with %2 flags!', %game.highestFlagReturnName, %game.highestFlagReturnCount ); - - if ( $Host::HuntersRecords::Count[$currentMission] !$= "" && $Host::HuntersRecords::Name[$currentMission] !$= "" ) - messageClient( %client, 'MsgDebriefResult', "", '%1 holds the record with a return count of %2 flags!', $Host::HuntersRecords::Name[$currentMission], $Host::HuntersRecords::Count[$currentMission] ); - - if ( %game.greedFlagName !$= "" ) - messageClient( %client, 'MsgDebriefResult', "", '%1 gets the honorary greed award for dropping %2 flags!', %game.greedFlagName, %game.greedFlagCount ); - - // Player scores: - messageClient( %client, 'MsgDebriefAddLine', "", 'PLAYERSCOREKILLS' ); - %count = $TeamRank[0, count]; - for ( %i = 0; %i < %count; %i++ ) - { - %cl = $TeamRank[0, %i]; - if ( %cl.score $= "" ) - %score = 0; - else - %score = %cl.score; - if ( %cl.kills $= "" ) - %kills = 0; - else - %kills = %cl.kills; - messageClient( %client, 'MsgDebriefAddLine', "", ' %1 %2 %3', %cl.name, %score, %kills ); - } - - // Show observers: - %count = ClientGroup.getCount(); - %header = false; - for ( %i = 0; %i < %count; %i++ ) - { - %cl = ClientGroup.getObject( %i ); - if ( %cl.team <= 0 ) - { - if ( !%header ) - { - messageClient( %client, 'MsgDebriefAddLine', "", '\nOBSERVERSSCORE' ); - %header = true; - } - - %score = %cl.score $= "" ? 0 : %cl.score; - messageClient( %client, 'MsgDebriefAddLine', "", ' %1 %2', %cl.name, %score ); - } - } -} - -function HuntersGame::applyConcussion(%game, %player) -{ - //%game.dropFlag( %player ); -} +//--------------------------------------// +// HuntersGame.cs // +//--------------------------------------// + +//--- GAME RULES BEGIN --- +//Kill other players to make them drop flags +//Return flags to the Nexus for points +//The more flags brought to Nexus at one time, the more each flag scores +//GREED mode: you must return 8 or more flags at once to score +//HOARD mode: no returns between 5 and 2 min. left in game +//Flag Colors: Red = 1pt, Blue = 2pts, Yellow = 4pts, Green = 8pts +//--- GAME RULES END --- + +package HuntersGame { + +function Nexus::objectiveInit(%data, %object) +{ + Game.Nexus = %object; + Game.Nexus.playThread(0, "ambient"); + Game.Nexus.setThreadDir(0, true); + //The flash animation plays forwards, then back automatically, so we have to alternate the thread direcction... + Game.Nexus.flashThreadDir = true; + +} + +function NexusBase::objectiveInit(%data, %object) +{ + Game.NexusBase = %object; + Game.NexusBase.playthread(0, "ambient"); + Game.NexusBase.setThreadDir(0, true); +} + +function NexusCap::objectiveInit(%data, %object) +{ + Game.NexusCap = %object; + Game.NexusCap.playthread(0, "ambient"); + Game.NexusCap.setThreadDir(0, true); +} + +}; + +$InvBanList[Hunters, "TurretOutdoorDeployable"] = 1; +$InvBanList[Hunters, "TurretIndoorDeployable"] = 1; +$InvBanList[Hunters, "ElfBarrelPack"] = 1; +$InvBanList[Hunters, "MortarBarrelPack"] = 1; +$InvBanList[Hunters, "PlasmaBarrelPack"] = 1; +$InvBanList[Hunters, "AABarrelPack"] = 1; +$InvBanList[Hunters, "MissileBarrelPack"] = 1; +$InvBanList[Hunters, "Mine"] = 1; +$InvBanList[Hunters, "MiningTool"] = 1; + +datablock EffectProfile(HuntersFlagPickupEffect) +{ + effectname = "misc/hunters_flag_snatch"; + minDistance = 2.5; + maxDistance = 5.0; +}; + +datablock AudioProfile(HuntersFlagPickupSound) +{ + filename = "fx/misc/hunters_flag_snatch.wav"; + description = AudioClose3d; + effect = HuntersFlagPickupEffect; + preload = true; +}; + + +//exec the AI script +exec("scripts/aiHunters.cs"); + +//exec the records script +if (isFile("prefs/HuntersRecords.cs")) + exec("prefs/HuntersRecords.cs"); + +//----------------------------------------------------------------------------- +//Game initialization functions + +function HuntersGame::setUpTeams(%game) +{ + // Force the numTeams variable to one: + DefaultGame::setUpTeams(%game); + %game.numTeams = 1; + + // allow teams 1->31 to listen to each other (team 0 can only listen to self) + for(%i = 1; %i < 32; %i++) + setSensorGroupListenMask(%i, 0xfffffffe); +} + +function HuntersGame::initGameVars(%game) +{ + %game.SCORE_PER_SUICIDE = -1; + %game.SCORE_PER_DEATH = 0; + %game.SCORE_PER_KILL = 1; + + %game.teamMode = false; + + if (!isDemo()) + %game.greedMode = $Host::HuntersGreedMode; + else + %game.greedMode = false; + %game.greedMinFlags = 8; //min number of flags you must have before you can cap + + if (!isDemo()) + %game.hoardMode = $Host::HuntersHoardMode; + else + %game.hoardMode = false; + %game.HoardStartTime = 5; //time left in the game at which hoard mode will start + %game.HoardDuration = 3; //duration of the hoard period + %game.HoardEndTime = %game.HoardStartTime - %game.HoardDuration; + + %game.yardSaleMin = 10; + + //make sure there is enough time in the match to actually have a hoard mode... + if ($host::timeLimit < %game.hoardStartTime + 1) + %game.hoardMode = false; + + %game.maxSensorGroup = 0; + + %game.highestFlagReturnCount = 10; //initialize to 10 - don't bother recording less than that... + %game.highestFlagReturnName = ""; + %game.greedFlagCount = 10; //initialize to 10 - don't bother recording greed less than that... + %game.greedFlagName = ""; + + //this is how many humans have to be playing in order to set a record + %game.numHumansForRecord = 4; + + //this is how many milliseconds before a warning is issued for camping near the Nexus + %game.nexusCampingTime = 10000; + + %game.flagHoarder = ""; + %game.flagHoarderMin = 15; + + //vars for how long before the flag is deleted, and the fade transition time... + %game.flagLifeTimeMS = 120000; + %game.fadeTimeMS = 2000; + + %game.flagMsgDelayMS = 3000; + %game.oobThrowFlagsDelayMS = 3000; + + // targets for each of the flag types (except for base which is properly skinned already) + HuntersFlag1.target = -1; // red + HuntersFlag2.target = allocTarget("", 'Blue', "", "", 0, "", ""); + HuntersFlag4.target = allocTarget("", 'Yellow', "", "", 0, "", ""); + HuntersFlag8.target = allocTarget("", 'Green', "", "", 0, "", ""); +} + +function HuntersGame::allowsProtectedStatics(%game) +{ + return true; +} + +function HuntersGame::missionLoadDone(%game) +{ + //default version sets up teams - must be called first... + DefaultGame::missionLoadDone(%game); + + //initialize the score and flag count for all the players + %count = ClientGroup.getCount(); + for(%i = 0; %i < %count; %i++) + { + %client = ClientGroup.getObject(%i); + %game.resetScore(%client); + %client.flagCount = 1; + %client.trackWaypoint = ""; + %client.playerTrackLine = -1; + } + $TopClient = -1; + $TopClientScore = 0; + + //create the Flag group + $FlagGroup = nameToID("MissionCleanup/FlagGroup"); + if ($FlagGroup <= 0) + { + $FlagGroup = new SimGroup("FlagGroup"); + MissionCleanup.add($FlagGroup); + } + + //create the "yard sale waypoint set" + if(nameToId("HuntersYardSaleSet") <= 0) + { + $HuntersYardSaleSet = new SimSet("HuntersYardSaleSet"); + MissionCleanup.add($HuntersYardSaleSet); + } +} + + +function HuntersGame::startMatch(%game) +{ + //call the default + DefaultGame::startMatch(%game); + + //schedule the hoard countdowns + %game.setupHoardCountdown(); +} + +function HuntersGame::setupHoardCountdown(%game) +{ + //delete all previous scheduled calls... + cancel(%game.hoardStart30); + cancel(%game.hoardStart10); + cancel(%game.hoardStart5); + cancel(%game.hoardStart4); + cancel(%game.hoardStart3); + cancel(%game.hoardStart2); + cancel(%game.hoardStart1); + cancel(%game.hoardStart0); + + cancel(%game.hoardEnd30); + cancel(%game.hoardEnd10); + cancel(%game.hoardEnd5); + cancel(%game.hoardEnd4); + cancel(%game.hoardEnd3); + cancel(%game.hoardEnd2); + cancel(%game.hoardEnd1); + cancel(%game.hoardEnd0); + + //schedule hoard mode start notify calls + %curTimeLeftMS = ($Host::TimeLimit * 60 * 1000) + $missionStartTime - getSimTime(); + %hoardStartTimeMS = %game.HoardStartTime * 60 * 1000; + + if (%curTimeLeftMS >= %hoardStartTimeMS + 30000) + %game.hoardStart30 = %game.schedule(%curTimeLeftMS - (%hoardStartTimeMS + 30000), "notifyHoardStart", 30); + + if (%curTimeLeftMS >= %hoardStartTimeMS + 10000) + %game.hoardStart10 = %game.schedule(%curTimeLeftMS - (%hoardStartTimeMS + 10000), "notifyHoardStart", 10); + + if (%curTimeLeftMS >= %hoardStartTimeMS + 5000) + %game.hoardStart5 = %game.schedule(%curTimeLeftMS - (%hoardStartTimeMS + 5000), "notifyHoardStart", 5); + + if (%curTimeLeftMS >= %hoardStartTimeMS + 4000) + %game.hoardStart4 = %game.schedule(%curTimeLeftMS - (%hoardStartTimeMS + 4000), "notifyHoardStart", 4); + + if (%curTimeLeftMS >= %hoardStartTimeMS + 3000) + %game.hoardStart3 = %game.schedule(%curTimeLeftMS - (%hoardStartTimeMS + 3000), "notifyHoardStart", 3); + + if (%curTimeLeftMS >= %hoardStartTimeMS + 2000) + %game.hoardStart2 = %game.schedule(%curTimeLeftMS - (%hoardStartTimeMS + 2000), "notifyHoardStart", 2); + + if (%curTimeLeftMS >= %hoardStartTimeMS + 1000) + %game.hoardStart1 = %game.schedule(%curTimeLeftMS - (%hoardStartTimeMS + 1000), "notifyHoardStart", 1); + + if (%curTimeLeftMS >= %hoardStartTimeMS) + %game.hoardStart0 = %game.schedule(%curTimeLeftMS - %hoardStartTimeMS, "notifyHoardStart", 0); + + + //schedule hoard mode end notify calls + %hoardEndTimeMS = %game.HoardEndTime * 60 * 1000; + + if (%curTimeLeftMS >= %hoardEndTimeMS + 30000) + %game.hoardEnd30 = %game.schedule(%curTimeLeftMS - (%hoardEndTimeMS + 30000), "notifyHoardEnd", 30); + + if (%curTimeLeftMS >= %hoardEndTimeMS + 10000) + %game.hoardEnd10 = %game.schedule(%curTimeLeftMS - (%hoardEndTimeMS + 10000), "notifyHoardEnd", 10); + + if (%curTimeLeftMS >= %hoardEndTimeMS + 5000) + %game.hoardEnd5 = %game.schedule(%curTimeLeftMS - (%hoardEndTimeMS + 5000), "notifyHoardEnd", 5); + + if (%curTimeLeftMS >= %hoardEndTimeMS + 4000) + %game.hoardEnd4 = %game.schedule(%curTimeLeftMS - (%hoardEndTimeMS + 4000), "notifyHoardEnd", 4); + + if (%curTimeLeftMS >= %hoardEndTimeMS + 3000) + %game.hoardEnd3 = %game.schedule(%curTimeLeftMS - (%hoardEndTimeMS + 3000), "notifyHoardEnd", 3); + + if (%curTimeLeftMS >= %hoardEndTimeMS + 2000) + %game.hoardEnd2 = %game.schedule(%curTimeLeftMS - (%hoardEndTimeMS + 2000), "notifyHoardEnd", 2); + + if (%curTimeLeftMS >= %hoardEndTimeMS + 1000) + %game.hoardEnd1 = %game.schedule(%curTimeLeftMS - (%hoardEndTimeMS + 1000), "notifyHoardEnd", 1); + + if (%curTimeLeftMS >= %hoardEndTimeMS) + %game.hoardEnd0 = %game.schedule(%curTimeLeftMS - %hoardEndTimeMS, "notifyHoardEnd", 0); +} + +function HuntersGame::notifyHoardStart(%game, %seconds) +{ + if (%game.HoardMode) + { + if (%seconds > 1) + messageAll('MsgHuntersHoardNotifyStart', '\c2%1 seconds left until the HOARD period begins.~wfx/misc/hunters_%1.wav', %seconds); + else if (%seconds == 1) + messageAll('MsgHuntersHoardNotifyStart', '\c21 second left until the HOARD period begins.~wfx/misc/hunters_1.wav'); + else + { + messageAll('MsgHuntHoardNotifyStarted', '\c2The HOARD period has begun.~wfx/misc/hunters_horde.wav'); + logEcho("hoard mode start"); + %game.setNexusDisabled(); + cancel(%game.greedNexusFlash); + } + } +} + +function HuntersGame::notifyHoardEnd(%game, %seconds) +{ + if (%game.HoardMode) + { + if (%seconds > 1) + messageAll('MsgHuntersHoardNotifyEnd', '\c2%1 seconds left until the HOARD period ends.~wfx/misc/hunters_%1.wav', %seconds); + else if (%seconds == 1) + messageAll('MsgHuntersHoardNotifyEnd', '\c21 second left until the HOARD period ends.~wfx/misc/hunters_1.wav'); + else + { + messageAll('MsgHuntersHoardNotifyEnded', '\c2The HOARD period has ended!~wfx/misc/hunters_greed.wav'); + logEcho("hoard mode end"); + %game.setNexusEnabled(); + cancel(%game.greedNexusFlash); + } + } +} + +function HuntersGame::clientJoinTeam( %game, %client, %team, %respawn ) +{ + %game.assignClientTeam( %client ); + + // Spawn the player: + %game.spawnPlayer( %client, %respawn ); +} + +//----------------------------------------------------------------------------- +//Player spawn/death functions + +function HuntersGame::assignClientTeam(%game, %client) +{ + %client.team = 0; + + //initialize the team array + for (%i = 1; %i < 32; %i++) + $HuntersTeamArray[%i] = false; + + %game.maxSensorGroup = 0; + %count = ClientGroup.getCount(); + for (%i = 0; %i < %count; %i++) + { + %cl = ClientGroup.getObject(%i); + if (%cl.team != 0) + $HuntersTeamArray[%cl.team] = true; + + //need to set the number of sensor groups to the max... + if (%cl.team > %game.maxSensorGroup) + %game.maxSensorGroup = %cl.team; + } + + //now loop through the team array, looking for an empty team + for (%i = 1; %i < 32; %i++) + { + if (! $HuntersTeamArray[%i]) + { + %client.team = %i; + + if (%client.team > %game.maxSensorGroup) + %game.maxSensorGroup = %client.team; + + break; + } + } + + // set player's skin pref here + setTargetSkin(%client.target, %client.skin); + + // Let everybody know you are no longer an observer: + messageAll( 'MsgClientJoinTeam', '\c1%1 has joined the hunt.', %client.name, "", %client, 1 ); + updateCanListenState( %client ); + + //now set the max number of sensor groups... + setSensorGroupCount(%game.maxSensorGroup + 1); +} + +function HuntersGame::createPlayer(%game, %client, %spawnLoc, %respawn) +{ + //first call the default + DefaultGame::createPlayer(%game, %client, %spawnLoc, %respawn); + + //now set the sensor group + %client.setSensorGroup(%client.team); +} + +function HuntersGame::pickPlayerSpawn(%game, %client, %respawn) +{ + return %game.pickTeamSpawn(1); +} + +function HuntersGame::playerSpawned(%game, %player, %armor) +{ + //intialize + %client = %player.client; + %client.flagCount = 1; + %client.isDead = false; + + //make sure they're not still taking camping damage... + cancel(%client.campingThread); + + + //continue with the default + DefaultGame::playerSpawned(%game, %player, %armor); +} + +function HuntersGame::onClientKilled(%game, %clVictim, %clKiller, %damageType, %implement, %damageLoc) +{ + //set the flag + %clVictim.isDead = true; + + //set the greed variable if required + if (!%game.teamMode && $missionRunning) + { + if (%clVictim.flagCount - 1 > %game.greedFlagCount) + { + %game.greedFlagCount = %clVictim.flagCount - 1; + %game.greedFlagName = getTaggedString(%clVictim.name); + } + } + + //first, drop all the flags + HuntersGame::dropFlag(%game, %clVictim.player); + + //now call the default game stuff + DefaultGame::onClientKilled(%game, %clVictim, %clKiller, %damageType, %implement, %damageLoc); + + messageClient(%clVictim, 'MsgHuntYouHaveFlags', "", 0); +} + +function HuntersGame::updateKillScores(%game, %clVictim, %clKiller, %damageType, %implement) +{ + if (%game.testKill(%clVictim, %clKiller)) //verify victim was an enemy + { + %game.awardScoreKill(%clKiller); + %game.awardScoreDeath(%clVictim); + } + else if (%game.testSuicide(%clVictim, %clKiller, %damageType)) //otherwise test for suicide + %game.awardScoreSuicide(%clVictim); +} + +function Huntersgame::awardScoreKill(%game, %client) +{ + //call the default + DefaultGame::awardScoreKill(%game, %client); + + //check if we have a new leader + if (!%game.teamMode && (%client.score > $TopClientScore)) + { + $TopClientScore = %client.score; + //this message is annoying! + //if (%client != $TopClient) + // messageAll('MsgHuntNewTopScore', '\c0%1 has taken the lead with a score of %2!~wfx/misc/flag_capture.wav', %client.name, %client.score); + $TopClient = %client; + } +} + +function Huntersgame::awardScoreSuicide(%game, %client) +{ + //call the default + DefaultGame::awardScoreSuicide(%game, %client); + + //check if we have a new leader + if (!%game.teamMode && %client == $TopClient && (%client.score < $TopClientScore)) + { + //first lower the topClientScore var + $TopClientScore = %client.score; + + //see if there's a new leader... + %highestScore = %client.score; + %highestScoreClient = -1; + for (%i = 0; %i < ClientGroup.getCount(); %i++) + { + %cl = ClientGroup.getObject(%i); + if (%cl.score > %highestScore) + { + %highestScore = %cl.score; + %highestScoreClient = %cl; + } + } + + //did we find someone? + if (%highestScoreClient > 0) + { + $TopClientScore = %highestScoreClient.score; + $TopClient = %highestScoreClient; + //this message is annoying... + //messageAll('MsgHuntNewTopScore', '\c0%1 is now in the lead with a score of %2!~wfx/misc/flag_capture.wav', %highestScoreClient.name, %highestScoreClient.score); + } + } +} + +function HuntersGame::equip(%game, %player) +{ + for(%i =0; %i<$InventoryHudCount; %i++) + %player.client.setInventoryHudItem($InventoryHudData[%i, itemDataName], 0, 1); + %player.client.clearBackpackIcon(); + + //%player.setArmor("Light"); + %player.setInventory(RepairKit,1); + %player.setInventory(Grenade,6); + %player.setInventory(Blaster,1); + %player.setInventory(Chaingun,1); + %player.setInventory(ChaingunAmmo, 100); + %player.setInventory(Disc,1); + %player.setInventory(DiscAmmo, 20); + %player.setInventory(EnergyPack,1); + %player.setInventory(TargetingLaser, 1); + %player.weaponCount = 3; + + %player.use("Disc"); +} + +//----------------------------------------------------------------------------- +//flag functions +function HuntersGame::playerDroppedFlag(%game, %player) +{ + // this stuff has all been moved to HuntersGame::dropFlag + // we really don't want something to happen for *every* flag a player drops anyway +} + +function HuntersStartFlagTimeOut(%flag) +{ + // start the fade out... + %flag.startFade(Game.fadeTimeMS, 0, true); + schedule(Game.fadeTimeMS, %flag, "HuntersEndFlagTimeOut", %flag); +} + +function HuntersEndFlagTimeOut(%flag) +{ + %flag.delete(); +} + +function HuntersYardSaleTimeOut(%waypoint) +{ + %waypoint.delete(); +} + +function HuntersGame::updateFlagHoarder(%game, %eventClient) +{ + %hoarder = -1; + %maxFlags = -1; + %count = ClientGroup.getCount(); + for (%i = 0; %i < %count; %i++) + { + %client = ClientGroup.getObject(%i); + if (%client.flagCount > %game.flagHoarderMin && %client.flagCount > %maxFlags) + { + %maxflags = %client.flagCount; + %hoarder = %client; + } + } + + //if we found our hoarder, set the waypoint, otherwise, delete it + if (%hoarder > 0) + { + //only update if the event (capping, picking up flag, etc...) was the actual hoarder + if (!isObject(%game.flagHoarder) || %game.flagHoarder == %eventClient) + { + if (!isObject(%game.hoarderWaypoint)) + { + //create a waypoint at player's location... + %game.hoarderWaypoint = new WayPoint() + { + position = %hoarder.player.position; + rotation = "1 0 0 0"; + scale = "1 1 1"; + name = "Flag Hoarder Was Here"; + dataBlock = "WayPointMarker"; + lockCount = "0"; + homingCount = "0"; + team = 0; + }; + + //add the waypoint to the cleanup group + MissionCleanup.add(%game.hoarderWaypoint); + } + + //set the position + %game.flagHoarder = %hoarder; + %game.hoarderWaypoint.setTransform(%hoarder.player.getWorldBoxCenter() SPC "0 0 1 0"); + } + } + else if (isObject(%game.hoarderWaypoint)) + { + %game.flaghoarder = ""; + %game.hoarderWaypoint.delete(); + } +} + +function HuntersGame::sendFlagCountMessage(%game, %client) +{ + //send the messages + if (%client.flagCount - 1 == 1) + { + messageAllExcept(%client, -1, 'MsgHuntPlayerHasFlags', '\c2%1 now has 1 flag.', %client.name, 1); + messageClient(%client, 'MsgHuntYouHaveFlags', '\c2You now have 1 flag.', %client.flagCount - 1); + } + else if (%client.flagCount - 1 > 1) + { + messageAllExcept(%client, -1, 'MsgHuntPlayerHasFlags', '\c2%1 now has %2 flags.', %client.name, %client.flagCount - 1); + messageClient(%client, 'MsgHuntYouHaveFlags', '\c2You now have %1 flags.', %client.flagCount - 1); + } +} + +function HuntersGame::playerTouchFlag(%game, %player, %flag) +{ + //make sure the player is still alive + %client = %player.client; + if (%player.getState() !$= "Dead") + { + //increase the count bye the flag value + %flagValue = %flag.value; + %client.flagCount += %flagValue; + + //delete the flag + %flag.delete(); + + //if the client has 5 or more flags, mount an image + if (%client.flagCount >= 5) + %player.mountImage(HuntersFlagImage, $FlagSlot); + + //schedule an update message + cancel(%client.flagMsgPending); + %client.flagMsgPending = %game.schedule(%game.flagMsgDelayMS, "sendFlagCountMessage", %client); + messageClient(%client, 'MsgHuntYouHaveFlags', "", %client.flagCount - 1); + + //update the log... + logEcho(%client.nameBase@" (pl "@%player@"/cl "@%client@") has "@%client.flagCount-1@" flags"); + + //play the sound pickup in 3D + %player.playAudio(0, HuntersFlagPickupSound); + + //see if the client could set the record + if (!%game.teamMode && !%client.couldSetRecord) + { + %numFlags = %client.flagCount - 1; + if (%numFlags > 10 && %numFlags > $Host::HuntersRecords::Count[$currentMission]) + { + //see if we have at least 4 non-AI players + %humanCount = 0; + %count = ClientGroup.getCount(); + for (%i = 0; %i < %count; %i++) + { + %cl = ClientGroup.getObject(%i); + if (!%cl.isAIControlled()) + %humanCount++; + if (%humanCount >= %game.numHumansForRecord) + break; + } + + if (%humanCount >= %game.numHumansForRecord) + { + %client.couldSetRecord = true; + + //send a message right away... + if (isEventPending(%client.flagMsgPending)) + { + cancel(%client.flagMsgPending); + %game.sendFlagCountMessage(%client); + } + + //send a message to everyone + messageAllExcept(%client, -1, 'MsgHuntPlayerCouldSetRecord', '\c2%1 has enough flags to set the record for this mission!~wfx/misc/flag_return.wav'); + messageClient(%client, 'MsgHuntYouCouldSetRecord', '\c2You have enough flags to set the record for this mission!~wfx/misc/flag_return.wav'); + } + } + } + + //new tracking - *everyone* automatically tracks the "flag hoarder" if they have at least 15 flags + %game.updateFlagHoarder(%client); + } +} + +function HuntersGame::checkTimeLimit(%game) +{ + DefaultGame::checkTimeLimit(%game); + + //make sure the hoard counter is also up to date + %curTimeLeftMS = ($Host::TimeLimit * 60 * 1000) + $missionStartTime - getSimTime(); + messageAll('MsgHuntHoardStatus', "", %game.HoardMode, $Host::TimeLimit, %curTimeLeftMS, %game.HoardStartTime, %game.HoardDuration); +} + +function HuntersGame::timeLimitReached(%game) +{ + logEcho("game over (timelimit)"); + %game.gameOver(); + cycleMissions(); +} + +function HuntersGame::scoreLimitReached(%game) +{ + //no such thing as a score limit in Hunters... +} + +function HuntersGame::gameOver(%game) +{ + //call the default + DefaultGame::gameOver(%game); + + messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.gameover.wav" ); + + messageAll('MsgClearObjHud', ""); + for(%i = 0; %i < ClientGroup.getCount(); %i ++) + { + %client = ClientGroup.getObject(%i); + Game.resetScore(%client); + cancel(%client.oobSched); + } +} + +function HuntersGame::checkScoreLimit(%game, %client) +{ + //no such thing as a score limit in Hunters... +} + +//----------------------------------------------------------------------------- +//Nexus functions + +function HuntersGame::setNexusDisabled(%game) +{ + //set the animations + Game.Nexus.playThread(1, "transition"); + Game.NexusCap.playthread(1, "transition"); + Game.NexusBase.playthread(1, "transition"); + Game.Nexus.setThreadDir(1, true); + Game.NexusCap.setThreadDir(1, true); + Game.NexusBase.setThreadDir(1, true); +} + +function HuntersGame::setNexusEnabled(%game) +{ + //set the animations + Game.Nexus.playThread(1, "transition"); + Game.NexusCap.playthread(1, "transition"); + Game.NexusBase.playthread(1, "transition"); + Game.Nexus.setThreadDir(1, false); + Game.NexusCap.setThreadDir(1, false); + Game.NexusBase.setThreadDir(1, false); +} + +function HuntersGame::flashNexus(%game) +{ + //set the animations + Game.Nexus.playThread(1, "flash"); + Game.NexusCap.playthread(1, "flash"); + Game.NexusBase.playthread(1, "flash"); + Game.Nexus.setThreadDir(1, Game.Nexus.flashThreadDir); + Game.NexusCap.setThreadDir(1, Game.Nexus.flashThreadDir); + Game.NexusBase.setThreadDir(1, Game.Nexus.flashThreadDir); + Game.Nexus.flashThreadDir = !Game.Nexus.flashThreadDir; +} + +function HuntersGame::NexusSparkEmitter(%game, %client, %cap, %numToScore) +{ + if (isObject(%client.nexusEmitter)) + %client.nexusEmitter.delete(); + + %client.nexusEmitter = new ParticleEmissionDummy() + { + //position = getWord(%client.player.position, 0) SPC getWord(%client.player.position, 1) SPC getWord(%client.player.position, 2) + 3; + position = (%cap ? Game.nexus.getWorldBoxCenter() : %client.player.getWorldBoxCenter()); + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = defaultEmissionDummy; + emitter = (%cap ? NexusParticleCapEmitter : NexusParticleDeniedEmitter); + velocity = "1"; + }; + MissionCleanup.add(%client.nexusEmitter); + + //the effect should only last a few seconds + if (%cap) + { + %timeMS = (%numToScore < 10 ? 200 : %numToScore * 20); + %client.nexusEmitter.schedule(%timeMS, "delete"); + } + else + %client.nexusEmitter.schedule(200, "delete"); +} + +function HuntersGame::hoardModeActive(%game, %wouldBeActive) +{ + if (%wouldBeActive $= "") + %wouldBeActive = false; + + //see if hoard mode is on and active + if (%game.HoardMode || %wouldBeActive) + { + %missionEndTime = ($Host::TimeLimit * 60 * 1000) + $missionStartTime; + %timeLeftMS = %missionEndTime - getSimTime(); + + %hoardStartTime = %game.HoardStartTime * 60 * 1000; + %hoardEndTime = %hoardStartTime - (%game.HoardDuration * 60 * 1000); + if (%timeLeftMS <= %hoardStartTime && %timeLeftMS > %hoardEndTime) + return true; + } + return false; +} + +function Nexus::onCollision(%data, %obj, %colObj) +{ + //make sure it was a player that entered the trigger + if((%colObj.getDataBlock().className $= Armor) && (%colObj.getState() !$= "Dead")) + { + %player = %colObj; + %client = %player.client; + + // if player has been to the nexus within last 5 seconds, don't keep spamming messages + if((getSimTime() - %player.lastNexusTime) < 5000) + return; + + %player.lastNexusTime = getSimTime(); + + if(Game.hoardModeActive()) + { + messageClient(%client, 'MsgHuntHoardNoCap', '\c2Hoard mode is in effect! You cannot return any flags right now.~wfx/powered/nexus_deny.wav'); + + //apply a "bounce" impulse to the player + %velocity = %player.getVelocity(); + if (VectorDist("0 0 0", %velocity) < 2) + %velocityNorm = "0 20 0"; + else + %velocityNorm = VectorScale(VectorNormalize(%velocity), 20); + %vector = VectorScale(%velocityNorm, -200); + %player.applyImpulse(%player.position, %vector); + + Game.NexusSparkEmitter(%client, false); + return; + } + + // you can't cap your own flag + %numToScore = %client.flagCount - 1; + if (Game.greedMode && (%numToScore < Game.GreedMinFlags) && (%numToScore >= 1)) + { + messageClient(%client, 'MsgHuntNeedGreed', '\c2Greed mode is ON! You must have %1 flags before you can return them.~wfx/powered/nexus_deny.wav', Game.GreedMinFlags); + + //transition the Nexus to the "off" animation and back again + Game.flashNexus(); + + //apply a "bounce" impuse to the player + %velocity = %player.getVelocity(); + if (VectorDist("0 0 0", %velocity) < 2) + %velocityNorm = "0 20 0"; + else + %velocityNorm = VectorScale(VectorNormalize(%velocity), 20); + %vector = VectorScale(%velocityNorm, -200); + %player.applyImpulse(%player.position, %vector); + + Game.NexusSparkEmitter(%client, false); + return; + } + + //send the flags message right away... + if (isEventPending(%client.flagMsgPending)) + { + cancel(%client.flagMsgPending); + %game.sendFlagCountMessage(%client); + } + + //unless the nexus is very near the mission boundary, there should be no oobSched to cancel, but... + cancel(%client.oobSched); + + //score the flags + %totalScore = (%numToScore * (%numToScore + 1)) / 2; + if (Game.teamMode) + { + $teamScore[%client.team] += %totalScore; + logEcho(%client.nameBase@" (pl "@%player@"/cl "@%client@") score "@%numToScore@" flags worth "@%totalScore@" pts for team "@%client.team); + messageAll('MsgTeamScoreIs', "", %client.team, $teamScore[%client.team]); + Game.recalcTeamRanks(%client.team); + } + else + { + %client.flagPoints += %totalScore; + logEcho(%client.nameBase@" (pl "@%player@"/cl "@%client@") score "@%numToScore@" flags worth "@%totalScore@" pts"); + Game.recalcScore(%client); + + //see if we should set the highest for the mission here + if (%numToScore > Game.highestFlagReturnCount) + { + Game.highestFlagReturnCount = %numToScore; + Game.highestFlagReturnName = getTaggedString(%client.name); + } + } + + //reset the flags + %client.flagCount = 1; + %client.couldSetRecord = false; + %player.unMountImage($FlagSlot); + messageClient(%client, 'MsgHuntYouHaveFlags', "", 0); + + //see if it's the top score + if (!Game.teamMode && (%client.score > $TopClientScore)) + %topScore = true; + else + %topScore = false; + + //send the messages + if (%numToScore <= 0) + { + messageClient(%client, 'MsgHuntYouNeedHelp', '\c2Pick up flags and bring them here to score points.~wfx/misc/nexus_idle.wav'); + } + else if (%numToScore == 1) + { + if(Game.teamMode) + messageAllExcept(%client, -1, 'MsgHuntPlayerScored', '\c2%1 returned 1 flag (1 point) for %2.~wfx/misc/nexus_cap.wav', %client.name, $TeamName[%client.team], 1); + else + { + messageAllExcept(%client, -1, 'MsgHuntPlayerScored', '\c2%1 returned 1 flag for 1 point.~wfx/misc/nexus_cap.wav', %client.name, 1); + + //new tracking - *everyone* automatically tracks the "flag hoarder" if they have at least 15 flags + Game.updateFlagHoarder(%client); + } + + //add the nexus effect + Game.NexusSparkEmitter(%client, true, %numToScore); + + messageClient(%client, 'MsgHuntYouScored', '\c2You returned 1 flag for 1 point.~wfx/misc/nexus_cap.wav', 1); + } + else if (%numToScore < 5) + { + if(Game.teamMode) + messageAllExcept(%client, -1, 'MsgHuntPlayerScored', '\c2%1 returned %2 flags (%3 points) for %4.~wfx/misc/nexus_cap.wav', %client.name, %numToScore, %totalScore, $TeamName[%client.team]); + else + { + messageAllExcept(%client, -1, 'MsgHuntPlayerScored', '\c2%1 returned %2 flags for %3 points.~wfx/misc/nexus_cap.wav', %client.name, %numToScore, %totalScore); + + //new tracking - *everyone* automatically tracks the "flag hoarder" if they have at least 15 flags + Game.updateFlagHoarder(%client); + } + + //add the nexus effect + Game.NexusSparkEmitter(%client, true, %numToScore); + + messageClient(%client, 'MsgHuntYouScored', '\c2You returned %1 flags for %2 points.~wfx/misc/nexus_cap.wav', %numToScore, %totalScore); + } + else + { + if(Game.teamMode) + messageAllExcept(%client, -1, 'MsgHuntPlayerScored', '\c2%1 returned %2 flags (%3 points) for %4.~wfx/misc/nexus_cap.wav', %client.name, %numToScore, %totalScore, $TeamName[%client.team]); + else + { + messageAllExcept(%client, -1, 'MsgHuntPlayerScored', '\c2%1 returned %2 flags for %3 points.~wfx/misc/nexus_cap.wav', %client.name, %numToScore, %totalScore); + + //new tracking - *everyone* automatically tracks the "flag hoarder" if they have at least 15 flags + Game.updateFlagHoarder(%client); + } + + //add the nexus effect + Game.NexusSparkEmitter(%client, true, %numToScore); + + messageClient(%client, 'MsgHuntYouScored', '\c2You returned %1 flags for %2 points.~wfx/misc/nexus_cap.wav', %numToScore, %totalScore); + } + + //see if it's the top score + if (%topScore) + { + $TopClientScore = %client.score; + if (%client == $TopClient) + { + if (%numToScore >= 5) + messageAll('MsgHuntTopScore', '\c0%1 is leading with a score of %2!~wfx/misc/flag_capture.wav', %client.name, %client.score); + else + messageAll('MsgHuntTopScore', '\c0%1 is leading with a score of %2!', %client.name, %client.score); + } + else + messageAll('MsgHuntNewTopScore', '\c0%1 has taken the lead with a score of %2!~wfx/misc/flag_capture.wav', %client.name, %client.score); + $TopClient = %client; + } + + //see if it's a record + if (%numToScore > 10 && %numToScore > $Host::HuntersRecords::Count[$currentMission]) + { + //see if we have at least 4 non-AI players + %humanCount = 0; + %count = ClientGroup.getCount(); + for (%i = 0; %i < %count; %i++) + { + %cl = ClientGroup.getObject(%i); + if (!%cl.isAIControlled()) + %humanCount++; + if (%humanCount >= Game.numHumansForRecord) + break; + } + + if (%humanCount >= Game.numHumansForRecord) + { + $Host::HuntersRecords::Count[$currentMission] = %numToScore; + $Host::HuntersRecords::Name[$currentMission] = getTaggedString(%client.name); + + //send a message to everyone + messageAllExcept(%client, -1, 'MsgHuntPlayerSetRecord', '\c2%1 set the record for this mission with a return of %2 flags!~wfx/misc/flag_return.wav', %client.name, %numToScore); + messageClient(%client, 'MsgHuntYouSetRecord', '\c2You set the record for this mission with a return of %1 flags!~wfx/misc/flag_return.wav', %numToScore); + + //update the records file... + export( "$Host::HuntersRecords::*", "prefs/HuntersRecords.cs", false ); + + //once the record has been set, reset everyone's tag + for (%i = 0; %i < %count; %i++) + { + %cl = ClientGroup.getObject(%count); + %cl.couldSetRecord = false; + } + } + } + + if(Game.teamMode) + Game.checkScoreLimit(%team); + else + Game.checkScoreLimit(%client); + } +} + +function HuntersGame::clientMissionDropReady(%game, %client) +{ + //%client.rank = ClientGroup.getCount(); + messageClient(%client, 'MsgClientReady',"", %game.class); + //messageClient(%client, 'MsgHuntGreedStatus', "", %game.greedMode, %game.GreedMinFlags); + //%curTimeLeftMS = ($Host::TimeLimit * 60 * 1000) + $missionStartTime - getSimTime(); + //messageClient(%client, 'MsgHuntHoardStatus', "", %game.HoardMode, $Host::TimeLimit, %curTimeLeftMS, %game.HoardStartTime, %game.HoardDuration); + messageClient(%client, 'MsgHuntYouHaveFlags', "", 0); + messageClient(%client, 'MsgYourScoreIs', "", 0); + // MES function below does not exist + //%game.populateRankArray(%client); + //messageClient(%client, 'MsgYourRankIs', "", -1); + + messageClient(%client, 'MsgMissionDropInfo', '\c0You are in mission %1 (%2).', $MissionDisplayName, $MissionTypeDisplayName, $ServerName ); + + DefaultGame::clientMissionDropReady(%game, %client); +} + +function HuntersGame::AIHasJoined(%game, %client) +{ + //let everyone know the player has joined the game + //messageAllExcept(%client, -1, 'MsgClientJoin', '%1 joined the game.', %client.name, "", %client, 1); +} + +function HuntersGame::resetScore(%game, %client) +{ + %client.score = 0; + %client.suicides = 0; + %client.kills = 0; + %client.teamKills = 0; + %client.deaths = 0; + %client.flagPoints = 0; +} + +function HuntersGame::recalcScore(%game, %cl) +{ + if (%cl <= 0) + return; + + %killValue = %cl.kills * %game.SCORE_PER_KILL; + %deathValue = %cl.deaths * %game.SCORE_PER_DEATH; + + if (%killValue - %deathValue == 0) + %killPoints = 0; + else + %killPoints = (%killValue * %killValue) / (%killValue - %deathValue); + + %cl.score = %killPoints; + %cl.score += %cl.flagPoints; + %cl.score += %cl.suicides * %game.SCORE_PER_SUICIDE; + //%cl.score = mFloatLength(%cl.score, 1); + %cl.score = mFloor(%cl.score); + + //must send the message to update the HUD + messageClient(%cl, 'MsgYourScoreIs', "", %cl.score); + + %game.recalcTeamRanks(%cl); +} + +function HuntersGame::sendGameVoteMenu( %game, %client, %key ) +{ + // Don't send any options if a vote is already running: + if ( %game.scheduleVote $= "" ) + { + // First send the common options: + DefaultGame::sendGameVoteMenu( %game, %client, %key ); + + if (!isDemo()) + { + if(!%client.isAdmin) + { + // Now send the Hunters-specific options: + if ( %game.greedMode ) + messageClient( %client, 'MsgVoteItem', "", %key, 'VoteGreedMode', 'disable greed mode', 'Vote Disable GREED Mode' ); + else + messageClient( %client, 'MsgVoteItem', "", %key, 'VoteGreedMode', 'enable greed mode', 'Vote Enable GREED Mode' ); + + if ( %game.HoardMode ) + messageClient( %client, 'MsgVoteItem', "", %key, 'VoteHoardMode', 'disable hoard mode', 'Vote Disable HOARD Mode' ); + else + messageClient( %client, 'MsgVoteItem', "", %key, 'VoteHoardMode', 'enable hoard mode', 'Vote Enable HOARD Mode' ); + } + else + { + if ( %game.greedMode ) + messageClient( %client, 'MsgVoteItem', "", %key, 'VoteGreedMode', 'disable greed mode', 'Disable GREED Mode' ); + else + messageClient( %client, 'MsgVoteItem', "", %key, 'VoteGreedMode', 'enable greed mode', 'Enable GREED Mode' ); + + if ( %game.HoardMode ) + messageClient( %client, 'MsgVoteItem', "", %key, 'VoteHoardMode', 'disable hoard mode', 'Disable HOARD Mode' ); + else + messageClient( %client, 'MsgVoteItem', "", %key, 'VoteHoardMode', 'enable hoard mode', 'Enable HOARD Mode' ); + } + } + } +} + +function HuntersGame::voteGreedMode( %game, %admin, %player ) +{ + %cause = ""; + %setto = ""; + if ( %admin ) + { + if ( %game.greedMode ) + { + messageAll( 'AdminDisableGreedMode', '\c2The Admin has disabled GREED mode.~wfx/misc/hunters_greed.wav' ); + %game.greedMode = false; + %setto = "disabled"; + } + else + { + messageAll( 'AdminEnableGreedMode', '\c2The Admin has enabled GREED mode.~wfx/misc/hunters_greed.wav' ); + %game.greedMode = true; + %setto = "enabled"; + } + %cause = "(admin)"; + } + else + { + %totalVotes = %game.totalVotesFor + %game.totalVotesAgainst; + if ( %totalVotes > 0 && ( %game.totalVotesFor / %totalVotes ) > 0.7 ) + { + if ( %game.greedMode ) + { + messageAll( 'MsgVotePassed', '\c2GREED mode was disabled by vote.~wfx/misc/hunters_greed.wav' ); + %game.greedMode = false; + %setto = "disabled"; + } + else + { + messageAll( 'MsgVotePassed', '\c2GREED mode was enabled by vote.~wfx/misc/hunters_greed.wav' ); + %game.greedMode = true; + %setto = "enabled"; + } + %cause = "(vote)"; +// alxPlay(VotePassSound, 0, 0, 0); + } + else + { + if ( %game.greedMode ) + messageAll( 'MsgVoteFailed', '\c2Disable GREED mode vote did not pass, %1 to %2.', %game.totalVotesFor, %game.totalVotesAgainst ); + else + messageAll( 'MsgVoteFailed', '\c2Enable GREED mode vote did not pass, %1 to %2.', %game.totalVotesFor, %game.totalVotesAgainst ); +// alxPlay(VoteNotPassSound, 0, 0, 0); + } + } + + //send the global message + messageAll('MsgHuntGreedStatus', "", %game.greedMode, %game.GreedMinFlags); + if(%setto !$= "") + logEcho("greed mode "@%setto SPC %cause); + + //store the result + if (%game.teamMode) + $Host::TeamHuntersGreedMode = %game.greedMode; + else + $Host::HuntersGreedMode = %game.greedMode; +} + +function HuntersGame::voteHoardMode( %game, %admin, %player ) +{ + %cause = ""; + %setto = ""; + + if ( %admin ) + { + if ( %game.HoardMode ) + { + messageAll( 'AdminDisableHoardMode', '\c2The Admin has disabled HOARD mode.' ); + %game.HoardMode = false; + %setto = "disabled"; + } + else + { + messageAll( 'AdminEnableHoardMode', '\c2The Admin has enabled HOARD mode.' ); + %game.HoardMode = true; + %setto = "enabled"; + } + %cause = "(admin)"; + } + else + { + %totalVotes = %game.totalVotesFor + %game.totalVotesAgainst; + if ( %totalVotes > 0 && ( %game.totalVotesFor / %totalVotes ) > 0.7 ) + { + if ( %game.HoardMode ) + { + messageAll( 'MsgVotePassed', '\c2HOARD mode was disabled by vote.' ); + %game.HoardMode = false; + %setto = "disabled"; + } + else + { + messageAll( 'MsgVotePassed', '\c2HOARD mode was enabled by vote.' ); + %game.HoardMode = true; + %setto = "enabled"; + } + %cause = "(vote)"; +// alxPlay(VotePassSound, 0, 0, 0); + } + else + { + if ( %game.HoardMode ) + messageAll( 'MsgVoteFailed', '\c2Disable HOARD mode vote did not pass, %1 to %2.', %game.totalVotesFor, %game.totalVotesAgainst ); + else + messageAll( 'MsgVoteFailed', '\c2Enable HOARD mode vote did not pass, %1 to %2.', %game.totalVotesFor, %game.totalVotesAgainst ); +// alxPlay(VoteNotPassSound, 0, 0, 0); + } + } + + //send the global message + %curTimeLeftMS = ($Host::TimeLimit * 60 * 1000) + $missionStartTime - getSimTime(); + messageAll('MsgHuntHoardStatus', "", %game.HoardMode, $Host::TimeLimit, %curTimeLeftMS, %game.HoardStartTime, %game.HoardDuration); + if(%setto !$= "") + logEcho("hoard mode "@%setto SPC %cause); + + //store the result + if (%game.teamMode) + $Host::TeamHuntersHoardMode = %game.HoardMode; + else + $Host::HuntersHoardMode = %game.HoardMode; +} + +function HuntersGame::voteChangeTimeLimit( %game, %admin, %newLimit ) +{ + %oldTimeLimit = $Host::TimeLimit; + DefaultGame::voteChangeTimeLimit(%game, %admin, %newLimit); + + //if the time limit changed, this will affect hoard mode: + if ($Host::TimeLimit != %oldTimeLimit) + { + %game.setupHoardCountdown(); + } +} + +function createDroppedFlag(%data, %value, %player, %game) +{ + %client = %player.client; + %playerPos = %player.getWorldBoxCenter(); + + // create a flag and throw it + %droppedflag = new Item() { + position = %playerPos; + rotation = "0 0 1 " @ (getRandom() * 360); + scale = "1 1 1"; + dataBlock = %data; + collideable = "0"; + static = "0"; + rotate = "0"; + team = "0"; + }; + $FlagGroup.add(%droppedflag); + %droppedFlag.value = %value; + + // set the flags target (for proper skin) + %droppedFlag.setTarget(%data.target); + + //throw the flag randomly away from the body + if (%client.isDead) + { + %vec = (-1.0 + getRandom() * 2.0) SPC (-1.0 + getRandom() * 2.0) SPC getRandom(); + %vec = VectorScale(%vec, 1000 + (getRandom() * 500)); + + // Add player's velocity + %vec = vectorAdd(%vec, %player.getVelocity()); + } + + //else if the player is Out of bounds, throw them in the direction of the nexus + else if (%client.outOfBounds) + { + %towardsNexusVec = VectorSub(%game.nexus.position, %player.position); + %towardsNexusVec = getWord(%towardsNexusVec, 0) SPC getWord(%towardsNexusVec, 1) SPC "0"; + %towardsNexusVec = VectorNormalize(%towardsNexusVec); + + //add a little noise + %vec = getWord(%towardsNexusVec, 0) + (-0.3 + getRandom() * 0.6) SPC + getWord(%towardsNexusVec, 1) + (-0.3 + getRandom() * 0.6) SPC + getWord(%towardsNexusVec, 2); + %vec = VectorScale(%vec, 1000 + (getRandom() * 500)); + } + + //else throw them more or less in the direction the player was facing... + else + { + %playerFacingVec = MatrixMulVector("0 0 0 " @ getWords(%client.player.getTransform(), 3, 6), "0 1 0"); + %playerFacingVec = VectorNormalize(%playerFacingVec); + + //add a little noise + %vec = getWord(%playerFacingVec, 0) + (-0.3 + getRandom() * 0.6) SPC + getWord(%playerFacingVec, 1) + (-0.3 + getRandom() * 0.6) SPC + getWord(%playerFacingVec, 2); + %vec = VectorScale(%vec, 1000 + (getRandom() * 500)); + + // Add player's velocity + %vec = vectorAdd(%vec, %player.getVelocity()); + } + + %droppedflag.applyImpulse(%playerPos, %vec); + %droppedflag.setCollisionTimeout(%player); + schedule(%game.flagLifeTimeMS, %droppedflag, "HuntersStartFlagTimeOut", %droppedflag); +} + +function HuntersGame::throwFlags(%game, %player) +{ + %client = %player.client; + + //find out how many flags to drop + if (%client.isDead) + %numFlags = %client.flagCount; + else + %numFlags = %client.flagCount - 1; + + if (%numFlags <= 0) + return; + //send the flags message right away... + if (isEventPending(%client.flagMsgPending)) + { + cancel(%client.flagMsgPending); + %game.sendFlagCountMessage(%client); + } + + %numFlagsToDrop = %numFlags; + + //reset the count (which doesn't matter if player is dead) + %client.flagCount = 1; + %client.couldSetRecord = false; + + //drop the flags + %flagIncrement = 1; + %db[1] = HuntersFlag1; + %db[2] = HuntersFlag2; + %db[4] = HuntersFlag4; + %db[8] = HuntersFlag8; + + %i = 0; + while (%i < %numFlagsToDrop) + { + for (%j = 0; %j < 5; %j++) + { + %numFlagsLeft = %numFlagsToDrop - %i; + if (%numFlagsLeft >= %flagIncrement) + { + createDroppedFlag(%db[%flagIncrement], %flagIncrement, %player, %game); + %i += %flagIncrement; + } + else + { + // cleanup + if (%numFlagsLeft >= 8) + { + createDroppedFlag(%db[8], 8, %player, %game); + %i += 8; + %numFlagsLeft -= 8; + } + if (%numFlagsLeft >= 4) + { + createDroppedFlag(%db[4], 4, %player, %game); + %i += 4; + %numFlagsLeft -= 4; + } + if (%numFlagsLeft >= 2) + { + createDroppedFlag(%db[2], 2, %player, %game); + %i += 2; + %numFlagsLeft -= 2; + } + if (%numFlagsLeft >= 1) + { + createDroppedFlag(%db[1], 1, %player, %game); + %i += 1; + %numFlagsLeft -= 1; + } + + if (%i != %numFlagsToDrop || %numFlagsLeft != 0) + { + error("Error, missing a flag!"); + } + break; + } + } + + if (%flagIncrement < 8) + %flagIncrement = %flagIncrement * 2; + } + + //yard sale! + if (%numFlags >= %game.yardSaleMin) + { + messageAll('MsgHuntYardSale', '\c2YARD SALE!!!~wfx/misc/yardsale.wav'); + + //create a waypoint at player's location... + %yardWaypoint = new WayPoint() + { + position = %player.position; + rotation = "1 0 0 0"; + scale = "1 1 1"; + name = "YARD SALE!"; + dataBlock = "WayPointMarker"; + lockCount = "0"; + homingCount = "0"; + team = "0"; + }; + + //add the waypoint to the cleanup group + MissionCleanup.add(%yardWaypoint); + $HuntersYardSaleSet.add(%yardWaypoint); + schedule(30000, %yardWaypoint, "HuntersYardSaleTimeOut", %yardWaypoint); + } + + //remove any mounted flag from the player + %player.unMountImage($FlagSlot); + + //update the client's hud + messageClient(%client, 'MsgHuntYouHaveFlags', "", 0); + + //new tracking - *everyone* automatically tracks the "flag hoarder" if they have at least 15 flags + %game.updateFlagHoarder(%client); +} + +function HuntersGame::dropFlag(%game, %player) +{ + //first throw the flags + %game.throwFlags(%player); + + //send the messages + if (%numFlags == 1) + { + messageAllExcept(%client, -1, 'MsgHuntPlayerDroppedFlags', '\c0%1 dropped 1 flag.', %client.name, 1); + messageClient(%client, 'MsgHuntYouDroppedFlags', '\c0You dropped 1 flag.', 1); + } + else if (%numFlags > 1) + { + messageAllExcept(%client, -1, 'MsgHuntPlayerDroppedFlags', '\c0%1 dropped %2 flags.', %client.name, %numFlags); + messageClient(%client, 'MsgHuntYouDroppedFlags', '\c0You dropped %1 flags.', %numFlags); + } + logEcho(%client.nameBase@" (pl "@%player@"/cl "@%client@") dropped "@%numFlags@" flags"); +} + +function HuntersGame::enterMissionArea(%game, %playerData, %player) +{ + if(%player.getState() $= "Dead") + return; + + %client = %player.client; + %client.outOfBounds = false; + cancel(%client.oobSched); + messageClient(%player.client, 'MsgEnterMissionArea', '\c1You are back in the mission area.'); + logEcho(%player.client.nameBase@" (pl "@%player@"/cl "@%player.client@") entered mission area"); + cancel(%player.alertThread); +} + +function HuntersGame::leaveMissionArea(%game, %playerData, %player) +{ + if(%player.getState() $= "Dead") + return; + + // strip flags and throw them back into the mission area + %client = %player.client; + %client.outOfBounds = true; + if (%player.client.flagCount > 1) + messageClient(%player.client, 'MsgLeaveMissionArea', '\c1You have left the mission area and will lose your flags!~wfx/misc/warning_beep.wav'); + else + messageClient(%player.client, 'MsgLeaveMissionArea', '\c1You have left the mission area.~wfx/misc/warning_beep.wav'); + + %client.oobSched = %game.schedule(%game.oobThrowFlagsDelayMS, "outOfBoundsThrowFlags", %client); + logEcho(%player.client.nameBase@" (pl "@%player@"/cl "@%player.client@") left mission area"); +} + +function HuntersGame::outOfBoundsThrowFlags(%game, %client) +{ + %player = %client.player; + if (!%client.outOfBounds) + return; + + if (%client.flagCount > 1) + { + %game.throwFlags(%player); + messageClient(%player.client, 'MsgLeaveMissionArea', '\c1You are out of the mission area and have lost your flags!~wfx/misc/flag_taken.wav'); + } + + //set the next schedule check + %client.oobSched = %game.schedule(%game.oobThrowFlagsDelayMS, "outOfBoundsThrowFlags", %client); +} + +function HuntersGame::onEnterTrigger(%game, %triggerName, %data, %obj, %colobj) +{ + //schedule a warning in 10 seconds + %client = %colobj.client; + %client.campingThread = %game.schedule(game.nexusCampingTime, "CampingDamage", %client, true); +} + +function HuntersGame::onLeaveTrigger(%game, %triggerName, %data, %obj, %colobj) +{ + %client = %colobj.client; + cancel(%client.campingThread); +} + +function HuntersGame::CampingDamage(%game, %client, %firstWarning) +{ + //make sure we're still alive... + %player = %client.player; + if (!isObject(%player) || %player.getState() $= "Dead") + return; + + //if the match hasn't yet started, don't warn or apply damage yet... + if (!$MatchStarted) + { + %client.campingThread = %game.schedule(game.nexusCampingTime / 2, "CampingDamage", %client, true); + } + else if (%firstWarning) + { + messageClient(%client, 'MsgHuntersNoCampZone', '\c2No camping near the Nexus.', 1); + %client.campingThread = %game.schedule(game.nexusCampingTime / 2, "CampingDamage", %client, false); + } + else + { + %player.setDamageFlash(0.1); + %player.damage(0, %player.position, 0.05, $DamageType::NexusCamping); + %client.campingThread = %game.schedule(1000, "CampingDamage", %client, false); + } + +} + +function HuntersGame::updateScoreHud(%game, %client, %tag) +{ + //tricky stuff here... use two columns if we have more than 15 clients... + %numClients = $TeamRank[0, count]; + if (%numClients > $ScoreHudMaxVisible) + %numColumns = 2; + + // Clear the header: + messageClient( %client, 'SetScoreHudHeader', "", "" ); + + // Send header: + if ( %numColumns == 2 ) + messageClient( %client, 'SetScoreHudSubheader', "", '\tPLAYER\tSCORE\tFLAGS\tPLAYER\tSCORE\tFLAGS' ); + else + messageClient( %client, 'SetScoreHudSubheader', "", '\tPLAYER\tSCORE\tFLAGS' ); + + //find out who has the most flags + %maxFlagsClient = -1; + %maxFlags = -1; + for (%i = 0; %i < %numClients; %i++) + { + %cl = $TeamRank[0, %i]; + if (%cl.flagCount > %maxFlags) + { + %maxFlags = %cl.flagCount - 1; + %maxFlagsClient = %cl; + } + } + + //if no one has any flags, don't hilite anyone... + if (%maxFlags <= 0) + %maxFlagsClient = -1; + + %countMax = %numClients; + if ( %countMax > ( 2 * $ScoreHudMaxVisible ) ) + { + if ( %countMax & 1 ) + %countMax++; + %countMax = %countMax / 2; + } + else if ( %countMax > $ScoreHudMaxVisible ) + %countMax = $ScoreHudMaxVisible; + + for (%index = 0; %index < %countMax; %index++) + { + //get the client info + %col1Client = $TeamRank[0, %index]; + %col1ClientScore = %col1Client.score $= "" ? 0 : %col1Client.score; + %col1ClientFlags = %col1Client.flagCount - 1; + if (%col1ClientFlags <= 0) + %col1ClientFlags = ""; + %col1Style = ""; + if ( %col1Client == %maxFlagsClient ) + %col1Style = ""; + else if ( %col1Client == %client ) + %col1Style = ""; + + //see if we have two columns + if (%numColumns == 2) + { + %col2Client = ""; + %col2ClientScore = ""; + %col2ClientFlags = ""; + %col2Style = ""; + + //get the column 2 client info + %col2Index = %index + %countMax; + if (%col2Index < %numClients) + { + %col2Client = $TeamRank[0, %col2Index]; + %col2ClientScore = %col2Client.score $= "" ? 0 : %col2Client.score; + %col2ClientFlags = %col2Client.flagCount - 1; + if (%col2ClientFlags <= 0) + %col2ClientFlags = ""; + if ( %col2Client == %maxFlagsClient ) + %col2Style = ""; + else if ( %col2Client == %client ) + %col2Style = ""; + } + } + + //if the client is not an observer, send the message + if (%client.team != 0) + { + if ( %numColumns == 2 ) + messageClient( %client, 'SetLineHud', "", %tag, %index, '%7\t%1%2%3%8%4%5%6', + %col1Client.name, %col1ClientScore, %col1ClientFlags, %col2Client.name, %col2ClientScore, %col2ClientFlags, %col1Style, %col2Style ); + else + messageClient( %client, 'SetLineHud', "", %tag, %index, '%4\t%1%2%3', + %col1Client.name, %col1ClientScore, %col1ClientFlags, %col1Style ); + } + + //else for observers, create an anchor around the player name so they can be observed + else + { + if ( %numColumns == 2 ) + { + + //this is lame, but we can only have up to %9 args + if ( %col2Client == %maxFlagsClient ) + { + messageClient( %client, 'SetLineHud', "", %tag, %index, '%7\t%1%2%3%4%5%6', + %col1Client.name, %col1ClientScore, %col1ClientFlags, + %col2Client.name, %col2ClientScore, %col2ClientFlags, + %col1Style, %col1Client, %col2Client); + } + else if ( %col2Client == %client ) + { + messageClient( %client, 'SetLineHud', "", %tag, %index, '%7\t%1%2%3%4%5%6', + %col1Client.name, %col1ClientScore, %col1ClientFlags, + %col2Client.name, %col2ClientScore, %col2ClientFlags, + %col1Style, %col1Client, %col2Client); + } + else + { + messageClient( %client, 'SetLineHud', "", %tag, %index, '%7\t%1%2%3%4%5%6', + %col1Client.name, %col1ClientScore, %col1ClientFlags, + %col2Client.name, %col2ClientScore, %col2ClientFlags, + %col1Style, %col1Client, %col2Client); + } + } + else + messageClient( %client, 'SetLineHud', "", %tag, %index, '%4\t%1%2%3', + %col1Client.name, %col1ClientScore, %col1ClientFlags, %col1Style, %col1Client ); + } + } + + // Tack on the list of observers: + %observerCount = 0; + for (%i = 0; %i < ClientGroup.getCount(); %i++) + { + %cl = ClientGroup.getObject(%i); + if (%cl.team == 0) + %observerCount++; + } + + if (%observerCount > 0) + { + messageClient( %client, 'SetLineHud', "", %tag, %index, ""); + %index++; + messageClient(%client, 'SetLineHud', "", %tag, %index, '\tOBSERVERS (%1)TIME', %observerCount); + %index++; + for (%i = 0; %i < ClientGroup.getCount(); %i++) + { + %cl = ClientGroup.getObject(%i); + //if this is an observer + if (%cl.team == 0) + { + %obsTime = getSimTime() - %cl.observerStartTime; + %obsTimeStr = %game.formatTime(%obsTime, false); + messageClient( %client, 'SetLineHud', "", %tag, %index, '\t%1%2', + %cl.name, %obsTimeStr ); + %index++; + } + } + } + + //clear the rest of Hud so we don't get old lines hanging around... + messageClient( %client, 'ClearHud', "", %tag, %index ); +} + +function HuntersGame::sendDebriefing( %game, %client ) +{ + // Mission result: + if ( $TeamRank[0, 0].score > 0 ) + messageClient( %client, 'MsgDebriefResult', "", '%1 wins with a score of %2!', $TeamRank[0, 0].name, $TeamRank[0, 0].score ); + else + messageClient( %client, 'MsgDebriefResult', "", 'Nobody wins!' ); + + + if ( %game.highestFlagReturnName !$= "" ) + messageClient( %client, 'MsgDebriefResult', "", '%1 had the highest return count with %2 flags!', %game.highestFlagReturnName, %game.highestFlagReturnCount ); + + if ( $Host::HuntersRecords::Count[$currentMission] !$= "" && $Host::HuntersRecords::Name[$currentMission] !$= "" ) + messageClient( %client, 'MsgDebriefResult', "", '%1 holds the record with a return count of %2 flags!', $Host::HuntersRecords::Name[$currentMission], $Host::HuntersRecords::Count[$currentMission] ); + + if ( %game.greedFlagName !$= "" ) + messageClient( %client, 'MsgDebriefResult', "", '%1 gets the honorary greed award for dropping %2 flags!', %game.greedFlagName, %game.greedFlagCount ); + + // Player scores: + messageClient( %client, 'MsgDebriefAddLine', "", 'PLAYERSCOREKILLS' ); + %count = $TeamRank[0, count]; + for ( %i = 0; %i < %count; %i++ ) + { + %cl = $TeamRank[0, %i]; + if ( %cl.score $= "" ) + %score = 0; + else + %score = %cl.score; + if ( %cl.kills $= "" ) + %kills = 0; + else + %kills = %cl.kills; + messageClient( %client, 'MsgDebriefAddLine', "", ' %1 %2 %3', %cl.name, %score, %kills ); + } + + // Show observers: + %count = ClientGroup.getCount(); + %header = false; + for ( %i = 0; %i < %count; %i++ ) + { + %cl = ClientGroup.getObject( %i ); + if ( %cl.team <= 0 ) + { + if ( !%header ) + { + messageClient( %client, 'MsgDebriefAddLine', "", '\nOBSERVERSSCORE' ); + %header = true; + } + + %score = %cl.score $= "" ? 0 : %cl.score; + messageClient( %client, 'MsgDebriefAddLine', "", ' %1 %2', %cl.name, %score ); + } + } +} + +function HuntersGame::applyConcussion(%game, %player) +{ + //%game.dropFlag( %player ); +} diff --git a/scripts/Importer/Building.cs b/scripts/Importer/Building.cs index 38fa85e..6b2fcc7 100644 --- a/scripts/Importer/Building.cs +++ b/scripts/Importer/Building.cs @@ -1,238 +1,238 @@ -//------------------------------------------------------------------------------ -// A lil sumthin by Alviss -// For C&C - -//------------------------------------------------------------------------------ -// Execution -//------------------------------------------------------------------------------ - -// This clears the building index's in one swoop -function BuildingManagerInit() -{ - if (isObject(BuildingManager)) - BuildingManager.Delete(); - - new ScriptObject(BuildingManager) {}; -} - -//------------------------------------------------------------------------------ - -exec("scripts/Importer/BuildingDatablocks.cs"); -exec("scripts/Importer/BuildingGroups.cs"); -exec("scripts/Importer/Buildings/ConstructionYard.cs"); -exec("scripts/Importer/Converter.cs"); - -// adding the buildings - -//------------------------------------------------------------------------------ -// Functions -//------------------------------------------------------------------------------ - -function exebuild() -{ - exec("scripts/functionality/Building.cs"); -} - - -function LoadCCBuilding(%client, %building, %center) -{ - %team = %client.team; - - // This is used to keep duplicate buildings from joining the same group - // So, like, we don't have 3 group's named PowerPlant. - // EDIT: I realize it wouldn't matter now, but i'm too lazy to remove all my work - BuildingManager.BuildingInc[%building, %team]++; - - switch$(%building) - { - case "ConYard": - Build_ConstructionYard(%client, %center, %team); - - case "PowerPlant": - Build_PowerPlant(%client, %center, %team); - - } - - // set a timer to unify the building - NametoId("MissionCleanup/Buildings"@%team@"/"@%building @ BuildingManager.BuildingInc[%building, %team]).Schedule(2000, "UnifyBuildings"); - // it uses a timer because none of the objects have the required parameters set yet, plus it's a good idea - // to wait until all the pieces are loaded. -} - -//------------------------------------------------------------------------------ -// CCMod Package -//------------------------------------------------------------------------------ - -package CCMod -{ - //------------------------------------------ - // echos and logs the exec call - function exec(%target) - { -// LogEvent(%target); - - //error("Count : " @ DatablockGroup.getCount()); - - parent::exec(%target); - } - - //------------------------------------------ - // So you don't get a lame red spam wall in the console. - function setTargetSensorGroup(%target, %team) - { - if (%target <= 0) - return; - - parent::setTargetSensorGroup(%target, %team); - } - - //------------------------------------------ - // So you don't get a lame red spam wall in the console. - function setTargetName(%target, %name) - { - if (%target <= 0) - return; - - parent::setTargetName(%target, %name); - } - //------------------------------------------ - // to capture the MCV when it deploys - function StaticShapeData::OnAdd(%data, %obj) - { - // it's a building piece. - if (StrStr(%data.GetName(), "BuildingBlock") != -1) - { - if (%obj.TheFloor && %obj.type $= "ConYard") - { - $CCGame::MCV[%obj.team] = %obj; - - } - } - - Parent::OnAdd(%data, %obj); - } - - //------------------------------------------ - // door functions - function StaticShapeData::OnCollision(%data, %obj) - { - // DoorCode - if (%obj.IsDoor) - { - %obj.ClosePosition = %obj.GetPosition(); - %obj.SetPosition("0 0 -100"); - - schedule(2000, 0, "eval", %obj@".SetPosition("@%obj@".ClosePosition);"); - } - } - - //------------------------------------------ - // captures incoming damage - function StaticShapeData::damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType) - { - // it's a building piece. - if (StrStr(%data.GetName(), "BuildingBlock") != -1) - GrabBaseDamageCall(%data, %targetObject, %sourceObject, %position, %amount, %damageType); - else - parent::damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType); - } - - //------------------------------------------ - // captures incoming destroyed call - function StaticShapeData::onDestroyed(%this,%obj,%prevState) - { - $BuildingCount[%obj.type, %obj.team]--; - $Power[%obj.team] -= $Power[%obj.team]; - CheckPowerGoodLevel(%obj.team); - -// $TeamDeployedCount[%obj.team, AdvGuardTurretBasePack]--; - } - -}; - -if (!isActivePackage(CCMod)) - ActivatePackage(CCMod); - -//------------------------------------------------------------------------------ -// Support Functions -//------------------------------------------------------------------------------ - -function addToBuildingGroup(%object) -{ - %TeamGroup = nameToID("Buildings"@%object.team); - - if (%TeamGroup <= 0) - { - %TeamGroup = new SimGroup("Buildings"@%object.team); - MissionCleanup.add(%TeamGroup); - } - - %index = BuildingManager.BuildingInc[%object.Type, %object.team]; - - %BuildingsGroup = nameToID("Buildings"@%object.team@"/"@%object.Type @ %index); - - if ($CCTypeToName[%object.Type, %object.team] !$= %object.Type) - { - setTargetName(%object.target,addTaggedString($CCTypeToName[%object.Type, %object.team])); - } - - if (%BuildingsGroup <= 0) - { - %BuildingsGroup = new SimGroup(%object.Type @ %index); - %TeamGroup.add(%BuildingsGroup); - } - - %BuildingsGroup.Index = %index; - - %BuildingsGroup.add(%object); -} - -//------------------------------------------------------------------------------ - -function ShapeBase::SightObject(%player, %range) -{ - if (%range $= "") - %range = 100; - - %pos = %player.getEyePoint(); - %vec = %player.getEyeVector(); - - %targetpos = vectoradd(%pos, vectorscale(%vec, %range)); - %ray = containerraycast(%pos, %targetpos, $typemasks::StaticShapeObjectType, %player); - - return getword(%ray, 0); -} - -//------------------------------------------------------------------------------ - -function ShapeBase::SightPos(%player, %range) -{ - if (%range $= "") - %range = 100; - - %pos = %player.getEyePoint(); - %vec = %player.getEyeVector(); - - %targetpos = vectoradd(%pos, vectorscale(%vec, %range)); - %ray = containerraycast(%pos, %targetpos, $typemasks::StaticShapeObjectType | $typemasks::TerrainObjectType, %player); - - return getwords(%ray, 1,3); -} - -//------------------------------------------------------------------------------ - -function ShapeBase::getEyePoint(%player) -{ - %eyePt = getWords(%player.getEyeTransform(), 0, 2); - return %eyePt; -} - -//------------------------------------------------------------------------------ - -function SimObject::setPosition(%obj, %pos) -{ - %rot = getWords(%obj.getTransform(), 3, 6); - %trans = %pos@" "@%rot; - %obj.setTransform(%trans); -} - +//------------------------------------------------------------------------------ +// A lil sumthin by Alviss +// For C&C + +//------------------------------------------------------------------------------ +// Execution +//------------------------------------------------------------------------------ + +// This clears the building index's in one swoop +function BuildingManagerInit() +{ + if (isObject(BuildingManager)) + BuildingManager.Delete(); + + new ScriptObject(BuildingManager) {}; +} + +//------------------------------------------------------------------------------ + +exec("scripts/Importer/BuildingDatablocks.cs"); +exec("scripts/Importer/BuildingGroups.cs"); +exec("scripts/Importer/Buildings/ConstructionYard.cs"); +exec("scripts/Importer/Converter.cs"); + +// adding the buildings + +//------------------------------------------------------------------------------ +// Functions +//------------------------------------------------------------------------------ + +function exebuild() +{ + exec("scripts/functionality/Building.cs"); +} + + +function LoadCCBuilding(%client, %building, %center) +{ + %team = %client.team; + + // This is used to keep duplicate buildings from joining the same group + // So, like, we don't have 3 group's named PowerPlant. + // EDIT: I realize it wouldn't matter now, but i'm too lazy to remove all my work + BuildingManager.BuildingInc[%building, %team]++; + + switch$(%building) + { + case "ConYard": + Build_ConstructionYard(%client, %center, %team); + + case "PowerPlant": + Build_PowerPlant(%client, %center, %team); + + } + + // set a timer to unify the building + NametoId("MissionCleanup/Buildings"@%team@"/"@%building @ BuildingManager.BuildingInc[%building, %team]).Schedule(2000, "UnifyBuildings"); + // it uses a timer because none of the objects have the required parameters set yet, plus it's a good idea + // to wait until all the pieces are loaded. +} + +//------------------------------------------------------------------------------ +// CCMod Package +//------------------------------------------------------------------------------ + +package CCMod +{ + //------------------------------------------ + // echos and logs the exec call + function exec(%target) + { +// LogEvent(%target); + + //error("Count : " @ DatablockGroup.getCount()); + + parent::exec(%target); + } + + //------------------------------------------ + // So you don't get a lame red spam wall in the console. + function setTargetSensorGroup(%target, %team) + { + if (%target <= 0) + return; + + parent::setTargetSensorGroup(%target, %team); + } + + //------------------------------------------ + // So you don't get a lame red spam wall in the console. + function setTargetName(%target, %name) + { + if (%target <= 0) + return; + + parent::setTargetName(%target, %name); + } + //------------------------------------------ + // to capture the MCV when it deploys + function StaticShapeData::OnAdd(%data, %obj) + { + // it's a building piece. + if (StrStr(%data.GetName(), "BuildingBlock") != -1) + { + if (%obj.TheFloor && %obj.type $= "ConYard") + { + $CCGame::MCV[%obj.team] = %obj; + + } + } + + Parent::OnAdd(%data, %obj); + } + + //------------------------------------------ + // door functions + function StaticShapeData::OnCollision(%data, %obj) + { + // DoorCode + if (%obj.IsDoor) + { + %obj.ClosePosition = %obj.GetPosition(); + %obj.SetPosition("0 0 -100"); + + schedule(2000, 0, "eval", %obj@".SetPosition("@%obj@".ClosePosition);"); + } + } + + //------------------------------------------ + // captures incoming damage + function StaticShapeData::damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType) + { + // it's a building piece. + if (StrStr(%data.GetName(), "BuildingBlock") != -1) + GrabBaseDamageCall(%data, %targetObject, %sourceObject, %position, %amount, %damageType); + else + parent::damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType); + } + + //------------------------------------------ + // captures incoming destroyed call + function StaticShapeData::onDestroyed(%this,%obj,%prevState) + { + $BuildingCount[%obj.type, %obj.team]--; + $Power[%obj.team] -= $Power[%obj.team]; + CheckPowerGoodLevel(%obj.team); + +// $TeamDeployedCount[%obj.team, AdvGuardTurretBasePack]--; + } + +}; + +if (!isActivePackage(CCMod)) + ActivatePackage(CCMod); + +//------------------------------------------------------------------------------ +// Support Functions +//------------------------------------------------------------------------------ + +function addToBuildingGroup(%object) +{ + %TeamGroup = nameToID("Buildings"@%object.team); + + if (%TeamGroup <= 0) + { + %TeamGroup = new SimGroup("Buildings"@%object.team); + MissionCleanup.add(%TeamGroup); + } + + %index = BuildingManager.BuildingInc[%object.Type, %object.team]; + + %BuildingsGroup = nameToID("Buildings"@%object.team@"/"@%object.Type @ %index); + + if ($CCTypeToName[%object.Type, %object.team] !$= %object.Type) + { + setTargetName(%object.target,addTaggedString($CCTypeToName[%object.Type, %object.team])); + } + + if (%BuildingsGroup <= 0) + { + %BuildingsGroup = new SimGroup(%object.Type @ %index); + %TeamGroup.add(%BuildingsGroup); + } + + %BuildingsGroup.Index = %index; + + %BuildingsGroup.add(%object); +} + +//------------------------------------------------------------------------------ + +function ShapeBase::SightObject(%player, %range) +{ + if (%range $= "") + %range = 100; + + %pos = %player.getEyePoint(); + %vec = %player.getEyeVector(); + + %targetpos = vectoradd(%pos, vectorscale(%vec, %range)); + %ray = containerraycast(%pos, %targetpos, $typemasks::StaticShapeObjectType, %player); + + return getword(%ray, 0); +} + +//------------------------------------------------------------------------------ + +function ShapeBase::SightPos(%player, %range) +{ + if (%range $= "") + %range = 100; + + %pos = %player.getEyePoint(); + %vec = %player.getEyeVector(); + + %targetpos = vectoradd(%pos, vectorscale(%vec, %range)); + %ray = containerraycast(%pos, %targetpos, $typemasks::StaticShapeObjectType | $typemasks::TerrainObjectType, %player); + + return getwords(%ray, 1,3); +} + +//------------------------------------------------------------------------------ + +function ShapeBase::getEyePoint(%player) +{ + %eyePt = getWords(%player.getEyeTransform(), 0, 2); + return %eyePt; +} + +//------------------------------------------------------------------------------ + +function SimObject::setPosition(%obj, %pos) +{ + %rot = getWords(%obj.getTransform(), 3, 6); + %trans = %pos@" "@%rot; + %obj.setTransform(%trans); +} + diff --git a/scripts/Importer/BuildingDatablocks.cs b/scripts/Importer/BuildingDatablocks.cs index ba1d09e..10e8990 100644 --- a/scripts/Importer/BuildingDatablocks.cs +++ b/scripts/Importer/BuildingDatablocks.cs @@ -1,133 +1,133 @@ -//------------------------------------------------------------------------------ -// A lil sumthin by Alviss - -// Datablock script with all the building datablocks. -//------------------------------------------------------------------------------ -// Datablock -//------------------------------------------------------------------------------ -datablock StaticShapeData(BuildingBlock0) : StaticShapeDamageProfile -{ - className = "BuildingPiece"; - shapeFile = "Pmiscf.dts"; - - maxDamage = 20; - destroyedLevel = 20; - disabledLevel = 19; - - isShielded = true; - energyPerDamagePoint = 240; - maxEnergy = 50; - rechargeRate = 0.25; - - explosion = HandGrenadeExplosion; - expDmgRadius = 3.0; - expDamage = 0.1; - expImpulse = 200.0; - - dynamicType = $TypeMasks::StaticShapeObjectType; - deployedObject = true; - cmdCategory = "DSupport"; - cmdIcon = CMDSensorIcon; - cmdMiniIconName = "commander/MiniIcons/com_deploymotionsensor"; - targetNameTag = 'Building Piece'; - deployAmbientThread = true; - debrisShapeName = "debris_generic_small.dts"; - debris = DeployableDebris; - heatSignature = 0; - needsPower = false; -}; - -datablock StaticShapeData(BuildingBlock1) : BuildingBlock0 -{ - shapeFile = "smiscf.dts"; -}; - -datablock StaticShapeData(BuildingBlock2) : BuildingBlock0 -{ - shapeFile = "stackable2l.dts"; -}; - -datablock StaticShapeData(BuildingBlock3) : BuildingBlock0 -{ - shapeFile = "stackable2m.dts"; -}; - -datablock StaticShapeData(BuildingBlock4) : BuildingBlock0 -{ - shapeFile = "stackable3l.dts"; -}; - -datablock StaticShapeData(BuildingBlock5) : BuildingBlock0 -{ - shapeFile = "stackable4m.dts"; -}; - -datablock StaticShapeData(BuildingBlock6) : BuildingBlock0 -{ - shapeFile = "Xmiscf.dts"; -}; - -//-------------------- -// Hack to turn item names into the Type names -// We won't need them once all the buildings are converted. -// - -// Words like, Deployable, BasePack, Turret -// are all removed from the item name, and then referenced the this table. - -//$CCItemToType[PowerPlant] = "PowerPlant"; -//$CCItemToType[Barracks] = "Barracks"; -//$CCItemToType[TiberiumRefinery] = "Tiberium"; -//$CCItemToType[CommCenter] = "CommCenter"; -//$CCItemToType[GTower] = "GuardTower"; -//$CCItemToType[WeaponsFactory] = "WarFact"; -//$CCItemToType[GunTurret] = "Gun"; // < lol -//$CCItemToType[NPA] = "LaserBatt"; -//$CCItemToType[AdvPowerPlant] = "AdvPowerPlant"; -//$CCItemToType[EnrichGenerator] = "Enrich"; -//$CCItemToType[AdvGuard] = "AdvGuard"; -//$CCItemToType[AABat] = "AABat"; -//$CCItemToType[IonControl] = "IonControl"; -//$CCItemToType[Obelisk] = "Obelisk"; -//$CCItemToType[SAM] = "SAMSite"; -//$CCItemToType[TempOfNod] = "TempleOfNod"; -//$CCItemToType[PEC] = "ParticleEC"; - -$CCItemToType[PowerPlantDeployable] = "PowerPlant"; -$CCItemToType[BarracksDeployable] = "Barracks"; -$CCItemToType[TiberiumRefinery] = "Tiberium"; -$CCItemToType[CommCenterDeployable] = "CommCenter"; -$CCItemToType[GTowerTurretBasePack] = "GuardTower"; -$CCItemToType[WeaponsFactoryDeployable] = "WarFact"; -$CCItemToType[TurretBasePack] = "Gun"; // < lol -$CCItemToType[NPATurretBasePack] = "LaserBatt"; -$CCItemToType[AdvPowerPlantDeployable] = "AdvPowerPlant"; -$CCItemToType[EnrichGeneratorDeployable] = "Enrich"; -$CCItemToType[AdvGuardTurretBasePack] = "AdvGuard"; -$CCItemToType[AABatTurretBasePack] = "AABat"; -$CCItemToType[IonControlDeployable] = "IonControl"; -$CCItemToType[ObeliskTurretBasePack] = "Obelisk"; -$CCItemToType[SAMTurretBasePack] = "SAMSite"; -$CCItemToType[TempleOfNod] = "TempleOfNod"; -$CCItemToType[PECTurretBasePack] = "ParticleEC"; - -$CCTypeToItem[PowerPlant] = "PowerPlantDeployable"; -$CCTypeToItem[Barracks] = "BarracksDeployable"; -$CCTypeToItem[Tiberium] = "TiberiumRefineryDeployable"; -$CCTypeToItem[CommCenter] = "CommCenterDeployable"; -$CCTypeToItem[GuardTower] = "GTowerTurretBasePack"; -$CCTypeToItem[WarFact] = "WeaponsFactoryDeployable"; -$CCTypeToItem[Gun] = "TurretBasePack"; // < lol -$CCTypeToItem[LaserBatt] = "NPATurretBasePack"; -$CCTypeToItem[AdvPowerPlant] = "AdvPowerPlantDeployable"; -$CCTypeToItem[Enrich] = "EnrichGeneratorDeployable"; -$CCTypeToItem[AdvGuard] = "AdvGuardTurretBasePack"; -$CCTypeToItem[AABat] = "AABatTurretBasePack"; -$CCTypeToItem[IonControl] = "IonControlDeployable"; -$CCTypeToItem[Obelisk] = "ObeliskTurretBasePack"; -$CCTypeToItem[SAMSite] = "SAMTurretBasePack"; -$CCTypeToItem[TempOfNod] = "TempleOfNod"; -$CCTypeToItem[ParticleEC] = "PECTurretBasePack"; - - - +//------------------------------------------------------------------------------ +// A lil sumthin by Alviss + +// Datablock script with all the building datablocks. +//------------------------------------------------------------------------------ +// Datablock +//------------------------------------------------------------------------------ +datablock StaticShapeData(BuildingBlock0) : StaticShapeDamageProfile +{ + className = "BuildingPiece"; + shapeFile = "Pmiscf.dts"; + + maxDamage = 20; + destroyedLevel = 20; + disabledLevel = 19; + + isShielded = true; + energyPerDamagePoint = 240; + maxEnergy = 50; + rechargeRate = 0.25; + + explosion = HandGrenadeExplosion; + expDmgRadius = 3.0; + expDamage = 0.1; + expImpulse = 200.0; + + dynamicType = $TypeMasks::StaticShapeObjectType; + deployedObject = true; + cmdCategory = "DSupport"; + cmdIcon = CMDSensorIcon; + cmdMiniIconName = "commander/MiniIcons/com_deploymotionsensor"; + targetNameTag = 'Building Piece'; + deployAmbientThread = true; + debrisShapeName = "debris_generic_small.dts"; + debris = DeployableDebris; + heatSignature = 0; + needsPower = false; +}; + +datablock StaticShapeData(BuildingBlock1) : BuildingBlock0 +{ + shapeFile = "smiscf.dts"; +}; + +datablock StaticShapeData(BuildingBlock2) : BuildingBlock0 +{ + shapeFile = "stackable2l.dts"; +}; + +datablock StaticShapeData(BuildingBlock3) : BuildingBlock0 +{ + shapeFile = "stackable2m.dts"; +}; + +datablock StaticShapeData(BuildingBlock4) : BuildingBlock0 +{ + shapeFile = "stackable3l.dts"; +}; + +datablock StaticShapeData(BuildingBlock5) : BuildingBlock0 +{ + shapeFile = "stackable4m.dts"; +}; + +datablock StaticShapeData(BuildingBlock6) : BuildingBlock0 +{ + shapeFile = "Xmiscf.dts"; +}; + +//-------------------- +// Hack to turn item names into the Type names +// We won't need them once all the buildings are converted. +// + +// Words like, Deployable, BasePack, Turret +// are all removed from the item name, and then referenced the this table. + +//$CCItemToType[PowerPlant] = "PowerPlant"; +//$CCItemToType[Barracks] = "Barracks"; +//$CCItemToType[TiberiumRefinery] = "Tiberium"; +//$CCItemToType[CommCenter] = "CommCenter"; +//$CCItemToType[GTower] = "GuardTower"; +//$CCItemToType[WeaponsFactory] = "WarFact"; +//$CCItemToType[GunTurret] = "Gun"; // < lol +//$CCItemToType[NPA] = "LaserBatt"; +//$CCItemToType[AdvPowerPlant] = "AdvPowerPlant"; +//$CCItemToType[EnrichGenerator] = "Enrich"; +//$CCItemToType[AdvGuard] = "AdvGuard"; +//$CCItemToType[AABat] = "AABat"; +//$CCItemToType[IonControl] = "IonControl"; +//$CCItemToType[Obelisk] = "Obelisk"; +//$CCItemToType[SAM] = "SAMSite"; +//$CCItemToType[TempOfNod] = "TempleOfNod"; +//$CCItemToType[PEC] = "ParticleEC"; + +$CCItemToType[PowerPlantDeployable] = "PowerPlant"; +$CCItemToType[BarracksDeployable] = "Barracks"; +$CCItemToType[TiberiumRefinery] = "Tiberium"; +$CCItemToType[CommCenterDeployable] = "CommCenter"; +$CCItemToType[GTowerTurretBasePack] = "GuardTower"; +$CCItemToType[WeaponsFactoryDeployable] = "WarFact"; +$CCItemToType[TurretBasePack] = "Gun"; // < lol +$CCItemToType[NPATurretBasePack] = "LaserBatt"; +$CCItemToType[AdvPowerPlantDeployable] = "AdvPowerPlant"; +$CCItemToType[EnrichGeneratorDeployable] = "Enrich"; +$CCItemToType[AdvGuardTurretBasePack] = "AdvGuard"; +$CCItemToType[AABatTurretBasePack] = "AABat"; +$CCItemToType[IonControlDeployable] = "IonControl"; +$CCItemToType[ObeliskTurretBasePack] = "Obelisk"; +$CCItemToType[SAMTurretBasePack] = "SAMSite"; +$CCItemToType[TempleOfNod] = "TempleOfNod"; +$CCItemToType[PECTurretBasePack] = "ParticleEC"; + +$CCTypeToItem[PowerPlant] = "PowerPlantDeployable"; +$CCTypeToItem[Barracks] = "BarracksDeployable"; +$CCTypeToItem[Tiberium] = "TiberiumRefineryDeployable"; +$CCTypeToItem[CommCenter] = "CommCenterDeployable"; +$CCTypeToItem[GuardTower] = "GTowerTurretBasePack"; +$CCTypeToItem[WarFact] = "WeaponsFactoryDeployable"; +$CCTypeToItem[Gun] = "TurretBasePack"; // < lol +$CCTypeToItem[LaserBatt] = "NPATurretBasePack"; +$CCTypeToItem[AdvPowerPlant] = "AdvPowerPlantDeployable"; +$CCTypeToItem[Enrich] = "EnrichGeneratorDeployable"; +$CCTypeToItem[AdvGuard] = "AdvGuardTurretBasePack"; +$CCTypeToItem[AABat] = "AABatTurretBasePack"; +$CCTypeToItem[IonControl] = "IonControlDeployable"; +$CCTypeToItem[Obelisk] = "ObeliskTurretBasePack"; +$CCTypeToItem[SAMSite] = "SAMTurretBasePack"; +$CCTypeToItem[TempOfNod] = "TempleOfNod"; +$CCTypeToItem[ParticleEC] = "PECTurretBasePack"; + + + diff --git a/scripts/Importer/BuildingGroups.cs b/scripts/Importer/BuildingGroups.cs index b86a5b9..7c946e5 100644 --- a/scripts/Importer/BuildingGroups.cs +++ b/scripts/Importer/BuildingGroups.cs @@ -1,153 +1,153 @@ -//------------------------------------------------------------------------------ -// A lil sumthin by Alviss -// For C&C -//------------------------------------------------------------------------------ - -$CCBuildingHealth["ConYard"] = 750; -$CCBuildingHealth["PowerPlant"] = 250; -$CCBuildingHealth["AdvPowerPlant"] = 500; -$CCBuildingHealth["Barracks"] = 300; - -//------------------------------------------------------------------------------ -// SimGroup Functions -//------------------------------------------------------------------------------ - -function SimGroup::UnifyBuildings(%group) -{ - // get the max health, have to remove the Index suffix - %group.MaxHp = $CCBuildingHealth[ StrReplace(%group.getName(), %group.Index, "") ]; - - // give all the pieces the nameplate of the building - for (%i = 0; %i < %group.GetCount(); %i++) - { - %obj = %group.GetObject(%i); - - if (%obj.GetTarget() == -1) - { - // best function i've ever learned. :) - %target = CreateTarget(%obj, "", "", "", "", %obj.team, ""); - %obj.SetTarget(%target); - } - - %name = $CCTypeToName[%obj.Type, %obj.Team]; - - setTargetName(%obj.getTarget(), AddTaggedString(%name)); - } - - // let all the pieces know the change. - %group.SetHealth(%group.MaxHp); -} - -//------------------------------------------------------------------------------ - -function SimGroup::SetHealth(%group, %Hp) -{ - %group.Hp = %hp; - - if (%hp <= 0) - { - %group.DestroyBuilding(); - return; - } - - %percent = %hp / %group.MaxHp; - - echo(%percent); - for (%i = 0; %i < %group.GetCount(); %i++) - { - %obj = %group.GetObject(%i); - - %max = %obj.getDatablock().maxDamage; - - %obj.SetDamageLevel( %max - (%percent * %max) ); - } - -} - -//------------------------------------------------------------------------------ - -function SimGroup::DestroyBuilding(%group) -{ - %type = StrReplace(%group.getName(), %group.Index, ""); - - for (%i = 0; %i < %group.GetCount(); %i++) - { - %obj = %group.GetObject(%i); - %team = %obj.team; - - // set the health to zero, so it explodes - %obj.SetDamageLevel( 0 ); - schedule(1000, 0, Killit, %obj); - } - - $BuildingCount[%type, %team]--; - - if (%type $= "ConYard") - { - Game.gameOver(); - CycleMissions(); - } - - if (%type $= "PowerPlant") - { - $TeamDeployedCount[%team, $CCTypeToItem[%type]]--; - $Power[%team] -= 250; - CheckPowerLowLevel(%team); - } - if (%type $= "AdvPowerPlant") - { - $TeamDeployedCount[%team, $CCTypeToItem[%type]]--; - $Power[%team] -= 500; - CheckPowerLowLevel(%team); - } - -} - - -//------------------------------------------------------------------------------ -// SimObject Functions -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -// This function intercepts incoming damage calls and subtracts the dmg from the building MaxHp -function GrabBaseDamageCall(%data, %targetObject, %sourceObject, %position, %amount, %damageType) -{ - if (!$TeamDamage) - { - if (isObject(%sourceObject)) - { - //see if the object is being shot by a friendly - if(%sourceObject.getDataBlock().catagory $= "Vehicles") - %attackerTeam = getVehicleAttackerTeam(%sourceObject); - else - %attackerTeam = %sourceObject.team; - } - - if (%attackerTeam == %targetObject.team) - return; - } - - %damageScale = %data.damageScale[%damageType]; - if (%damageScale !$= "") - %amount *= %damageScale; - - if (%targetObject.getTarget() != -1) - { - %building = %targetObject.getGroup(); - - if (isObject(%building)) - { - %building.SetHealth(%building.HP - %amount); - - } - } - -} - - - - - - - - +//------------------------------------------------------------------------------ +// A lil sumthin by Alviss +// For C&C +//------------------------------------------------------------------------------ + +$CCBuildingHealth["ConYard"] = 750; +$CCBuildingHealth["PowerPlant"] = 250; +$CCBuildingHealth["AdvPowerPlant"] = 500; +$CCBuildingHealth["Barracks"] = 300; + +//------------------------------------------------------------------------------ +// SimGroup Functions +//------------------------------------------------------------------------------ + +function SimGroup::UnifyBuildings(%group) +{ + // get the max health, have to remove the Index suffix + %group.MaxHp = $CCBuildingHealth[ StrReplace(%group.getName(), %group.Index, "") ]; + + // give all the pieces the nameplate of the building + for (%i = 0; %i < %group.GetCount(); %i++) + { + %obj = %group.GetObject(%i); + + if (%obj.GetTarget() == -1) + { + // best function i've ever learned. :) + %target = CreateTarget(%obj, "", "", "", "", %obj.team, ""); + %obj.SetTarget(%target); + } + + %name = $CCTypeToName[%obj.Type, %obj.Team]; + + setTargetName(%obj.getTarget(), AddTaggedString(%name)); + } + + // let all the pieces know the change. + %group.SetHealth(%group.MaxHp); +} + +//------------------------------------------------------------------------------ + +function SimGroup::SetHealth(%group, %Hp) +{ + %group.Hp = %hp; + + if (%hp <= 0) + { + %group.DestroyBuilding(); + return; + } + + %percent = %hp / %group.MaxHp; + + echo(%percent); + for (%i = 0; %i < %group.GetCount(); %i++) + { + %obj = %group.GetObject(%i); + + %max = %obj.getDatablock().maxDamage; + + %obj.SetDamageLevel( %max - (%percent * %max) ); + } + +} + +//------------------------------------------------------------------------------ + +function SimGroup::DestroyBuilding(%group) +{ + %type = StrReplace(%group.getName(), %group.Index, ""); + + for (%i = 0; %i < %group.GetCount(); %i++) + { + %obj = %group.GetObject(%i); + %team = %obj.team; + + // set the health to zero, so it explodes + %obj.SetDamageLevel( 0 ); + schedule(1000, 0, Killit, %obj); + } + + $BuildingCount[%type, %team]--; + + if (%type $= "ConYard") + { + Game.gameOver(); + CycleMissions(); + } + + if (%type $= "PowerPlant") + { + $TeamDeployedCount[%team, $CCTypeToItem[%type]]--; + $Power[%team] -= 250; + CheckPowerLowLevel(%team); + } + if (%type $= "AdvPowerPlant") + { + $TeamDeployedCount[%team, $CCTypeToItem[%type]]--; + $Power[%team] -= 500; + CheckPowerLowLevel(%team); + } + +} + + +//------------------------------------------------------------------------------ +// SimObject Functions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// This function intercepts incoming damage calls and subtracts the dmg from the building MaxHp +function GrabBaseDamageCall(%data, %targetObject, %sourceObject, %position, %amount, %damageType) +{ + if (!$TeamDamage) + { + if (isObject(%sourceObject)) + { + //see if the object is being shot by a friendly + if(%sourceObject.getDataBlock().catagory $= "Vehicles") + %attackerTeam = getVehicleAttackerTeam(%sourceObject); + else + %attackerTeam = %sourceObject.team; + } + + if (%attackerTeam == %targetObject.team) + return; + } + + %damageScale = %data.damageScale[%damageType]; + if (%damageScale !$= "") + %amount *= %damageScale; + + if (%targetObject.getTarget() != -1) + { + %building = %targetObject.getGroup(); + + if (isObject(%building)) + { + %building.SetHealth(%building.HP - %amount); + + } + } + +} + + + + + + + + diff --git a/scripts/Importer/Converter.cs b/scripts/Importer/Converter.cs index e76f82b..26d6f2f 100644 --- a/scripts/Importer/Converter.cs +++ b/scripts/Importer/Converter.cs @@ -1,133 +1,133 @@ -//------------------------------ -// Construction Mod save file to C&C Building file converter script. -// A lil sumthin by Alviss -// 24/06/09 -//------------------------------ - -function ccConvertSave(%sender,%args) -{ -// %name = "Conv_test"; - //%Fullname = "Convertion_test"; - - %name = GetWord(%args, 0); - %fullname = GetWords(%args, 1); - - %obj = %sender.player.SightObject(100); - - // this is our flag to set as the bottom-most piece - %obj.TheFloor = 1; - - ConvertSave(%sender, %name, %Fullname, %obj); -} - - -//---------------------------------------------------- -// function to convert all the pieces in a server into a new save format -function ConvertSave(%client, %name, %Fullname, %floor) -{ - // %floor is the bottom-msot piece - - %start = %floor.getPosition(); - %tHeight = getTerrainHeight(%start); - %start = GetWords(%start, 0, 1) SPC 0; - - %nf = new fileobject() {}; - %nf.OpenforWrite(%Fullname@".cs"); - - %nf.WriteLine("//------------------------------------------------------------------------------"); - %nf.WriteLine("// Saved By "@%client.namebase); - %nf.WriteLine(""); - - %dgroup = nametoId("deployables"); - - %nf.WriteLine("function Build_"@%Fullname@"(%client, %center, %team)"); - %nf.WriteLine("{"); - %nf.WriteLine(" if (%team $= \"\")"); - %nf.WriteLine(" %team = 1;"); - //%nf.WriteLine("schedule(2000, 0, \"eval\", \"$Building = "\"\"";\");"); - //%nf.WriteLine("%datablock = (%team == 1) ? \"BuildingBlock0\" : \"BuildingBlock6\";"); - - %nf.WriteLine("%offset = VectorSub(GetWords(%center, 0, 1) SPC GetWord(%center, 2), \""@%start@"\");"); - %nf.WriteLine(""); - - for (%i = 0; %i < %dgroup.GetCount(); %i++) - { - %obj = %dGroup.getObject(%i); - - %db = %obj.getDataBlock().getname(); - - if (%obj.team == %client.team && %db !$= "") - { - // BD mod - - %newline = "%building = new (StaticShape) () {datablock = "@%db@";"; - - // position mod - - %pos = %obj.getPosition(); - - %z = GetWord(%pos, 2) - %tHeight; - - %pos = GetWords(%pos, 0, 1) SPC %z; - - %newline = %newline @ "Position = VectorAdd(\""@%pos@"\", %offset);"; - - // Rotation mod (modifed by Dark Dragon DX to fix rotation issue) - - // %rot = %obj.getRotation(); - %rot = getWords(%obj.getTransform(), 3, 6); - - // %newline = %newline @ "Rotation = \""@%rot@"\";"; - - // Scale mod - - %Scale = %obj.Scale; - - %newline = %newline @ "Scale = \""@%Scale@"\";"; - - // Floor mod - - if (%obj.TheFloor) - { - %newline = %newline @ "TheFloor = \"true\";"; - - %obj.TheFloor = ""; - } - - // type mod - - %newline = %newline @ "Type = \""@%name@"\";"; - - // Team mod - - %newline = %newline @ "team = %team;};"; - - // Unification - - %newline = %newline @ "addToDeployGroup(%obj);"; - - // write - - %nf.WriteLine(%newline); - %nf.WriteLine("%building.setRotation(\x22"@%rot@"\x22);"); - } - - } - - %nf.WriteLine("}"); - %nf.Close(); - %nf.Delete(); - -} - -$CC_ConvTable["DeployedSpine"] = "%datablock"; // white/black pads are team based -$CC_ConvTable["DeployedSpine2"] = "%datablock"; // white/black pads are team based - -$CC_ConvTable["DeployedSpine5"] = "\"BuildingBlock1\""; // brown pad - -$CC_ConvTable["DeployedCrate8"] = "\"BuildingBlock5\""; // Recycle Unit -$CC_ConvTable["DeployedCrate4"] = "\"BuildingBlock2\""; // Quantum Battery -$CC_ConvTable["DeployedCrate3"] = "\"BuildingBlock3\""; // 4 tubes -$CC_ConvTable["DeployedCrate7"] = "\"BuildingBlock4\""; // Mag Cooler -$CC_ConvTable["DeployedCrate9"] = "\"BuildingBlock5\""; // Cylinder - +//------------------------------ +// Construction Mod save file to C&C Building file converter script. +// A lil sumthin by Alviss +// 24/06/09 +//------------------------------ + +function ccConvertSave(%sender,%args) +{ +// %name = "Conv_test"; + //%Fullname = "Convertion_test"; + + %name = GetWord(%args, 0); + %fullname = GetWords(%args, 1); + + %obj = %sender.player.SightObject(100); + + // this is our flag to set as the bottom-most piece + %obj.TheFloor = 1; + + ConvertSave(%sender, %name, %Fullname, %obj); +} + + +//---------------------------------------------------- +// function to convert all the pieces in a server into a new save format +function ConvertSave(%client, %name, %Fullname, %floor) +{ + // %floor is the bottom-msot piece + + %start = %floor.getPosition(); + %tHeight = getTerrainHeight(%start); + %start = GetWords(%start, 0, 1) SPC 0; + + %nf = new fileobject() {}; + %nf.OpenforWrite(%Fullname@".cs"); + + %nf.WriteLine("//------------------------------------------------------------------------------"); + %nf.WriteLine("// Saved By "@%client.namebase); + %nf.WriteLine(""); + + %dgroup = nametoId("deployables"); + + %nf.WriteLine("function Build_"@%Fullname@"(%client, %center, %team)"); + %nf.WriteLine("{"); + %nf.WriteLine(" if (%team $= \"\")"); + %nf.WriteLine(" %team = 1;"); + //%nf.WriteLine("schedule(2000, 0, \"eval\", \"$Building = "\"\"";\");"); + //%nf.WriteLine("%datablock = (%team == 1) ? \"BuildingBlock0\" : \"BuildingBlock6\";"); + + %nf.WriteLine("%offset = VectorSub(GetWords(%center, 0, 1) SPC GetWord(%center, 2), \""@%start@"\");"); + %nf.WriteLine(""); + + for (%i = 0; %i < %dgroup.GetCount(); %i++) + { + %obj = %dGroup.getObject(%i); + + %db = %obj.getDataBlock().getname(); + + if (%obj.team == %client.team && %db !$= "") + { + // BD mod + + %newline = "%building = new (StaticShape) () {datablock = "@%db@";"; + + // position mod + + %pos = %obj.getPosition(); + + %z = GetWord(%pos, 2) - %tHeight; + + %pos = GetWords(%pos, 0, 1) SPC %z; + + %newline = %newline @ "Position = VectorAdd(\""@%pos@"\", %offset);"; + + // Rotation mod (modifed by Dark Dragon DX to fix rotation issue) + + // %rot = %obj.getRotation(); + %rot = getWords(%obj.getTransform(), 3, 6); + + // %newline = %newline @ "Rotation = \""@%rot@"\";"; + + // Scale mod + + %Scale = %obj.Scale; + + %newline = %newline @ "Scale = \""@%Scale@"\";"; + + // Floor mod + + if (%obj.TheFloor) + { + %newline = %newline @ "TheFloor = \"true\";"; + + %obj.TheFloor = ""; + } + + // type mod + + %newline = %newline @ "Type = \""@%name@"\";"; + + // Team mod + + %newline = %newline @ "team = %team;};"; + + // Unification + + %newline = %newline @ "addToDeployGroup(%obj);"; + + // write + + %nf.WriteLine(%newline); + %nf.WriteLine("%building.setRotation(\x22"@%rot@"\x22);"); + } + + } + + %nf.WriteLine("}"); + %nf.Close(); + %nf.Delete(); + +} + +$CC_ConvTable["DeployedSpine"] = "%datablock"; // white/black pads are team based +$CC_ConvTable["DeployedSpine2"] = "%datablock"; // white/black pads are team based + +$CC_ConvTable["DeployedSpine5"] = "\"BuildingBlock1\""; // brown pad + +$CC_ConvTable["DeployedCrate8"] = "\"BuildingBlock5\""; // Recycle Unit +$CC_ConvTable["DeployedCrate4"] = "\"BuildingBlock2\""; // Quantum Battery +$CC_ConvTable["DeployedCrate3"] = "\"BuildingBlock3\""; // 4 tubes +$CC_ConvTable["DeployedCrate7"] = "\"BuildingBlock4\""; // Mag Cooler +$CC_ConvTable["DeployedCrate9"] = "\"BuildingBlock5\""; // Cylinder + diff --git a/scripts/LaunchLanGui.cs b/scripts/LaunchLanGui.cs index 648bb19..43bc839 100644 --- a/scripts/LaunchLanGui.cs +++ b/scripts/LaunchLanGui.cs @@ -1,387 +1,387 @@ -//-------------------------------------------------------- -function QueryServers( %searchCriteria ) -{ - GMJ_Browser.lastQuery = %searchCriteria; - LaunchGame( "JOIN" ); -} - -//-------------------------------------------------------- -function QueryOnlineServers() -{ - QueryServers("Master"); -} - -//-------------------------------------------------------- -// Launch gui functions -//-------------------------------------------------------- -function PlayOffline() -{ - $FirstLaunch = true; - setNetPort(0); - $PlayingOnline = false; - Canvas.setContent(LaunchGui); -} - -//-------------------------------------------------------- -function OnlineLogIn() -{ - $FirstLaunch = true; - setNetPort(0); - $PlayingOnline = true; - FilterEditGameType.clear(); - FilterEditMissionType.clear(); - queryMasterGameTypes(); - // Start the Email checking... - EmailGui.checkSchedule = schedule( 5000, 0, CheckEmail, true ); - - // Load the player database... - %guid = getField( WONGetAuthInfo(), 3 ); - if ( %guid > 0 ) - loadPlayerDatabase( "prefs/pyrdb" @ %guid ); - Canvas.setContent(LaunchGui); -} - -//-------------------------------------------------------- -function LaunchToolbarMenu::onSelect(%this, %id, %text) -{ - switch(%id) - { - case 0: - LaunchGame(); - case 1: // Start Training Mission - LaunchTraining(); - case 2: - LaunchNews(); - case 3: - LaunchForums(); - case 4: - LaunchEmail(); - case 5: // Join Chat Room - Canvas.pushDialog(JoinChatDlg); - case 6: - LaunchBrowser(); - case 7: // Options - Canvas.pushDialog(OptionsDlg); - case 8: // Play Recording - Canvas.pushDialog(RecordingsDlg); - case 9: // Quit - if(isObject($IRCClient.tcp)) - IRCClient::quit(); - LaunchTabView.closeAllTabs(); - if (!isDemo()) - quit(); - else - Canvas.setContent(DemoEndGui); - //case 10: // Log Off - // LaunchTabView.closeAllTabs(); - // PlayOffline(); - //case 11: // Log On - // LaunchTabView.closeAllTabs(); - // OnlineLogIn(); - case 12: - LaunchCredits(); - case 13: - Canvas.setContent(RPGBrowserGui); - } -} - -//-------------------------------------------------------- -function LaunchToolbarDlg::onWake(%this) -{ - // Play the shell hum: - if ( $HudHandle[shellScreen] $= "" ) - $HudHandle[shellScreen] = alxPlay( ShellScreenHumSound, 0, 0, 0 ); - - LaunchToolbarMenu.clear(); - - if ( isDemo() ) - { - LaunchToolbarMenu.add( 1, "CAMPAIGN" ); - LaunchToolbarMenu.add( 0, "GAME" ); - LaunchToolbarMenu.add( 2, "NEWS" ); - LaunchToolbarMenu.add( 13, "MOD BROWSER" ); - } - else if ( $PlayingOnline ) - { - LaunchToolbarMenu.add( 0, "GAME" ); - LaunchToolbarMenu.add( 4, "EMAIL" ); - LaunchToolbarMenu.add( 5, "CHAT" ); - LaunchToolbarMenu.add( 6, "BROWSER" ); - LaunchToolbarMenu.add( 13, "MOD BROWSER" ); - } - else - { - LaunchToolbarMenu.add( 1, "CAMPAIGN" ); - LaunchToolbarMenu.add( 0, "LAN GAME" ); - LaunchToolbarMenu.add( 13, "MOD BROWSER" ); - } - - LaunchToolbarMenu.addSeparator(); - LaunchToolbarMenu.add( 7, "SETTINGS" ); - if ( !isDemo() ) - LaunchToolbarMenu.add( 8, "RECORDINGS" ); - LaunchToolbarMenu.add( 12, "CREDITS" ); - - LaunchToolbarMenu.addSeparator(); - LaunchToolbarMenu.add( 9, "QUIT" ); - - %on = false; - for ( %tab = 0; %tab < LaunchTabView.tabCount(); %tab++ ) - { - if ( LaunchTabView.isTabActive( %tab ) ) - { - %on = true; - break; - } - } - - LaunchToolbarCloseButton.setVisible( %on ); -} - -//---------------------------------------------------------------------------- -// Launch Tab Group functions: -//---------------------------------------------------------------------------- -function OpenLaunchTabs( %gotoWarriorSetup ) -{ - if ( LaunchTabView.tabCount() > 0 || !$FirstLaunch ) - return; - - $FirstLaunch = ""; - - // Set up all of the launch bar tabs: - if ( isDemo() ) - { - LaunchTabView.addLaunchTab( "CAMPAIGN", TrainingGui ); - LaunchTabView.addLaunchTab( "GAME", GameGui ); - LaunchTabView.addLaunchTab( "NEWS", NewsGui ); - LaunchTabView.addLaunchTab( "FORUMS", "", true ); - LaunchTabView.addLaunchTab( "EMAIL", "", true ); - LaunchTabView.addLaunchTab( "CHAT", "", true ); - LaunchTabView.addLaunchTab( "BROWSER", "", true ); - %launchGui = NewsGui; - } - else if ( $PlayingOnline ) - { - LaunchTabView.addLaunchTab( "GAME", GameGui ); - LaunchTabView.addLaunchTab( "EMAIL", EmailGui ); - LaunchTabView.addLaunchTab( "CHAT", ChatGui ); - LaunchTabView.addLaunchTab( "BROWSER", TribeandWarriorBrowserGui); - - switch$ ( $pref::Shell::LaunchGui ) - { - case "News": %launchGui = NewsGui; - case "Forums": %launchGui = ForumsGui; - case "Email": %launchGui = EmailGui; - case "Chat": %launchGui = ChatGui; - case "Browser": %launchGui = TribeandWarriorBrowserGui; - case "Mod Browser": %launchGui = RPGBrowserGui; - default: %launchGui = GameGui; - } - } - else - { - LaunchTabView.addLaunchTab( "CAMPAIGN", TrainingGui ); - LaunchTabView.addLaunchTab( "LAN GAME", GameGui ); - %launchGui = TrainingGui; - } - - if ( %gotoWarriorSetup ) - LaunchGame( "WARRIOR" ); - else - LaunchTabView.viewTab( "", %launchGui, 0 ); - - if ( $IssueVoodooWarning && !$pref::SawVoodooWarning ) - { - $pref::SawVoodooWarning = 1; - schedule( 0, 0, MessageBoxOK, "WARNING", "A Voodoo card has been detected. If you experience any graphical oddities, you should try the WickedGl drivers available at www.wicked3d.com" ); - } -} - -//-------------------------------------------------------- -function LaunchTabView::addLaunchTab( %this, %text, %gui, %makeInactive ) -{ - %tabCount = %this.tabCount(); - %this.gui[%tabCount] = %gui; - %this.key[%tabCount] = 0; - %this.addTab( %tabCount, %text ); - if ( %makeInactive ) - %this.setTabActive( %tabCount, false ); -} - -//-------------------------------------------------------- -function LaunchTabView::onSelect( %this, %id, %text ) -{ - // Ignore the ID - it can't be trusted. - %tab = %this.getSelectedTab(); - - if ( isObject( %this.gui[%tab] ) ) - { - Canvas.setContent( %this.gui[%tab] ); - %this.gui[%tab].setKey( %this.key[%tab] ); - %this.lastTab = %tab; - } -} - -//-------------------------------------------------------- -function LaunchTabView::viewLastTab( %this ) -{ - if ( %this.tabCount() == 0 || %this.lastTab $= "" ) - return; - - %this.setSelectedByIndex( %this.lastTab ); -} - -//-------------------------------------------------------- -function LaunchTabView::viewTab( %this, %text, %gui, %key ) -{ - %tabCount = %this.tabCount(); - for ( %tab = 0; %tab < %tabCount; %tab++ ) - if ( %this.gui[%tab] $= %gui && %this.key[%tab] $= %key ) - break; - - if ( %tab == %tabCount ) - { - // Add a new tab: - %this.gui[%tab] = %gui; - %this.key[%tab] = %key; - // WARNING! This id may not be unique and therefore should - // not be relied on! Use index instead! - %this.addTab( %tab, %text ); - } - - if ( %this.getSelectedTab() != %tab ) - %this.setSelectedByIndex( %tab ); -} - -//-------------------------------------------------------- -function LaunchTabView::closeCurrentTab( %this ) -{ - %tab = %this.getSelectedTab(); - %this.closeTab( %this.gui[%tab], %this.key[%tab] ); -} - -//-------------------------------------------------------- -function LaunchTabView::closeTab( %this, %gui, %key ) -{ - %tabCount = %this.tabCount(); - %activeCount = 0; - for ( %i = 0; %i < %tabCount; %i++ ) - { - if ( %this.gui[%i] $= %gui && %this.key[%i] $= %key ) - %tab = %i; - else if ( %this.isTabActive( %i ) ) - %activeCount++; - } - - if ( %tab == %tabCount ) - return; - - for( %i = %tab; %i < %tabCount; %i++ ) - { - %this.gui[%i] = %this.gui[%i+1]; - %this.key[%i] = %this.key[%i+1]; - } - - %this.removeTabByIndex( %tab ); - %gui.onClose( %key ); - - if ( %activeCount == 0 ) - { - %this.lastTab = ""; - Canvas.setContent( LaunchGui ); - } -} - -//-------------------------------------------------------- -function LaunchTabView::closeAllTabs( %this ) -{ - %tabCount = %this.tabCount(); - for ( %i = 0; %i < %tabCount; %i++ ) - { - if ( isObject( %this.gui[%i] ) ) - %this.gui[%i].onClose( %this.key[%i] ); - %this.gui[%i] = ""; - %this.key[%i] = ""; - } - - %this.clear(); -} - -//---------------------------------------------------------------------------- -// LaunchGui functions: -//---------------------------------------------------------------------------- -function LaunchGui::onAdd(%this) -{ - %this.getWarrior = true; -} - -//---------------------------------------------------------------------------- -function LaunchGui::onWake(%this) -{ - $enableDirectInput = "0"; - deactivateDirectInput(); - Canvas.pushDialog(LaunchToolbarDlg); - if ( !$FirstLaunch ) - LaunchTabView.viewLastTab(); - - if ( !isDemo() ) - checkNamesAndAliases(); - else - OpenLaunchTabs(); -} - -//---------------------------------------------------------------------------- -function LaunchGui::onSleep(%this) -{ - //alxStop($HudHandle['shellScreen']); - Canvas.popDialog( LaunchToolbarDlg ); -} - -//---------------------------------------------------------------------------- -function checkNamesAndAliases() -{ - %gotoWarriorSetup = false; - if ( $PlayingOnline ) - { - // When first launching, make sure we have a valid warrior: - if ( LaunchGui.getWarrior ) - { - %cert = WONGetAuthInfo(); - if ( %cert !$= "" ) - { - LaunchGui.getWarrior = ""; - if ( %cert $= "" ) - %warrior = $CreateAccountWarriorName; - else - %warrior = getField( %cert, 0 ); - - %warriorIdx = -1; - for ( %i = 0; %i < $pref::Player::count; %i++ ) - { - if ( %warrior $= getField( $pref::Player[%i], 0 ) ) - { - %warriorIdx = %i; - break; - } - } - - if ( %warriorIdx == -1 ) - { - // Create new warrior: - $pref::Player[$pref::Player::Count] = %warrior @ "\tHuman Male\tbeagle\tMale1"; - $pref::Player::Current = $pref::Player::Count; - $pref::Player::Count++; - %gotoWarriorSetup = true; - } - } - else - MessageBoxOK( "WARNING", "Failed to get account information. You may need to quit the game and log in again." ); - } - } - else if ( $pref::Player::Count == 0 ) - { - %gotoWarriorSetup = true; - } - - OpenLaunchTabs( %gotoWarriorSetup ); -} +//-------------------------------------------------------- +function QueryServers( %searchCriteria ) +{ + GMJ_Browser.lastQuery = %searchCriteria; + LaunchGame( "JOIN" ); +} + +//-------------------------------------------------------- +function QueryOnlineServers() +{ + QueryServers("Master"); +} + +//-------------------------------------------------------- +// Launch gui functions +//-------------------------------------------------------- +function PlayOffline() +{ + $FirstLaunch = true; + setNetPort(0); + $PlayingOnline = false; + Canvas.setContent(LaunchGui); +} + +//-------------------------------------------------------- +function OnlineLogIn() +{ + $FirstLaunch = true; + setNetPort(0); + $PlayingOnline = true; + FilterEditGameType.clear(); + FilterEditMissionType.clear(); + queryMasterGameTypes(); + // Start the Email checking... + EmailGui.checkSchedule = schedule( 5000, 0, CheckEmail, true ); + + // Load the player database... + %guid = getField( WONGetAuthInfo(), 3 ); + if ( %guid > 0 ) + loadPlayerDatabase( "prefs/pyrdb" @ %guid ); + Canvas.setContent(LaunchGui); +} + +//-------------------------------------------------------- +function LaunchToolbarMenu::onSelect(%this, %id, %text) +{ + switch(%id) + { + case 0: + LaunchGame(); + case 1: // Start Training Mission + LaunchTraining(); + case 2: + LaunchNews(); + case 3: + LaunchForums(); + case 4: + LaunchEmail(); + case 5: // Join Chat Room + Canvas.pushDialog(JoinChatDlg); + case 6: + LaunchBrowser(); + case 7: // Options + Canvas.pushDialog(OptionsDlg); + case 8: // Play Recording + Canvas.pushDialog(RecordingsDlg); + case 9: // Quit + if(isObject($IRCClient.tcp)) + IRCClient::quit(); + LaunchTabView.closeAllTabs(); + if (!isDemo()) + quit(); + else + Canvas.setContent(DemoEndGui); + //case 10: // Log Off + // LaunchTabView.closeAllTabs(); + // PlayOffline(); + //case 11: // Log On + // LaunchTabView.closeAllTabs(); + // OnlineLogIn(); + case 12: + LaunchCredits(); + case 13: + Canvas.setContent(RPGBrowserGui); + } +} + +//-------------------------------------------------------- +function LaunchToolbarDlg::onWake(%this) +{ + // Play the shell hum: + if ( $HudHandle[shellScreen] $= "" ) + $HudHandle[shellScreen] = alxPlay( ShellScreenHumSound, 0, 0, 0 ); + + LaunchToolbarMenu.clear(); + + if ( isDemo() ) + { + LaunchToolbarMenu.add( 1, "CAMPAIGN" ); + LaunchToolbarMenu.add( 0, "GAME" ); + LaunchToolbarMenu.add( 2, "NEWS" ); + LaunchToolbarMenu.add( 13, "MOD BROWSER" ); + } + else if ( $PlayingOnline ) + { + LaunchToolbarMenu.add( 0, "GAME" ); + LaunchToolbarMenu.add( 4, "EMAIL" ); + LaunchToolbarMenu.add( 5, "CHAT" ); + LaunchToolbarMenu.add( 6, "BROWSER" ); + LaunchToolbarMenu.add( 13, "MOD BROWSER" ); + } + else + { + LaunchToolbarMenu.add( 1, "CAMPAIGN" ); + LaunchToolbarMenu.add( 0, "LAN GAME" ); + LaunchToolbarMenu.add( 13, "MOD BROWSER" ); + } + + LaunchToolbarMenu.addSeparator(); + LaunchToolbarMenu.add( 7, "SETTINGS" ); + if ( !isDemo() ) + LaunchToolbarMenu.add( 8, "RECORDINGS" ); + LaunchToolbarMenu.add( 12, "CREDITS" ); + + LaunchToolbarMenu.addSeparator(); + LaunchToolbarMenu.add( 9, "QUIT" ); + + %on = false; + for ( %tab = 0; %tab < LaunchTabView.tabCount(); %tab++ ) + { + if ( LaunchTabView.isTabActive( %tab ) ) + { + %on = true; + break; + } + } + + LaunchToolbarCloseButton.setVisible( %on ); +} + +//---------------------------------------------------------------------------- +// Launch Tab Group functions: +//---------------------------------------------------------------------------- +function OpenLaunchTabs( %gotoWarriorSetup ) +{ + if ( LaunchTabView.tabCount() > 0 || !$FirstLaunch ) + return; + + $FirstLaunch = ""; + + // Set up all of the launch bar tabs: + if ( isDemo() ) + { + LaunchTabView.addLaunchTab( "CAMPAIGN", TrainingGui ); + LaunchTabView.addLaunchTab( "GAME", GameGui ); + LaunchTabView.addLaunchTab( "NEWS", NewsGui ); + LaunchTabView.addLaunchTab( "FORUMS", "", true ); + LaunchTabView.addLaunchTab( "EMAIL", "", true ); + LaunchTabView.addLaunchTab( "CHAT", "", true ); + LaunchTabView.addLaunchTab( "BROWSER", "", true ); + %launchGui = NewsGui; + } + else if ( $PlayingOnline ) + { + LaunchTabView.addLaunchTab( "GAME", GameGui ); + LaunchTabView.addLaunchTab( "EMAIL", EmailGui ); + LaunchTabView.addLaunchTab( "CHAT", ChatGui ); + LaunchTabView.addLaunchTab( "BROWSER", TribeandWarriorBrowserGui); + + switch$ ( $pref::Shell::LaunchGui ) + { + case "News": %launchGui = NewsGui; + case "Forums": %launchGui = ForumsGui; + case "Email": %launchGui = EmailGui; + case "Chat": %launchGui = ChatGui; + case "Browser": %launchGui = TribeandWarriorBrowserGui; + case "Mod Browser": %launchGui = RPGBrowserGui; + default: %launchGui = GameGui; + } + } + else + { + LaunchTabView.addLaunchTab( "CAMPAIGN", TrainingGui ); + LaunchTabView.addLaunchTab( "LAN GAME", GameGui ); + %launchGui = TrainingGui; + } + + if ( %gotoWarriorSetup ) + LaunchGame( "WARRIOR" ); + else + LaunchTabView.viewTab( "", %launchGui, 0 ); + + if ( $IssueVoodooWarning && !$pref::SawVoodooWarning ) + { + $pref::SawVoodooWarning = 1; + schedule( 0, 0, MessageBoxOK, "WARNING", "A Voodoo card has been detected. If you experience any graphical oddities, you should try the WickedGl drivers available at www.wicked3d.com" ); + } +} + +//-------------------------------------------------------- +function LaunchTabView::addLaunchTab( %this, %text, %gui, %makeInactive ) +{ + %tabCount = %this.tabCount(); + %this.gui[%tabCount] = %gui; + %this.key[%tabCount] = 0; + %this.addTab( %tabCount, %text ); + if ( %makeInactive ) + %this.setTabActive( %tabCount, false ); +} + +//-------------------------------------------------------- +function LaunchTabView::onSelect( %this, %id, %text ) +{ + // Ignore the ID - it can't be trusted. + %tab = %this.getSelectedTab(); + + if ( isObject( %this.gui[%tab] ) ) + { + Canvas.setContent( %this.gui[%tab] ); + %this.gui[%tab].setKey( %this.key[%tab] ); + %this.lastTab = %tab; + } +} + +//-------------------------------------------------------- +function LaunchTabView::viewLastTab( %this ) +{ + if ( %this.tabCount() == 0 || %this.lastTab $= "" ) + return; + + %this.setSelectedByIndex( %this.lastTab ); +} + +//-------------------------------------------------------- +function LaunchTabView::viewTab( %this, %text, %gui, %key ) +{ + %tabCount = %this.tabCount(); + for ( %tab = 0; %tab < %tabCount; %tab++ ) + if ( %this.gui[%tab] $= %gui && %this.key[%tab] $= %key ) + break; + + if ( %tab == %tabCount ) + { + // Add a new tab: + %this.gui[%tab] = %gui; + %this.key[%tab] = %key; + // WARNING! This id may not be unique and therefore should + // not be relied on! Use index instead! + %this.addTab( %tab, %text ); + } + + if ( %this.getSelectedTab() != %tab ) + %this.setSelectedByIndex( %tab ); +} + +//-------------------------------------------------------- +function LaunchTabView::closeCurrentTab( %this ) +{ + %tab = %this.getSelectedTab(); + %this.closeTab( %this.gui[%tab], %this.key[%tab] ); +} + +//-------------------------------------------------------- +function LaunchTabView::closeTab( %this, %gui, %key ) +{ + %tabCount = %this.tabCount(); + %activeCount = 0; + for ( %i = 0; %i < %tabCount; %i++ ) + { + if ( %this.gui[%i] $= %gui && %this.key[%i] $= %key ) + %tab = %i; + else if ( %this.isTabActive( %i ) ) + %activeCount++; + } + + if ( %tab == %tabCount ) + return; + + for( %i = %tab; %i < %tabCount; %i++ ) + { + %this.gui[%i] = %this.gui[%i+1]; + %this.key[%i] = %this.key[%i+1]; + } + + %this.removeTabByIndex( %tab ); + %gui.onClose( %key ); + + if ( %activeCount == 0 ) + { + %this.lastTab = ""; + Canvas.setContent( LaunchGui ); + } +} + +//-------------------------------------------------------- +function LaunchTabView::closeAllTabs( %this ) +{ + %tabCount = %this.tabCount(); + for ( %i = 0; %i < %tabCount; %i++ ) + { + if ( isObject( %this.gui[%i] ) ) + %this.gui[%i].onClose( %this.key[%i] ); + %this.gui[%i] = ""; + %this.key[%i] = ""; + } + + %this.clear(); +} + +//---------------------------------------------------------------------------- +// LaunchGui functions: +//---------------------------------------------------------------------------- +function LaunchGui::onAdd(%this) +{ + %this.getWarrior = true; +} + +//---------------------------------------------------------------------------- +function LaunchGui::onWake(%this) +{ + $enableDirectInput = "0"; + deactivateDirectInput(); + Canvas.pushDialog(LaunchToolbarDlg); + if ( !$FirstLaunch ) + LaunchTabView.viewLastTab(); + + if ( !isDemo() ) + checkNamesAndAliases(); + else + OpenLaunchTabs(); +} + +//---------------------------------------------------------------------------- +function LaunchGui::onSleep(%this) +{ + //alxStop($HudHandle['shellScreen']); + Canvas.popDialog( LaunchToolbarDlg ); +} + +//---------------------------------------------------------------------------- +function checkNamesAndAliases() +{ + %gotoWarriorSetup = false; + if ( $PlayingOnline ) + { + // When first launching, make sure we have a valid warrior: + if ( LaunchGui.getWarrior ) + { + %cert = WONGetAuthInfo(); + if ( %cert !$= "" ) + { + LaunchGui.getWarrior = ""; + if ( %cert $= "" ) + %warrior = $CreateAccountWarriorName; + else + %warrior = getField( %cert, 0 ); + + %warriorIdx = -1; + for ( %i = 0; %i < $pref::Player::count; %i++ ) + { + if ( %warrior $= getField( $pref::Player[%i], 0 ) ) + { + %warriorIdx = %i; + break; + } + } + + if ( %warriorIdx == -1 ) + { + // Create new warrior: + $pref::Player[$pref::Player::Count] = %warrior @ "\tHuman Male\tbeagle\tMale1"; + $pref::Player::Current = $pref::Player::Count; + $pref::Player::Count++; + %gotoWarriorSetup = true; + } + } + else + MessageBoxOK( "WARNING", "Failed to get account information. You may need to quit the game and log in again." ); + } + } + else if ( $pref::Player::Count == 0 ) + { + %gotoWarriorSetup = true; + } + + OpenLaunchTabs( %gotoWarriorSetup ); +} diff --git a/scripts/NSGame.cs b/scripts/NSGame.cs index 128b6c0..0ff8015 100644 --- a/scripts/NSGame.cs +++ b/scripts/NSGame.cs @@ -1,627 +1,627 @@ -// DisplayName = Natural Selection - -//--- GAME RULES BEGIN --- -// Destroy the other team. -//--- GAME RULES END --- - -//exec the AI scripts -exec("scripts/aiNS.cs"); - -$RequiresClient[NS] = false; -$InvBanList[NS, "C4Charge"] = 1; - -//-- tracking --- -function NSGame::initGameVars(%game) -{ - //%game. = ""; //I guess I'll eventually set some, but most are loaded via BASIC files -} - -package NSGame -{ -function blah(){} //Eh.. -}; - -function NSGame::setUpTeams(%game) -{ - defaultGame::setUpTeams(%game); - %game.numTeams = 1; - setSensorGroupCount(4); - $TeamDamage = true; //Allow team Damage -} - -function NSGame::getTeamSkin(%game, %team) -{ - if($host::tournamentMode) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - { - return $teamSkin[%team]; - } - - else - { - //error("CTFGame::getTeamSkin"); - if(!$host::useCustomSkins) - { - %terrain = MissionGroup.musicTrack; - //error("Terrain type is: " SPC %terrain); - switch$(%terrain) - { - case "lush": - if(%team == 1) - %skin = 'beagle'; - else if(%team == 2) - %skin = 'dsword'; - else %skin = 'base'; - - case "badlands": - if(%team == 1) - %skin = 'swolf'; - else if(%team == 2) - %skin = 'dsword'; - else %skin = 'base'; - - case "ice": - if(%team == 1) - %skin = 'swolf'; - else if(%team == 2) - %skin = 'beagle'; - else %skin = 'base'; - - case "desert": - if(%team == 1) - %skin = 'cotp'; - else if(%team == 2) - %skin = 'beagle'; - else %skin = 'base'; - - case "Volcanic": - if(%team == 1) - %skin = 'dsword'; - else if(%team == 2) - %skin = 'cotp'; - else %skin = 'base'; - - default: - if(%team == 2) - %skin = 'baseb'; - else %skin = 'base'; - } - } - else %skin = $teamSkin[%team]; - - //error("%skin = " SPC getTaggedString(%skin)); - return %skin; -} -} - -function NSGame::getTeamName(%game, %team) -{ - // --------------------------------------------------- - // z0dd - ZOD 3/30/02. Only display default team names - //if ( isDemo() || $host::tournamentMode) - return $TeamName[%team]; - // --------------------------------------------------- -} - -//-------------------------------------------------------------------------- -function NSGame::missionLoadDone(%game) -{ - //default version sets up teams - must be called first... - DefaultGame::missionLoadDone(%game); -} - -function NSGame::showStalemateTargets(%game) -{ - cancel(%game.stalemateSchedule); - - //show the targets - for (%i = 1; %i <= 2; %i++) - { - %flag = $TeamFlag[%i]; - - //find the object to scope/waypoint.... - //render the target hud icon for slot 1 (a centermass flag) - //if we just set him as always sensor vis, it'll work fine. - if (isObject(%flag.carrier)) - setTargetAlwaysVisMask(%flag.carrier.getTarget(), 0x7); - } - //schedule the targets to hide - %game.stalemateObjsVisible = true; - %game.stalemateSchedule = %game.schedule(%game.stalemateDurationMS, hideStalemateTargets); -} - -function NSGame::timeLimitReached(%game) -{ - logEcho("game over (timelimit)"); - %game.gameOver(); - cycleMissions(); -} - -function NSGame::scoreLimitReached(%game) -{ - logEcho("game over (scorelimit)"); - %game.gameOver(); - cycleMissions(); -} - -function NSGame::gameOver(%game) -{ - //call the default - DefaultGame::gameOver(%game); - messageAll('MsgClearObjHud', ""); -} - -function NSGame::onClientDamaged(%game, %clVictim, %clAttacker, %damageType, %implement, %damageLoc) -{ - if(%clVictim.headshot && %damageType == $DamageType::Laser && %clVictim.team != %clAttacker.team) - { - %clAttacker.scoreHeadshot++; - if (%game.SCORE_PER_HEADSHOT != 0) - { - messageClient(%clAttacker, 'msgHeadshot', '\c0You received a %1 point bonus for a successful headshot.', %game.SCORE_PER_HEADSHOT); - messageTeamExcept(%clAttacker, 'msgHeadshot', '\c5%1 hit a sniper rifle headshot.', %clAttacker.name); // z0dd - ZOD, 8/15/02. Tell team - } - %game.recalcScore(%clAttacker); - } - - // ----------------------------------------------- - // z0dd - ZOD, 8/25/02. Rear Lance hits - if(%clVictim.rearshot && %damageType == $DamageType::ShockLance && %clVictim.team != %clAttacker.team) - { - %clAttacker.scoreRearshot++; - if (%game.SCORE_PER_REARSHOT != 0) - { - messageClient(%clAttacker, 'msgRearshot', '\c0You received a %1 point bonus for a successful rearshot.', %game.SCORE_PER_REARSHOT); - messageTeamExcept(%clAttacker, 'msgRearshot', '\c5%1 hit a shocklance rearshot.', %clAttacker.name); - } - %game.recalcScore(%clAttacker); - } - // ----------------------------------------------- - - //the DefaultGame will set some vars - DefaultGame::onClientDamaged(%game, %clVictim, %clAttacker, %damageType, %implement, %damageLoc); - - //if victim is carrying a flag and is not on the attackers team, mark the attacker as a threat for x seconds(for scoring purposes) - if ((%clVictim.holdingFlag !$= "") && (%clVictim.team != %clAttacker.team)) - { - %clAttacker.dmgdFlagCarrier = true; - cancel(%clAttacker.threatTimer); //restart timer - %clAttacker.threatTimer = schedule(%game.TIME_CONSIDERED_FLAGCARRIER_THREAT, %clAttacker.dmgdFlagCarrier = false); - } -} - -//////////////////////////////////////////////////////////////////////////////////////// -function NSGame::clientMissionDropReady(%game, %client) -{ - messageClient(%client, 'MsgClientReady',"", "SinglePlayerGame"); //Force the SP game objective hud to setup - %game.resetScore(%client); - - messageClient(%client, 'MsgMissionDropInfo', '\c0You are in mission %1 (%2).', $MissionDisplayName, $MissionTypeDisplayName, $ServerName ); - - DefaultGame::clientMissionDropReady(%game, %client); - - //Force client Spawn since we're ready now - schedule(1000,0,"forceClientSpawn",%client,true); - - %client.setControlObject(%client.player); - commandToClient(%client,'bottomPrint',"Try not to die.",3); - - //Since this is an RPG gamemode, be sure some things are correct. (May have been a mission switch from CTF or some other gamemode) - commandToClient(%client,'SetScoreText',"PDA - Personal Data Assistant"); - //Make sure the data hud is working. - messageClient(%client,'MsgSPCurrentObjective1',"",'Location: Unknown.'); - messageClient(%client,'MsgSPCurrentObjective2',"",'Money: $%1.',%client.money); -} - -function NSGame::assignClientTeam(%game, %client, %respawn) -{ - DefaultGame::assignClientTeam(%game, %client, %respawn); - // if player's team is not on top of objective hud, switch lines - messageClient(%client, 'MsgCheckTeamLines', "", %client.team); -} - -function NSGame::applyConcussion(%game, %player) -{ -} - -function NSGame::vehicleDestroyed(%game, %vehicle, %destroyer) -{ -} - -function NSGame::onClientKilled(%game, %clVictim, %clKiller, %damageType, %implement, %damageLocation) -{ - defaultGame::onClientKilled(%game, %clVictim, %clKiller, %damageType, %implement, %damageLocation); - commandToClient(%clVictim,'HandleScriptedCommand',2); - //commandToClient(%clVictim,'alxPlayMusic',"T2BOL/Music/TribesHymn.mp3"); //Add a little music that becomes audible if the player idles in death for a bit.. - //No, play this epic audio: - schedule(2000,0,"messageClient",%clVictim,'MsgDeath',"~wfx/Lose.wav"); - forceScoreScreenOpen(%clVictim,"DEATH"); - $Data::ShouldApply[%clVictim.GUID] = false; - - if (%clVictim.isAIControlled()) - %clVictim.drop(); -} - -//...very very messy PDA code below!! - -function NSGame::updateScoreHud(%game, %client, %tag) //This is just here for when the PDA is first opened. -{ - if (%client.PDAPage $= "") - { - messageClient( %client, 'ClearHud', "", 'scoreScreen', 0 ); - - messageClient( %client, 'SetScoreHudHeader', "", 'Main Page'); - messageClient( %client, 'SetScoreHudSubheader', "", "Please select a command."); - - %index = 0; - messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Command List:"); - %index++; - messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "-Self Statistics"); - %index++; - messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "-Electronic Mail"); - %index++; - messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "-View Inventory"); - %index++; - messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "-Clan Management"); - %index++; - messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "-Save Game"); - - %client.PDAPage = "MAIN"; - } -} -function NSGame::createPlayer(%game, %client, %spawnLoc, %respawn) -{ -DefaultGame::createPlayer(%game, %client, %spawnLoc, %respawn); -commandToClient(%client,'HandleScriptedCommand',9,formatTimeString("HHnn") SPC "Hrs."); -} - -function NSGame::processGameLink(%game, %client, %arg1, %arg2, %arg3, %arg4, %arg5) -{ -messageClient( %client, 'ClearHud', "", 'scoreScreen', 0 ); - -//Special handles here.. -if (getSubStr(%arg1,0,5) $= "EMAIL" && getSubStr(%arg1,5,1) !$= "" && isNumber(getSubStr(%arg1,5,1))) -{ -%id = getSubStr(%arg1,5,strLen(%arg1)); -%client.email = %id; -messageClient( %client, 'SetScoreHudHeader', "", 'Electronic MailClose'); -messageClient( %client, 'SetScoreHudSubheader', "", "Delete E-Mail "@$Data::EMail::Date[%client.GUID,%i]@"Reply"); -%index = 0; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'From %1:',$Data::EMail::Sender[%client.GUID,%i]); -%index++; -%count = getSubStrOccurance($Data::EMail::Content[%client.GUID,%id],"\t"); -echo(%count); - -if (%count != 0) -for (%i = 0; %i < %count; %i++) -{ -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, '%1',getField($Data::EMail::Contents[%client.GUID,%id],%i)); -%index++; -} -else -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, '%1',$Data::EMail::Contents[%client.GUID,%id]); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Back To Listing"); -return; -} -else if (getSubStr(%arg1,0,7) $= "EMAILID" && isNumber(getSubStr(%arg1,7,strLen(%arg1)))) -{ -%id = getSubStr(%arg1,7,strLen(%arg1)); -%guid = $Data::Client[%id]; -%count = $Data::EMail::Count[%guid]; -%name = $Data::ClientName[%id]; -%clid = plNameToCid(%name); -if (checkEmails(%guid,%client.emailTitle)) -return; -messageClient( %client, 'SetScoreHudHeader', "", 'Electronic MailClose'); -messageClient( %client, 'SetScoreHudSubheader', "", 'E-Mail sent to %1.',%name); -messageClient( %client, 'SetLineHud', "", 'scoreScreen', 1, 'Back to Listing'); -$Data::EMail::Title[%guid,%count] = %client.emailTitle; -$Data::EMail::Sender[%guid,%count] = %client.namebase; -$Data::EMail::Contents[%guid,%count] = %client.emailCont; -$Data::EMail::Date[%guid,%count] = formatTimeString("DD, MM dd, yy @ hh:nn A"); -$Data::EMail::Count[%guid]++; -if (IsObject(%clid)) -messageClient(%clid,'msgClient','\c3Received an E-Mail from %1. ~wfx/misc/warning_beep.wav',%client.namebase); -return; -} - -switch$ (%arg1) -{ -case "CLOSE": -closeScoreScreen(%client); -case "BACK": //Resets you to the main menu -messageClient( %client, 'SetScoreHudHeader', "", 'Main PageClose'); -messageClient( %client, 'SetScoreHudSubheader', "", "Please select a command."); - - %index = 0; - messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Command List:"); - %index++; - messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "-Self Statistics"); - %index++; - messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "-Electronic Mail"); - %index++; - messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "-View Inventory"); - %index++; - messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "-Clan Management"); - %index++; - messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "-Save Game"); - -%client.PDAPage = "MAIN"; - -case "CLNSTP": -messageClient( %client, 'SetScoreHudHeader', "", 'Clan ManagementClose'); -messageClient( %client, 'SetScoreHudSubheader', "", "Showing clan setup."); -%index = 0; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Clan Name: %1 [Change]',%client.clanN); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Clan Tag: %1 [Change]',%client.clanT); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Short Description: %1 [Change]',%client.description); -%index++; - -if (%client.clanN !$= "" && %client.clanT !$= "") -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Done'); -%index++; - -%client.PDAPage = "CLNSTP"; - -case "EMAIL": -messageClient( %client, 'SetScoreHudHeader', "", 'Electronic MailClose'); -messageClient( %client, 'SetScoreHudSubheader', "", "Showing E-Mails in sequential order."); - -%index = 0; -%count = $Data::EMail::Count[%client.GUID]; -for (%i = 0; %i <= %count; %i++) -{ - if ($Data::EMail::Title[%client.GUID,%i] !$= "") - { - messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, '%2 - %3',%i,$Data::EMail::Sender[%client.GUID,%i],$Data::EMail::Title[%client.GUID,%i]); - %index++; - } -} - -if (%index == 0) -{ -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "There are no E-Mails to show."); -%index++; -} - -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "[Compose an E-Mail]"); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Back To Main Menu"); -%index++; - -case "EMAILSEND": -messageClient( %client, 'SetScoreHudHeader', "", 'Electronic MailClose'); -messageClient( %client, 'SetScoreHudSubheader', "", "New E-Mail"); - -%index = 0; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Title: %1 [Change]',%client.emailTitle); -%index++; - -%count = getSubStrOccurance(%client.emailCont,"\t"); - -if (%count != 0) -for (%i = 0; %i < %count; %i++) -{ -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Contents: %1 [Change]',%client.emailCont); -} -else -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Contents: %1 [Change]',%client.emailCont); -%index++; -if (%client.emailTitle !$= "" && %client.emailcont !$= "") -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Select Receptiant'); - -case "RECPT": -messageClient( %client, 'SetScoreHudHeader', "", 'Electronic MailClose'); -messageClient( %client, 'SetScoreHudSubheader', "", "Select Receptiant"); - -%count = $Data::ClientCount; -%index = 0; -for (%i = 0; %i < %count; %i++) -{ - messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, '%2',%i,$Data::ClientName[%i]); - %index++; -} - -case "CLNFN": -if ($Data::IsInClan[%client.GUID]) -{ -%ID = $Data::ClanID[%client.GUID]; - if ($Data::ClanLeaderGUID[%ID] == %client.GUID) - { - $Data::ClanName[%ID] = %client.clanN; - $Data::ClanTag[%ID] = %client.clanT; - $Data::ClanDesc[%ID] = %client.description; - forceScoreScreenOpen(%client,"CLNMG"); - } -} -else -{ -$Data::IsInCLan[%client.GUID] = true; - -if ($Data::ClanCount $= "") -$Data::ClanCount = 0; - -$Data::ClanName[$Data::ClanCount] = %client.clanN; -$Data::ClanTag[$Data::ClanCount] = %client.clanT; -$Data::ClanDesc[$Data::ClanCount] = %client.desc; -$Data::ClanLeader[$Data::ClanCount] = %client.namebase; -$Data::ClanLeaderGUID[$Data::ClanCount] = %client.GUID; -$Data::ClanMember[$Data::ClanCount, 0] = %client.GUID; -$Data::ClanID[%client.GUID] = $Data::ClanCount; -$Data::ClanCount++; -setName(%client,"\cp\c7" @ %client.clanT @ "\c6" @ %client.namebase @ "\co"); -saveGame(); -forceScoreScreenOpen(%client,"CLNMG"); -} - -%client.PDAPage = "MAIN"; - -case "CLNMG": -messageClient( %client, 'SetScoreHudHeader', "", 'Clan ManagementClose'); -messageClient( %client, 'SetScoreHudSubheader', "", "Showing clan management."); -%index = 0; - -if (!$Data::IsInClan[%client.GUID]) -{ -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'You are not in a clan. Try creating a [New Clan].'); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Or view the [List] of clans.'); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Back To Main Menu"); -} -else -{ -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Clan Name: %1',$Data::ClanName[$Data::ClanID[%client.GUID]]); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Clan Tag: %1', $Data::ClanTag[$Data::ClanID[%client.GUID]]); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Short Description: %1',%client.description); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, ''); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, '[View] member list.'); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, '[View] other clans.'); -if ($Data::IsInClan[%client.GUID] && $Data::ClanLeaderGUID[$Data::ClanID[%client.GUID]] == %client.GUID) -{ -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, '[Edit] Clan.'); -} -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Back To Main Menu"); -} - -%client.PDAPage = "CLNMG"; - -case "CLNMBR": -%client.PDAPage = "CLNMBR"; - -messageClient( %client, 'SetScoreHudHeader', "", 'Clan ManagementClose'); -messageClient( %client, 'SetScoreHudSubheader', "", "Showing member list."); -%index = 0; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Name: %1',%client.namebase); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Back To Previous Page'); -%index++; - - -case "SLFSTS": //Self Statistics -messageClient( %client, 'SetScoreHudHeader', "", 'Self StatisticsClose'); -messageClient( %client, 'SetScoreHudSubheader', "", "Showing your stats."); -%index = 0; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Name: %1',%client.namebase); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Race: %1',%client.race); -%index++; - -if (%client.money $= "") -%client.money = 0; //You got zilch. - -%trans = %client.player.getTransform(); -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Cash: $%1',%client.money); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'GPS Coordinates: %1 %2 %3',getWord(%trans,0),getWord(%trans,1),getWord(%trans,2)); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, ''); -%index++; - -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Refresh'); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Back To Main Menu"); -%client.PDAPage = "SLFSTS"; - -case "INVENTORY": //View Inventory -messageClient( %client, 'SetScoreHudHeader', "", 'Show InventoryClose'); -messageClient( %client, 'SetScoreHudSubheader', "", "Showing your inventory."); -%index = 0; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Minerals--'); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Steel: %1 units.', %client.units["Steel"]); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Back To Main Menu"); -%client.PDAPage = "INVENTORY"; - -case "DEATH": -if (isObject(%client.player) && %client.player.getState() $= "Move") -return; - -messageClient( %client, 'SetScoreHudHeader', "", 'Death'); -messageClient( %client, 'SetScoreHudSubheader', "", "You have died."); - -messageClient( %client, 'SetLineHud', "", 'scoreScreen', 0, "Respawn"); -%client.PDAPage = "DEATH"; - -case "DELETE": -messageClient( %client, 'SetScoreHudHeader', "", 'Electronic MailClose'); -messageClient( %client, 'SetScoreHudSubheader', "", "E-Mail deleted."); -messageClient( %client, 'SetLineHud', "", 'scoreScreen', 0, 'Back to Listing'); -$Data::EMail::Title[%client.GUID,%client.email] = ""; - -case "SAVE": -saveGame(); -closeScoreScreen(%client); -messageClient(%client,'msgSaveSuccess',"\c3Game successfully saved."); - -case "RESPAWN": -if (isObject(%client.player) && %client.player.getState() $= "Move") -return; - -%client.PDAPage = "MAIN"; -forceClientSpawn(%client); - -case "SLFSTS": //Self Statistics -messageClient( %client, 'SetScoreHudHeader', "", 'Self StatisticsClose'); -messageClient( %client, 'SetScoreHudSubheader', "", "Showing your stats."); -%index = 0; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Name: %1',%client.namebase); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Race: %1',%client.race); -%index++; - -if (%client.race $= "Draakan") -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Type: %1',%client.sex); -else -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Sex: %1',%client.sex); -%index++; - -if (%client.money $= "") -%client.money = 0; //You got zilch. - -%trans = %client.player.getTransform(); -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Cash: $%1',%client.money); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'GPS Coordinates: %1 %2 %3',getWord(%trans,0),getWord(%trans,1),getWord(%trans,2)); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, ''); -%index++; - -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Refresh'); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Back To Main Menu"); -%client.PDAPage = "SLFSTS"; - -default: //If something fails, return to the main menu. -serverCmdProcessGameLink(%client,"BACK"); -} -} - -function serverCmdShowHud(%client, %tag) -{ - %tagName = getWord(%tag, 1); - %tag = getWord(%tag, 0); - - if (%tag $= 'scoreScreen') - serverCmdProcessGameLink(%client,%client.PDAPage); - - messageClient(%client, 'OpenHud', "", %tag); - switch$ (%tagname) - { - case "vehicleHud": - vehicleHud::updateHud(1,%client,%tag); - case "scoreScreen": - updateScoreHudThread(%client, %tag); - } -} - +// DisplayName = Natural Selection + +//--- GAME RULES BEGIN --- +// Destroy the other team. +//--- GAME RULES END --- + +//exec the AI scripts +exec("scripts/aiNS.cs"); + +$RequiresClient[NS] = false; +$InvBanList[NS, "C4Charge"] = 1; + +//-- tracking --- +function NSGame::initGameVars(%game) +{ + //%game. = ""; //I guess I'll eventually set some, but most are loaded via BASIC files +} + +package NSGame +{ +function blah(){} //Eh.. +}; + +function NSGame::setUpTeams(%game) +{ + defaultGame::setUpTeams(%game); + %game.numTeams = 1; + setSensorGroupCount(4); + $TeamDamage = true; //Allow team Damage +} + +function NSGame::getTeamSkin(%game, %team) +{ + if($host::tournamentMode) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + { + return $teamSkin[%team]; + } + + else + { + //error("CTFGame::getTeamSkin"); + if(!$host::useCustomSkins) + { + %terrain = MissionGroup.musicTrack; + //error("Terrain type is: " SPC %terrain); + switch$(%terrain) + { + case "lush": + if(%team == 1) + %skin = 'beagle'; + else if(%team == 2) + %skin = 'dsword'; + else %skin = 'base'; + + case "badlands": + if(%team == 1) + %skin = 'swolf'; + else if(%team == 2) + %skin = 'dsword'; + else %skin = 'base'; + + case "ice": + if(%team == 1) + %skin = 'swolf'; + else if(%team == 2) + %skin = 'beagle'; + else %skin = 'base'; + + case "desert": + if(%team == 1) + %skin = 'cotp'; + else if(%team == 2) + %skin = 'beagle'; + else %skin = 'base'; + + case "Volcanic": + if(%team == 1) + %skin = 'dsword'; + else if(%team == 2) + %skin = 'cotp'; + else %skin = 'base'; + + default: + if(%team == 2) + %skin = 'baseb'; + else %skin = 'base'; + } + } + else %skin = $teamSkin[%team]; + + //error("%skin = " SPC getTaggedString(%skin)); + return %skin; +} +} + +function NSGame::getTeamName(%game, %team) +{ + // --------------------------------------------------- + // z0dd - ZOD 3/30/02. Only display default team names + //if ( isDemo() || $host::tournamentMode) + return $TeamName[%team]; + // --------------------------------------------------- +} + +//-------------------------------------------------------------------------- +function NSGame::missionLoadDone(%game) +{ + //default version sets up teams - must be called first... + DefaultGame::missionLoadDone(%game); +} + +function NSGame::showStalemateTargets(%game) +{ + cancel(%game.stalemateSchedule); + + //show the targets + for (%i = 1; %i <= 2; %i++) + { + %flag = $TeamFlag[%i]; + + //find the object to scope/waypoint.... + //render the target hud icon for slot 1 (a centermass flag) + //if we just set him as always sensor vis, it'll work fine. + if (isObject(%flag.carrier)) + setTargetAlwaysVisMask(%flag.carrier.getTarget(), 0x7); + } + //schedule the targets to hide + %game.stalemateObjsVisible = true; + %game.stalemateSchedule = %game.schedule(%game.stalemateDurationMS, hideStalemateTargets); +} + +function NSGame::timeLimitReached(%game) +{ + logEcho("game over (timelimit)"); + %game.gameOver(); + cycleMissions(); +} + +function NSGame::scoreLimitReached(%game) +{ + logEcho("game over (scorelimit)"); + %game.gameOver(); + cycleMissions(); +} + +function NSGame::gameOver(%game) +{ + //call the default + DefaultGame::gameOver(%game); + messageAll('MsgClearObjHud', ""); +} + +function NSGame::onClientDamaged(%game, %clVictim, %clAttacker, %damageType, %implement, %damageLoc) +{ + if(%clVictim.headshot && %damageType == $DamageType::Laser && %clVictim.team != %clAttacker.team) + { + %clAttacker.scoreHeadshot++; + if (%game.SCORE_PER_HEADSHOT != 0) + { + messageClient(%clAttacker, 'msgHeadshot', '\c0You received a %1 point bonus for a successful headshot.', %game.SCORE_PER_HEADSHOT); + messageTeamExcept(%clAttacker, 'msgHeadshot', '\c5%1 hit a sniper rifle headshot.', %clAttacker.name); // z0dd - ZOD, 8/15/02. Tell team + } + %game.recalcScore(%clAttacker); + } + + // ----------------------------------------------- + // z0dd - ZOD, 8/25/02. Rear Lance hits + if(%clVictim.rearshot && %damageType == $DamageType::ShockLance && %clVictim.team != %clAttacker.team) + { + %clAttacker.scoreRearshot++; + if (%game.SCORE_PER_REARSHOT != 0) + { + messageClient(%clAttacker, 'msgRearshot', '\c0You received a %1 point bonus for a successful rearshot.', %game.SCORE_PER_REARSHOT); + messageTeamExcept(%clAttacker, 'msgRearshot', '\c5%1 hit a shocklance rearshot.', %clAttacker.name); + } + %game.recalcScore(%clAttacker); + } + // ----------------------------------------------- + + //the DefaultGame will set some vars + DefaultGame::onClientDamaged(%game, %clVictim, %clAttacker, %damageType, %implement, %damageLoc); + + //if victim is carrying a flag and is not on the attackers team, mark the attacker as a threat for x seconds(for scoring purposes) + if ((%clVictim.holdingFlag !$= "") && (%clVictim.team != %clAttacker.team)) + { + %clAttacker.dmgdFlagCarrier = true; + cancel(%clAttacker.threatTimer); //restart timer + %clAttacker.threatTimer = schedule(%game.TIME_CONSIDERED_FLAGCARRIER_THREAT, %clAttacker.dmgdFlagCarrier = false); + } +} + +//////////////////////////////////////////////////////////////////////////////////////// +function NSGame::clientMissionDropReady(%game, %client) +{ + messageClient(%client, 'MsgClientReady',"", "SinglePlayerGame"); //Force the SP game objective hud to setup + %game.resetScore(%client); + + messageClient(%client, 'MsgMissionDropInfo', '\c0You are in mission %1 (%2).', $MissionDisplayName, $MissionTypeDisplayName, $ServerName ); + + DefaultGame::clientMissionDropReady(%game, %client); + + //Force client Spawn since we're ready now + schedule(1000,0,"forceClientSpawn",%client,true); + + %client.setControlObject(%client.player); + commandToClient(%client,'bottomPrint',"Try not to die.",3); + + //Since this is an RPG gamemode, be sure some things are correct. (May have been a mission switch from CTF or some other gamemode) + commandToClient(%client,'SetScoreText',"PDA - Personal Data Assistant"); + //Make sure the data hud is working. + messageClient(%client,'MsgSPCurrentObjective1',"",'Location: Unknown.'); + messageClient(%client,'MsgSPCurrentObjective2',"",'Money: $%1.',%client.money); +} + +function NSGame::assignClientTeam(%game, %client, %respawn) +{ + DefaultGame::assignClientTeam(%game, %client, %respawn); + // if player's team is not on top of objective hud, switch lines + messageClient(%client, 'MsgCheckTeamLines', "", %client.team); +} + +function NSGame::applyConcussion(%game, %player) +{ +} + +function NSGame::vehicleDestroyed(%game, %vehicle, %destroyer) +{ +} + +function NSGame::onClientKilled(%game, %clVictim, %clKiller, %damageType, %implement, %damageLocation) +{ + defaultGame::onClientKilled(%game, %clVictim, %clKiller, %damageType, %implement, %damageLocation); + commandToClient(%clVictim,'HandleScriptedCommand',2); + //commandToClient(%clVictim,'alxPlayMusic',"T2BOL/Music/TribesHymn.mp3"); //Add a little music that becomes audible if the player idles in death for a bit.. + //No, play this epic audio: + schedule(2000,0,"messageClient",%clVictim,'MsgDeath',"~wfx/Lose.wav"); + forceScoreScreenOpen(%clVictim,"DEATH"); + $Data::ShouldApply[%clVictim.GUID] = false; + + if (%clVictim.isAIControlled()) + %clVictim.drop(); +} + +//...very very messy PDA code below!! + +function NSGame::updateScoreHud(%game, %client, %tag) //This is just here for when the PDA is first opened. +{ + if (%client.PDAPage $= "") + { + messageClient( %client, 'ClearHud', "", 'scoreScreen', 0 ); + + messageClient( %client, 'SetScoreHudHeader', "", 'Main Page'); + messageClient( %client, 'SetScoreHudSubheader', "", "Please select a command."); + + %index = 0; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Command List:"); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "-Self Statistics"); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "-Electronic Mail"); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "-View Inventory"); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "-Clan Management"); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "-Save Game"); + + %client.PDAPage = "MAIN"; + } +} +function NSGame::createPlayer(%game, %client, %spawnLoc, %respawn) +{ +DefaultGame::createPlayer(%game, %client, %spawnLoc, %respawn); +commandToClient(%client,'HandleScriptedCommand',9,formatTimeString("HHnn") SPC "Hrs."); +} + +function NSGame::processGameLink(%game, %client, %arg1, %arg2, %arg3, %arg4, %arg5) +{ +messageClient( %client, 'ClearHud', "", 'scoreScreen', 0 ); + +//Special handles here.. +if (getSubStr(%arg1,0,5) $= "EMAIL" && getSubStr(%arg1,5,1) !$= "" && isNumber(getSubStr(%arg1,5,1))) +{ +%id = getSubStr(%arg1,5,strLen(%arg1)); +%client.email = %id; +messageClient( %client, 'SetScoreHudHeader', "", 'Electronic MailClose'); +messageClient( %client, 'SetScoreHudSubheader', "", "Delete E-Mail "@$Data::EMail::Date[%client.GUID,%i]@"Reply"); +%index = 0; +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'From %1:',$Data::EMail::Sender[%client.GUID,%i]); +%index++; +%count = getSubStrOccurance($Data::EMail::Content[%client.GUID,%id],"\t"); +echo(%count); + +if (%count != 0) +for (%i = 0; %i < %count; %i++) +{ +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, '%1',getField($Data::EMail::Contents[%client.GUID,%id],%i)); +%index++; +} +else +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, '%1',$Data::EMail::Contents[%client.GUID,%id]); +%index++; +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Back To Listing"); +return; +} +else if (getSubStr(%arg1,0,7) $= "EMAILID" && isNumber(getSubStr(%arg1,7,strLen(%arg1)))) +{ +%id = getSubStr(%arg1,7,strLen(%arg1)); +%guid = $Data::Client[%id]; +%count = $Data::EMail::Count[%guid]; +%name = $Data::ClientName[%id]; +%clid = plNameToCid(%name); +if (checkEmails(%guid,%client.emailTitle)) +return; +messageClient( %client, 'SetScoreHudHeader', "", 'Electronic MailClose'); +messageClient( %client, 'SetScoreHudSubheader', "", 'E-Mail sent to %1.',%name); +messageClient( %client, 'SetLineHud', "", 'scoreScreen', 1, 'Back to Listing'); +$Data::EMail::Title[%guid,%count] = %client.emailTitle; +$Data::EMail::Sender[%guid,%count] = %client.namebase; +$Data::EMail::Contents[%guid,%count] = %client.emailCont; +$Data::EMail::Date[%guid,%count] = formatTimeString("DD, MM dd, yy @ hh:nn A"); +$Data::EMail::Count[%guid]++; +if (IsObject(%clid)) +messageClient(%clid,'msgClient','\c3Received an E-Mail from %1. ~wfx/misc/warning_beep.wav',%client.namebase); +return; +} + +switch$ (%arg1) +{ +case "CLOSE": +closeScoreScreen(%client); +case "BACK": //Resets you to the main menu +messageClient( %client, 'SetScoreHudHeader', "", 'Main PageClose'); +messageClient( %client, 'SetScoreHudSubheader', "", "Please select a command."); + + %index = 0; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Command List:"); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "-Self Statistics"); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "-Electronic Mail"); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "-View Inventory"); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "-Clan Management"); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "-Save Game"); + +%client.PDAPage = "MAIN"; + +case "CLNSTP": +messageClient( %client, 'SetScoreHudHeader', "", 'Clan ManagementClose'); +messageClient( %client, 'SetScoreHudSubheader', "", "Showing clan setup."); +%index = 0; +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Clan Name: %1 [Change]',%client.clanN); +%index++; +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Clan Tag: %1 [Change]',%client.clanT); +%index++; +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Short Description: %1 [Change]',%client.description); +%index++; + +if (%client.clanN !$= "" && %client.clanT !$= "") +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Done'); +%index++; + +%client.PDAPage = "CLNSTP"; + +case "EMAIL": +messageClient( %client, 'SetScoreHudHeader', "", 'Electronic MailClose'); +messageClient( %client, 'SetScoreHudSubheader', "", "Showing E-Mails in sequential order."); + +%index = 0; +%count = $Data::EMail::Count[%client.GUID]; +for (%i = 0; %i <= %count; %i++) +{ + if ($Data::EMail::Title[%client.GUID,%i] !$= "") + { + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, '%2 - %3',%i,$Data::EMail::Sender[%client.GUID,%i],$Data::EMail::Title[%client.GUID,%i]); + %index++; + } +} + +if (%index == 0) +{ +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "There are no E-Mails to show."); +%index++; +} + +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "[Compose an E-Mail]"); +%index++; +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Back To Main Menu"); +%index++; + +case "EMAILSEND": +messageClient( %client, 'SetScoreHudHeader', "", 'Electronic MailClose'); +messageClient( %client, 'SetScoreHudSubheader', "", "New E-Mail"); + +%index = 0; +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Title: %1 [Change]',%client.emailTitle); +%index++; + +%count = getSubStrOccurance(%client.emailCont,"\t"); + +if (%count != 0) +for (%i = 0; %i < %count; %i++) +{ +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Contents: %1 [Change]',%client.emailCont); +} +else +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Contents: %1 [Change]',%client.emailCont); +%index++; +if (%client.emailTitle !$= "" && %client.emailcont !$= "") +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Select Receptiant'); + +case "RECPT": +messageClient( %client, 'SetScoreHudHeader', "", 'Electronic MailClose'); +messageClient( %client, 'SetScoreHudSubheader', "", "Select Receptiant"); + +%count = $Data::ClientCount; +%index = 0; +for (%i = 0; %i < %count; %i++) +{ + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, '%2',%i,$Data::ClientName[%i]); + %index++; +} + +case "CLNFN": +if ($Data::IsInClan[%client.GUID]) +{ +%ID = $Data::ClanID[%client.GUID]; + if ($Data::ClanLeaderGUID[%ID] == %client.GUID) + { + $Data::ClanName[%ID] = %client.clanN; + $Data::ClanTag[%ID] = %client.clanT; + $Data::ClanDesc[%ID] = %client.description; + forceScoreScreenOpen(%client,"CLNMG"); + } +} +else +{ +$Data::IsInCLan[%client.GUID] = true; + +if ($Data::ClanCount $= "") +$Data::ClanCount = 0; + +$Data::ClanName[$Data::ClanCount] = %client.clanN; +$Data::ClanTag[$Data::ClanCount] = %client.clanT; +$Data::ClanDesc[$Data::ClanCount] = %client.desc; +$Data::ClanLeader[$Data::ClanCount] = %client.namebase; +$Data::ClanLeaderGUID[$Data::ClanCount] = %client.GUID; +$Data::ClanMember[$Data::ClanCount, 0] = %client.GUID; +$Data::ClanID[%client.GUID] = $Data::ClanCount; +$Data::ClanCount++; +setName(%client,"\cp\c7" @ %client.clanT @ "\c6" @ %client.namebase @ "\co"); +saveGame(); +forceScoreScreenOpen(%client,"CLNMG"); +} + +%client.PDAPage = "MAIN"; + +case "CLNMG": +messageClient( %client, 'SetScoreHudHeader', "", 'Clan ManagementClose'); +messageClient( %client, 'SetScoreHudSubheader', "", "Showing clan management."); +%index = 0; + +if (!$Data::IsInClan[%client.GUID]) +{ +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'You are not in a clan. Try creating a [New Clan].'); +%index++; +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Or view the [List] of clans.'); +%index++; +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Back To Main Menu"); +} +else +{ +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Clan Name: %1',$Data::ClanName[$Data::ClanID[%client.GUID]]); +%index++; +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Clan Tag: %1', $Data::ClanTag[$Data::ClanID[%client.GUID]]); +%index++; +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Short Description: %1',%client.description); +%index++; +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, ''); +%index++; +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, '[View] member list.'); +%index++; +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, '[View] other clans.'); +if ($Data::IsInClan[%client.GUID] && $Data::ClanLeaderGUID[$Data::ClanID[%client.GUID]] == %client.GUID) +{ +%index++; +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, '[Edit] Clan.'); +} +%index++; +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Back To Main Menu"); +} + +%client.PDAPage = "CLNMG"; + +case "CLNMBR": +%client.PDAPage = "CLNMBR"; + +messageClient( %client, 'SetScoreHudHeader', "", 'Clan ManagementClose'); +messageClient( %client, 'SetScoreHudSubheader', "", "Showing member list."); +%index = 0; +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Name: %1',%client.namebase); +%index++; +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Back To Previous Page'); +%index++; + + +case "SLFSTS": //Self Statistics +messageClient( %client, 'SetScoreHudHeader', "", 'Self StatisticsClose'); +messageClient( %client, 'SetScoreHudSubheader', "", "Showing your stats."); +%index = 0; +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Name: %1',%client.namebase); +%index++; +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Race: %1',%client.race); +%index++; + +if (%client.money $= "") +%client.money = 0; //You got zilch. + +%trans = %client.player.getTransform(); +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Cash: $%1',%client.money); +%index++; +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'GPS Coordinates: %1 %2 %3',getWord(%trans,0),getWord(%trans,1),getWord(%trans,2)); +%index++; +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, ''); +%index++; + +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Refresh'); +%index++; +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Back To Main Menu"); +%client.PDAPage = "SLFSTS"; + +case "INVENTORY": //View Inventory +messageClient( %client, 'SetScoreHudHeader', "", 'Show InventoryClose'); +messageClient( %client, 'SetScoreHudSubheader', "", "Showing your inventory."); +%index = 0; +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Minerals--'); +%index++; +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Steel: %1 units.', %client.units["Steel"]); +%index++; +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Back To Main Menu"); +%client.PDAPage = "INVENTORY"; + +case "DEATH": +if (isObject(%client.player) && %client.player.getState() $= "Move") +return; + +messageClient( %client, 'SetScoreHudHeader', "", 'Death'); +messageClient( %client, 'SetScoreHudSubheader', "", "You have died."); + +messageClient( %client, 'SetLineHud', "", 'scoreScreen', 0, "Respawn"); +%client.PDAPage = "DEATH"; + +case "DELETE": +messageClient( %client, 'SetScoreHudHeader', "", 'Electronic MailClose'); +messageClient( %client, 'SetScoreHudSubheader', "", "E-Mail deleted."); +messageClient( %client, 'SetLineHud', "", 'scoreScreen', 0, 'Back to Listing'); +$Data::EMail::Title[%client.GUID,%client.email] = ""; + +case "SAVE": +saveGame(); +closeScoreScreen(%client); +messageClient(%client,'msgSaveSuccess',"\c3Game successfully saved."); + +case "RESPAWN": +if (isObject(%client.player) && %client.player.getState() $= "Move") +return; + +%client.PDAPage = "MAIN"; +forceClientSpawn(%client); + +case "SLFSTS": //Self Statistics +messageClient( %client, 'SetScoreHudHeader', "", 'Self StatisticsClose'); +messageClient( %client, 'SetScoreHudSubheader', "", "Showing your stats."); +%index = 0; +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Name: %1',%client.namebase); +%index++; +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Race: %1',%client.race); +%index++; + +if (%client.race $= "Draakan") +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Type: %1',%client.sex); +else +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Sex: %1',%client.sex); +%index++; + +if (%client.money $= "") +%client.money = 0; //You got zilch. + +%trans = %client.player.getTransform(); +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Cash: $%1',%client.money); +%index++; +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'GPS Coordinates: %1 %2 %3',getWord(%trans,0),getWord(%trans,1),getWord(%trans,2)); +%index++; +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, ''); +%index++; + +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Refresh'); +%index++; +messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Back To Main Menu"); +%client.PDAPage = "SLFSTS"; + +default: //If something fails, return to the main menu. +serverCmdProcessGameLink(%client,"BACK"); +} +} + +function serverCmdShowHud(%client, %tag) +{ + %tagName = getWord(%tag, 1); + %tag = getWord(%tag, 0); + + if (%tag $= 'scoreScreen') + serverCmdProcessGameLink(%client,%client.PDAPage); + + messageClient(%client, 'OpenHud', "", %tag); + switch$ (%tagname) + { + case "vehicleHud": + vehicleHud::updateHud(1,%client,%tag); + case "scoreScreen": + updateScoreHudThread(%client, %tag); + } +} + diff --git a/scripts/OptionsDlg.cs b/scripts/OptionsDlg.cs index 9b091c5..b9d6201 100644 --- a/scripts/OptionsDlg.cs +++ b/scripts/OptionsDlg.cs @@ -1,2678 +1,2684 @@ -//------------------------------------------------------------------------------ -// -// OptionsDlg.cs -// -//------------------------------------------------------------------------------ -$max_screenerror = 25; -$min_TSScreenError = 2; -$max_TSScreenError = 20; -$min_TSDetailAdjust = 0.6; -$max_TSDetailAdjust = 1.0; -//------------------------------------------------------------------------------ -function OptionsDlg::onWake( %this ) -{ - OP_VideoPane.setVisible( false ); - OP_GraphicsPane.setVisible( false ); - OP_TexturesPane.setVisible( false ); - OP_SoundPane.setVisible( false ); - OP_VoicePane.setVisible( false ); - OP_ControlsPane.setVisible( false ); - OP_NetworkPane.setVisible( false ); - OP_GamePane.setVisible( false ); - - OP_VideoTab.setValue( false ); - OP_GraphicsTab.setValue( false ); - OP_TexturesTab.setValue( false ); - OP_SoundTab.setValue( false ); - OP_VoiceTab.setValue( false ); - OP_ControlsTab.setValue( false ); - OP_NetworkTab.setValue( false ); - OP_GameTab.setValue( false ); - - // Initialize the Video Pane controls: - // First the Video Driver menu: - %buffer = getDisplayDeviceList(); - %count = getFieldCount( %buffer ); - for ( %i = 0; %i < %count; %i++ ) - OP_VideoDriverMenu.add( getField( %buffer, %i ), %i ); - - // Select the current device: - OP_FullScreenTgl.setValue( $pref::Video::fullScreen ); - - %selId = OP_VideoDriverMenu.findText( $pref::Video::displayDevice ); - if ( %selId == -1 ) - %selId = 0; // How did THAT happen? - OP_VideoDriverMenu.setSelected( %selId ); - OP_VideoDriverMenu.onSelect( %selId, "" ); - OP_FullScreenTgl.onAction(); - - OP_ApplyBtn.setActive( false ); - - // Initialize the Graphics Options controls: - OptionsDlg::deviceDependent( %this ); - - // Radeon cards don't switch color depth good until they release their beta drivers which fix this problem. - if( $RadeonRenderer == true ) - OP_BPPMenu.setActive( false ); - - OP_GammaSlider.setValue( $pref::OpenGL::gammaCorrection ); - OP_GammaSlider.setActive( $Video::setGammaCorrectionSupported ); - - OP_TerrainSlider.setValue( $max_screenerror - $pref::Terrain::screenError ); - OP_ShapeSlider.setValue( ( $max_TSScreenError - $pref::TS::screenError ) / ( $max_TSScreenError - $min_TSScreenError ) ); - OP_ShadowSlider.setValue( $pref::Shadows ); - OP_InteriorDetailSlider.setValue( $pref::Interior::detailAdjust ); - OP_VisibleDistanceSlider.setValue( $pref::VisibleDistanceMod ); - OP_ParticleDensitySlider.setValue( 4.0 - $pref::ParticleDensity ); - OP_DynamicLightSlider.setValue( 100 - $pref::Interior::DynamicLightsClipPix ); - updateDynamicLightSliderState(); - OP_SkyDetailMenu.init(); - if ( !$pref::SkyOn ) - %selId = 5; - else if ( $pref::numCloudLayers >= 0 && $pref::numCloudLayers < 4 ) - %selId = 4 - $pref::numCloudLayers; - else - %selId = 1; - OP_SkyDetailMenu.setSelected( %selId ); - OP_SkyDetailMenu.setText( OP_SkyDetailMenu.getTextById( %selId ) ); - OP_PlayerRenderMenu.init(); - %selId = $pref::Player::renderMyPlayer | ( $pref::Player::renderMyItems << 1 ); - OP_PlayerRenderMenu.setSelected( %selId ); - OP_VertexLightTgl.setValue( $pref::Interior::VertexLighting ); - - // Initialize the Textures Options controls: - OP_TerrainTexSlider.setValue( 6 - $pref::Terrain::texDetail ); - - // We're using the noDrawArraysAlpha variable here because we've already - // gone gold (hard to add a new profiling variable). But the Voodoo2/3/3500 - // cards that have the 256x256 texture limitation (in OpenGL) also have the - // noDrawArraysAlpha hack on...so that works out nice - %mipRange = $pref::OpenGL::noDrawArraysAlpha ? 4.0 : 5.0; - OP_ShapeTexSlider.setValue( (5 - $pref::OpenGL::mipReduction) / %mipRange ); - OP_BuildingTexSlider.setValue( (5 - $pref::OpenGL::interiorMipReduction) / %mipRange ); - OP_SkyTexSlider.setValue( (5 - $pref::OpenGL::skyMipReduction) / %mipRange ); - if ( !isDemo() ) - OP_HiResSkinTgl.setValue( $pref::use512PlayerSkins ); - - // Initialize the Sound Options controls: - // provider menu - %count = alxGetContexti(ALC_PROVIDER_COUNT); - for(%i = 0; %i < %count; %i++) - OP_AudioProviderMenu.add(alxGetContextstr(ALC_PROVIDER_NAME, %i), %i); - %selId = alxGetContexti(ALC_PROVIDER); - OP_AudioProviderMenu.setSelected(%selId); - OP_AudioResetProvider.setActive(false); - - // environment provider: disable and uncheck if not an environment provider - %envProvider = audioIsEnvironmentProvider(alxGetContextstr(ALC_PROVIDER_NAME, %selId)); - - if(!%envProvider) - OP_AudioEnvironmentTgl.setValue(false); - OP_AudioEnvironmentTgl.setActive(%envProvider); - - // speaker menu - %count = alxGetContexti(ALC_SPEAKER_COUNT); - for(%i = 0; %i < %count; %i++) - OP_AudioSpeakerMenu.add(alxGetContextstr(ALC_SPEAKER_NAME, %i), %i); - %selId = alxGetContexti(ALC_SPEAKER); - OP_AudioSpeakerMenu.setSelected(%selId); - OP_AudioSpeakerMenu.onSelect(%selId, ""); - - OP_AudioFrequencyMenu.init(); - OP_AudioBitRateMenu.init(); - OP_AudioChannelsMenu.init(); - - // don't allow changing of of mixer settings while in a game... - %active = !isObject(ServerConnection); - OP_AudioFrequencyMenu.setActive(%active); - // Changing these audio settings doesn't help Linux performance - if ( $platform $= "linux" ) - { - OP_AudioBitRateMenu.setActive(false); - OP_AudioChannelsMenu.setActive(false); - } - else - { - OP_AudioBitRateMenu.setActive(%active); - OP_AudioChannelsMenu.setActive(%active); - } - - // only allow for disable - if(!%active) - OP_AudioEnvironmentTgl.setActive(%active); - - OP_AudioProviderMenu.setActive(%active); - OP_AudioSpeakerMenu.setActive(%active); - - OP_MasterVolumeSlider.setValue( $pref::Audio::masterVolume ); - OP_EffectsVolumeSlider.setValue( $pref::Audio::effectsVolume ); - OP_VoiceBindVolumeSlider.setValue( $pref::Audio::radioVolume ); - OP_GuiVolumeSlider.setValue( $pref::Audio::guiVolume ); - OP_MusicTgl.onAction(); - OP_MusicVolumeSlider.setValue( $pref::Audio::musicVolume ); - - // Initialize the Voice Settings controls: - OP_MicrophoneEnabledTgl.onAction(); - OP_MicrophoneVolumeSlider.setValue( $pref::Audio::voiceVolume ); - OP_InputBoostSlider.setValue( $pref::Audio::captureGainScale ); - OP_VoiceListenMenu.init(); - OP_VoiceSendMenu.init(); - OP_VoiceCodecInfo.init(); - updateInputBoost(); - - // Initialize the Control Options controls: - OP_ControlGroupMenu.init(); - - if ( isJoystickDetected() ) - { - OP_JoystickTgl.setValue( $pref::Input::JoystickEnabled ); - OP_JoystickTgl.setActive( true ); - OP_ConfigureJoystickBtn.setActive( $pref::Input::JoystickEnabled ); - } - else - { - OP_JoystickTgl.setValue( false ); - OP_JoystickTgl.setActive( false ); - $pref::Input::JoystickEnabled = false; - OP_ConfigureJoystickBtn.setActive( false ); - } - - // Initialize the Network Options controls: - OP_NetworkDisplayHud.init(); - if( !OP_NetworkPresetsMenu.size() ) - OP_NetworkPresetsMenu.init(); - OP_PacketRateSlider.setValue( $pref::Net::PacketRateToClient ); - OP_PacketSizeSlider.setValue( $pref::Net::PacketSize ); - OP_UpdateRateSlider.setValue( $pref::Net::PacketRateToServer ); - if ( !OP_MasterServerMenu.size() ) - OP_MasterServerMenu.init(); - %selId = OP_MasterServerMenu.findText( $pref::Net::DisplayOnMaster ); - if ( %selId == -1 ) - %selId = 1; - OP_MasterServerMenu.setSelected( %selId ); - if ( !OP_RegionMenu.size() ) - OP_RegionMenu.init(); - OP_RegionMenu.setSelected( $pref::Net::RegionMask ); - - // Initialize the Game Options controls: - OP_ZoomSpeedSlider.setValue( 500 - $pref::Player::zoomSpeed ); - OP_LaunchScreenMenu.init(); - - %selId = OP_LaunchScreenMenu.findText( $pref::Shell::LaunchGui ); - if ( %selId == -1 ) - %selId = 1; - OP_LaunchScreenMenu.setText( OP_LaunchScreenMenu.getTextById( %selId ) ); - OP_LaunchScreenMenu.setSelected( %selId ); - - // Hide controls that are not relevant to the demo: - if ( isDemo() ) - { - OP_MasterServerTxt.setVisible( false ); - OP_MasterServerMenu.setVisible( false ); - OP_CheckEmailTgl.setVisible( false ); - OP_ChatDisconnectTgl.setVisible( false ); - OP_EditChatMenuBtn.setVisible( false ); - OP_LaunchScreenTxt.setVisible( false ); - OP_LaunchScreenMenu.setVisible( false ); - } - - %this.setPane( %this.pane ); -} - -//------------------------------------------------------------------------------ -function OptionsDlg::deviceDependent( %this ) -{ - if ( $SwapIntervalSupported ) - { - OP_VSyncTgl.setValue( $pref::Video::disableVerticalSync ); - OP_VSyncTgl.setActive( true ); - } - else - { - OP_VSyncTgl.setValue( false ); - OP_VSyncTgl.setActive( false ); - } - - if ( isDemo() ) - { - OP_TexQualityMenu.setText( "Palletized" ); - OP_TexQualityMenu.setActive( false ); - } - else - { - OP_TexQualityMenu.init(); - if ( $pref::OpenGL::forcePalettedTexture ) - { - $pref::OpenGL::force16bittexture = false; - %selId = 1; - } - else if ( $pref::OpenGL::force16bittexture ) - %selId = 2; - else - %selId = 3; - OP_TexQualityMenu.setSelected( %selId ); - } - - OP_CompressMenu.init(); - if ( $TextureCompressionSupported && !$pref::OpenGL::disableARBTextureCompression ) - { - OP_CompressLabel.setVisible( true ); - OP_CompressLabel_Disabled.setVisible( false ); - OP_CompressMenu.setActive( true ); - if ( !$pref::OpenGL::allowCompression ) - OP_CompressMenu.setSelected( 1 ); - else if ( $pref::OpenGL::compressionHint $= "GL_NICEST" ) - OP_CompressMenu.setSelected( 3 ); - else - OP_CompressMenu.setSelected( 2 ); - } - else - { - OP_CompressLabel_Disabled.setVisible( true ); - OP_CompressLabel.setVisible( false ); - OP_CompressMenu.setActive( false ); - OP_CompressMenu.setText( "None" ); - } - - if ( $FogCoordSupported ) - { - OP_IntTexturedFogTgl.setValue( $pref::Interior::TexturedFog ); - OP_IntTexturedFogTgl.setActive( true ); - } - else - { - OP_IntTexturedFogTgl.setValue( true ); - OP_IntTexturedFogTgl.setActive( false ); - } - - OP_AnisotropySlider.setValue( $pref::OpenGL::anisotropy ); - OP_AnisotropySlider.setActive( $AnisotropySupported ); - if ( $AnisotropySupported ) - { - OP_AnisotropyLabel.setVisible( true ); - OP_AnisotropyLabel_Disabled.setVisible( false ); - } - else - { - OP_AnisotropyLabel_Disabled.setVisible( true ); - OP_AnisotropyLabel.setVisible( false ); - } - - OP_EnvMapTgl.setValue($pref::environmentMaps); - OP_EnvMapTgl.setActive($pref::OpenGL::allowTexGen); -} - -//------------------------------------------------------------------------------ -function OptionsDlg::onSleep( %this ) -{ - OP_VideoDriverMenu.clear(); - OP_ResMenu.clear(); - OP_BPPMenu.clear(); - OP_AudioProviderMenu.clear(); - OP_AudioSpeakerMenu.clear(); - OP_NetworkDisplayHud.uninit(); - - if ( %this.resetAudio ) - { - echo( "Resetting the audio driver..." ); - audioSetDriver( "none" ); - audioSetDriver( $pref::Audio::activeDriver ); - %this.resetAudio = ""; - - // Play the shell hum: (all sources are gone) - if($HudHandle[shellScreen] $= "") - alxStop($HudHandle[shellScreen]); - - $HudHandle[shellScreen] = alxPlay(ShellScreenHumSound, 0, 0, 0); - } - - if ( isObject( ServerConnection ) && isTextureFlushRequired() ) - MessageBoxYesNo( "WARNING", "You have made changes that require Tribes 2 to flush the texture cache. " - @ "Doing this while the game is running can take a long time. " - @ "Do you wish to continue?", - "OptionsDlg.saveSettings();", "returnFromSettings();" ); - else - %this.saveSettings(); -} - -//------------------------------------------------------------------------------ -function isTextureFlushRequired() -{ - if ( $pref::Interior::VertexLighting != OP_VertexLightTgl.getValue() ) - return( true ); - - // We're using the noDrawArraysAlpha variable here because we've already - // gone gold (hard to add a new profiling variable). But the Voodoo2/3/3500 - // cards that have the 256x256 texture limitation (in OpenGL) also have the - // noDrawArraysAlpha hack on...so that works out nice - %mipRange = $pref::OpenGL::noDrawArraysAlpha ? 4 : 5; - if ( $pref::OpenGL::mipReduction != 5 - mFloor( OP_ShapeTexSlider.getValue() * %mipRange ) ) - return( true ); - - if ( $pref::OpenGL::interiorMipReduction != 5 - mFloor( OP_BuildingTexSlider.getValue() * %mipRange ) ) - return( true ); - - if ( $pref::OpenGL::skyMipReduction != 5 - mFloor( OP_SkyTexSlider.getValue() * %mipRange ) ) - return( true ); - - if ( $AnisotropySupported && $pref::OpenGL::anisotropy != OP_AnisotropySlider.getValue() ) - return( true ); - - if ( !isDemo() ) - { - %id = OP_TexQualityMenu.getSelected(); - if ( $pref::OpenGL::forcePalettedTexture ) - { - if ( %id != 1 ) - return( true ); - } - else if ( $pref::OpenGL::force16bittexture ) - { - if ( %id != 2 ) - return( true ); - } - else if ( %id != 3 ) - return( true ); - } - - if ( $TextureCompressionSupported && !$pref::OpenGL::disableARBTextureCompression ) - { - %id = OP_CompressMenu.getSelected(); - if ( $pref::OpenGL::allowCompression ) - { - if ( $pref::OpenGL::compressionHint $= "GL_FASTEST" ) - { - if ( %id != 2 ) - return( true ); - } - else if ( $pref::OpenGL::compressionHint $= "GL_NICEST" ) - { - if ( %id != 3 ) - return( true ); - } - else if ( %id == 1 ) - return( true ); - } - else if ( %id > 1 ) - return( true ); - } - - return( false ); -} - -//------------------------------------------------------------------------------ -function returnFromSettings() -{ - // to unpause singlePlayerGame when returning from options - if ( isObject( Game ) ) - Game.OptionsDlgSleep(); -} - -//------------------------------------------------------------------------------ -function OptionsDlg::saveSettings( %this ) -{ - // Save off any prefs that don't auto-update: - %flushTextures = false; - - if ( $SwapIntervalSupported && OP_VSyncTgl.getValue() != $pref::Video::disableVerticalSync ) - { - $pref::Video::disableVerticalSync = OP_VSyncTgl.getValue(); - setVerticalSync( !$pref::Video::disableVerticalSync ); - } - - %temp = OP_SkyDetailMenu.getSelected(); - if ( %temp == 5 ) - $pref::SkyOn = false; - else - { - $pref::SkyOn = true; - $pref::numCloudLayers = ( 4 - %temp ); - } - - if ( $FogCoordSupported ) - $pref::Interior::TexturedFog = OP_IntTexturedFogTgl.getValue(); - - if ( $pref::Interior::VertexLighting != OP_VertexLightTgl.getValue() ) - { - $pref::Interior::VertexLighting = OP_VertexLightTgl.getValue(); - %flushTextures = true; - } - - %temp = OP_PlayerRenderMenu.getSelected(); - $pref::Player::renderMyPlayer = %temp & 1; - $pref::Player::renderMyItems = %temp & 2; - - if ( !isDemo() ) - { - switch ( OP_TexQualityMenu.getSelected() ) - { - case 1: // 8-bit - if ( !$pref::OpenGL::forcePalettedTexture || $pref::OpenGL::force16bittexture ) - { - $pref::OpenGL::forcePalettedTexture = true; - $pref::OpenGL::force16bittexture = false; - %flushTextures = true; - } - case 2: // 16-bit - if ( $pref::OpenGL::forcePalettedTexture || !$pref::OpenGL::force16bittexture ) - { - $pref::OpenGL::forcePalettedTexture = false; - $pref::OpenGL::force16bittexture = true; - %flushTextures = true; - } - case 3: // 32-bit - if ( $pref::OpenGL::forcePalettedTexture || $pref::OpenGL::force16bittexture ) - { - $pref::OpenGL::forcePalettedTexture = false; - $pref::OpenGL::force16bittexture = false; - %flushTextures = true; - } - } - OP_TexQualityMenu.clear(); - } - - $pref::Terrain::texDetail = 6 - mFloor( OP_TerrainTexSlider.getValue() ); - - // We're using the noDrawArraysAlpha variable here because we've already - // gone gold (hard to add a new profiling variable). But the Voodoo2/3/3500 - // cards that have the 256x256 texture limitation (in OpenGL) also have the - // noDrawArraysAlpha hack on...so that works out nice - %mipRange = $pref::OpenGL::noDrawArraysAlpha ? 4 : 5; - - %temp = 5 - mFloor( OP_ShapeTexSlider.getValue() * %mipRange ); - if ( $pref::OpenGL::mipReduction != %temp ) - { - $pref::OpenGL::mipReduction = %temp; - setOpenGLMipReduction( $pref::OpenGL::mipReduction ); - %flushTextures = true; - } - - %temp = 5 - mFloor( OP_BuildingTexSlider.getValue() * %mipRange ); - if ( $pref::OpenGL::interiorMipReduction != %temp ) - { - $pref::OpenGL::interiorMipReduction = %temp; - setOpenGLInteriorMipReduction( $pref::OpenGL::interiorMipReduction ); - %flushTextures = true; - } - - %temp = 5 - mFloor( OP_SkyTexSlider.getValue() * %mipRange ); - if ( $pref::OpenGL::skyMipReduction != %temp ) - { - $pref::OpenGL::skyMipReduction = %temp; - setOpenGLSkyMipReduction( $pref::OpenGL::skyMipReduction ); - %flushTextures = true; - } - - if ( $TextureCompressionSupported && !$pref::OpenGL::disableARBTextureCompression ) - { - %temp = OP_CompressMenu.getSelected(); - if ( $pref::OpenGL::allowCompression ) - { - switch ( %temp ) - { - case 2: - if ( $pref::OpenGL::compressionHint !$= "GL_FASTEST" ) - { - $pref::OpenGL::compressionHint = "GL_FASTEST"; - setOpenGLTextureCompressionHint( $pref::OpenGL::compressionHint ); - %flushTextures = true; - } - - case 3: - if ( $pref::OpenGL::compressionHint !$= "GL_NICEST" ) - { - $pref::OpenGL::compressionHint = "GL_NICEST"; - setOpenGLTextureCompressionHint( $pref::OpenGL::compressionHint ); - %flushTextures = true; - } - - default: // None - $pref::OpenGL::allowCompression = false; - %flushTextures = true; - } - } - else if ( %temp > 1 ) - { - $pref::OpenGL::allowCompression = true; - if ( %temp == 3 ) - $pref::OpenGL::compressionHint = "GL_NICEST"; - else - $pref::OpenGL::compressionHint = "GL_FASTEST"; - setOpenGLTextureCompressionHint( $pref::OpenGL::compressionHint ); - %flushTextures = true; - } - } - OP_CompressMenu.clear(); - - if ( $AnisotropySupported ) - { - %temp = OP_AnisotropySlider.getValue(); - if ( $pref::OpenGL::anisotropy != %temp ) - { - $pref::OpenGL::anisotropy = %temp; - setOpenGLAnisotropy( $pref::OpenGL::anisotropy ); - %flushTextures = true; - } - } - - if ( !isDemo() ) - { - if ( OP_HiResSkinTgl.getValue() != $pref::use512PlayerSkins ) - { - $pref::use512PlayerSkins = OP_HiResSkinTgl.getValue(); - if ( Canvas.getContent() == GameGui.getId() && GM_WarriorPane.isVisible() ) - GMW_PlayerModel.update(); - } - } - - $pref::Terrain::screenError = $max_screenerror - mFloor( OP_TerrainSlider.getValue() ); - $pref::TS::screenError = $max_TSScreenError - mFloor( OP_ShapeSlider.getValue() * ( $max_TSScreenError - $min_TSScreenError ) ); - $pref::TS::detailAdjust = $min_TSDetailAdjust + OP_ShapeSlider.getValue() * ( $max_TSDetailAdjust - $min_TSDetailAdjust ); - $pref::Shadows = OP_ShadowSlider.getValue(); - $pref::ParticleDensity = 4.0 - OP_ParticleDensitySlider.getValue(); - %val = 100 - OP_DynamicLightSlider.getValue(); - $pref::Interior::DynamicLightsClipPix = $pref::Terrain::DynamicLightsClipPix = %val; - $pref::Interior::DynamicLightsFadePix = $pref::Terrain::DynamicLightsFadePix = 2 * %val; - setShadowDetailLevel( $pref::Shadows ); - $pref::Interior::detailAdjust = OP_InteriorDetailSlider.getValue(); - $pref::VisibleDistanceMod = OP_VisibleDistanceSlider.getValue(); - - $pref::Audio::musicVolume = OP_MusicVolumeSlider.getValue(); - $pref::Audio::masterVolume = OP_MasterVolumeSlider.getValue(); - $pref::Audio::effectsVolume = OP_EffectsVolumeSlider.getValue(); - alxSetChannelVolume( $EffectAudioType, $pref::Audio::effectsVolume ); - $pref::Audio::voiceVolume = OP_MicrophoneVolumeSlider.getValue(); - alxSetChannelVolume( $VoiceAudioType, $pref::Audio::voiceVolume ); - $pref::Audio::radioVolume = OP_VoiceBindVolumeSlider.getValue(); - alxSetChannelVolume( $ChatAudioType, $pref::Audio::radioVolume ); - $pref::Audio::guiVolume = OP_GuiVolumeSlider.getValue(); - alxSetChannelVolume( $GuiAudioType, $pref::Audio::guiVolume); - $pref::Audio::captureGainScale = OP_InputBoostSlider.getValue(); - if ( !$missionRunning ) - MusicPlayer.stop(); - - if ( $pref::Audio::enableVoiceCapture ) - { - %reinit = false; - %selId = OP_VoiceListenMenu.getSelected(); - if ( $pref::Audio::decodingMask != %selId ) - { - $pref::Audio::decodingMask = %selId; - %reinit = true; - } - - %selId = OP_VoiceSendMenu.getSelected(); - if ( $pref::Audio::encodingLevel != %selId ) - { - $pref::Audio::encodingLevel = %selId; - %reinit = true; - } - - if ( %reinit ) - { - alxCaptureDestroy(); - alxCaptureInit(); - - // If in a game, let the server know about the altered settings: - if ( isObject( ServerConnection ) ) - commandToServer( 'SetVoiceInfo', $pref::Audio::voiceChannels, $pref::Audio::decodingMask, $pref::Audio::encodingLevel ); - } - } - - updateNetworkSettings(); - - $pref::Player::zoomSpeed = 500 - mFloor( OP_ZoomSpeedSlider.getValue() ); - setZoomSpeed( $pref::Player::zoomSpeed ); - - $pref::Shell::LaunchGui = OP_LaunchScreenMenu.getText(); - - export( "$pref::*", "prefs/ClientPrefs.cs", false ); - saveActiveMapFile(); - - if ( %flushTextures ) - { - // Give the Options Dialog a chance to go away: - OptionsDlg.schedule( 0, doTextureFlush ); - } - - returnFromSettings(); -} - -//------------------------------------------------------------------------------ -function OptionsDlg::doTextureFlush( %this ) -{ - MessagePopup( "PLEASE WAIT", "Flushing texture cache...\nThis may take a while" ); - Canvas.repaint(); - flushTextureCache(); - CloseMessagePopup(); -} - -//------------------------------------------------------------------------------ -function OptionsDlg::setPane( %this, %pane ) -{ - if((%this.pane $= "Sound") && !$missionRunning) - MusicPlayer.stop(); - - if ( %this.pane !$= "None" ) - { - %paneCtrl = "OP_" @ %this.pane @ "Pane"; - %paneCtrl.setVisible( false ); - - %tabCtrl = "OP_" @ %this.pane @ "Tab"; - %tabCtrl.setValue( false ); - } - - %paneCtrl = "OP_" @ %pane @ "Pane"; - %paneCtrl.setVisible( true ); - - %tabCtrl = "OP_" @ %pane @ "Tab"; - %tabCtrl.setValue( true ); - - %this.pane = %pane; -} - -//------------------------------------------------------------------------------ -function OptionsDlg::applyGraphicChanges( %this ) -{ - %newDriver = OP_VideoDriverMenu.getText(); - %newRes = OP_ResMenu.getText(); - %newBpp = OP_BPPMenu.getText(); - %newFullScreen = OP_FullScreenTgl.getValue(); - - if ( %newDriver !$= $pref::Video::displayDevice ) - { - setDisplayDevice( %newDriver, firstWord( %newRes ), getWord( %newRes, 1 ), %newBpp, %newFullScreen ); - OptionsDlg::deviceDependent( %this ); - } - else - setScreenMode( firstWord( %newRes ), getWord( %newRes, 1 ), %newBpp, %newFullScreen ); - - OP_ApplyBtn.updateState(); -} - - -//------------------------------------------------------------------------------ -function OP_VideoDriverMenu::onSelect( %this, %id, %text ) -{ - // Attempt to keep the same res and bpp settings: - if ( OP_ResMenu.size() > 0 ) - %prevRes = OP_ResMenu.getText(); - else - %prevRes = getWords( $pref::Video::resolution, 0, 1 ); - - // Check if this device is full-screen only: - if ( isDeviceFullScreenOnly( %this.getText() ) ) - { - OP_FullScreenTgl.setValue( true ); - OP_FullScreenTgl.setActive( false ); - OP_FullScreenTgl.onAction(); - } - else - OP_FullScreenTgl.setActive( true ); - - if ( OP_FullScreenTgl.getValue() ) - { - if ( OP_BPPMenu.size() > 0 ) - %prevBPP = OP_BPPMenu.getText(); - else - %prevBPP = getWord( $pref::Video::resolution, 2 ); - } - - // Fill the resolution and bit depth lists: - OP_ResMenu.init( %this.getText(), OP_FullScreenTgl.getValue() ); - OP_BPPMenu.init( %this.getText() ); - - // Try to select the previous settings: - %selId = OP_ResMenu.findText( %prevRes ); - if ( %selId == -1 ) - %selId = 0; - OP_ResMenu.setSelected( %selId ); - - if ( OP_FullScreenTgl.getValue() ) - { - %selId = OP_BPPMenu.findText( %prevBPP ); - if ( %selId == -1 ) - %selId = 0; - OP_BPPMenu.setSelected( %selId ); - OP_BPPMenu.setText( OP_BPPMenu.getTextById( %selId ) ); - } - else - OP_BPPMenu.setText( "Default" ); - - OP_ApplyBtn.updateState(); -} - -//------------------------------------------------------------------------------ -function OP_ResMenu::init( %this, %device, %fullScreen ) -{ - %this.clear(); - %resList = getResolutionList( %device ); - %resCount = getFieldCount( %resList ); - %deskRes = getDesktopResolution(); - %count = 0; - for ( %i = 0; %i < %resCount; %i++ ) - { - %res = getWords( getField( %resList, %i ), 0, 1 ); - - if ( !%fullScreen ) - { - if ( firstWord( %res ) >= firstWord( %deskRes ) ) - continue; - if ( getWord( %res, 1 ) >= getWord( %deskRes, 1 ) ) - continue; - } - - // Only add to list if it isn't there already: - if ( %this.findText( %res ) == -1 ) - { - %this.add( %res, %count ); - %count++; - } - } -} - -//------------------------------------------------------------------------------ -function OP_ResMenu::onSelect( %this, %id, %text ) -{ - OP_ApplyBtn.updateState(); -} - -//------------------------------------------------------------------------------ -function OP_BPPMenu::init( %this, %device ) -{ - %this.clear(); - - if ( %device $= "Voodoo2" ) - %this.add( "16", 0 ); - else - { - %resList = getResolutionList( %device ); - %resCount = getFieldCount( %resList ); - %count = 0; - for ( %i = 0; %i < %resCount; %i++ ) - { - %bpp = getWord( getField( %resList, %i ), 2 ); - - // Only add to list if it isn't there already: - if ( %this.findText( %bpp ) == -1 ) - { - %this.add( %bpp, %count ); - %count++; - } - } - } -} - -//------------------------------------------------------------------------------ -function OP_BPPMenu::onSelect( %this, %id, %text ) -{ - OP_ApplyBtn.updateState(); -} - -//------------------------------------------------------------------------------ -function OP_FullScreenTgl::onAction( %this ) -{ - // Attempt to maintain current settings: - %selId = OP_ResMenu.getSelected(); - if ( %selId == -1 ) - %selId = 0; - %prevRes = OP_ResMenu.getTextById( %selId ); - - OP_ResMenu.init( OP_VideoDriverMenu.getText(), %this.getValue() ); - - %selId = OP_ResMenu.findText( %prevRes ); - if ( %selId == -1 ) - %selId = 0; - OP_ResMenu.setSelected( %selId ); - - if ( %this.getValue() ) - { - %selId = OP_BPPMenu.findText( getWord( $pref::Video::resolution, 2 ) ); - if ( %selId == - 1 ) - %selId = 0; - OP_BPPMenu.setSelected( %selId ); - OP_BPPMenu.setText( OP_BPPMenu.getTextById( %selId ) ); - OP_BPPMenu.setActive( true ); - } - else - { - OP_BPPMenu.setText( "Default" ); - OP_BPPMenu.setActive( false ); - } - - OP_ApplyBtn.updateState(); -} - -//------------------------------------------------------------------------------ -function OP_ApplyBtn::updateState( %this ) -{ - %active = false; - - if ( OP_VideoDriverMenu.getText() !$= $pref::Video::displayDevice ) - %active = true; - else if ( OP_ResMenu.getText() !$= getWords( $pref::Video::resolution, 0, 1 ) ) - %active = true; - else if ( OP_FullScreenTgl.getValue() != $pref::Video::fullScreen ) - %active = true; - else if ( OP_FullScreenTgl.getValue() ) - { - if ( OP_BPPMenu.getText() !$= getWord( $pref::Video::resolution, 2 ) ) - %active = true; - } - - %this.setActive( %active ); -} - -//------------------------------------------------------------------------------ -//------------------------------------------------------------------------------ -// Graphics Settings: -// -function updateGammaCorrection() -{ - $pref::OpenGL::gammaCorrection = OP_GammaSlider.getValue(); - videoSetGammaCorrection( $pref::OpenGL::gammaCorrection ); -} - -//------------------------------------------------------------------------------ -function updateTerrainDetail() -{ - $pref::Terrain::screenError = $max_screenerror - mFloor( OP_TerrainSlider.getValue()); - if ( OP_TerrainSlider.getValue() != $max_screenerror - $pref::Terrain::screenError ) - OP_TerrainSlider.setValue( $max_screenerror - $pref::Terrain::screenError ); -} - -//------------------------------------------------------------------------------ -function updateDynamicLightSliderState() -{ - %on = $pref::Interior::DynamicLights || $pref::Terrain::dynamicLights; - OP_DynamicLightText.setVisible( %on ); - OP_DynamicLightText_Disabled.setVisible( !%on ); - OP_DynamicLightSlider.setActive( %on ); -} - -//------------------------------------------------------------------------------ -function OP_SkyDetailMenu::init( %this ) -{ - %this.clear(); - %this.add( "Full Sky", 1 ); - %this.add( "Two Cloud Layers", 2 ); - %this.add( "One Cloud Layer", 3 ); - %this.add( "Sky Box Only", 4 ); - %this.add( "No Sky", 5 ); -} - -//------------------------------------------------------------------------------ -function OP_PlayerRenderMenu::init( %this ) -{ - %this.clear(); - %this.add( "Player and Items", 3 ); - %this.add( "Player only", 1 ); - %this.add( "Items only", 2 ); - %this.add( "Neither Player nor Items", 0 ); -} - -//------------------------------------------------------------------------------ -//------------------------------------------------------------------------------ -// Texture Settings: -// -function OP_CompressMenu::init( %this ) -{ - %this.clear(); - %this.add( "None", 1 ); - %this.add( "Fastest", 2 ); - %this.add( "Nicest", 3 ); -} - -//------------------------------------------------------------------------------ -function OP_TexQualityMenu::init( %this ) -{ - %this.clear(); - if ( $PalettedTextureSupported ) - %this.add( "Palletized", 1 ); - %this.add( "16 bit", 2 ); - %this.add( "32 bit", 3 ); -} - -//------------------------------------------------------------------------------ -function OP_TexQualityMenu::onSelect( %this, %id, %text ) -{ - if ( %id == 1 ) - { - // Disable these with palletized textures by default: - OP_EnvMapTgl.setValue( false ); - //OP_EnvMapTgl.setActive( false ); - OP_IntEnvMapTgl.setValue( false ); - //OP_IntEnvMapTgl.setActive( false ); - } -// else -// { -// OP_EnvMapTgl.setActive( true ); -// OP_IntEnvMapTgl.setActive( true ); -// } -} - -//------------------------------------------------------------------------------ -//------------------------------------------------------------------------------ -// Audio Settings: -// -function setAudioProvider(%idx) -{ - alxContexti(ALC_PROVIDER, %idx); - $pref::Audio::provider = alxGetContextstr(ALC_PROVIDER_NAME, %idx); - - %active = audioIsEnvironmentProvider($pref::Audio::provider); - - // unset tgl if cannot be environment provider - if(!%active) - OP_AudioEnvironmentTgl.setValue(false); - OP_AudioEnvironmentTgl.setActive(%active); - - audioUpdateProvider($pref::Audio::provider); - OP_AudioProviderMenu.setSelected(%idx); -} - -//------------------------------------------------------------------------------ -function OP_AudioEnvironmentTgl::onAction(%this) -{ - alxEnableEnvironmental(%this.getValue()); -} - -//------------------------------------------------------------------------------ -function OP_AudioProviderMenu::onSelect(%this, %id, %text) -{ - if(%id != $Audio::originalProvider) - { - if(!%this.seenWarning) - { - MessageBoxOK("Warning", "Changing sound drivers may result in incompatibilities and game oddities. If you experience such oddities, hit \"Reset\" to restore defaults.", ""); - %this.seenWarning = true; - } - OP_AudioResetProvider.setActive(true); - } - setAudioProvider(%id); -} - -//------------------------------------------------------------------------------ -function OP_AudioResetProvider::onAction(%this) -{ - setAudioProvider($Audio::originalProvider); - %this.setActive(false); -} -//------------------------------------------------------------------------------ -function OP_AudioSpeakerMenu::onSelect(%this, %id, %text) -{ - alxContexti(ALC_SPEAKER, %id); - $pref::Audio::speakerType = alxGetContextstr(ALC_SPEAKER_NAME, %id); -} - -//------------------------------------------------------------------------------ -function OP_AudioFrequencyMenu::init( %this ) -{ - %this.clear(); - %this.add( "11 KHz", 0 ); - %this.add( "22 KHz", 1 ); - %this.add( "44 KHz", 2 ); - - switch ( $pref::Audio::frequency ) - { - case 11025: %this.setSelected( 0 ); - case 22050: %this.setSelected( 1 ); - default: %this.setSelected( 2 ); - } -} - -//------------------------------------------------------------------------------ -function OP_AudioFrequencyMenu::onSelect( %this, %id, %text ) -{ - switch ( %id ) - { - case 0: %newVal = 11025; - case 1: %newVal = 22050; - default: %newVal = 44100; - } - - if ( $pref::Audio::frequency != %newVal ) - { - $pref::Audio::frequency = %newVal; - OptionsDlg.resetAudio = true; - } -} - -//------------------------------------------------------------------------------ -function OP_AudioBitRateMenu::init( %this ) -{ - %this.clear(); - %this.add( "8 bit", 0 ); - %this.add( "16 bit", 1 ); - - if ( $pref::Audio::sampleBits == 8 ) - %this.setSelected( 0 ); - else - %this.setSelected( 1 ); -} - -//------------------------------------------------------------------------------ -function OP_AudioBitRateMenu::onSelect( %this, %id, %text ) -{ - %newVal = %id == 0 ? 8 : 16; - if ( $pref::Audio::sampleBits != %newVal ) - { - $pref::Audio::sampleBits = %newVal; - OptionsDlg.resetAudio = true; - } -} - -//------------------------------------------------------------------------------ -function OP_AudioChannelsMenu::init( %this ) -{ - %this.clear(); - %this.add( "One", 0 ); - %this.add( "Two", 1 ); - - if ( $pref::Audio::channels == 1 ) - %this.setSelected( 0 ); - else - %this.setSelected( 1 ); -} - -//------------------------------------------------------------------------------ -function OP_AudioChannelsMenu::onSelect( %this, %id, %text ) -{ - %newVal = %id == 0 ? 1 : 2; - if ( $pref::Audio::channels != %newVal ) - { - $pref::Audio::channels = %newVal; - OptionsDlg.resetAudio = true; - } -} - -//------------------------------------------------------------------------------ -function OP_MusicTgl::onAction( %this ) -{ - %on = %this.getValue(); - OP_MusicVolumeLabel.setVisible( %on ); - OP_MusicVolumeLabel_Disabled.setVisible( !%on ); - OP_MusicVolumeSlider.setActive( %on ); - $pref::Audio::musicEnabled = %on; - - if ( %on ) - MusicPlayer.play(); - else - MusicPlayer.stop(); -} - -//------------------------------------------------------------------------------ -function updateMusicVolume() -{ - %volume = OP_MusicVolumeSlider.getValue(); - alxSetChannelVolume( $MusicAudioType, %volume ); -} - -//------------------------------------------------------------------------------ -function updateGuiVolume() -{ - %volume = OP_GuiVolumeSlider.getValue(); - alxSetChannelVolume( $GuiAudioType, %volume ); -} - -//------------------------------------------------------------------------------ -function updateMasterVolume() -{ - %volume = OP_MasterVolumeSlider.getValue(); - alxListenerf( AL_GAIN_LINEAR, %volume ); -} - - -//------------------------------------------------------------------------------ -//------------------------------------------------------------------------------ -// Voice Settings: -// -function OP_MicrophoneEnabledTgl::onAction( %this ) -{ - %on = %this.getValue(); - OP_RecordTestBtn.setActive( %on ); - OP_MicVolumeLabel.setVisible( %on ); - OP_MicVolumeLabel_Disabled.setVisible( !%on ); - OP_MicrophoneVolumeSlider.setActive( %on ); - OP_InputBoostLabel.setVisible( %on ); - OP_InputBoostLabel_Disabled.setVisible( !%on ); - OP_InputBoostSlider.setActive( %on ); - OP_InputBoostPercentTxt.setVisible( %on ); - OP_VoiceListenLabel.setVisible( %on ); - OP_VoiceListenLabel_Disabled.setVisible( !%on ); - OP_VoiceListenMenu.setActive( %on ); - OP_VoiceSendLabel.setVisible( %on ); - OP_VoiceSendLabel_Disabled.setVisible( !%on ); - OP_VoiceSendMenu.setActive( %on ); - - if(%on != alxIsEnabled("capture")) - { - if(%on) - alxCaptureInit(); - else - alxCaptureDestroy(); - } -} - -//------------------------------------------------------------------------------ -function updateInputBoost() -{ - %val = OP_InputBoostSlider.getValue(); - alxSetCaptureGainScale( %val ); - %val = mFloor(%val * 100); - OP_InputBoostPercentTxt.setValue(%val @ "%"); -} - -//------------------------------------------------------------------------------ -function OP_RecordTestBtn::onAction( %this ) -{ - alxCaptureStart(true); -} - -//------------------------------------------------------------------------------ -function localCaptureStart( %method ) -{ - if(%method $= "record") - { - OP_RecordTestBtn.setActive(false); - OP_RecordTestBtn.setValue(">> Recording <<"); - } - else - { - OP_RecordTestBtn.setActive(false); - OP_RecordTestBtn.setValue(">> Playing <<"); - } -} - -//------------------------------------------------------------------------------ -function localCaptureStop( %method ) -{ - if(%method $= "play") - { - OP_RecordTestBtn.setActive(true); - OP_RecordTestBtn.setValue("Test Record"); - } -} - -//------------------------------------------------------------------------------ -function OP_VoiceListenMenu::init( %this ) -{ - %this.clear(); - %this.add( "", 0 ); - if ( $platform !$= "linux" ) { - %this.add( ".v12", 1 ); - %this.add( ".v12 - .v24", 3 ); - %this.add( ".v12 - .v29", 7 ); - } - if ( $platform $= "linux" ) { - %this.add( "GSM" , 8 ); - } - - switch ( $pref::Audio::decodingMask ) - { - case 0 or 3 or 7 or 8: - %this.setSelected( $pref::Audio::decodingMask ); - default: - %this.setSelected( 1 ); - } -} - -//------------------------------------------------------------------------------ -function OP_VoiceSendMenu::init( %this ) -{ - %this.clear(); - if ( $platform !$= "linux" ) { - %this.add( ".v12", 0 ); - %this.add( ".v24", 1 ); - %this.add( ".v29", 2 ); - } - if ( $platform $= "linux" ) { - %this.add( "GSM", 3 ); - } - - %this.setSelected($pref::Audio::encodingLevel); -} - -function OP_VoiceCodecInfo::init( %this ) -{ - %headerStyle = ""; - if ( $platform $= "linux" ) { - %displayText = "" @ %headerStyle @ "Voice Codec Information:" NL - "\n" @ - " GSM: fixed bitrate codec (6.6 kbits/sec linux only)" NL - "\n" @ - "" @ - "Setting your codec levels too high can have adverse" @ - " affects on network performance." @ - ""; - } else { - %displayText = "" @ %headerStyle @ "Voice Codec Information:" NL - "\n" @ - " .v12: variable bitrate codec (~1.2 kbits/sec win only)" NL - " .v24: fixed bitrate codec (2.4 kbits/sec win only)" NL - " .v29: fixed bitrate codec (2.9 kbits/sec win only)" NL - "\n" @ - "" @ - "Setting your codec levels too high can have adverse" @ - " affects on network performance." @ - ""; - } - - %this.setText(%displayText); - %this.setActive(false); -} - -//------------------------------------------------------------------------------ -//------------------------------------------------------------------------------ -// Driver Info dialog: -// -function DriverInfoDlg::onWake( %this ) -{ - %headerStyle = ""; - %infoString = getVideoDriverInfo(); - %displayText = "" @ %headerStyle @ "VENDOR:" NL - " " @ getField( %infoString, 0 ) NL - "" @ %headerStyle @ "RENDERER:" NL - " " @ getField( %infoString, 1 ) NL - "" @ %headerStyle @ "VERSION " @ getField( %infoString, 2 ) NL - "\n" @ - "" @ %headerStyle @ "SUPPORTED OPENGL EXTENSIONS:" NL - getField( %infoString, 3 ); - - DriverInfoText.setText( %displayText ); -} - -//------------------------------------------------------------------------------ -//------------------------------------------------------------------------------ -// Control remapper section: -// -$RemapCount = 0; -$RemapName[$RemapCount] = "Forward"; -$RemapCmd[$RemapCount] = "moveforward"; -$RemapCount++; -$RemapName[$RemapCount] = "Backward"; -$RemapCmd[$RemapCount] = "movebackward"; -$RemapCount++; -$RemapName[$RemapCount] = "Strafe Left"; -$RemapCmd[$RemapCount] = "moveleft"; -$RemapCount++; -$RemapName[$RemapCount] = "Strafe Right"; -$RemapCmd[$RemapCount] = "moveright"; -$RemapCount++; -$RemapName[$RemapCount] = "Turn Left"; -$RemapCmd[$RemapCount] = "turnLeft"; -$RemapCount++; -$RemapName[$RemapCount] = "Turn Right"; -$RemapCmd[$RemapCount] = "turnRight"; -$RemapCount++; -$RemapName[$RemapCount] = "Look Up"; -$RemapCmd[$RemapCount] = "panUp"; -$RemapCount++; -$RemapName[$RemapCount] = "Look Down"; -$RemapCmd[$RemapCount] = "panDown"; -$RemapCount++; -$RemapName[$RemapCount] = "Jump"; -$RemapCmd[$RemapCount] = "jump"; -$RemapCount++; -$RemapName[$RemapCount] = "Jet Pack"; -$RemapCmd[$RemapCount] = "mouseJet"; -$RemapCount++; -$RemapName[$RemapCount] = "Fire Weapon"; -$RemapCmd[$RemapCount] = "mouseFire"; -$RemapCount++; -$RemapName[$RemapCount] = "Zoom"; -$RemapCmd[$RemapCount] = "toggleZoom"; -$RemapCount++; -$RemapName[$RemapCount] = "Cycle Zoom Level"; -$RemapCmd[$RemapCount] = "setZoomFOV"; -$RemapCount++; -$RemapName[$RemapCount] = "Weapon Slot One"; -$RemapCmd[$RemapCount] = "useFirstWeaponSlot"; -$RemapCount++; -$RemapName[$RemapCount] = "Weapon Slot Two"; -$RemapCmd[$RemapCount] = "useSecondWeaponSlot"; -$RemapCount++; -$RemapName[$RemapCount] = "Weapon Slot Three"; -$RemapCmd[$RemapCount] = "useThirdWeaponSlot"; -$RemapCount++; -$RemapName[$RemapCount] = "Weapon Slot Four"; -$RemapCmd[$RemapCount] = "useFourthWeaponSlot"; -$RemapCount++; -$RemapName[$RemapCount] = "Weapon Slot Five"; -$RemapCmd[$RemapCount] = "useFifthWeaponSlot"; -$RemapCount++; -$RemapName[$RemapCount] = "Weapon Slot Six"; -$RemapCmd[$RemapCount] = "useSixthWeaponSlot"; -$RemapCount++; -$RemapName[$RemapCount] = "Blaster"; -$RemapCmd[$RemapCount] = "useBlaster"; -$RemapCount++; -$RemapName[$RemapCount] = "Plasma Rifle"; -$RemapCmd[$RemapCount] = "usePlasma"; -$RemapCount++; -$RemapName[$RemapCount] = "Chaingun"; -$RemapCmd[$RemapCount] = "useChaingun"; -$RemapCount++; -$RemapName[$RemapCount] = "Spinfusor"; -$RemapCmd[$RemapCount] = "useDisc"; -$RemapCount++; -$RemapName[$RemapCount] = "Grenade Launcher"; -$RemapCmd[$RemapCount] = "useGrenadeLauncher"; -$RemapCount++; -$RemapName[$RemapCount] = "Laser Rifle"; -$RemapCmd[$RemapCount] = "useSniperRifle"; -$RemapCount++; -$RemapName[$RemapCount] = "ELF Projector"; -$RemapCmd[$RemapCount] = "useELFGun"; -$RemapCount++; -$RemapName[$RemapCount] = "Fusion Mortar"; -$RemapCmd[$RemapCount] = "useMortar"; -$RemapCount++; -$RemapName[$RemapCount] = "Missile Launcher"; -$RemapCmd[$RemapCount] = "useMissileLauncher"; -$RemapCount++; -$RemapName[$RemapCount] = "Shocklance"; -$RemapCmd[$RemapCount] = "useShockLance"; -$RemapCount++; -$RemapName[$RemapCount] = "Targeting Laser"; -$RemapCmd[$RemapCount] = "useTargetingLaser"; -$RemapCount++; -$RemapName[$RemapCount] = "Previous Weapon"; -$RemapCmd[$RemapCount] = "prevWeapon"; -$RemapCount++; -$RemapName[$RemapCount] = "Next Weapon"; -$RemapCmd[$RemapCount] = "nextWeapon"; -$RemapCount++; -$RemapName[$RemapCount] = "Throw Grenade"; -$RemapCmd[$RemapCount] = "throwGrenade"; -$RemapCount++; -$RemapName[$RemapCount] = "Place Mine"; -$RemapCmd[$RemapCount] = "placeMine"; -$RemapCount++; -$RemapName[$RemapCount] = "Use Pack"; -$RemapCmd[$RemapCount] = "useBackpack"; -$RemapCount++; -$RemapName[$RemapCount] = "Use Health Kit"; -$RemapCmd[$RemapCount] = "useRepairKit"; -$RemapCount++; -$RemapName[$RemapCount] = "Deploy Beacon"; -$RemapCmd[$RemapCount] = "placeBeacon"; -$RemapCount++; -$RemapName[$RemapCount] = "Inventory"; -$RemapCmd[$RemapCount] = "toggleInventoryHud"; -$RemapCount++; -$RemapName[$RemapCount] = "Favorite 1"; -$RemapCmd[$RemapCount] = "selectFavorite1"; -$RemapCount++; -$RemapName[$RemapCount] = "Favorite 2"; -$RemapCmd[$RemapCount] = "selectFavorite2"; -$RemapCount++; -$RemapName[$RemapCount] = "Favorite 3"; -$RemapCmd[$RemapCount] = "selectFavorite3"; -$RemapCount++; -$RemapName[$RemapCount] = "Favorite 4"; -$RemapCmd[$RemapCount] = "selectFavorite4"; -$RemapCount++; -$RemapName[$RemapCount] = "Favorite 5"; -$RemapCmd[$RemapCount] = "selectFavorite5"; -$RemapCount++; -$RemapName[$RemapCount] = "Favorite 6"; -$RemapCmd[$RemapCount] = "selectFavorite6"; -$RemapCount++; -$RemapName[$RemapCount] = "Favorite 7"; -$RemapCmd[$RemapCount] = "selectFavorite7"; -$RemapCount++; -$RemapName[$RemapCount] = "Favorite 8"; -$RemapCmd[$RemapCount] = "selectFavorite8"; -$RemapCount++; -$RemapName[$RemapCount] = "Favorite 9"; -$RemapCmd[$RemapCount] = "selectFavorite9"; -$RemapCount++; -$RemapName[$RemapCount] = "Favorite 10"; -$RemapCmd[$RemapCount] = "selectFavorite10"; -$RemapCount++; -$RemapName[$RemapCount] = "Favorite 11"; -$RemapCmd[$RemapCount] = "selectFavorite11"; -$RemapCount++; -$RemapName[$RemapCount] = "Favorite 12"; -$RemapCmd[$RemapCount] = "selectFavorite12"; -$RemapCount++; -$RemapName[$RemapCount] = "Favorite 13"; -$RemapCmd[$RemapCount] = "selectFavorite13"; -$RemapCount++; -$RemapName[$RemapCount] = "Favorite 14"; -$RemapCmd[$RemapCount] = "selectFavorite14"; -$RemapCount++; -$RemapName[$RemapCount] = "Favorite 15"; -$RemapCmd[$RemapCount] = "selectFavorite15"; -$RemapCount++; -$RemapName[$RemapCount] = "Favorite 16"; -$RemapCmd[$RemapCount] = "selectFavorite16"; -$RemapCount++; -$RemapName[$RemapCount] = "Favorite 17"; -$RemapCmd[$RemapCount] = "selectFavorite17"; -$RemapCount++; -$RemapName[$RemapCount] = "Favorite 18"; -$RemapCmd[$RemapCount] = "selectFavorite18"; -$RemapCount++; -$RemapName[$RemapCount] = "Favorite 19"; -$RemapCmd[$RemapCount] = "selectFavorite19"; -$RemapCount++; -$RemapName[$RemapCount] = "Favorite 20"; -$RemapCmd[$RemapCount] = "selectFavorite20"; -$RemapCount++; -$RemapName[$RemapCount] = "Select Energy Pack"; -$RemapCmd[$RemapCount] = "quickPackEnergyPack"; -$RemapCount++; -$RemapName[$RemapCount] = "Select Repair Pack"; -$RemapCmd[$RemapCount] = "quickPackRepairPack"; -$RemapCount++; -$RemapName[$RemapCount] = "Select Shield Pack"; -$RemapCmd[$RemapCount] = "quickPackShieldPack"; -$RemapCount++; -$RemapName[$RemapCount] = "Select Cloaking Pack"; -$RemapCmd[$RemapCount] = "quickPackCloakPack"; -$RemapCount++; -$RemapName[$RemapCount] = "Select Sensor Jammer"; -$RemapCmd[$RemapCount] = "quickPackJammerPack"; -$RemapCount++; -$RemapName[$RemapCount] = "Select Ammo Pack"; -$RemapCmd[$RemapCount] = "quickPackAmmoPack"; -$RemapCount++; -$RemapName[$RemapCount] = "Select Satchel Charge"; -$RemapCmd[$RemapCount] = "quickPackSatchelCharge"; -$RemapCount++; -$RemapName[$RemapCount] = "Select Inv Station"; -$RemapCmd[$RemapCount] = "quickPackDeployableStation"; -$RemapCount++; -$RemapName[$RemapCount] = "Select Spider Turret"; -$RemapCmd[$RemapCount] = "quickPackIndoorTurret"; -$RemapCount++; -$RemapName[$RemapCount] = "Select Landspike Turret"; -$RemapCmd[$RemapCount] = "quickPackOutdoorTurret"; -$RemapCount++; -$RemapName[$RemapCount] = "Select Motion Sensor"; -$RemapCmd[$RemapCount] = "quickPackMotionSensor"; -$RemapCount++; -$RemapName[$RemapCount] = "Select Deploy Pulse"; -$RemapCmd[$RemapCount] = "quickPackPulse"; -$RemapCount++; -$RemapName[$RemapCount] = "Select Plasma Barrel"; -$RemapCmd[$RemapCount] = "quickPackPlasmaBarrel"; -$RemapCount++; -$RemapName[$RemapCount] = "Select Missile Barrel"; -$RemapCmd[$RemapCount] = "quickPackMissileBarrel"; -$RemapCount++; -$RemapName[$RemapCount] = "Select AA Barrel"; -$RemapCmd[$RemapCount] = "quickPackAABarrel"; -$RemapCount++; -$RemapName[$RemapCount] = "Select Mortar Barrel"; -$RemapCmd[$RemapCount] = "quickPackMortarBarrel"; -$RemapCount++; -$RemapName[$RemapCount] = "Select Elf Barrel"; -$RemapCmd[$RemapCount] = "quickPackElfBarrel"; -$RemapCount++; -$RemapName[$RemapCount] = "Select Grenade"; -$RemapCmd[$RemapCount] = "quickPackGrenade"; -$RemapCount++; -$RemapName[$RemapCount] = "Select Flash Grenade"; -$RemapCmd[$RemapCount] = "quickPackFlashGrenade"; -$RemapCount++; -$RemapName[$RemapCount] = "Select Concussion"; -$RemapCmd[$RemapCount] = "quickPackConcussionGrenade"; -$RemapCount++; -$RemapName[$RemapCount] = "Select Camera"; -$RemapCmd[$RemapCount] = "quickPackCameraGrenade"; -$RemapCount++; -$RemapName[$RemapCount] = "Select Flare Grenade"; -$RemapCmd[$RemapCount] = "quickPackFlareGrenade"; -$RemapCount++; -$RemapName[$RemapCount] = "Command Circuit"; -$RemapCmd[$RemapCount] = "toggleCommanderMap"; -$RemapCount++; -$RemapName[$RemapCount] = "Toggle Task List"; -$RemapCmd[$RemapCount] = "toggleTaskListDlg"; -$RemapCount++; -$RemapName[$RemapCount] = "Accept Task"; -$RemapCmd[$RemapCount] = "fnAcceptTask"; -$RemapCount++; -$RemapName[$RemapCount] = "Decline Task"; -$RemapCmd[$RemapCount] = "fnDeclineTask"; -$RemapCount++; -$RemapName[$RemapCount] = "Task Completed"; -$RemapCmd[$RemapCount] = "fnTaskCompleted"; -$RemapCount++; -$RemapName[$RemapCount] = "Reset Task List"; -$RemapCmd[$RemapCount] = "fnResetTaskList"; -$RemapCount++; -$RemapName[$RemapCount] = "Vote Yes"; -$RemapCmd[$RemapCount] = "voteYes"; -$RemapCount++; -$RemapName[$RemapCount] = "Vote No"; -$RemapCmd[$RemapCount] = "voteNo"; -$RemapCount++; -$RemapName[$RemapCount] = "Voice Chat Menu"; -$RemapCmd[$RemapCount] = "activateChatMenuHud"; -$RemapCount++; -$RemapName[$RemapCount] = "Global Chat"; -$RemapCmd[$RemapCount] = "ToggleMessageHud"; -$RemapCount++; -$RemapName[$RemapCount] = "Team Chat"; -$RemapCmd[$RemapCount] = "TeamMessageHud"; -$RemapCount++; -$RemapName[$RemapCount] = "Resize Chat Hud"; -$RemapCmd[$RemapCount] = "resizeChatHud"; -$RemapCount++; -$RemapName[$RemapCount] = "Toggle Microphone"; -$RemapCmd[$RemapCount] = "voiceCapture"; -$RemapCount++; -$RemapName[$RemapCount] = "Toggle Help Text"; -$RemapCmd[$RemapCount] = "toggleHelpGui"; -$RemapCount++; -$RemapName[$RemapCount] = "Score Screen"; -$RemapCmd[$RemapCount] = "toggleScoreScreen"; -$RemapCount++; -$RemapName[$RemapCount] = "Free Look"; -$RemapCmd[$RemapCount] = "toggleFreeLook"; -$RemapCount++; -$RemapName[$RemapCount] = "Exterior View"; -$RemapCmd[$RemapCount] = "toggleFirstPerson"; -$RemapCount++; -$RemapName[$RemapCount] = "Drop Weapon"; -$RemapCmd[$RemapCount] = "throwWeapon"; -$RemapCount++; -$RemapName[$RemapCount] = "Drop Pack"; -$RemapCmd[$RemapCount] = "throwPack"; -$RemapCount++; -$RemapName[$RemapCount] = "Drop Flag"; -$RemapCmd[$RemapCount] = "throwFlag"; -$RemapCount++; -$RemapName[$RemapCount] = "Suicide"; -$RemapCmd[$RemapCount] = "suicide"; -$RemapCount++; -$RemapName[$RemapCount] = "Toggle Personal Wypts"; -$RemapCmd[$RemapCount] = "toggleHudWaypoints"; -$RemapCount++; -$RemapName[$RemapCount] = "Toggle Mission Wypts"; -$RemapCmd[$RemapCount] = "toggleHudMarkers"; -$RemapCount++; -$RemapName[$RemapCount] = "Toggle Beacons"; -$RemapCmd[$RemapCount] = "toggleHudTargets"; -$RemapCount++; -$RemapName[$RemapCount] = "Toggle Commands"; -$RemapCmd[$RemapCount] = "toggleHudCommands"; -$RemapCount++; -$RemapName[$RemapCount] = "Interact / Use"; -$RemapCmd[$RemapCount] = "InteractWithObject"; -$RemapCount++; -$RemapName[$RemapCount] = "Icrease Frequency"; -$RemapCmd[$RemapCount] = "IcreaseRadioFrequency"; -$RemapCount++; -$RemapName[$RemapCount] = "Decrease Frequency"; -$RemapCmd[$RemapCount] = "DecreaseRadioFrequency"; -$RemapCount++; -if ( !isDemo() ) -{ - $RemapName[$RemapCount] = "Start Demo Record"; - $RemapCmd[$RemapCount] = "startRecordingDemo"; - $RemapCount++; - $RemapName[$RemapCount] = "Stop Demo Record"; - $RemapCmd[$RemapCount] = "stopRecordingDemo"; - $RemapCount++; -} -$RemapName[$RemapCount] = "Chat Page Up"; -$RemapCmd[$RemapCount] = "pageMessageHudUp"; -$RemapCount++; -$RemapName[$RemapCount] = "Chat Page Down"; -$RemapCmd[$RemapCount] = "pageMessageHudDown"; -$RemapCount++; -$RemapName[$RemapCount] = "Toggle Net Meter"; -$RemapCmd[$RemapCount] = "toggleNetDisplayHud"; -$RemapCount++; - -$ObsRemapCount = 0; -$ObsRemapName[$ObsRemapCount] = "Move Up"; -$ObsRemapCmd[$ObsRemapCount] = "moveup"; -$ObsRemapCount++; -$ObsRemapName[$ObsRemapCount] = "Move Down"; -$ObsRemapCmd[$ObsRemapCount] = "movedown"; -$ObsRemapCount++; -$ObsRemapName[$ObsRemapCount] = "Toggle Observer Mode"; -$ObsRemapCmd[$ObsRemapCount] = "jump"; -$ObsRemapCount++; -$ObsRemapName[$ObsRemapCount] = "Spawn/Previous"; -$ObsRemapCmd[$ObsRemapCount] = "mouseFire"; -$ObsRemapCount++; -$ObsRemapName[$ObsRemapCount] = "Cycle Camera/Next"; -$ObsRemapCmd[$ObsRemapCount] = "mouseJet"; -$ObsRemapCount++; - -//------------------------------------------------------------------------------ -function restoreDefaultMappings() -{ - moveMap.delete(); - exec( "scripts/controlDefaults.cs" ); - $pref::Input::ActiveConfig = "MyConfig"; - OP_RemapList.fillList(); -} - -//------------------------------------------------------------------------------ -function isMapFile( %file ) -{ - %fObject = new FileObject(); - if ( !%fObject.openForRead( %file ) ) - return( false ); - - while ( !%fObject.isEOF() ) - { - %line = %fObject.readLine(); - if ( %line $= "// Tribes 2 Input Map File" ) - { - %fObject.close(); - return( true ); - } - } - - %fObject.close(); - return( false ); -} - -//------------------------------------------------------------------------------ -function isValidMapFileSaveName( %file ) -{ - if (isDemo()) - %basePath = "demo_base/"; - else - %basePath = "base/"; - if ( !isWriteableFileName( %basePath @ %file ) ) - return( false ); - - if ( isFile( %file ) ) - return( isMapFile( %file ) ); - - return( true ); -} - -//------------------------------------------------------------------------------ -function loadMapFile( %filename ) -{ - exec( "prefs/" @ %filename @ ".cs" ); - $pref::Input::ActiveConfig = %filename; - OP_RemapList.fillList(); -} - -//------------------------------------------------------------------------------ -function saveActiveMapFile() -{ - if ( isValidMapFileSaveName( "prefs/" @ $pref::Input::ActiveConfig @ ".cs" ) ) - saveMapFile( $pref::Input::ActiveConfig ); - else - ShellGetSaveFilename( "SAVE CONTROL CONFIG", "prefs/*.cs", "isMapFile", "saveMapFile", "" ); -} - -//------------------------------------------------------------------------------ -function saveMapFile( %filename ) -{ - if ( strcspn( %filename, "\\/?*\"\'<>|" ) < strlen( %filename ) ) - { - MessageBoxOK( "SAVE FAILED", "Filenames may not contain any of the following characters:" NL "\\ / ? * < > \" \' |", - "ShellGetSaveFilename( \"SAVE CONTROL CONFIG\", \"prefs/*.cs\", \"isMapFile\", \"saveMapFile\", $pref::Input::ActiveConfig );" ); - return; - } - - if (isDemo()) - %basePath = "demo_base/"; - else - %basePath = "base/"; - %mapFile = "prefs/" @ %filename @ ".cs"; - if ( !isWriteableFileName( %basePath @ %mapFile ) ) - { - MessageBoxOK( "SAVE FAILED", "That is not a writeable file name. Please choose another file name.", - "ShellGetSaveFilename( \"SAVE CONTROL CONFIG\", \"prefs/*.cs\", \"isMapFile\", \"saveMapFile\", $pref::Input::ActiveConfig );" ); - return; - } - - if ( isFile( %mapFile ) && !isMapFile( %mapFile ) ) - { - MessageBoxOK( "SAVE FAILED", "A file of that name already exists and is not an input configuration file. Please choose another file name.", - "ShellGetSaveFilename( \"SAVE CONTROL CONFIG\", \"prefs/*.cs\", \"isMapFile\", \"saveMapFile\", $pref::Input::ActiveConfig );" ); - return; - } - - moveMap.save( %mapFile ); - // Append the observer action map: - observerMap.save( %mapFile, true ); - - // Write out the console toggle key: - %fObject = new FileObject(); - if ( %fObject.openForAppend( %mapFile ) ) - { - %bind = GlobalActionMap.getBinding( "toggleConsole" ); - if ( %bind !$= "" ) - { - %fObject.writeLine( "GlobalActionMap.bind(keyboard, \"" @ getField( %bind, 1 ) @ "\", toggleConsole);" ); - %fObject.close(); - } - } - %fObject.delete(); - - $pref::Input::ActiveConfig = %filename; -} - -//------------------------------------------------------------------------------ -function getMapDisplayName( %device, %action ) -{ - if ( %device $= "keyboard" ) - return( %action ); - else if ( strstr( %device, "mouse" ) != -1 ) - { - // Substitute "mouse" for "button" in the action string: - %pos = strstr( %action, "button" ); - if ( %pos != -1 ) - { - %mods = getSubStr( %action, 0, %pos ); - %object = getSubStr( %action, %pos, 1000 ); - %instance = getSubStr( %object, strlen( "button" ), 1000 ); - return( %mods @ "mouse" @ ( %instance + 1 ) ); - } - else - error( "Mouse input object other than button passed to getDisplayMapName!" ); - } - else if ( strstr( %device, "joystick" ) != -1 ) - { - // Substitute "joystick" for "button" in the action string: - %pos = strstr( %action, "button" ); - if ( %pos != -1 ) - { - %mods = getSubStr( %action, 0, %pos ); - %object = getSubStr( %action, %pos, 1000 ); - %instance = getSubStr( %object, strlen( "button" ), 1000 ); - return( %mods @ "joystick" @ ( %instance + 1 ) ); - } - else - { - %pos = strstr( %action, "pov" ); - if ( %pos != -1 ) - { - %wordCount = getWordCount( %action ); - %mods = %wordCount > 1 ? getWords( %action, 0, %wordCount - 2 ) @ " " : ""; - %object = getWord( %action, %wordCount - 1 ); - switch$ ( %object ) - { - case "upov": %object = "POV1 up"; - case "dpov": %object = "POV1 down"; - case "lpov": %object = "POV1 left"; - case "rpov": %object = "POV1 right"; - case "upov2": %object = "POV2 up"; - case "dpov2": %object = "POV2 down"; - case "lpov2": %object = "POV2 left"; - case "rpov2": %object = "POV2 right"; - default: %object = "??"; - } - return( %mods @ %object ); - } - else - error( "Unsupported Joystick input object passed to getDisplayMapName!" ); - } - } - - return( "??" ); -} - -//------------------------------------------------------------------------------ -function buildFullMapString( %index ) -{ - switch$ ( OP_ControlsPane.group ) - { - case "Observer": - %actionMap = observerMap; - %name = $ObsRemapName[%index]; - %cmd = $ObsRemapCmd[%index]; - - case "Main": - %actionMap = moveMap; - %name = $RemapName[%index]; - %cmd = $RemapCmd[%index]; - - default: - %actionMap = RTSMap; - %name = $RTSRemapName[%index]; - %cmd = $RTSRemapCmd[%index]; - } - - %temp = %actionMap.getBinding( %cmd ); - %device = getField( %temp, 0 ); - %object = getField( %temp, 1 ); - if ( %device !$= "" && %object !$= "" ) - %mapString = getMapDisplayName( %device, %object ); - else - %mapString = ""; - - return( %name TAB %mapString ); -} - -//------------------------------------------------------------------------------ -function OP_ControlGroupMenu::init( %this ) -{ - %selId = %this.getSelected(); - %this.clear(); - %this.add( "Main", 0 ); - %this.add( "Observer", 1 ); - %this.add( "RTS", 2 ); - %this.setSelected( %selId ); - %this.onSelect( %selId, %this.getTextById( %selId ) ); -} - -//------------------------------------------------------------------------------ -function OP_ControlGroupMenu::onSelect( %this, %id, %text ) -{ - OP_ControlsPane.group = %text; - OP_RemapList.fillList(); -} - -//------------------------------------------------------------------------------ -function OP_RemapList::fillList( %this ) -{ - switch$ ( OP_ControlsPane.group ) - { - case "Observer": %count = $ObsRemapCount; - case "RTS": %count = $RTSRemapCount; - default: %count = $RemapCount; - } - - %this.clear(); - for ( %i = 0; %i < %count; %i++ ) - %this.addRow( %i, buildFullMapString( %i ) ); - - // Set the console key: - %bind = GlobalActionMap.getBinding( "toggleConsole" ); - OP_ConsoleKeyBtn.setValue( getField( %bind, 1 ) ); -} - -//------------------------------------------------------------------------------ -function OP_RemapList::onDeleteKey( %this, %rowId ) -{ - switch$ ( OP_ControlsPane.group ) - { - case "Observer": - %actionMap = observerMap; - %cmd = $ObsRemapCmd[%rowId]; - case "Main": - %actionMap = moveMap; - %cmd = $RemapCmd[%rowId]; - default: - %actionMap = RTSMap; - %cmd = $RTSRemapCmd[%rowId]; - } - clearMapping( %actionMap, %cmd ); - %this.setRowById( %rowId, buildFullMapString( %rowId ) ); -} - -//------------------------------------------------------------------------------ -function OP_RemapList::doRemap( %this ) -{ - %selId = %this.getSelectedId(); - switch$ ( OP_ControlsPane.group ) - { - case "Observer": %name = $ObsRemapName[%selId]; - case "RTS": %name = $RTSRemapName[%selId]; - default: %name = $RemapName[%selId]; - } - - RemapFrame.setTitle( "REMAP \"" @ %name @ "\"" ); - RemapInputCtrl.mode = "move"; - RemapInputCtrl.index = %selId; - Canvas.pushDialog( RemapDlg ); -} - -//------------------------------------------------------------------------------ -function OP_ConsoleKeyBtn::doRemap( %this ) -{ - RemapFrame.setTitle( "REMAP \"Toggle Console\"" ); - RemapInputCtrl.mode = "consoleKey"; - RemapInputCtrl.index = 0; - Canvas.pushDialog( RemapDlg ); -} - -//------------------------------------------------------------------------------ -function RemapDlg::onWake( %this ) -{ - $enableDirectInput = "1"; - activateDirectInput(); - - if ( RemapInputCtrl.mode $= "consoleKey" ) - RemapText.setText( "Press a key to assign it to this action" NL "or Esc to cancel..." ); - else - RemapText.setText( "Press a key or button to assign it to this action" NL "or Esc to cancel..." ); -} - -//------------------------------------------------------------------------------ -function RemapDlg::onSleep( %this ) -{ - $enableDirectInput = "1"; - deactivateDirectInput(); -} - -//------------------------------------------------------------------------------ -function findRemapCmdIndex( %command ) -{ - switch$ ( OP_ControlsPane.group ) - { - case "Observer": - for ( %i = 0; %i < $ObsRemapCount; %i++ ) - { - if ( %command $= $ObsRemapCmd[%i] ) - return( %i ); - } - case "RTS": - for ( %i = 0; %i < $RTSRemapCount; %i++ ) - { - if ( %command $= $RTSRemapCmd[%i] ) - return( %i ); - } - default: - for ( %i = 0; %i < $RemapCount; %i++ ) - { - if ( %command $= $RemapCmd[%i] ) - return( %i ); - } - } - - return( -1 ); -} - -//------------------------------------------------------------------------------ -function clearMapping( %actionMap, %cmd ) -{ - %fullMapString = %actionMap.getBinding( %cmd ); - %mapCount = getRecordCount( %fullMapString ); - for ( %i = 0; %i < %mapCount; %i++ ) - { - %temp = getRecord( %fullMapString, %i ); - %actionMap.unbind( getField( %temp, 0 ), getField( %temp, 1 ) ); - } -} - -//------------------------------------------------------------------------------ -function redoMapping( %actionMap, %device, %action, %cmd, %oldIndex, %newIndex ) -{ - //%actionMap.bind( %device, %action, $RemapCmd[%newIndex] ); - %actionMap.bind( %device, %action, %cmd ); - OP_RemapList.setRowById( %oldIndex, buildFullMapString( %oldIndex ) ); - OP_RemapList.setRowById( %newIndex, buildFullMapString( %newIndex ) ); -} - -//------------------------------------------------------------------------------ -function redoConsoleMapping( %action, %oldIndex ) -{ - moveMap.unbind( "keyboard", %action ); - GlobalActionMap.bind( "keyboard", %action, "toggleConsole" ); - OP_ConsoleKeyBtn.setValue( %action ); - OP_RemapList.setRowById( %oldIndex, buildFullMapString( %oldIndex ) ); -} - -//------------------------------------------------------------------------------ -function RemapInputCtrl::onInputEvent( %this, %device, %action ) -{ - //error( "** onInputEvent called - device = " @ %device @ ", action = " @ %action @ " **" ); - Canvas.popDialog( RemapDlg ); - - // Test for the reserved keystrokes: - if ( %device $= "keyboard" ) - { - // Cancel... - if ( %action $= "escape" ) - { - // Do nothing... - return; - } - } - - if ( %this.mode $= "consoleKey" ) - { - if ( %device !$= "keyboard" ) - { - MessageBoxOK( "REMAP FAILED", "This command can only be bound to keys on the keyboard!" ); - return; - } - - %prevMap = GlobalActionMap.getCommand( %device, %action ); - if ( %prevMap !$= "" ) - { - MessageBoxOK( "REMAP FAILED", "\"" @ getMapDisplayName( %device, %action ) @ "\" is already bound to a non-remappable command!" ); - return; - } - - %mvMap = moveMap.getCommand( %device, %action ); - if ( %mvMap $= "" ) - { - GlobalActionMap.bind( %device, %action, "toggleConsole" ); - OP_ConsoleKeyBtn.setValue( %action ); - } - else - { - %mapName = getMapDisplayName( %device, %action ); - %mvMapIndex = findRemapCmdIndex( %mvMap ); - if ( %mvMapIndex == -1 ) - MessageBoxOK( "REMAP FAILED", "\"" @ %mapName @ "\" is already bound to a non-remappable command!" ); - else - MessageBoxYesNo( "WARNING", "\"" @ %mapName @ "\" is already bound to \"" - @ $RemapName[%mvMapIndex] @ "\"!" - NL "Do you want to undo this mapping?", - "redoConsoleMapping(\"" @ %action @ "\", " @ %mvMapIndex @ ");", "" ); - return; - } - } - else - { - switch$ ( OP_ControlsPane.group ) - { - case "Observer": - %actionMap = observerMap; - %cmd = $ObsRemapCmd[%this.index]; - %name = $ObsRemapName[%this.index]; - - case "RTS": - %actionMap = RTSMap; - %cmd = $RTSRemapCmd[%this.index]; - %name = $RTSRemapName[%this.index]; - - default: - %actionMap = moveMap; - %cmd = $RemapCmd[%this.index]; - %name = $RemapName[%this.index]; - } - - // First check to see if the given action is already mapped: - %prevMap = %actionMap.getCommand( %device, %action ); - if ( %prevMap !$= %cmd ) - { - if ( %prevMap $= "" ) - { - %actionMap.bind( %device, %action, %cmd ); - OP_RemapList.setRowById( %this.index, buildFullMapString( %this.index ) ); - } - else - { - %mapName = getMapDisplayName( %device, %action ); - %prevMapIndex = findRemapCmdIndex( %prevMap ); - if ( %prevMapIndex == -1 ) - MessageBoxOK( "REMAP FAILED", "\"" @ %mapName @ "\" is already bound to a non-remappable command!" ); - else - { - switch$ ( OP_ControlsPane.group ) - { - case "Observer": - %prevCmdName = $ObsRemapName[%prevMapIndex]; - case "RTS": - %prevCmdName = $RTSRemapName[%prevMapIndex]; - default: - %prevCmdName = $RemapName[%prevMapIndex]; - } - - MessageBoxYesNo( "WARNING", - "\"" @ %mapName @ "\" is already bound to \"" - @ %prevCmdName @ "\"!\nDo you want to undo this mapping?", - "redoMapping(" @ %actionMap @ ", " @ %device @ ", \"" @ %action @ "\", \"" @ %cmd @ "\", " @ %prevMapIndex @ ", " @ %this.index @ ");", "" ); - } - return; - } - } - } -} - -//------------------------------------------------------------------------------ -function OP_JoystickTgl::onAction( %this ) -{ - %on = %this.getValue(); - if ( %on ) - enableJoystick(); - else - disableJoystick(); - - OP_ConfigureJoystickBtn.setActive( %on ); -} - -//------------------------------------------------------------------------------ -function MouseConfigDlg::onWake( %this ) -{ - MouseXSlider.setValue( moveMap.getScale( mouse, xaxis ) / 2 ); - MouseYSlider.setValue( moveMap.getScale( mouse, yaxis ) / 2 ); - InvertMouseTgl.setValue( moveMap.isInverted( mouse, yaxis ) ); - - MouseZActionMenu.clear(); - MouseZActionMenu.add( "Nothing", 1 ); - MouseZActionMenu.add( "Cycle Weapon", 2 ); - MouseZActionMenu.add( "Next Weapon Only", 3 ); -// MouseZActionMenu.add( "Cycle Zoom Level", 4 ); - - %bind = moveMap.getCommand( "mouse", "zaxis" ); - %selId = 1; - switch$ ( %bind ) - { - case "cycleWeaponAxis": - %selId = 2; - case "cycleNextWeaponOnly": - %selId = 3; - } - MouseZActionMenu.setSelected( %selId ); -} - -//------------------------------------------------------------------------------ -function MouseConfigDlg::onOK( %this ) -{ - %xSens = MouseXSlider.getValue() * 2; - %ySens = MouseYSlider.getValue() * 2; - moveMap.bind( mouse, xaxis, "S", %xSens, "yaw" ); - %yFlags = InvertMouseTgl.getValue() ? "SI" : "S"; - moveMap.bind( mouse, yaxis, %yFlags, %ySens, "pitch" ); - - switch ( MouseZActionMenu.getSelected() ) - { - case 2: - moveMap.bind( mouse, zaxis, cycleWeaponAxis ); - case 3: - moveMap.bind( mouse, zaxis, cycleNextWeaponOnly ); - default: - moveMap.unbind( mouse, zaxis ); - } - - Canvas.popDialog( MouseConfigDlg ); -} - -//------------------------------------------------------------------------------ -function MouseXSlider::sync( %this ) -{ - %thisValue = %this.getValue(); - MouseXText.setValue( "(" @ getSubStr( %thisValue, 0, 4 ) @ ")" ); - if ( $pref::Input::LinkMouseSensitivity ) - { - if ( MouseYSlider.getValue() != %thisValue ) - MouseYSlider.setValue( %thisValue ); - } -} - -//------------------------------------------------------------------------------ -function MouseYSlider::sync( %this ) -{ - %thisValue = %this.getValue(); - MouseYText.setValue( "(" @ getSubStr( %thisValue, 0, 4 ) @ ")" ); - if ( $pref::Input::LinkMouseSensitivity ) - { - if ( MouseXSlider.getValue() != %thisValue ) - MouseXSlider.setValue( %thisValue ); - } -} - -//------------------------------------------------------------------------------ -// Joystick Config dialog: -//------------------------------------------------------------------------------ -$JoyRemapCount = 0; -$JoyRemapName[$JoyRemapCount] = "Look Up/Down"; -$JoyRemapCmd[$JoyRemapCount] = "joyPitch"; -$JoyRemapCount++; -$JoyRemapName[$JoyRemapCount] = "Turn Left/Right"; -$JoyRemapCmd[$JoyRemapCount] = "joyYaw"; -$JoyRemapCount++; -$JoyRemapName[$JoyRemapCount] = "Move Forward/Backward"; -$JoyRemapCmd[$JoyRemapCount] = "joystickMoveY"; -$JoyRemapCount++; -$JoyRemapName[$JoyRemapCount] = "Strafe Left/Right"; -$JoyRemapCmd[$JoyRemapCount] = "joystickMoveX"; -$JoyRemapCount++; -$JoyRemapName[$JoyRemapCount] = "Cycle Weapon"; -$JoyRemapCmd[$JoyRemapCount] = "cycleWeaponAxis"; -$JoyRemapCount++; - -//------------------------------------------------------------------------------ -function JoystickConfigDlg::onWake( %this ) -{ - // Add all of the axis tabs: - %temp = getJoystickAxes( 0 ); - %tryCount = getField( %temp, 0 ); - $JoyAxisCount = 0; - - for ( %i = 0; %i < %tryCount; %i++ ) - { - %type = getField( %temp, %i + 1 ); - switch$ ( %type ) - { - case "X": %tabName = "X Axis"; %tabType = "xaxis"; - case "Y": %tabName = "Y Axis"; %tabType = "yaxis"; - case "Z": %tabName = "Z Axis"; %tabType = "zaxis"; - case "R": %tabName = "R Axis"; %tabType = "rxaxis"; - case "U": %tabName = "U Axis"; %tabType = "ryaxis"; - case "V": %tabName = "V Axis"; %tabType = "rzaxis"; - case "S": %tabName = "Slider"; %tabType = "slider"; - case "L": %tabName = "Slider 2"; %tabType = "slider2"; - default: %tabName = ""; - } - - if ( %tabName !$= "" ) - { - $JoyAxisTab[$JoyAxisCount] = new ShellTabButton() { - profile = "ShellTabProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "29" SPC ( 52 + ( %i * 30 ) ); - extent = "100 38"; - minExtent = "48 38"; - visible = "1"; - command = "JoystickConfigDlg.setPane(" @ %i @ ");"; - helpTag = "0"; - text = %tabName; - type = %tabType; - }; - - $JoyAxisCount++; - JoystickConfigFrame.add( $JoyAxisTab[%i] ); - } - } - - // Fill the action menu: - JoyAxisActionMenu.clear(); - for ( %i = 0; %i < $JoyRemapCount; %i++ ) - JoyAxisActionMenu.add( $JoyRemapName[%i], %i ); - JoyAxisActionMenu.add( "Nothing", 255 ); - - // Select the first axis: - %this.setPane( %this.pane ); -} - -//------------------------------------------------------------------------------ -function JoystickConfigDlg::onSleep( %this ) -{ - // Save the current pane's settings: - bindJoystickAxis( %this.pane, JoyAxisActionMenu.getSelected() ); - for ( %i = 0; %i < $JoyAxisCount; %i++ ) - { - JoystickConfigFrame.remove( $JoyAxisTab[%i] ); - $JoyAxisTab[%i].delete(); - } -} - -//------------------------------------------------------------------------------ -function JoystickConfigDlg::setPane( %this, %pane ) -{ - if ( %this.pane != %pane ) - { - // Save the previous axes' settings: - bindJoystickAxis( %this.pane, JoyAxisActionMenu.getSelected() ); - %this.pane = %pane; - } - - for ( %i = 0; %i < $joyAxisCount; %i++ ) - $JoyAxisTab[%i].setValue( %i == %pane ); - - // Update the config controls: - %axisType = $JoyAxisTab[%pane].type; - %bind = moveMap.getCommand( "joystick", %axisType ); - if ( %bind !$= "" ) - { - for ( %i = 0; %i < $JoyRemapCount; %i++ ) - { - if ( $JoyRemapCmd[%i] $= %bind ) - { - JoyAxisActionMenu.setSelected( %i ); - JoyAxisActionMenu.setText( $JoyRemapName[%i] ); - JoyAxisActionMenu.onSelect( %i, "" ); - break; - } - } - - if ( %i == $JoyRemapCount ) - { - JoyAxisActionMenu.setSelected( 255 ); // 255 is the code for "Nothing" - JoyAxisActionMenu.onSelect( 255, "" ); - } - - %scale = moveMap.getScale( "joystick", %axisType ); - JoyAxisSlider.setValue( %scale / 100 ); - %deadZone = moveMap.getDeadZone( "joystick", %axisType ); - if ( %deadZone $= "0 0" ) - DeadZoneSlider.setValue( 0.0 ); - else - DeadZoneSlider.setValue( abs( firstWord( %deadZone ) ) / %scale ); - InvertJoyAxisTgl.setValue( moveMap.isInverted( "joystick", %axisType ) ); - //JoyAxisRelativeTgl.setValue( moveMap.isRelativeAxis( "joystick", %axisType ) ); - } - else - { - JoyAxisActionMenu.setSelected( 255 ); // 255 is the code for "Nothing" - JoyAxisActionMenu.onSelect( 255, "" ); - JoyAxisSlider.setValue( 0.5 ); - DeadZoneSlider.setValue( 0.0 ); - InvertJoyAxisTgl.setValue( false ); - //JoyAxisRelativeTgl.setValue( %axisType $= "slider" ); - } -} - -//------------------------------------------------------------------------------ -function JoyAxisActionMenu::onSelect( %this, %id, %text ) -{ - %on = ( %id < $JoyRemapCount ); - JoyAxisSlider.setActive( %on ); - JoySensText.setVisible( %on ); - DeadZoneSlider.setActive( %on ); - DeadZoneText.setVisible( %on ); - InvertJoyAxisTgl.setActive( %on ); - //JoyAxisRelativeTgl.setActive( %on ); -} - -//------------------------------------------------------------------------------ -function JoySensText::update( %this ) -{ - %this.setValue( "(" @ getSubStr( JoyAxisSlider.getValue(), 0, 4 ) @ ")" ); -} - -//------------------------------------------------------------------------------ -function DeadZoneText::update( %this ) -{ - %val = DeadZoneSlider.getValue(); - %percent = %val * 100; - %temp = strstr( %percent, "." ); - if ( %temp != -1 ) - %percent = getSubStr( %percent, 0, %temp ); - - %this.setValue( "(" @ %percent @ "%)" ); -} - -//------------------------------------------------------------------------------ -function bindJoystickAxis( %axisIndex, %cmdIndex ) -{ - %cmd = $JoyRemapCmd[%cmdIndex]; - %axis = $JoyAxisTab[%axisIndex].type; - if ( %cmdIndex > $JoyRemapCount ) - { - // Make sure the axis is unbound: - moveMap.unbind( "joystick", %axis ); - return; - } - - %sens = JoyAxisSlider.getValue() * 100; - %delta = DeadZoneSlider.getValue() * %sens; - %flags = "S"; - if ( InvertJoyAxisTgl.getValue() ) - %flags = %flags @ "I"; -// if ( JoyAxisRelativeTgl.getValue() ) -// %flags = %flags @ "L"; - if ( %delta > 0 ) - { - %deadZone = "-" @ %delta SPC %delta; - moveMap.bind( "joystick", %axis, %flags @ "D", %deadZone, %sens, %cmd ); - } - else - moveMap.bind( "joystick", %axis, %flags, %sens, %cmd ); -} - -//------------------------------------------------------------------------------ -//------------------------------------------------------------------------------ -// Network Settings: -// - -function updateNetworkSettings() -{ - $pref::Net::PacketRateToClient = mFloor( OP_PacketRateSlider.getValue() ); - $pref::Net::PacketSize = mFloor( OP_PacketSizeSlider.getValue() ); - $pref::Net::PacketRateToServer = mFloor( OP_UpdateRateSlider.getValue() ); - - // check the max rate: - if ( isObject( ServerConnection ) ) - ServerConnection.checkMaxRate(); - if ( isObject( ClientGroup ) ) - { - %count = ClientGroup.getCount(); - for ( %i = 0; %i < %count; %i++ ) - { - %cl = ClientGroup.getObject( %i ); - %cl.checkMaxRate(); - } - } -} - -function OP_NetworkDisplayHud::init(%this) -{ - %this.getPrefs(); - - %this.textHeight = 14; - %this.textOffset = 2; - - if(!%this.infoCallback) - { - %this.textProfile = 0; - return; - } - - // profile for the text fields - %this.textProfile = new GuiControlProfile() - { - fontType = $ShellButtonFont; - fontSize = $ShellButtonFontSize; - autoSizeWidth = true; - autoSizeHeight = true; - fontColors[6] = "128 128 128"; - }; - - %yOffset = %this.textOffset; - - for(%i = 0; %i < 6; %i++) - { - // set the text color - %this.textProfile.fontColors[%i] = %this.fieldColors[%i]; - - // create the text field - %this.textField[%i] = new GuiTextCtrl() - { - profile = %this.textProfile; - horizSizing = "right"; - vertSizing = "bottom"; - position = "20 " @ %yOffset; - extent = "190 " @ %this.textHeight; - visible = "1"; - }; - - // create the toggle field - %this.toggleField[%i] = new GuiTextCtrl() - { - profile = ShellActiveTextProfile; - horizSizing = "right"; - vertSizing = "bottom"; - position = "5 " @ %yOffset; - extent = "15 " @ %this.textHeight; - visible = "1"; - }; - - // create a mouse object - %this.mouseField[%i] = new GuiMouseEventCtrl(NetworkDisplayMouseCtrl) - { - profile = GuiDefaultProfile; - horizSizing = "right"; - vertSizing = "bottom"; - position = "10 " @ %yOffset; - extent = "200 " @ %this.textHeight; - visible = "1"; - fieldIndex = %i; - }; - - OP_NetworkDisplayTextFrame.add(%this.textField[%i]); - OP_NetworkDisplayTextFrame.add(%this.toggleField[%i]); - OP_NetworkDisplayTextFrame.add(%this.mouseField[%i]); - - %yOffset += (%this.textHeight + %this.textOffset); - } - %this.infoUpdate(0, 0, 0, 0, 0, 0); -} - -function NetworkDisplayMouseCtrl::onMouseDown(%this) -{ - %b = OP_NetworkDisplayHud.renderField[%this.fieldIndex]; - OP_NetworkDisplayHud.renderField[%this.fieldIndex] = !%b; - OP_NetworkDisplayHud.updateToggles(); -} - -function OP_NetworkDisplayHud::uninit(%this) -{ - if(!%this.infoCallback) - return; - - if(isObject(%this.textProfile)) - %this.textProfile.delete(); - - for(%i = 0; %i < 6; %i++) - { - if(isObject(%this.textField[%i])) - %this.textField[%i].delete(); - - if(isObject(%this.toggleField[%i])) - %this.toggleField[%i].delete(); - - if(isObject(%this.mouseField[%i])) - %this.mouseField[%i].delete(); - } -} - -function OP_NetworkDisplayHud::updateToggles(%this) -{ - // update the toggles - $pref::Net::graphFields = 0; - - for(%i = 0; %i < 6; %i++) - { - $pref::Net::graphFields |= %this.renderField[%i] << %i; - %this.toggleField[%i].setText(%this.renderField[%i] ? "+" : "-"); - } -} - -function OP_NetworkDisplayHud::infoUpdate(%this, %ping, %packetLoss, %sendPackets, %sendBytes, %receivePackets, %receiveBytes) -{ - %this.updateToggles(); - - // set the text - %this.textField[0].setText("\c0Ping: " @ mFormatFloat(%ping, "%4.0f") @ "ms"); - %this.textField[1].setText("\c1Packet Loss: " @ mFormatFloat(%packetLoss, "%3.0f") @ "%"); - %this.textField[2].setText("\c2Send Packets: " @ mFormatFloat(%sendPackets, "%2.1f") @ "pps"); - %this.textField[3].setText("\c3Send Bytes: " @ mFormatFloat(%sendBytes, "%5.0f") @ "bps"); - %this.textField[4].setText("\c4Receive Packets: " @ mFormatFloat(%receivePackets, "%2.1f") @ "pps"); - %this.textField[5].setText("\c5Receive Bytes: " @ mFormatFloat(%receiveBytes, "%5.0f") @ "bps"); -} - -// "" -// [1,32] [8,32] [100,450] -$NetworkPresetCount = 0; -$NetworkPreset[$NetworkPresetCount] = "28.8 Modem\t12\t16\t200"; $NetworkPresetCount++; -$NetworkPreset[$NetworkPresetCount] = "56K Modem\t16\t20\t240"; $NetworkPresetCount++; -$NetworkPreset[$NetworkPresetCount] = "DSL\t20\t24\t350"; $NetworkPresetCount++; -$NetworkPreset[$NetworkPresetCount] = "Cable\t24\t24\t400"; $NetworkPresetCount++; -$NetworkPreset[$NetworkPresetCount] = "T1/LAN\t32\t32\t450"; $NetworkPresetCount++; - -function OP_NetworkPresetsMenu::init( %this ) -{ - %this.clear(); - for(%i = 0; %i < $NetworkPresetCount; %i++) - %this.add( getField($NetworkPreset[%i], 0), %i); - - // don't update settings on init (only update when values change) - %this.updateSettings = false; - %this.setSelected($pref::Net::Preset); - %this.updateSettings = true; -} - -function OP_NetworkPresetsMenu::onSelect( %this, %id, %text ) -{ - OP_PacketRateSlider.setValue( getField($NetworkPreset[%id], 1) ); - OP_UpdateRateSlider.setValue( getField($NetworkPreset[%id], 2) ); - OP_PacketSizeSlider.setValue( getField($NetworkPreset[%id], 3) ); - - if(%this.updateSettings) - updateNetworkSettings(); - $pref::Net::Preset = %id; -} - -//------------------------------------------------------------------------------ -function OP_MasterServerMenu::init( %this ) -{ - %this.clear(); - // You can change these strings, but NOT THE IDS! - %this.add( "Always", 1 ); - %this.add( "When Not Full", 2 ); - %this.add( "Never", 3 ); -} - -//------------------------------------------------------------------------------ -function OP_MasterServerMenu::onSelect( %this, %id, %text ) -{ - switch( %id ) - { - case 2: - $pref::Net::DisplayOnMaster = "NotFull"; - case 3: - $pref::Net::DisplayOnMaster = "Never"; - default: - $pref::Net::DisplayOnMaster = "Always"; - } -} - -//------------------------------------------------------------------------------ -function OP_RegionMenu::init( %this ) -{ - %this.clear(); - %this.add( "North America East", 1 ); - %this.add( "North America West", 2 ); - %this.add( "South America", 4 ); - %this.add( "Australia", 8 ); - %this.add( "Asia", 16 ); - %this.add( "Europe", 32 ); -} - -//------------------------------------------------------------------------------ -function OP_RegionMenu::onSelect( %this, %id, %text ) -{ - $pref::Net::RegionMask = %id; -} - -//------------------------------------------------------------------------------ -//------------------------------------------------------------------------------ -// Game Settings: -// -function OP_LaunchScreenMenu::init( %this ) -{ - %this.clear(); - %this.add( "Game", 1 ); - %this.add( "Email", 4 ); - %this.add( "Chat", 5 ); - %this.add( "Browser", 6 ); - %this.add( "Mod Browser", 7 ); -} - -//------------------------------------------------------------------------------ -function toggleInvertYAxis() -{ - // Catch the case where this is toggled in-game while in a vehicle: - if ( isObject( passengerKeys ) ) - { - %bind = passengerKeys.getBinding( pitch ); - if ( %bind !$= "" ) - { - %device = getField( %bind, 0 ); - %action = getField( %bind, 1 ); - %flags = $pref::Vehicle::InvertYAxis ? "SDI" : "SD"; - %deadZone = passengerKeys.getDeadZone( %device, %action ); - %scale = passengerKeys.getScale( %device, %action ); - passengerKeys.bind( %device, %action, %flags, %deadZone, %scale, pitch ); - } - } -} - -//------------------------------------------------------------------------------ -function toggleImmersion() -{ - MessageBoxOK( "Force Feedback", "This will take effect the next time you start Tribes 2." ); -} - -//------------------------------------------------------------------------------ -function toggleVehicleTeleportPref() -{ - // If we are in a game, let the server know we've changed; - if ( isObject( ServerConnection ) ) - commandToServer( 'EnableVehicleTeleport', $pref::Vehicle::pilotTeleport ); -} +//------------------------------------------------------------------------------ +// +// OptionsDlg.cs +// +//------------------------------------------------------------------------------ +$max_screenerror = 25; +$min_TSScreenError = 2; +$max_TSScreenError = 20; +$min_TSDetailAdjust = 0.6; +$max_TSDetailAdjust = 1.0; +//------------------------------------------------------------------------------ +function OptionsDlg::onWake( %this ) +{ + OP_VideoPane.setVisible( false ); + OP_GraphicsPane.setVisible( false ); + OP_TexturesPane.setVisible( false ); + OP_SoundPane.setVisible( false ); + OP_VoicePane.setVisible( false ); + OP_ControlsPane.setVisible( false ); + OP_NetworkPane.setVisible( false ); + OP_GamePane.setVisible( false ); + + OP_VideoTab.setValue( false ); + OP_GraphicsTab.setValue( false ); + OP_TexturesTab.setValue( false ); + OP_SoundTab.setValue( false ); + OP_VoiceTab.setValue( false ); + OP_ControlsTab.setValue( false ); + OP_NetworkTab.setValue( false ); + OP_GameTab.setValue( false ); + + // Initialize the Video Pane controls: + // First the Video Driver menu: + %buffer = getDisplayDeviceList(); + %count = getFieldCount( %buffer ); + for ( %i = 0; %i < %count; %i++ ) + OP_VideoDriverMenu.add( getField( %buffer, %i ), %i ); + + // Select the current device: + OP_FullScreenTgl.setValue( $pref::Video::fullScreen ); + + %selId = OP_VideoDriverMenu.findText( $pref::Video::displayDevice ); + if ( %selId == -1 ) + %selId = 0; // How did THAT happen? + OP_VideoDriverMenu.setSelected( %selId ); + OP_VideoDriverMenu.onSelect( %selId, "" ); + OP_FullScreenTgl.onAction(); + + OP_ApplyBtn.setActive( false ); + + // Initialize the Graphics Options controls: + OptionsDlg::deviceDependent( %this ); + + // Radeon cards don't switch color depth good until they release their beta drivers which fix this problem. + if( $RadeonRenderer == true ) + OP_BPPMenu.setActive( false ); + + OP_GammaSlider.setValue( $pref::OpenGL::gammaCorrection ); + OP_GammaSlider.setActive( $Video::setGammaCorrectionSupported ); + + OP_TerrainSlider.setValue( $max_screenerror - $pref::Terrain::screenError ); + OP_ShapeSlider.setValue( ( $max_TSScreenError - $pref::TS::screenError ) / ( $max_TSScreenError - $min_TSScreenError ) ); + OP_ShadowSlider.setValue( $pref::Shadows ); + OP_InteriorDetailSlider.setValue( $pref::Interior::detailAdjust ); + OP_VisibleDistanceSlider.setValue( $pref::VisibleDistanceMod ); + OP_ParticleDensitySlider.setValue( 4.0 - $pref::ParticleDensity ); + OP_DynamicLightSlider.setValue( 100 - $pref::Interior::DynamicLightsClipPix ); + updateDynamicLightSliderState(); + OP_SkyDetailMenu.init(); + if ( !$pref::SkyOn ) + %selId = 5; + else if ( $pref::numCloudLayers >= 0 && $pref::numCloudLayers < 4 ) + %selId = 4 - $pref::numCloudLayers; + else + %selId = 1; + OP_SkyDetailMenu.setSelected( %selId ); + OP_SkyDetailMenu.setText( OP_SkyDetailMenu.getTextById( %selId ) ); + OP_PlayerRenderMenu.init(); + %selId = $pref::Player::renderMyPlayer | ( $pref::Player::renderMyItems << 1 ); + OP_PlayerRenderMenu.setSelected( %selId ); + OP_VertexLightTgl.setValue( $pref::Interior::VertexLighting ); + + // Initialize the Textures Options controls: + OP_TerrainTexSlider.setValue( 6 - $pref::Terrain::texDetail ); + + // We're using the noDrawArraysAlpha variable here because we've already + // gone gold (hard to add a new profiling variable). But the Voodoo2/3/3500 + // cards that have the 256x256 texture limitation (in OpenGL) also have the + // noDrawArraysAlpha hack on...so that works out nice + %mipRange = $pref::OpenGL::noDrawArraysAlpha ? 4.0 : 5.0; + OP_ShapeTexSlider.setValue( (5 - $pref::OpenGL::mipReduction) / %mipRange ); + OP_BuildingTexSlider.setValue( (5 - $pref::OpenGL::interiorMipReduction) / %mipRange ); + OP_SkyTexSlider.setValue( (5 - $pref::OpenGL::skyMipReduction) / %mipRange ); + if ( !isDemo() ) + OP_HiResSkinTgl.setValue( $pref::use512PlayerSkins ); + + // Initialize the Sound Options controls: + // provider menu + %count = alxGetContexti(ALC_PROVIDER_COUNT); + for(%i = 0; %i < %count; %i++) + OP_AudioProviderMenu.add(alxGetContextstr(ALC_PROVIDER_NAME, %i), %i); + %selId = alxGetContexti(ALC_PROVIDER); + OP_AudioProviderMenu.setSelected(%selId); + OP_AudioResetProvider.setActive(false); + + // environment provider: disable and uncheck if not an environment provider + %envProvider = audioIsEnvironmentProvider(alxGetContextstr(ALC_PROVIDER_NAME, %selId)); + + if(!%envProvider) + OP_AudioEnvironmentTgl.setValue(false); + OP_AudioEnvironmentTgl.setActive(%envProvider); + + // speaker menu + %count = alxGetContexti(ALC_SPEAKER_COUNT); + for(%i = 0; %i < %count; %i++) + OP_AudioSpeakerMenu.add(alxGetContextstr(ALC_SPEAKER_NAME, %i), %i); + %selId = alxGetContexti(ALC_SPEAKER); + OP_AudioSpeakerMenu.setSelected(%selId); + OP_AudioSpeakerMenu.onSelect(%selId, ""); + + OP_AudioFrequencyMenu.init(); + OP_AudioBitRateMenu.init(); + OP_AudioChannelsMenu.init(); + + // don't allow changing of of mixer settings while in a game... + %active = !isObject(ServerConnection); + OP_AudioFrequencyMenu.setActive(%active); + // Changing these audio settings doesn't help Linux performance + if ( $platform $= "linux" ) + { + OP_AudioBitRateMenu.setActive(false); + OP_AudioChannelsMenu.setActive(false); + } + else + { + OP_AudioBitRateMenu.setActive(%active); + OP_AudioChannelsMenu.setActive(%active); + } + + // only allow for disable + if(!%active) + OP_AudioEnvironmentTgl.setActive(%active); + + OP_AudioProviderMenu.setActive(%active); + OP_AudioSpeakerMenu.setActive(%active); + + OP_MasterVolumeSlider.setValue( $pref::Audio::masterVolume ); + OP_EffectsVolumeSlider.setValue( $pref::Audio::effectsVolume ); + OP_VoiceBindVolumeSlider.setValue( $pref::Audio::radioVolume ); + OP_GuiVolumeSlider.setValue( $pref::Audio::guiVolume ); + OP_MusicTgl.onAction(); + OP_MusicVolumeSlider.setValue( $pref::Audio::musicVolume ); + + // Initialize the Voice Settings controls: + OP_MicrophoneEnabledTgl.onAction(); + OP_MicrophoneVolumeSlider.setValue( $pref::Audio::voiceVolume ); + OP_InputBoostSlider.setValue( $pref::Audio::captureGainScale ); + OP_VoiceListenMenu.init(); + OP_VoiceSendMenu.init(); + OP_VoiceCodecInfo.init(); + updateInputBoost(); + + // Initialize the Control Options controls: + OP_ControlGroupMenu.init(); + + if ( isJoystickDetected() ) + { + OP_JoystickTgl.setValue( $pref::Input::JoystickEnabled ); + OP_JoystickTgl.setActive( true ); + OP_ConfigureJoystickBtn.setActive( $pref::Input::JoystickEnabled ); + } + else + { + OP_JoystickTgl.setValue( false ); + OP_JoystickTgl.setActive( false ); + $pref::Input::JoystickEnabled = false; + OP_ConfigureJoystickBtn.setActive( false ); + } + + // Initialize the Network Options controls: + OP_NetworkDisplayHud.init(); + if( !OP_NetworkPresetsMenu.size() ) + OP_NetworkPresetsMenu.init(); + OP_PacketRateSlider.setValue( $pref::Net::PacketRateToClient ); + OP_PacketSizeSlider.setValue( $pref::Net::PacketSize ); + OP_UpdateRateSlider.setValue( $pref::Net::PacketRateToServer ); + if ( !OP_MasterServerMenu.size() ) + OP_MasterServerMenu.init(); + %selId = OP_MasterServerMenu.findText( $pref::Net::DisplayOnMaster ); + if ( %selId == -1 ) + %selId = 1; + OP_MasterServerMenu.setSelected( %selId ); + if ( !OP_RegionMenu.size() ) + OP_RegionMenu.init(); + OP_RegionMenu.setSelected( $pref::Net::RegionMask ); + + // Initialize the Game Options controls: + OP_ZoomSpeedSlider.setValue( 500 - $pref::Player::zoomSpeed ); + OP_LaunchScreenMenu.init(); + + %selId = OP_LaunchScreenMenu.findText( $pref::Shell::LaunchGui ); + if ( %selId == -1 ) + %selId = 1; + OP_LaunchScreenMenu.setText( OP_LaunchScreenMenu.getTextById( %selId ) ); + OP_LaunchScreenMenu.setSelected( %selId ); + + // Hide controls that are not relevant to the demo: + if ( isDemo() ) + { + OP_MasterServerTxt.setVisible( false ); + OP_MasterServerMenu.setVisible( false ); + OP_CheckEmailTgl.setVisible( false ); + OP_ChatDisconnectTgl.setVisible( false ); + OP_EditChatMenuBtn.setVisible( false ); + OP_LaunchScreenTxt.setVisible( false ); + OP_LaunchScreenMenu.setVisible( false ); + } + + %this.setPane( %this.pane ); +} + +//------------------------------------------------------------------------------ +function OptionsDlg::deviceDependent( %this ) +{ + if ( $SwapIntervalSupported ) + { + OP_VSyncTgl.setValue( $pref::Video::disableVerticalSync ); + OP_VSyncTgl.setActive( true ); + } + else + { + OP_VSyncTgl.setValue( false ); + OP_VSyncTgl.setActive( false ); + } + + if ( isDemo() ) + { + OP_TexQualityMenu.setText( "Palletized" ); + OP_TexQualityMenu.setActive( false ); + } + else + { + OP_TexQualityMenu.init(); + if ( $pref::OpenGL::forcePalettedTexture ) + { + $pref::OpenGL::force16bittexture = false; + %selId = 1; + } + else if ( $pref::OpenGL::force16bittexture ) + %selId = 2; + else + %selId = 3; + OP_TexQualityMenu.setSelected( %selId ); + } + + OP_CompressMenu.init(); + if ( $TextureCompressionSupported && !$pref::OpenGL::disableARBTextureCompression ) + { + OP_CompressLabel.setVisible( true ); + OP_CompressLabel_Disabled.setVisible( false ); + OP_CompressMenu.setActive( true ); + if ( !$pref::OpenGL::allowCompression ) + OP_CompressMenu.setSelected( 1 ); + else if ( $pref::OpenGL::compressionHint $= "GL_NICEST" ) + OP_CompressMenu.setSelected( 3 ); + else + OP_CompressMenu.setSelected( 2 ); + } + else + { + OP_CompressLabel_Disabled.setVisible( true ); + OP_CompressLabel.setVisible( false ); + OP_CompressMenu.setActive( false ); + OP_CompressMenu.setText( "None" ); + } + + if ( $FogCoordSupported ) + { + OP_IntTexturedFogTgl.setValue( $pref::Interior::TexturedFog ); + OP_IntTexturedFogTgl.setActive( true ); + } + else + { + OP_IntTexturedFogTgl.setValue( true ); + OP_IntTexturedFogTgl.setActive( false ); + } + + OP_AnisotropySlider.setValue( $pref::OpenGL::anisotropy ); + OP_AnisotropySlider.setActive( $AnisotropySupported ); + if ( $AnisotropySupported ) + { + OP_AnisotropyLabel.setVisible( true ); + OP_AnisotropyLabel_Disabled.setVisible( false ); + } + else + { + OP_AnisotropyLabel_Disabled.setVisible( true ); + OP_AnisotropyLabel.setVisible( false ); + } + + OP_EnvMapTgl.setValue($pref::environmentMaps); + OP_EnvMapTgl.setActive($pref::OpenGL::allowTexGen); +} + +//------------------------------------------------------------------------------ +function OptionsDlg::onSleep( %this ) +{ + OP_VideoDriverMenu.clear(); + OP_ResMenu.clear(); + OP_BPPMenu.clear(); + OP_AudioProviderMenu.clear(); + OP_AudioSpeakerMenu.clear(); + OP_NetworkDisplayHud.uninit(); + + if ( %this.resetAudio ) + { + echo( "Resetting the audio driver..." ); + audioSetDriver( "none" ); + audioSetDriver( $pref::Audio::activeDriver ); + %this.resetAudio = ""; + + // Play the shell hum: (all sources are gone) + if($HudHandle[shellScreen] $= "") + alxStop($HudHandle[shellScreen]); + + $HudHandle[shellScreen] = alxPlay(ShellScreenHumSound, 0, 0, 0); + } + + if ( isObject( ServerConnection ) && isTextureFlushRequired() ) + MessageBoxYesNo( "WARNING", "You have made changes that require Tribes 2 to flush the texture cache. " + @ "Doing this while the game is running can take a long time. " + @ "Do you wish to continue?", + "OptionsDlg.saveSettings();", "returnFromSettings();" ); + else + %this.saveSettings(); +} + +//------------------------------------------------------------------------------ +function isTextureFlushRequired() +{ + if ( $pref::Interior::VertexLighting != OP_VertexLightTgl.getValue() ) + return( true ); + + // We're using the noDrawArraysAlpha variable here because we've already + // gone gold (hard to add a new profiling variable). But the Voodoo2/3/3500 + // cards that have the 256x256 texture limitation (in OpenGL) also have the + // noDrawArraysAlpha hack on...so that works out nice + %mipRange = $pref::OpenGL::noDrawArraysAlpha ? 4 : 5; + if ( $pref::OpenGL::mipReduction != 5 - mFloor( OP_ShapeTexSlider.getValue() * %mipRange ) ) + return( true ); + + if ( $pref::OpenGL::interiorMipReduction != 5 - mFloor( OP_BuildingTexSlider.getValue() * %mipRange ) ) + return( true ); + + if ( $pref::OpenGL::skyMipReduction != 5 - mFloor( OP_SkyTexSlider.getValue() * %mipRange ) ) + return( true ); + + if ( $AnisotropySupported && $pref::OpenGL::anisotropy != OP_AnisotropySlider.getValue() ) + return( true ); + + if ( !isDemo() ) + { + %id = OP_TexQualityMenu.getSelected(); + if ( $pref::OpenGL::forcePalettedTexture ) + { + if ( %id != 1 ) + return( true ); + } + else if ( $pref::OpenGL::force16bittexture ) + { + if ( %id != 2 ) + return( true ); + } + else if ( %id != 3 ) + return( true ); + } + + if ( $TextureCompressionSupported && !$pref::OpenGL::disableARBTextureCompression ) + { + %id = OP_CompressMenu.getSelected(); + if ( $pref::OpenGL::allowCompression ) + { + if ( $pref::OpenGL::compressionHint $= "GL_FASTEST" ) + { + if ( %id != 2 ) + return( true ); + } + else if ( $pref::OpenGL::compressionHint $= "GL_NICEST" ) + { + if ( %id != 3 ) + return( true ); + } + else if ( %id == 1 ) + return( true ); + } + else if ( %id > 1 ) + return( true ); + } + + return( false ); +} + +//------------------------------------------------------------------------------ +function returnFromSettings() +{ + // to unpause singlePlayerGame when returning from options + if ( isObject( Game ) ) + Game.OptionsDlgSleep(); +} + +//------------------------------------------------------------------------------ +function OptionsDlg::saveSettings( %this ) +{ + // Save off any prefs that don't auto-update: + %flushTextures = false; + + if ( $SwapIntervalSupported && OP_VSyncTgl.getValue() != $pref::Video::disableVerticalSync ) + { + $pref::Video::disableVerticalSync = OP_VSyncTgl.getValue(); + setVerticalSync( !$pref::Video::disableVerticalSync ); + } + + %temp = OP_SkyDetailMenu.getSelected(); + if ( %temp == 5 ) + $pref::SkyOn = false; + else + { + $pref::SkyOn = true; + $pref::numCloudLayers = ( 4 - %temp ); + } + + if ( $FogCoordSupported ) + $pref::Interior::TexturedFog = OP_IntTexturedFogTgl.getValue(); + + if ( $pref::Interior::VertexLighting != OP_VertexLightTgl.getValue() ) + { + $pref::Interior::VertexLighting = OP_VertexLightTgl.getValue(); + %flushTextures = true; + } + + %temp = OP_PlayerRenderMenu.getSelected(); + $pref::Player::renderMyPlayer = %temp & 1; + $pref::Player::renderMyItems = %temp & 2; + + if ( !isDemo() ) + { + switch ( OP_TexQualityMenu.getSelected() ) + { + case 1: // 8-bit + if ( !$pref::OpenGL::forcePalettedTexture || $pref::OpenGL::force16bittexture ) + { + $pref::OpenGL::forcePalettedTexture = true; + $pref::OpenGL::force16bittexture = false; + %flushTextures = true; + } + case 2: // 16-bit + if ( $pref::OpenGL::forcePalettedTexture || !$pref::OpenGL::force16bittexture ) + { + $pref::OpenGL::forcePalettedTexture = false; + $pref::OpenGL::force16bittexture = true; + %flushTextures = true; + } + case 3: // 32-bit + if ( $pref::OpenGL::forcePalettedTexture || $pref::OpenGL::force16bittexture ) + { + $pref::OpenGL::forcePalettedTexture = false; + $pref::OpenGL::force16bittexture = false; + %flushTextures = true; + } + } + OP_TexQualityMenu.clear(); + } + + $pref::Terrain::texDetail = 6 - mFloor( OP_TerrainTexSlider.getValue() ); + + // We're using the noDrawArraysAlpha variable here because we've already + // gone gold (hard to add a new profiling variable). But the Voodoo2/3/3500 + // cards that have the 256x256 texture limitation (in OpenGL) also have the + // noDrawArraysAlpha hack on...so that works out nice + %mipRange = $pref::OpenGL::noDrawArraysAlpha ? 4 : 5; + + %temp = 5 - mFloor( OP_ShapeTexSlider.getValue() * %mipRange ); + if ( $pref::OpenGL::mipReduction != %temp ) + { + $pref::OpenGL::mipReduction = %temp; + setOpenGLMipReduction( $pref::OpenGL::mipReduction ); + %flushTextures = true; + } + + %temp = 5 - mFloor( OP_BuildingTexSlider.getValue() * %mipRange ); + if ( $pref::OpenGL::interiorMipReduction != %temp ) + { + $pref::OpenGL::interiorMipReduction = %temp; + setOpenGLInteriorMipReduction( $pref::OpenGL::interiorMipReduction ); + %flushTextures = true; + } + + %temp = 5 - mFloor( OP_SkyTexSlider.getValue() * %mipRange ); + if ( $pref::OpenGL::skyMipReduction != %temp ) + { + $pref::OpenGL::skyMipReduction = %temp; + setOpenGLSkyMipReduction( $pref::OpenGL::skyMipReduction ); + %flushTextures = true; + } + + if ( $TextureCompressionSupported && !$pref::OpenGL::disableARBTextureCompression ) + { + %temp = OP_CompressMenu.getSelected(); + if ( $pref::OpenGL::allowCompression ) + { + switch ( %temp ) + { + case 2: + if ( $pref::OpenGL::compressionHint !$= "GL_FASTEST" ) + { + $pref::OpenGL::compressionHint = "GL_FASTEST"; + setOpenGLTextureCompressionHint( $pref::OpenGL::compressionHint ); + %flushTextures = true; + } + + case 3: + if ( $pref::OpenGL::compressionHint !$= "GL_NICEST" ) + { + $pref::OpenGL::compressionHint = "GL_NICEST"; + setOpenGLTextureCompressionHint( $pref::OpenGL::compressionHint ); + %flushTextures = true; + } + + default: // None + $pref::OpenGL::allowCompression = false; + %flushTextures = true; + } + } + else if ( %temp > 1 ) + { + $pref::OpenGL::allowCompression = true; + if ( %temp == 3 ) + $pref::OpenGL::compressionHint = "GL_NICEST"; + else + $pref::OpenGL::compressionHint = "GL_FASTEST"; + setOpenGLTextureCompressionHint( $pref::OpenGL::compressionHint ); + %flushTextures = true; + } + } + OP_CompressMenu.clear(); + + if ( $AnisotropySupported ) + { + %temp = OP_AnisotropySlider.getValue(); + if ( $pref::OpenGL::anisotropy != %temp ) + { + $pref::OpenGL::anisotropy = %temp; + setOpenGLAnisotropy( $pref::OpenGL::anisotropy ); + %flushTextures = true; + } + } + + if ( !isDemo() ) + { + if ( OP_HiResSkinTgl.getValue() != $pref::use512PlayerSkins ) + { + $pref::use512PlayerSkins = OP_HiResSkinTgl.getValue(); + if ( Canvas.getContent() == GameGui.getId() && GM_WarriorPane.isVisible() ) + GMW_PlayerModel.update(); + } + } + + $pref::Terrain::screenError = $max_screenerror - mFloor( OP_TerrainSlider.getValue() ); + $pref::TS::screenError = $max_TSScreenError - mFloor( OP_ShapeSlider.getValue() * ( $max_TSScreenError - $min_TSScreenError ) ); + $pref::TS::detailAdjust = $min_TSDetailAdjust + OP_ShapeSlider.getValue() * ( $max_TSDetailAdjust - $min_TSDetailAdjust ); + $pref::Shadows = OP_ShadowSlider.getValue(); + $pref::ParticleDensity = 4.0 - OP_ParticleDensitySlider.getValue(); + %val = 100 - OP_DynamicLightSlider.getValue(); + $pref::Interior::DynamicLightsClipPix = $pref::Terrain::DynamicLightsClipPix = %val; + $pref::Interior::DynamicLightsFadePix = $pref::Terrain::DynamicLightsFadePix = 2 * %val; + setShadowDetailLevel( $pref::Shadows ); + $pref::Interior::detailAdjust = OP_InteriorDetailSlider.getValue(); + $pref::VisibleDistanceMod = OP_VisibleDistanceSlider.getValue(); + + $pref::Audio::musicVolume = OP_MusicVolumeSlider.getValue(); + $pref::Audio::masterVolume = OP_MasterVolumeSlider.getValue(); + $pref::Audio::effectsVolume = OP_EffectsVolumeSlider.getValue(); + alxSetChannelVolume( $EffectAudioType, $pref::Audio::effectsVolume ); + $pref::Audio::voiceVolume = OP_MicrophoneVolumeSlider.getValue(); + alxSetChannelVolume( $VoiceAudioType, $pref::Audio::voiceVolume ); + $pref::Audio::radioVolume = OP_VoiceBindVolumeSlider.getValue(); + alxSetChannelVolume( $ChatAudioType, $pref::Audio::radioVolume ); + $pref::Audio::guiVolume = OP_GuiVolumeSlider.getValue(); + alxSetChannelVolume( $GuiAudioType, $pref::Audio::guiVolume); + $pref::Audio::captureGainScale = OP_InputBoostSlider.getValue(); + if ( !$missionRunning ) + MusicPlayer.stop(); + + if ( $pref::Audio::enableVoiceCapture ) + { + %reinit = false; + %selId = OP_VoiceListenMenu.getSelected(); + if ( $pref::Audio::decodingMask != %selId ) + { + $pref::Audio::decodingMask = %selId; + %reinit = true; + } + + %selId = OP_VoiceSendMenu.getSelected(); + if ( $pref::Audio::encodingLevel != %selId ) + { + $pref::Audio::encodingLevel = %selId; + %reinit = true; + } + + if ( %reinit ) + { + alxCaptureDestroy(); + alxCaptureInit(); + + // If in a game, let the server know about the altered settings: + if ( isObject( ServerConnection ) ) + commandToServer( 'SetVoiceInfo', $pref::Audio::voiceChannels, $pref::Audio::decodingMask, $pref::Audio::encodingLevel ); + } + } + + updateNetworkSettings(); + + $pref::Player::zoomSpeed = 500 - mFloor( OP_ZoomSpeedSlider.getValue() ); + setZoomSpeed( $pref::Player::zoomSpeed ); + + $pref::Shell::LaunchGui = OP_LaunchScreenMenu.getText(); + + export( "$pref::*", "prefs/ClientPrefs.cs", false ); + saveActiveMapFile(); + + if ( %flushTextures ) + { + // Give the Options Dialog a chance to go away: + OptionsDlg.schedule( 0, doTextureFlush ); + } + + returnFromSettings(); +} + +//------------------------------------------------------------------------------ +function OptionsDlg::doTextureFlush( %this ) +{ + MessagePopup( "PLEASE WAIT", "Flushing texture cache...\nThis may take a while" ); + Canvas.repaint(); + flushTextureCache(); + CloseMessagePopup(); +} + +//------------------------------------------------------------------------------ +function OptionsDlg::setPane( %this, %pane ) +{ + if((%this.pane $= "Sound") && !$missionRunning) + MusicPlayer.stop(); + + if ( %this.pane !$= "None" ) + { + %paneCtrl = "OP_" @ %this.pane @ "Pane"; + %paneCtrl.setVisible( false ); + + %tabCtrl = "OP_" @ %this.pane @ "Tab"; + %tabCtrl.setValue( false ); + } + + %paneCtrl = "OP_" @ %pane @ "Pane"; + %paneCtrl.setVisible( true ); + + %tabCtrl = "OP_" @ %pane @ "Tab"; + %tabCtrl.setValue( true ); + + %this.pane = %pane; +} + +//------------------------------------------------------------------------------ +function OptionsDlg::applyGraphicChanges( %this ) +{ + %newDriver = OP_VideoDriverMenu.getText(); + %newRes = OP_ResMenu.getText(); + %newBpp = OP_BPPMenu.getText(); + %newFullScreen = OP_FullScreenTgl.getValue(); + + if ( %newDriver !$= $pref::Video::displayDevice ) + { + setDisplayDevice( %newDriver, firstWord( %newRes ), getWord( %newRes, 1 ), %newBpp, %newFullScreen ); + OptionsDlg::deviceDependent( %this ); + } + else + setScreenMode( firstWord( %newRes ), getWord( %newRes, 1 ), %newBpp, %newFullScreen ); + + OP_ApplyBtn.updateState(); +} + + +//------------------------------------------------------------------------------ +function OP_VideoDriverMenu::onSelect( %this, %id, %text ) +{ + // Attempt to keep the same res and bpp settings: + if ( OP_ResMenu.size() > 0 ) + %prevRes = OP_ResMenu.getText(); + else + %prevRes = getWords( $pref::Video::resolution, 0, 1 ); + + // Check if this device is full-screen only: + if ( isDeviceFullScreenOnly( %this.getText() ) ) + { + OP_FullScreenTgl.setValue( true ); + OP_FullScreenTgl.setActive( false ); + OP_FullScreenTgl.onAction(); + } + else + OP_FullScreenTgl.setActive( true ); + + if ( OP_FullScreenTgl.getValue() ) + { + if ( OP_BPPMenu.size() > 0 ) + %prevBPP = OP_BPPMenu.getText(); + else + %prevBPP = getWord( $pref::Video::resolution, 2 ); + } + + // Fill the resolution and bit depth lists: + OP_ResMenu.init( %this.getText(), OP_FullScreenTgl.getValue() ); + OP_BPPMenu.init( %this.getText() ); + + // Try to select the previous settings: + %selId = OP_ResMenu.findText( %prevRes ); + if ( %selId == -1 ) + %selId = 0; + OP_ResMenu.setSelected( %selId ); + + if ( OP_FullScreenTgl.getValue() ) + { + %selId = OP_BPPMenu.findText( %prevBPP ); + if ( %selId == -1 ) + %selId = 0; + OP_BPPMenu.setSelected( %selId ); + OP_BPPMenu.setText( OP_BPPMenu.getTextById( %selId ) ); + } + else + OP_BPPMenu.setText( "Default" ); + + OP_ApplyBtn.updateState(); +} + +//------------------------------------------------------------------------------ +function OP_ResMenu::init( %this, %device, %fullScreen ) +{ + %this.clear(); + %resList = getResolutionList( %device ); + %resCount = getFieldCount( %resList ); + %deskRes = getDesktopResolution(); + %count = 0; + for ( %i = 0; %i < %resCount; %i++ ) + { + %res = getWords( getField( %resList, %i ), 0, 1 ); + + if ( !%fullScreen ) + { + if ( firstWord( %res ) >= firstWord( %deskRes ) ) + continue; + if ( getWord( %res, 1 ) >= getWord( %deskRes, 1 ) ) + continue; + } + + // Only add to list if it isn't there already: + if ( %this.findText( %res ) == -1 ) + { + %this.add( %res, %count ); + %count++; + } + } +} + +//------------------------------------------------------------------------------ +function OP_ResMenu::onSelect( %this, %id, %text ) +{ + OP_ApplyBtn.updateState(); +} + +//------------------------------------------------------------------------------ +function OP_BPPMenu::init( %this, %device ) +{ + %this.clear(); + + if ( %device $= "Voodoo2" ) + %this.add( "16", 0 ); + else + { + %resList = getResolutionList( %device ); + %resCount = getFieldCount( %resList ); + %count = 0; + for ( %i = 0; %i < %resCount; %i++ ) + { + %bpp = getWord( getField( %resList, %i ), 2 ); + + // Only add to list if it isn't there already: + if ( %this.findText( %bpp ) == -1 ) + { + %this.add( %bpp, %count ); + %count++; + } + } + } +} + +//------------------------------------------------------------------------------ +function OP_BPPMenu::onSelect( %this, %id, %text ) +{ + OP_ApplyBtn.updateState(); +} + +//------------------------------------------------------------------------------ +function OP_FullScreenTgl::onAction( %this ) +{ + // Attempt to maintain current settings: + %selId = OP_ResMenu.getSelected(); + if ( %selId == -1 ) + %selId = 0; + %prevRes = OP_ResMenu.getTextById( %selId ); + + OP_ResMenu.init( OP_VideoDriverMenu.getText(), %this.getValue() ); + + %selId = OP_ResMenu.findText( %prevRes ); + if ( %selId == -1 ) + %selId = 0; + OP_ResMenu.setSelected( %selId ); + + if ( %this.getValue() ) + { + %selId = OP_BPPMenu.findText( getWord( $pref::Video::resolution, 2 ) ); + if ( %selId == - 1 ) + %selId = 0; + OP_BPPMenu.setSelected( %selId ); + OP_BPPMenu.setText( OP_BPPMenu.getTextById( %selId ) ); + OP_BPPMenu.setActive( true ); + } + else + { + OP_BPPMenu.setText( "Default" ); + OP_BPPMenu.setActive( false ); + } + + OP_ApplyBtn.updateState(); +} + +//------------------------------------------------------------------------------ +function OP_ApplyBtn::updateState( %this ) +{ + %active = false; + + if ( OP_VideoDriverMenu.getText() !$= $pref::Video::displayDevice ) + %active = true; + else if ( OP_ResMenu.getText() !$= getWords( $pref::Video::resolution, 0, 1 ) ) + %active = true; + else if ( OP_FullScreenTgl.getValue() != $pref::Video::fullScreen ) + %active = true; + else if ( OP_FullScreenTgl.getValue() ) + { + if ( OP_BPPMenu.getText() !$= getWord( $pref::Video::resolution, 2 ) ) + %active = true; + } + + %this.setActive( %active ); +} + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +// Graphics Settings: +// +function updateGammaCorrection() +{ + $pref::OpenGL::gammaCorrection = OP_GammaSlider.getValue(); + videoSetGammaCorrection( $pref::OpenGL::gammaCorrection ); +} + +//------------------------------------------------------------------------------ +function updateTerrainDetail() +{ + $pref::Terrain::screenError = $max_screenerror - mFloor( OP_TerrainSlider.getValue()); + if ( OP_TerrainSlider.getValue() != $max_screenerror - $pref::Terrain::screenError ) + OP_TerrainSlider.setValue( $max_screenerror - $pref::Terrain::screenError ); +} + +//------------------------------------------------------------------------------ +function updateDynamicLightSliderState() +{ + %on = $pref::Interior::DynamicLights || $pref::Terrain::dynamicLights; + OP_DynamicLightText.setVisible( %on ); + OP_DynamicLightText_Disabled.setVisible( !%on ); + OP_DynamicLightSlider.setActive( %on ); +} + +//------------------------------------------------------------------------------ +function OP_SkyDetailMenu::init( %this ) +{ + %this.clear(); + %this.add( "Full Sky", 1 ); + %this.add( "Two Cloud Layers", 2 ); + %this.add( "One Cloud Layer", 3 ); + %this.add( "Sky Box Only", 4 ); + %this.add( "No Sky", 5 ); +} + +//------------------------------------------------------------------------------ +function OP_PlayerRenderMenu::init( %this ) +{ + %this.clear(); + %this.add( "Player and Items", 3 ); + %this.add( "Player only", 1 ); + %this.add( "Items only", 2 ); + %this.add( "Neither Player nor Items", 0 ); +} + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +// Texture Settings: +// +function OP_CompressMenu::init( %this ) +{ + %this.clear(); + %this.add( "None", 1 ); + %this.add( "Fastest", 2 ); + %this.add( "Nicest", 3 ); +} + +//------------------------------------------------------------------------------ +function OP_TexQualityMenu::init( %this ) +{ + %this.clear(); + if ( $PalettedTextureSupported ) + %this.add( "Palletized", 1 ); + %this.add( "16 bit", 2 ); + %this.add( "32 bit", 3 ); +} + +//------------------------------------------------------------------------------ +function OP_TexQualityMenu::onSelect( %this, %id, %text ) +{ + if ( %id == 1 ) + { + // Disable these with palletized textures by default: + OP_EnvMapTgl.setValue( false ); + //OP_EnvMapTgl.setActive( false ); + OP_IntEnvMapTgl.setValue( false ); + //OP_IntEnvMapTgl.setActive( false ); + } +// else +// { +// OP_EnvMapTgl.setActive( true ); +// OP_IntEnvMapTgl.setActive( true ); +// } +} + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +// Audio Settings: +// +function setAudioProvider(%idx) +{ + alxContexti(ALC_PROVIDER, %idx); + $pref::Audio::provider = alxGetContextstr(ALC_PROVIDER_NAME, %idx); + + %active = audioIsEnvironmentProvider($pref::Audio::provider); + + // unset tgl if cannot be environment provider + if(!%active) + OP_AudioEnvironmentTgl.setValue(false); + OP_AudioEnvironmentTgl.setActive(%active); + + audioUpdateProvider($pref::Audio::provider); + OP_AudioProviderMenu.setSelected(%idx); +} + +//------------------------------------------------------------------------------ +function OP_AudioEnvironmentTgl::onAction(%this) +{ + alxEnableEnvironmental(%this.getValue()); +} + +//------------------------------------------------------------------------------ +function OP_AudioProviderMenu::onSelect(%this, %id, %text) +{ + if(%id != $Audio::originalProvider) + { + if(!%this.seenWarning) + { + MessageBoxOK("Warning", "Changing sound drivers may result in incompatibilities and game oddities. If you experience such oddities, hit \"Reset\" to restore defaults.", ""); + %this.seenWarning = true; + } + OP_AudioResetProvider.setActive(true); + } + setAudioProvider(%id); +} + +//------------------------------------------------------------------------------ +function OP_AudioResetProvider::onAction(%this) +{ + setAudioProvider($Audio::originalProvider); + %this.setActive(false); +} +//------------------------------------------------------------------------------ +function OP_AudioSpeakerMenu::onSelect(%this, %id, %text) +{ + alxContexti(ALC_SPEAKER, %id); + $pref::Audio::speakerType = alxGetContextstr(ALC_SPEAKER_NAME, %id); +} + +//------------------------------------------------------------------------------ +function OP_AudioFrequencyMenu::init( %this ) +{ + %this.clear(); + %this.add( "11 KHz", 0 ); + %this.add( "22 KHz", 1 ); + %this.add( "44 KHz", 2 ); + + switch ( $pref::Audio::frequency ) + { + case 11025: %this.setSelected( 0 ); + case 22050: %this.setSelected( 1 ); + default: %this.setSelected( 2 ); + } +} + +//------------------------------------------------------------------------------ +function OP_AudioFrequencyMenu::onSelect( %this, %id, %text ) +{ + switch ( %id ) + { + case 0: %newVal = 11025; + case 1: %newVal = 22050; + default: %newVal = 44100; + } + + if ( $pref::Audio::frequency != %newVal ) + { + $pref::Audio::frequency = %newVal; + OptionsDlg.resetAudio = true; + } +} + +//------------------------------------------------------------------------------ +function OP_AudioBitRateMenu::init( %this ) +{ + %this.clear(); + %this.add( "8 bit", 0 ); + %this.add( "16 bit", 1 ); + + if ( $pref::Audio::sampleBits == 8 ) + %this.setSelected( 0 ); + else + %this.setSelected( 1 ); +} + +//------------------------------------------------------------------------------ +function OP_AudioBitRateMenu::onSelect( %this, %id, %text ) +{ + %newVal = %id == 0 ? 8 : 16; + if ( $pref::Audio::sampleBits != %newVal ) + { + $pref::Audio::sampleBits = %newVal; + OptionsDlg.resetAudio = true; + } +} + +//------------------------------------------------------------------------------ +function OP_AudioChannelsMenu::init( %this ) +{ + %this.clear(); + %this.add( "One", 0 ); + %this.add( "Two", 1 ); + + if ( $pref::Audio::channels == 1 ) + %this.setSelected( 0 ); + else + %this.setSelected( 1 ); +} + +//------------------------------------------------------------------------------ +function OP_AudioChannelsMenu::onSelect( %this, %id, %text ) +{ + %newVal = %id == 0 ? 1 : 2; + if ( $pref::Audio::channels != %newVal ) + { + $pref::Audio::channels = %newVal; + OptionsDlg.resetAudio = true; + } +} + +//------------------------------------------------------------------------------ +function OP_MusicTgl::onAction( %this ) +{ + %on = %this.getValue(); + OP_MusicVolumeLabel.setVisible( %on ); + OP_MusicVolumeLabel_Disabled.setVisible( !%on ); + OP_MusicVolumeSlider.setActive( %on ); + $pref::Audio::musicEnabled = %on; + + if ( %on ) + MusicPlayer.play(); + else + MusicPlayer.stop(); +} + +//------------------------------------------------------------------------------ +function updateMusicVolume() +{ + %volume = OP_MusicVolumeSlider.getValue(); + alxSetChannelVolume( $MusicAudioType, %volume ); +} + +//------------------------------------------------------------------------------ +function updateGuiVolume() +{ + %volume = OP_GuiVolumeSlider.getValue(); + alxSetChannelVolume( $GuiAudioType, %volume ); +} + +//------------------------------------------------------------------------------ +function updateMasterVolume() +{ + %volume = OP_MasterVolumeSlider.getValue(); + alxListenerf( AL_GAIN_LINEAR, %volume ); +} + + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +// Voice Settings: +// +function OP_MicrophoneEnabledTgl::onAction( %this ) +{ + %on = %this.getValue(); + OP_RecordTestBtn.setActive( %on ); + OP_MicVolumeLabel.setVisible( %on ); + OP_MicVolumeLabel_Disabled.setVisible( !%on ); + OP_MicrophoneVolumeSlider.setActive( %on ); + OP_InputBoostLabel.setVisible( %on ); + OP_InputBoostLabel_Disabled.setVisible( !%on ); + OP_InputBoostSlider.setActive( %on ); + OP_InputBoostPercentTxt.setVisible( %on ); + OP_VoiceListenLabel.setVisible( %on ); + OP_VoiceListenLabel_Disabled.setVisible( !%on ); + OP_VoiceListenMenu.setActive( %on ); + OP_VoiceSendLabel.setVisible( %on ); + OP_VoiceSendLabel_Disabled.setVisible( !%on ); + OP_VoiceSendMenu.setActive( %on ); + + if(%on != alxIsEnabled("capture")) + { + if(%on) + alxCaptureInit(); + else + alxCaptureDestroy(); + } +} + +//------------------------------------------------------------------------------ +function updateInputBoost() +{ + %val = OP_InputBoostSlider.getValue(); + alxSetCaptureGainScale( %val ); + %val = mFloor(%val * 100); + OP_InputBoostPercentTxt.setValue(%val @ "%"); +} + +//------------------------------------------------------------------------------ +function OP_RecordTestBtn::onAction( %this ) +{ + alxCaptureStart(true); +} + +//------------------------------------------------------------------------------ +function localCaptureStart( %method ) +{ + if(%method $= "record") + { + OP_RecordTestBtn.setActive(false); + OP_RecordTestBtn.setValue(">> Recording <<"); + } + else + { + OP_RecordTestBtn.setActive(false); + OP_RecordTestBtn.setValue(">> Playing <<"); + } +} + +//------------------------------------------------------------------------------ +function localCaptureStop( %method ) +{ + if(%method $= "play") + { + OP_RecordTestBtn.setActive(true); + OP_RecordTestBtn.setValue("Test Record"); + } +} + +//------------------------------------------------------------------------------ +function OP_VoiceListenMenu::init( %this ) +{ + %this.clear(); + %this.add( "", 0 ); + if ( $platform !$= "linux" ) { + %this.add( ".v12", 1 ); + %this.add( ".v12 - .v24", 3 ); + %this.add( ".v12 - .v29", 7 ); + } + if ( $platform $= "linux" ) { + %this.add( "GSM" , 8 ); + } + + switch ( $pref::Audio::decodingMask ) + { + case 0 or 3 or 7 or 8: + %this.setSelected( $pref::Audio::decodingMask ); + default: + %this.setSelected( 1 ); + } +} + +//------------------------------------------------------------------------------ +function OP_VoiceSendMenu::init( %this ) +{ + %this.clear(); + if ( $platform !$= "linux" ) { + %this.add( ".v12", 0 ); + %this.add( ".v24", 1 ); + %this.add( ".v29", 2 ); + } + if ( $platform $= "linux" ) { + %this.add( "GSM", 3 ); + } + + %this.setSelected($pref::Audio::encodingLevel); +} + +function OP_VoiceCodecInfo::init( %this ) +{ + %headerStyle = ""; + if ( $platform $= "linux" ) { + %displayText = "" @ %headerStyle @ "Voice Codec Information:" NL + "\n" @ + " GSM: fixed bitrate codec (6.6 kbits/sec linux only)" NL + "\n" @ + "" @ + "Setting your codec levels too high can have adverse" @ + " affects on network performance." @ + ""; + } else { + %displayText = "" @ %headerStyle @ "Voice Codec Information:" NL + "\n" @ + " .v12: variable bitrate codec (~1.2 kbits/sec win only)" NL + " .v24: fixed bitrate codec (2.4 kbits/sec win only)" NL + " .v29: fixed bitrate codec (2.9 kbits/sec win only)" NL + "\n" @ + "" @ + "Setting your codec levels too high can have adverse" @ + " affects on network performance." @ + ""; + } + + %this.setText(%displayText); + %this.setActive(false); +} + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +// Driver Info dialog: +// +function DriverInfoDlg::onWake( %this ) +{ + %headerStyle = ""; + %infoString = getVideoDriverInfo(); + %displayText = "" @ %headerStyle @ "VENDOR:" NL + " " @ getField( %infoString, 0 ) NL + "" @ %headerStyle @ "RENDERER:" NL + " " @ getField( %infoString, 1 ) NL + "" @ %headerStyle @ "VERSION " @ getField( %infoString, 2 ) NL + "\n" @ + "" @ %headerStyle @ "SUPPORTED OPENGL EXTENSIONS:" NL + getField( %infoString, 3 ); + + DriverInfoText.setText( %displayText ); +} + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +// Control remapper section: +// +$RemapCount = 0; +$RemapName[$RemapCount] = "Forward"; +$RemapCmd[$RemapCount] = "moveforward"; +$RemapCount++; +$RemapName[$RemapCount] = "Backward"; +$RemapCmd[$RemapCount] = "movebackward"; +$RemapCount++; +$RemapName[$RemapCount] = "Strafe Left"; +$RemapCmd[$RemapCount] = "moveleft"; +$RemapCount++; +$RemapName[$RemapCount] = "Strafe Right"; +$RemapCmd[$RemapCount] = "moveright"; +$RemapCount++; +$RemapName[$RemapCount] = "Turn Left"; +$RemapCmd[$RemapCount] = "turnLeft"; +$RemapCount++; +$RemapName[$RemapCount] = "Turn Right"; +$RemapCmd[$RemapCount] = "turnRight"; +$RemapCount++; +$RemapName[$RemapCount] = "Look Up"; +$RemapCmd[$RemapCount] = "panUp"; +$RemapCount++; +$RemapName[$RemapCount] = "Look Down"; +$RemapCmd[$RemapCount] = "panDown"; +$RemapCount++; +$RemapName[$RemapCount] = "Jump"; +$RemapCmd[$RemapCount] = "jump"; +$RemapCount++; +$RemapName[$RemapCount] = "Jet Pack"; +$RemapCmd[$RemapCount] = "mouseJet"; +$RemapCount++; +$RemapName[$RemapCount] = "Fire Weapon"; +$RemapCmd[$RemapCount] = "mouseFire"; +$RemapCount++; +$RemapName[$RemapCount] = "Zoom"; +$RemapCmd[$RemapCount] = "toggleZoom"; +$RemapCount++; +$RemapName[$RemapCount] = "Cycle Zoom Level"; +$RemapCmd[$RemapCount] = "setZoomFOV"; +$RemapCount++; +$RemapName[$RemapCount] = "Weapon Slot One"; +$RemapCmd[$RemapCount] = "useFirstWeaponSlot"; +$RemapCount++; +$RemapName[$RemapCount] = "Weapon Slot Two"; +$RemapCmd[$RemapCount] = "useSecondWeaponSlot"; +$RemapCount++; +$RemapName[$RemapCount] = "Weapon Slot Three"; +$RemapCmd[$RemapCount] = "useThirdWeaponSlot"; +$RemapCount++; +$RemapName[$RemapCount] = "Weapon Slot Four"; +$RemapCmd[$RemapCount] = "useFourthWeaponSlot"; +$RemapCount++; +$RemapName[$RemapCount] = "Weapon Slot Five"; +$RemapCmd[$RemapCount] = "useFifthWeaponSlot"; +$RemapCount++; +$RemapName[$RemapCount] = "Weapon Slot Six"; +$RemapCmd[$RemapCount] = "useSixthWeaponSlot"; +$RemapCount++; +$RemapName[$RemapCount] = "Blaster"; +$RemapCmd[$RemapCount] = "useBlaster"; +$RemapCount++; +$RemapName[$RemapCount] = "Plasma Rifle"; +$RemapCmd[$RemapCount] = "usePlasma"; +$RemapCount++; +$RemapName[$RemapCount] = "Chaingun"; +$RemapCmd[$RemapCount] = "useChaingun"; +$RemapCount++; +$RemapName[$RemapCount] = "Spinfusor"; +$RemapCmd[$RemapCount] = "useDisc"; +$RemapCount++; +$RemapName[$RemapCount] = "Grenade Launcher"; +$RemapCmd[$RemapCount] = "useGrenadeLauncher"; +$RemapCount++; +$RemapName[$RemapCount] = "Laser Rifle"; +$RemapCmd[$RemapCount] = "useSniperRifle"; +$RemapCount++; +$RemapName[$RemapCount] = "ELF Projector"; +$RemapCmd[$RemapCount] = "useELFGun"; +$RemapCount++; +$RemapName[$RemapCount] = "Fusion Mortar"; +$RemapCmd[$RemapCount] = "useMortar"; +$RemapCount++; +$RemapName[$RemapCount] = "Missile Launcher"; +$RemapCmd[$RemapCount] = "useMissileLauncher"; +$RemapCount++; +$RemapName[$RemapCount] = "Shocklance"; +$RemapCmd[$RemapCount] = "useShockLance"; +$RemapCount++; +$RemapName[$RemapCount] = "Targeting Laser"; +$RemapCmd[$RemapCount] = "useTargetingLaser"; +$RemapCount++; +$RemapName[$RemapCount] = "Previous Weapon"; +$RemapCmd[$RemapCount] = "prevWeapon"; +$RemapCount++; +$RemapName[$RemapCount] = "Next Weapon"; +$RemapCmd[$RemapCount] = "nextWeapon"; +$RemapCount++; +$RemapName[$RemapCount] = "Throw Grenade"; +$RemapCmd[$RemapCount] = "throwGrenade"; +$RemapCount++; +$RemapName[$RemapCount] = "Place Mine"; +$RemapCmd[$RemapCount] = "placeMine"; +$RemapCount++; +$RemapName[$RemapCount] = "Use Pack"; +$RemapCmd[$RemapCount] = "useBackpack"; +$RemapCount++; +$RemapName[$RemapCount] = "Use Health Kit"; +$RemapCmd[$RemapCount] = "useRepairKit"; +$RemapCount++; +$RemapName[$RemapCount] = "Deploy Beacon"; +$RemapCmd[$RemapCount] = "placeBeacon"; +$RemapCount++; +$RemapName[$RemapCount] = "Inventory"; +$RemapCmd[$RemapCount] = "toggleInventoryHud"; +$RemapCount++; +$RemapName[$RemapCount] = "Favorite 1"; +$RemapCmd[$RemapCount] = "selectFavorite1"; +$RemapCount++; +$RemapName[$RemapCount] = "Favorite 2"; +$RemapCmd[$RemapCount] = "selectFavorite2"; +$RemapCount++; +$RemapName[$RemapCount] = "Favorite 3"; +$RemapCmd[$RemapCount] = "selectFavorite3"; +$RemapCount++; +$RemapName[$RemapCount] = "Favorite 4"; +$RemapCmd[$RemapCount] = "selectFavorite4"; +$RemapCount++; +$RemapName[$RemapCount] = "Favorite 5"; +$RemapCmd[$RemapCount] = "selectFavorite5"; +$RemapCount++; +$RemapName[$RemapCount] = "Favorite 6"; +$RemapCmd[$RemapCount] = "selectFavorite6"; +$RemapCount++; +$RemapName[$RemapCount] = "Favorite 7"; +$RemapCmd[$RemapCount] = "selectFavorite7"; +$RemapCount++; +$RemapName[$RemapCount] = "Favorite 8"; +$RemapCmd[$RemapCount] = "selectFavorite8"; +$RemapCount++; +$RemapName[$RemapCount] = "Favorite 9"; +$RemapCmd[$RemapCount] = "selectFavorite9"; +$RemapCount++; +$RemapName[$RemapCount] = "Favorite 10"; +$RemapCmd[$RemapCount] = "selectFavorite10"; +$RemapCount++; +$RemapName[$RemapCount] = "Favorite 11"; +$RemapCmd[$RemapCount] = "selectFavorite11"; +$RemapCount++; +$RemapName[$RemapCount] = "Favorite 12"; +$RemapCmd[$RemapCount] = "selectFavorite12"; +$RemapCount++; +$RemapName[$RemapCount] = "Favorite 13"; +$RemapCmd[$RemapCount] = "selectFavorite13"; +$RemapCount++; +$RemapName[$RemapCount] = "Favorite 14"; +$RemapCmd[$RemapCount] = "selectFavorite14"; +$RemapCount++; +$RemapName[$RemapCount] = "Favorite 15"; +$RemapCmd[$RemapCount] = "selectFavorite15"; +$RemapCount++; +$RemapName[$RemapCount] = "Favorite 16"; +$RemapCmd[$RemapCount] = "selectFavorite16"; +$RemapCount++; +$RemapName[$RemapCount] = "Favorite 17"; +$RemapCmd[$RemapCount] = "selectFavorite17"; +$RemapCount++; +$RemapName[$RemapCount] = "Favorite 18"; +$RemapCmd[$RemapCount] = "selectFavorite18"; +$RemapCount++; +$RemapName[$RemapCount] = "Favorite 19"; +$RemapCmd[$RemapCount] = "selectFavorite19"; +$RemapCount++; +$RemapName[$RemapCount] = "Favorite 20"; +$RemapCmd[$RemapCount] = "selectFavorite20"; +$RemapCount++; +$RemapName[$RemapCount] = "Select Energy Pack"; +$RemapCmd[$RemapCount] = "quickPackEnergyPack"; +$RemapCount++; +$RemapName[$RemapCount] = "Select Repair Pack"; +$RemapCmd[$RemapCount] = "quickPackRepairPack"; +$RemapCount++; +$RemapName[$RemapCount] = "Select Shield Pack"; +$RemapCmd[$RemapCount] = "quickPackShieldPack"; +$RemapCount++; +$RemapName[$RemapCount] = "Select Cloaking Pack"; +$RemapCmd[$RemapCount] = "quickPackCloakPack"; +$RemapCount++; +$RemapName[$RemapCount] = "Select Sensor Jammer"; +$RemapCmd[$RemapCount] = "quickPackJammerPack"; +$RemapCount++; +$RemapName[$RemapCount] = "Select Ammo Pack"; +$RemapCmd[$RemapCount] = "quickPackAmmoPack"; +$RemapCount++; +$RemapName[$RemapCount] = "Select Satchel Charge"; +$RemapCmd[$RemapCount] = "quickPackSatchelCharge"; +$RemapCount++; +$RemapName[$RemapCount] = "Select Inv Station"; +$RemapCmd[$RemapCount] = "quickPackDeployableStation"; +$RemapCount++; +$RemapName[$RemapCount] = "Select Spider Turret"; +$RemapCmd[$RemapCount] = "quickPackIndoorTurret"; +$RemapCount++; +$RemapName[$RemapCount] = "Select Landspike Turret"; +$RemapCmd[$RemapCount] = "quickPackOutdoorTurret"; +$RemapCount++; +$RemapName[$RemapCount] = "Select Motion Sensor"; +$RemapCmd[$RemapCount] = "quickPackMotionSensor"; +$RemapCount++; +$RemapName[$RemapCount] = "Select Deploy Pulse"; +$RemapCmd[$RemapCount] = "quickPackPulse"; +$RemapCount++; +$RemapName[$RemapCount] = "Select Plasma Barrel"; +$RemapCmd[$RemapCount] = "quickPackPlasmaBarrel"; +$RemapCount++; +$RemapName[$RemapCount] = "Select Missile Barrel"; +$RemapCmd[$RemapCount] = "quickPackMissileBarrel"; +$RemapCount++; +$RemapName[$RemapCount] = "Select AA Barrel"; +$RemapCmd[$RemapCount] = "quickPackAABarrel"; +$RemapCount++; +$RemapName[$RemapCount] = "Select Mortar Barrel"; +$RemapCmd[$RemapCount] = "quickPackMortarBarrel"; +$RemapCount++; +$RemapName[$RemapCount] = "Select Elf Barrel"; +$RemapCmd[$RemapCount] = "quickPackElfBarrel"; +$RemapCount++; +$RemapName[$RemapCount] = "Select Grenade"; +$RemapCmd[$RemapCount] = "quickPackGrenade"; +$RemapCount++; +$RemapName[$RemapCount] = "Select Flash Grenade"; +$RemapCmd[$RemapCount] = "quickPackFlashGrenade"; +$RemapCount++; +$RemapName[$RemapCount] = "Select Concussion"; +$RemapCmd[$RemapCount] = "quickPackConcussionGrenade"; +$RemapCount++; +$RemapName[$RemapCount] = "Select Camera"; +$RemapCmd[$RemapCount] = "quickPackCameraGrenade"; +$RemapCount++; +$RemapName[$RemapCount] = "Select Flare Grenade"; +$RemapCmd[$RemapCount] = "quickPackFlareGrenade"; +$RemapCount++; +$RemapName[$RemapCount] = "Command Circuit"; +$RemapCmd[$RemapCount] = "toggleCommanderMap"; +$RemapCount++; +$RemapName[$RemapCount] = "Toggle Task List"; +$RemapCmd[$RemapCount] = "toggleTaskListDlg"; +$RemapCount++; +$RemapName[$RemapCount] = "Accept Task"; +$RemapCmd[$RemapCount] = "fnAcceptTask"; +$RemapCount++; +$RemapName[$RemapCount] = "Decline Task"; +$RemapCmd[$RemapCount] = "fnDeclineTask"; +$RemapCount++; +$RemapName[$RemapCount] = "Task Completed"; +$RemapCmd[$RemapCount] = "fnTaskCompleted"; +$RemapCount++; +$RemapName[$RemapCount] = "Reset Task List"; +$RemapCmd[$RemapCount] = "fnResetTaskList"; +$RemapCount++; +$RemapName[$RemapCount] = "Vote Yes"; +$RemapCmd[$RemapCount] = "voteYes"; +$RemapCount++; +$RemapName[$RemapCount] = "Vote No"; +$RemapCmd[$RemapCount] = "voteNo"; +$RemapCount++; +$RemapName[$RemapCount] = "Voice Chat Menu"; +$RemapCmd[$RemapCount] = "activateChatMenuHud"; +$RemapCount++; +$RemapName[$RemapCount] = "Global Chat"; +$RemapCmd[$RemapCount] = "ToggleMessageHud"; +$RemapCount++; +$RemapName[$RemapCount] = "Team Chat"; +$RemapCmd[$RemapCount] = "TeamMessageHud"; +$RemapCount++; +$RemapName[$RemapCount] = "Resize Chat Hud"; +$RemapCmd[$RemapCount] = "resizeChatHud"; +$RemapCount++; +$RemapName[$RemapCount] = "Toggle Microphone"; +$RemapCmd[$RemapCount] = "voiceCapture"; +$RemapCount++; +$RemapName[$RemapCount] = "Toggle Help Text"; +$RemapCmd[$RemapCount] = "toggleHelpGui"; +$RemapCount++; +$RemapName[$RemapCount] = "Score Screen"; +$RemapCmd[$RemapCount] = "toggleScoreScreen"; +$RemapCount++; +$RemapName[$RemapCount] = "Free Look"; +$RemapCmd[$RemapCount] = "toggleFreeLook"; +$RemapCount++; +$RemapName[$RemapCount] = "Exterior View"; +$RemapCmd[$RemapCount] = "toggleFirstPerson"; +$RemapCount++; +$RemapName[$RemapCount] = "Drop Weapon"; +$RemapCmd[$RemapCount] = "throwWeapon"; +$RemapCount++; +$RemapName[$RemapCount] = "Drop Pack"; +$RemapCmd[$RemapCount] = "throwPack"; +$RemapCount++; +$RemapName[$RemapCount] = "Drop Flag"; +$RemapCmd[$RemapCount] = "throwFlag"; +$RemapCount++; +$RemapName[$RemapCount] = "Suicide"; +$RemapCmd[$RemapCount] = "suicide"; +$RemapCount++; +$RemapName[$RemapCount] = "Toggle Personal Wypts"; +$RemapCmd[$RemapCount] = "toggleHudWaypoints"; +$RemapCount++; +$RemapName[$RemapCount] = "Toggle Mission Wypts"; +$RemapCmd[$RemapCount] = "toggleHudMarkers"; +$RemapCount++; +$RemapName[$RemapCount] = "Toggle Beacons"; +$RemapCmd[$RemapCount] = "toggleHudTargets"; +$RemapCount++; +$RemapName[$RemapCount] = "Toggle Commands"; +$RemapCmd[$RemapCount] = "toggleHudCommands"; +$RemapCount++; +$RemapName[$RemapCount] = "Interact / Use"; +$RemapCmd[$RemapCount] = "InteractWithObject"; +$RemapCount++; +$RemapName[$RemapCount] = "Increase Frequency"; +$RemapCmd[$RemapCount] = "IncreaseRadioFrequency"; +$RemapCount++; +$RemapName[$RemapCount] = "Decrease Frequency"; +$RemapCmd[$RemapCount] = "DecreaseRadioFrequency"; +$RemapCount++; +$RemapName[$RemapCount] = "Increase Voice"; +$RemapCmd[$RemapCount] = "IncreaseVoiceRange"; +$RemapCount++; +$RemapName[$RemapCount] = "Decrease Voice"; +$RemapCmd[$RemapCount] = "DecreaseVoiceRange"; +$RemapCount++; +if ( !isDemo() ) +{ + $RemapName[$RemapCount] = "Start Demo Record"; + $RemapCmd[$RemapCount] = "startRecordingDemo"; + $RemapCount++; + $RemapName[$RemapCount] = "Stop Demo Record"; + $RemapCmd[$RemapCount] = "stopRecordingDemo"; + $RemapCount++; +} +$RemapName[$RemapCount] = "Chat Page Up"; +$RemapCmd[$RemapCount] = "pageMessageHudUp"; +$RemapCount++; +$RemapName[$RemapCount] = "Chat Page Down"; +$RemapCmd[$RemapCount] = "pageMessageHudDown"; +$RemapCount++; +$RemapName[$RemapCount] = "Toggle Net Meter"; +$RemapCmd[$RemapCount] = "toggleNetDisplayHud"; +$RemapCount++; + +$ObsRemapCount = 0; +$ObsRemapName[$ObsRemapCount] = "Move Up"; +$ObsRemapCmd[$ObsRemapCount] = "moveup"; +$ObsRemapCount++; +$ObsRemapName[$ObsRemapCount] = "Move Down"; +$ObsRemapCmd[$ObsRemapCount] = "movedown"; +$ObsRemapCount++; +$ObsRemapName[$ObsRemapCount] = "Toggle Observer Mode"; +$ObsRemapCmd[$ObsRemapCount] = "jump"; +$ObsRemapCount++; +$ObsRemapName[$ObsRemapCount] = "Spawn/Previous"; +$ObsRemapCmd[$ObsRemapCount] = "mouseFire"; +$ObsRemapCount++; +$ObsRemapName[$ObsRemapCount] = "Cycle Camera/Next"; +$ObsRemapCmd[$ObsRemapCount] = "mouseJet"; +$ObsRemapCount++; + +//------------------------------------------------------------------------------ +function restoreDefaultMappings() +{ + moveMap.delete(); + exec( "scripts/controlDefaults.cs" ); + $pref::Input::ActiveConfig = "MyConfig"; + OP_RemapList.fillList(); +} + +//------------------------------------------------------------------------------ +function isMapFile( %file ) +{ + %fObject = new FileObject(); + if ( !%fObject.openForRead( %file ) ) + return( false ); + + while ( !%fObject.isEOF() ) + { + %line = %fObject.readLine(); + if ( %line $= "// Tribes 2 Input Map File" ) + { + %fObject.close(); + return( true ); + } + } + + %fObject.close(); + return( false ); +} + +//------------------------------------------------------------------------------ +function isValidMapFileSaveName( %file ) +{ + if (isDemo()) + %basePath = "demo_base/"; + else + %basePath = "base/"; + if ( !isWriteableFileName( %basePath @ %file ) ) + return( false ); + + if ( isFile( %file ) ) + return( isMapFile( %file ) ); + + return( true ); +} + +//------------------------------------------------------------------------------ +function loadMapFile( %filename ) +{ + exec( "prefs/" @ %filename @ ".cs" ); + $pref::Input::ActiveConfig = %filename; + OP_RemapList.fillList(); +} + +//------------------------------------------------------------------------------ +function saveActiveMapFile() +{ + if ( isValidMapFileSaveName( "prefs/" @ $pref::Input::ActiveConfig @ ".cs" ) ) + saveMapFile( $pref::Input::ActiveConfig ); + else + ShellGetSaveFilename( "SAVE CONTROL CONFIG", "prefs/*.cs", "isMapFile", "saveMapFile", "" ); +} + +//------------------------------------------------------------------------------ +function saveMapFile( %filename ) +{ + if ( strcspn( %filename, "\\/?*\"\'<>|" ) < strlen( %filename ) ) + { + MessageBoxOK( "SAVE FAILED", "Filenames may not contain any of the following characters:" NL "\\ / ? * < > \" \' |", + "ShellGetSaveFilename( \"SAVE CONTROL CONFIG\", \"prefs/*.cs\", \"isMapFile\", \"saveMapFile\", $pref::Input::ActiveConfig );" ); + return; + } + + if (isDemo()) + %basePath = "demo_base/"; + else + %basePath = "base/"; + %mapFile = "prefs/" @ %filename @ ".cs"; + if ( !isWriteableFileName( %basePath @ %mapFile ) ) + { + MessageBoxOK( "SAVE FAILED", "That is not a writeable file name. Please choose another file name.", + "ShellGetSaveFilename( \"SAVE CONTROL CONFIG\", \"prefs/*.cs\", \"isMapFile\", \"saveMapFile\", $pref::Input::ActiveConfig );" ); + return; + } + + if ( isFile( %mapFile ) && !isMapFile( %mapFile ) ) + { + MessageBoxOK( "SAVE FAILED", "A file of that name already exists and is not an input configuration file. Please choose another file name.", + "ShellGetSaveFilename( \"SAVE CONTROL CONFIG\", \"prefs/*.cs\", \"isMapFile\", \"saveMapFile\", $pref::Input::ActiveConfig );" ); + return; + } + + moveMap.save( %mapFile ); + // Append the observer action map: + observerMap.save( %mapFile, true ); + + // Write out the console toggle key: + %fObject = new FileObject(); + if ( %fObject.openForAppend( %mapFile ) ) + { + %bind = GlobalActionMap.getBinding( "toggleConsole" ); + if ( %bind !$= "" ) + { + %fObject.writeLine( "GlobalActionMap.bind(keyboard, \"" @ getField( %bind, 1 ) @ "\", toggleConsole);" ); + %fObject.close(); + } + } + %fObject.delete(); + + $pref::Input::ActiveConfig = %filename; +} + +//------------------------------------------------------------------------------ +function getMapDisplayName( %device, %action ) +{ + if ( %device $= "keyboard" ) + return( %action ); + else if ( strstr( %device, "mouse" ) != -1 ) + { + // Substitute "mouse" for "button" in the action string: + %pos = strstr( %action, "button" ); + if ( %pos != -1 ) + { + %mods = getSubStr( %action, 0, %pos ); + %object = getSubStr( %action, %pos, 1000 ); + %instance = getSubStr( %object, strlen( "button" ), 1000 ); + return( %mods @ "mouse" @ ( %instance + 1 ) ); + } + else + error( "Mouse input object other than button passed to getDisplayMapName!" ); + } + else if ( strstr( %device, "joystick" ) != -1 ) + { + // Substitute "joystick" for "button" in the action string: + %pos = strstr( %action, "button" ); + if ( %pos != -1 ) + { + %mods = getSubStr( %action, 0, %pos ); + %object = getSubStr( %action, %pos, 1000 ); + %instance = getSubStr( %object, strlen( "button" ), 1000 ); + return( %mods @ "joystick" @ ( %instance + 1 ) ); + } + else + { + %pos = strstr( %action, "pov" ); + if ( %pos != -1 ) + { + %wordCount = getWordCount( %action ); + %mods = %wordCount > 1 ? getWords( %action, 0, %wordCount - 2 ) @ " " : ""; + %object = getWord( %action, %wordCount - 1 ); + switch$ ( %object ) + { + case "upov": %object = "POV1 up"; + case "dpov": %object = "POV1 down"; + case "lpov": %object = "POV1 left"; + case "rpov": %object = "POV1 right"; + case "upov2": %object = "POV2 up"; + case "dpov2": %object = "POV2 down"; + case "lpov2": %object = "POV2 left"; + case "rpov2": %object = "POV2 right"; + default: %object = "??"; + } + return( %mods @ %object ); + } + else + error( "Unsupported Joystick input object passed to getDisplayMapName!" ); + } + } + + return( "??" ); +} + +//------------------------------------------------------------------------------ +function buildFullMapString( %index ) +{ + switch$ ( OP_ControlsPane.group ) + { + case "Observer": + %actionMap = observerMap; + %name = $ObsRemapName[%index]; + %cmd = $ObsRemapCmd[%index]; + + case "Main": + %actionMap = moveMap; + %name = $RemapName[%index]; + %cmd = $RemapCmd[%index]; + + default: + %actionMap = RTSMap; + %name = $RTSRemapName[%index]; + %cmd = $RTSRemapCmd[%index]; + } + + %temp = %actionMap.getBinding( %cmd ); + %device = getField( %temp, 0 ); + %object = getField( %temp, 1 ); + if ( %device !$= "" && %object !$= "" ) + %mapString = getMapDisplayName( %device, %object ); + else + %mapString = ""; + + return( %name TAB %mapString ); +} + +//------------------------------------------------------------------------------ +function OP_ControlGroupMenu::init( %this ) +{ + %selId = %this.getSelected(); + %this.clear(); + %this.add( "Main", 0 ); + %this.add( "Observer", 1 ); + %this.add( "RTS", 2 ); + %this.setSelected( %selId ); + %this.onSelect( %selId, %this.getTextById( %selId ) ); +} + +//------------------------------------------------------------------------------ +function OP_ControlGroupMenu::onSelect( %this, %id, %text ) +{ + OP_ControlsPane.group = %text; + OP_RemapList.fillList(); +} + +//------------------------------------------------------------------------------ +function OP_RemapList::fillList( %this ) +{ + switch$ ( OP_ControlsPane.group ) + { + case "Observer": %count = $ObsRemapCount; + case "RTS": %count = $RTSRemapCount; + default: %count = $RemapCount; + } + + %this.clear(); + for ( %i = 0; %i < %count; %i++ ) + %this.addRow( %i, buildFullMapString( %i ) ); + + // Set the console key: + %bind = GlobalActionMap.getBinding( "toggleConsole" ); + OP_ConsoleKeyBtn.setValue( getField( %bind, 1 ) ); +} + +//------------------------------------------------------------------------------ +function OP_RemapList::onDeleteKey( %this, %rowId ) +{ + switch$ ( OP_ControlsPane.group ) + { + case "Observer": + %actionMap = observerMap; + %cmd = $ObsRemapCmd[%rowId]; + case "Main": + %actionMap = moveMap; + %cmd = $RemapCmd[%rowId]; + default: + %actionMap = RTSMap; + %cmd = $RTSRemapCmd[%rowId]; + } + clearMapping( %actionMap, %cmd ); + %this.setRowById( %rowId, buildFullMapString( %rowId ) ); +} + +//------------------------------------------------------------------------------ +function OP_RemapList::doRemap( %this ) +{ + %selId = %this.getSelectedId(); + switch$ ( OP_ControlsPane.group ) + { + case "Observer": %name = $ObsRemapName[%selId]; + case "RTS": %name = $RTSRemapName[%selId]; + default: %name = $RemapName[%selId]; + } + + RemapFrame.setTitle( "REMAP \"" @ %name @ "\"" ); + RemapInputCtrl.mode = "move"; + RemapInputCtrl.index = %selId; + Canvas.pushDialog( RemapDlg ); +} + +//------------------------------------------------------------------------------ +function OP_ConsoleKeyBtn::doRemap( %this ) +{ + RemapFrame.setTitle( "REMAP \"Toggle Console\"" ); + RemapInputCtrl.mode = "consoleKey"; + RemapInputCtrl.index = 0; + Canvas.pushDialog( RemapDlg ); +} + +//------------------------------------------------------------------------------ +function RemapDlg::onWake( %this ) +{ + $enableDirectInput = "1"; + activateDirectInput(); + + if ( RemapInputCtrl.mode $= "consoleKey" ) + RemapText.setText( "Press a key to assign it to this action" NL "or Esc to cancel..." ); + else + RemapText.setText( "Press a key or button to assign it to this action" NL "or Esc to cancel..." ); +} + +//------------------------------------------------------------------------------ +function RemapDlg::onSleep( %this ) +{ + $enableDirectInput = "1"; + deactivateDirectInput(); +} + +//------------------------------------------------------------------------------ +function findRemapCmdIndex( %command ) +{ + switch$ ( OP_ControlsPane.group ) + { + case "Observer": + for ( %i = 0; %i < $ObsRemapCount; %i++ ) + { + if ( %command $= $ObsRemapCmd[%i] ) + return( %i ); + } + case "RTS": + for ( %i = 0; %i < $RTSRemapCount; %i++ ) + { + if ( %command $= $RTSRemapCmd[%i] ) + return( %i ); + } + default: + for ( %i = 0; %i < $RemapCount; %i++ ) + { + if ( %command $= $RemapCmd[%i] ) + return( %i ); + } + } + + return( -1 ); +} + +//------------------------------------------------------------------------------ +function clearMapping( %actionMap, %cmd ) +{ + %fullMapString = %actionMap.getBinding( %cmd ); + %mapCount = getRecordCount( %fullMapString ); + for ( %i = 0; %i < %mapCount; %i++ ) + { + %temp = getRecord( %fullMapString, %i ); + %actionMap.unbind( getField( %temp, 0 ), getField( %temp, 1 ) ); + } +} + +//------------------------------------------------------------------------------ +function redoMapping( %actionMap, %device, %action, %cmd, %oldIndex, %newIndex ) +{ + //%actionMap.bind( %device, %action, $RemapCmd[%newIndex] ); + %actionMap.bind( %device, %action, %cmd ); + OP_RemapList.setRowById( %oldIndex, buildFullMapString( %oldIndex ) ); + OP_RemapList.setRowById( %newIndex, buildFullMapString( %newIndex ) ); +} + +//------------------------------------------------------------------------------ +function redoConsoleMapping( %action, %oldIndex ) +{ + moveMap.unbind( "keyboard", %action ); + GlobalActionMap.bind( "keyboard", %action, "toggleConsole" ); + OP_ConsoleKeyBtn.setValue( %action ); + OP_RemapList.setRowById( %oldIndex, buildFullMapString( %oldIndex ) ); +} + +//------------------------------------------------------------------------------ +function RemapInputCtrl::onInputEvent( %this, %device, %action ) +{ + //error( "** onInputEvent called - device = " @ %device @ ", action = " @ %action @ " **" ); + Canvas.popDialog( RemapDlg ); + + // Test for the reserved keystrokes: + if ( %device $= "keyboard" ) + { + // Cancel... + if ( %action $= "escape" ) + { + // Do nothing... + return; + } + } + + if ( %this.mode $= "consoleKey" ) + { + if ( %device !$= "keyboard" ) + { + MessageBoxOK( "REMAP FAILED", "This command can only be bound to keys on the keyboard!" ); + return; + } + + %prevMap = GlobalActionMap.getCommand( %device, %action ); + if ( %prevMap !$= "" ) + { + MessageBoxOK( "REMAP FAILED", "\"" @ getMapDisplayName( %device, %action ) @ "\" is already bound to a non-remappable command!" ); + return; + } + + %mvMap = moveMap.getCommand( %device, %action ); + if ( %mvMap $= "" ) + { + GlobalActionMap.bind( %device, %action, "toggleConsole" ); + OP_ConsoleKeyBtn.setValue( %action ); + } + else + { + %mapName = getMapDisplayName( %device, %action ); + %mvMapIndex = findRemapCmdIndex( %mvMap ); + if ( %mvMapIndex == -1 ) + MessageBoxOK( "REMAP FAILED", "\"" @ %mapName @ "\" is already bound to a non-remappable command!" ); + else + MessageBoxYesNo( "WARNING", "\"" @ %mapName @ "\" is already bound to \"" + @ $RemapName[%mvMapIndex] @ "\"!" + NL "Do you want to undo this mapping?", + "redoConsoleMapping(\"" @ %action @ "\", " @ %mvMapIndex @ ");", "" ); + return; + } + } + else + { + switch$ ( OP_ControlsPane.group ) + { + case "Observer": + %actionMap = observerMap; + %cmd = $ObsRemapCmd[%this.index]; + %name = $ObsRemapName[%this.index]; + + case "RTS": + %actionMap = RTSMap; + %cmd = $RTSRemapCmd[%this.index]; + %name = $RTSRemapName[%this.index]; + + default: + %actionMap = moveMap; + %cmd = $RemapCmd[%this.index]; + %name = $RemapName[%this.index]; + } + + // First check to see if the given action is already mapped: + %prevMap = %actionMap.getCommand( %device, %action ); + if ( %prevMap !$= %cmd ) + { + if ( %prevMap $= "" ) + { + %actionMap.bind( %device, %action, %cmd ); + OP_RemapList.setRowById( %this.index, buildFullMapString( %this.index ) ); + } + else + { + %mapName = getMapDisplayName( %device, %action ); + %prevMapIndex = findRemapCmdIndex( %prevMap ); + if ( %prevMapIndex == -1 ) + MessageBoxOK( "REMAP FAILED", "\"" @ %mapName @ "\" is already bound to a non-remappable command!" ); + else + { + switch$ ( OP_ControlsPane.group ) + { + case "Observer": + %prevCmdName = $ObsRemapName[%prevMapIndex]; + case "RTS": + %prevCmdName = $RTSRemapName[%prevMapIndex]; + default: + %prevCmdName = $RemapName[%prevMapIndex]; + } + + MessageBoxYesNo( "WARNING", + "\"" @ %mapName @ "\" is already bound to \"" + @ %prevCmdName @ "\"!\nDo you want to undo this mapping?", + "redoMapping(" @ %actionMap @ ", " @ %device @ ", \"" @ %action @ "\", \"" @ %cmd @ "\", " @ %prevMapIndex @ ", " @ %this.index @ ");", "" ); + } + return; + } + } + } +} + +//------------------------------------------------------------------------------ +function OP_JoystickTgl::onAction( %this ) +{ + %on = %this.getValue(); + if ( %on ) + enableJoystick(); + else + disableJoystick(); + + OP_ConfigureJoystickBtn.setActive( %on ); +} + +//------------------------------------------------------------------------------ +function MouseConfigDlg::onWake( %this ) +{ + MouseXSlider.setValue( moveMap.getScale( mouse, xaxis ) / 2 ); + MouseYSlider.setValue( moveMap.getScale( mouse, yaxis ) / 2 ); + InvertMouseTgl.setValue( moveMap.isInverted( mouse, yaxis ) ); + + MouseZActionMenu.clear(); + MouseZActionMenu.add( "Nothing", 1 ); + MouseZActionMenu.add( "Cycle Weapon", 2 ); + MouseZActionMenu.add( "Next Weapon Only", 3 ); +// MouseZActionMenu.add( "Cycle Zoom Level", 4 ); + + %bind = moveMap.getCommand( "mouse", "zaxis" ); + %selId = 1; + switch$ ( %bind ) + { + case "cycleWeaponAxis": + %selId = 2; + case "cycleNextWeaponOnly": + %selId = 3; + } + MouseZActionMenu.setSelected( %selId ); +} + +//------------------------------------------------------------------------------ +function MouseConfigDlg::onOK( %this ) +{ + %xSens = MouseXSlider.getValue() * 2; + %ySens = MouseYSlider.getValue() * 2; + moveMap.bind( mouse, xaxis, "S", %xSens, "yaw" ); + %yFlags = InvertMouseTgl.getValue() ? "SI" : "S"; + moveMap.bind( mouse, yaxis, %yFlags, %ySens, "pitch" ); + + switch ( MouseZActionMenu.getSelected() ) + { + case 2: + moveMap.bind( mouse, zaxis, cycleWeaponAxis ); + case 3: + moveMap.bind( mouse, zaxis, cycleNextWeaponOnly ); + default: + moveMap.unbind( mouse, zaxis ); + } + + Canvas.popDialog( MouseConfigDlg ); +} + +//------------------------------------------------------------------------------ +function MouseXSlider::sync( %this ) +{ + %thisValue = %this.getValue(); + MouseXText.setValue( "(" @ getSubStr( %thisValue, 0, 4 ) @ ")" ); + if ( $pref::Input::LinkMouseSensitivity ) + { + if ( MouseYSlider.getValue() != %thisValue ) + MouseYSlider.setValue( %thisValue ); + } +} + +//------------------------------------------------------------------------------ +function MouseYSlider::sync( %this ) +{ + %thisValue = %this.getValue(); + MouseYText.setValue( "(" @ getSubStr( %thisValue, 0, 4 ) @ ")" ); + if ( $pref::Input::LinkMouseSensitivity ) + { + if ( MouseXSlider.getValue() != %thisValue ) + MouseXSlider.setValue( %thisValue ); + } +} + +//------------------------------------------------------------------------------ +// Joystick Config dialog: +//------------------------------------------------------------------------------ +$JoyRemapCount = 0; +$JoyRemapName[$JoyRemapCount] = "Look Up/Down"; +$JoyRemapCmd[$JoyRemapCount] = "joyPitch"; +$JoyRemapCount++; +$JoyRemapName[$JoyRemapCount] = "Turn Left/Right"; +$JoyRemapCmd[$JoyRemapCount] = "joyYaw"; +$JoyRemapCount++; +$JoyRemapName[$JoyRemapCount] = "Move Forward/Backward"; +$JoyRemapCmd[$JoyRemapCount] = "joystickMoveY"; +$JoyRemapCount++; +$JoyRemapName[$JoyRemapCount] = "Strafe Left/Right"; +$JoyRemapCmd[$JoyRemapCount] = "joystickMoveX"; +$JoyRemapCount++; +$JoyRemapName[$JoyRemapCount] = "Cycle Weapon"; +$JoyRemapCmd[$JoyRemapCount] = "cycleWeaponAxis"; +$JoyRemapCount++; + +//------------------------------------------------------------------------------ +function JoystickConfigDlg::onWake( %this ) +{ + // Add all of the axis tabs: + %temp = getJoystickAxes( 0 ); + %tryCount = getField( %temp, 0 ); + $JoyAxisCount = 0; + + for ( %i = 0; %i < %tryCount; %i++ ) + { + %type = getField( %temp, %i + 1 ); + switch$ ( %type ) + { + case "X": %tabName = "X Axis"; %tabType = "xaxis"; + case "Y": %tabName = "Y Axis"; %tabType = "yaxis"; + case "Z": %tabName = "Z Axis"; %tabType = "zaxis"; + case "R": %tabName = "R Axis"; %tabType = "rxaxis"; + case "U": %tabName = "U Axis"; %tabType = "ryaxis"; + case "V": %tabName = "V Axis"; %tabType = "rzaxis"; + case "S": %tabName = "Slider"; %tabType = "slider"; + case "L": %tabName = "Slider 2"; %tabType = "slider2"; + default: %tabName = ""; + } + + if ( %tabName !$= "" ) + { + $JoyAxisTab[$JoyAxisCount] = new ShellTabButton() { + profile = "ShellTabProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "29" SPC ( 52 + ( %i * 30 ) ); + extent = "100 38"; + minExtent = "48 38"; + visible = "1"; + command = "JoystickConfigDlg.setPane(" @ %i @ ");"; + helpTag = "0"; + text = %tabName; + type = %tabType; + }; + + $JoyAxisCount++; + JoystickConfigFrame.add( $JoyAxisTab[%i] ); + } + } + + // Fill the action menu: + JoyAxisActionMenu.clear(); + for ( %i = 0; %i < $JoyRemapCount; %i++ ) + JoyAxisActionMenu.add( $JoyRemapName[%i], %i ); + JoyAxisActionMenu.add( "Nothing", 255 ); + + // Select the first axis: + %this.setPane( %this.pane ); +} + +//------------------------------------------------------------------------------ +function JoystickConfigDlg::onSleep( %this ) +{ + // Save the current pane's settings: + bindJoystickAxis( %this.pane, JoyAxisActionMenu.getSelected() ); + for ( %i = 0; %i < $JoyAxisCount; %i++ ) + { + JoystickConfigFrame.remove( $JoyAxisTab[%i] ); + $JoyAxisTab[%i].delete(); + } +} + +//------------------------------------------------------------------------------ +function JoystickConfigDlg::setPane( %this, %pane ) +{ + if ( %this.pane != %pane ) + { + // Save the previous axes' settings: + bindJoystickAxis( %this.pane, JoyAxisActionMenu.getSelected() ); + %this.pane = %pane; + } + + for ( %i = 0; %i < $joyAxisCount; %i++ ) + $JoyAxisTab[%i].setValue( %i == %pane ); + + // Update the config controls: + %axisType = $JoyAxisTab[%pane].type; + %bind = moveMap.getCommand( "joystick", %axisType ); + if ( %bind !$= "" ) + { + for ( %i = 0; %i < $JoyRemapCount; %i++ ) + { + if ( $JoyRemapCmd[%i] $= %bind ) + { + JoyAxisActionMenu.setSelected( %i ); + JoyAxisActionMenu.setText( $JoyRemapName[%i] ); + JoyAxisActionMenu.onSelect( %i, "" ); + break; + } + } + + if ( %i == $JoyRemapCount ) + { + JoyAxisActionMenu.setSelected( 255 ); // 255 is the code for "Nothing" + JoyAxisActionMenu.onSelect( 255, "" ); + } + + %scale = moveMap.getScale( "joystick", %axisType ); + JoyAxisSlider.setValue( %scale / 100 ); + %deadZone = moveMap.getDeadZone( "joystick", %axisType ); + if ( %deadZone $= "0 0" ) + DeadZoneSlider.setValue( 0.0 ); + else + DeadZoneSlider.setValue( abs( firstWord( %deadZone ) ) / %scale ); + InvertJoyAxisTgl.setValue( moveMap.isInverted( "joystick", %axisType ) ); + //JoyAxisRelativeTgl.setValue( moveMap.isRelativeAxis( "joystick", %axisType ) ); + } + else + { + JoyAxisActionMenu.setSelected( 255 ); // 255 is the code for "Nothing" + JoyAxisActionMenu.onSelect( 255, "" ); + JoyAxisSlider.setValue( 0.5 ); + DeadZoneSlider.setValue( 0.0 ); + InvertJoyAxisTgl.setValue( false ); + //JoyAxisRelativeTgl.setValue( %axisType $= "slider" ); + } +} + +//------------------------------------------------------------------------------ +function JoyAxisActionMenu::onSelect( %this, %id, %text ) +{ + %on = ( %id < $JoyRemapCount ); + JoyAxisSlider.setActive( %on ); + JoySensText.setVisible( %on ); + DeadZoneSlider.setActive( %on ); + DeadZoneText.setVisible( %on ); + InvertJoyAxisTgl.setActive( %on ); + //JoyAxisRelativeTgl.setActive( %on ); +} + +//------------------------------------------------------------------------------ +function JoySensText::update( %this ) +{ + %this.setValue( "(" @ getSubStr( JoyAxisSlider.getValue(), 0, 4 ) @ ")" ); +} + +//------------------------------------------------------------------------------ +function DeadZoneText::update( %this ) +{ + %val = DeadZoneSlider.getValue(); + %percent = %val * 100; + %temp = strstr( %percent, "." ); + if ( %temp != -1 ) + %percent = getSubStr( %percent, 0, %temp ); + + %this.setValue( "(" @ %percent @ "%)" ); +} + +//------------------------------------------------------------------------------ +function bindJoystickAxis( %axisIndex, %cmdIndex ) +{ + %cmd = $JoyRemapCmd[%cmdIndex]; + %axis = $JoyAxisTab[%axisIndex].type; + if ( %cmdIndex > $JoyRemapCount ) + { + // Make sure the axis is unbound: + moveMap.unbind( "joystick", %axis ); + return; + } + + %sens = JoyAxisSlider.getValue() * 100; + %delta = DeadZoneSlider.getValue() * %sens; + %flags = "S"; + if ( InvertJoyAxisTgl.getValue() ) + %flags = %flags @ "I"; +// if ( JoyAxisRelativeTgl.getValue() ) +// %flags = %flags @ "L"; + if ( %delta > 0 ) + { + %deadZone = "-" @ %delta SPC %delta; + moveMap.bind( "joystick", %axis, %flags @ "D", %deadZone, %sens, %cmd ); + } + else + moveMap.bind( "joystick", %axis, %flags, %sens, %cmd ); +} + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +// Network Settings: +// + +function updateNetworkSettings() +{ + $pref::Net::PacketRateToClient = mFloor( OP_PacketRateSlider.getValue() ); + $pref::Net::PacketSize = mFloor( OP_PacketSizeSlider.getValue() ); + $pref::Net::PacketRateToServer = mFloor( OP_UpdateRateSlider.getValue() ); + + // check the max rate: + if ( isObject( ServerConnection ) ) + ServerConnection.checkMaxRate(); + if ( isObject( ClientGroup ) ) + { + %count = ClientGroup.getCount(); + for ( %i = 0; %i < %count; %i++ ) + { + %cl = ClientGroup.getObject( %i ); + %cl.checkMaxRate(); + } + } +} + +function OP_NetworkDisplayHud::init(%this) +{ + %this.getPrefs(); + + %this.textHeight = 14; + %this.textOffset = 2; + + if(!%this.infoCallback) + { + %this.textProfile = 0; + return; + } + + // profile for the text fields + %this.textProfile = new GuiControlProfile() + { + fontType = $ShellButtonFont; + fontSize = $ShellButtonFontSize; + autoSizeWidth = true; + autoSizeHeight = true; + fontColors[6] = "128 128 128"; + }; + + %yOffset = %this.textOffset; + + for(%i = 0; %i < 6; %i++) + { + // set the text color + %this.textProfile.fontColors[%i] = %this.fieldColors[%i]; + + // create the text field + %this.textField[%i] = new GuiTextCtrl() + { + profile = %this.textProfile; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 " @ %yOffset; + extent = "190 " @ %this.textHeight; + visible = "1"; + }; + + // create the toggle field + %this.toggleField[%i] = new GuiTextCtrl() + { + profile = ShellActiveTextProfile; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 " @ %yOffset; + extent = "15 " @ %this.textHeight; + visible = "1"; + }; + + // create a mouse object + %this.mouseField[%i] = new GuiMouseEventCtrl(NetworkDisplayMouseCtrl) + { + profile = GuiDefaultProfile; + horizSizing = "right"; + vertSizing = "bottom"; + position = "10 " @ %yOffset; + extent = "200 " @ %this.textHeight; + visible = "1"; + fieldIndex = %i; + }; + + OP_NetworkDisplayTextFrame.add(%this.textField[%i]); + OP_NetworkDisplayTextFrame.add(%this.toggleField[%i]); + OP_NetworkDisplayTextFrame.add(%this.mouseField[%i]); + + %yOffset += (%this.textHeight + %this.textOffset); + } + %this.infoUpdate(0, 0, 0, 0, 0, 0); +} + +function NetworkDisplayMouseCtrl::onMouseDown(%this) +{ + %b = OP_NetworkDisplayHud.renderField[%this.fieldIndex]; + OP_NetworkDisplayHud.renderField[%this.fieldIndex] = !%b; + OP_NetworkDisplayHud.updateToggles(); +} + +function OP_NetworkDisplayHud::uninit(%this) +{ + if(!%this.infoCallback) + return; + + if(isObject(%this.textProfile)) + %this.textProfile.delete(); + + for(%i = 0; %i < 6; %i++) + { + if(isObject(%this.textField[%i])) + %this.textField[%i].delete(); + + if(isObject(%this.toggleField[%i])) + %this.toggleField[%i].delete(); + + if(isObject(%this.mouseField[%i])) + %this.mouseField[%i].delete(); + } +} + +function OP_NetworkDisplayHud::updateToggles(%this) +{ + // update the toggles + $pref::Net::graphFields = 0; + + for(%i = 0; %i < 6; %i++) + { + $pref::Net::graphFields |= %this.renderField[%i] << %i; + %this.toggleField[%i].setText(%this.renderField[%i] ? "+" : "-"); + } +} + +function OP_NetworkDisplayHud::infoUpdate(%this, %ping, %packetLoss, %sendPackets, %sendBytes, %receivePackets, %receiveBytes) +{ + %this.updateToggles(); + + // set the text + %this.textField[0].setText("\c0Ping: " @ mFormatFloat(%ping, "%4.0f") @ "ms"); + %this.textField[1].setText("\c1Packet Loss: " @ mFormatFloat(%packetLoss, "%3.0f") @ "%"); + %this.textField[2].setText("\c2Send Packets: " @ mFormatFloat(%sendPackets, "%2.1f") @ "pps"); + %this.textField[3].setText("\c3Send Bytes: " @ mFormatFloat(%sendBytes, "%5.0f") @ "bps"); + %this.textField[4].setText("\c4Receive Packets: " @ mFormatFloat(%receivePackets, "%2.1f") @ "pps"); + %this.textField[5].setText("\c5Receive Bytes: " @ mFormatFloat(%receiveBytes, "%5.0f") @ "bps"); +} + +// "" +// [1,32] [8,32] [100,450] +$NetworkPresetCount = 0; +$NetworkPreset[$NetworkPresetCount] = "28.8 Modem\t12\t16\t200"; $NetworkPresetCount++; +$NetworkPreset[$NetworkPresetCount] = "56K Modem\t16\t20\t240"; $NetworkPresetCount++; +$NetworkPreset[$NetworkPresetCount] = "DSL\t20\t24\t350"; $NetworkPresetCount++; +$NetworkPreset[$NetworkPresetCount] = "Cable\t24\t24\t400"; $NetworkPresetCount++; +$NetworkPreset[$NetworkPresetCount] = "T1/LAN\t32\t32\t450"; $NetworkPresetCount++; + +function OP_NetworkPresetsMenu::init( %this ) +{ + %this.clear(); + for(%i = 0; %i < $NetworkPresetCount; %i++) + %this.add( getField($NetworkPreset[%i], 0), %i); + + // don't update settings on init (only update when values change) + %this.updateSettings = false; + %this.setSelected($pref::Net::Preset); + %this.updateSettings = true; +} + +function OP_NetworkPresetsMenu::onSelect( %this, %id, %text ) +{ + OP_PacketRateSlider.setValue( getField($NetworkPreset[%id], 1) ); + OP_UpdateRateSlider.setValue( getField($NetworkPreset[%id], 2) ); + OP_PacketSizeSlider.setValue( getField($NetworkPreset[%id], 3) ); + + if(%this.updateSettings) + updateNetworkSettings(); + $pref::Net::Preset = %id; +} + +//------------------------------------------------------------------------------ +function OP_MasterServerMenu::init( %this ) +{ + %this.clear(); + // You can change these strings, but NOT THE IDS! + %this.add( "Always", 1 ); + %this.add( "When Not Full", 2 ); + %this.add( "Never", 3 ); +} + +//------------------------------------------------------------------------------ +function OP_MasterServerMenu::onSelect( %this, %id, %text ) +{ + switch( %id ) + { + case 2: + $pref::Net::DisplayOnMaster = "NotFull"; + case 3: + $pref::Net::DisplayOnMaster = "Never"; + default: + $pref::Net::DisplayOnMaster = "Always"; + } +} + +//------------------------------------------------------------------------------ +function OP_RegionMenu::init( %this ) +{ + %this.clear(); + %this.add( "North America East", 1 ); + %this.add( "North America West", 2 ); + %this.add( "South America", 4 ); + %this.add( "Australia", 8 ); + %this.add( "Asia", 16 ); + %this.add( "Europe", 32 ); +} + +//------------------------------------------------------------------------------ +function OP_RegionMenu::onSelect( %this, %id, %text ) +{ + $pref::Net::RegionMask = %id; +} + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +// Game Settings: +// +function OP_LaunchScreenMenu::init( %this ) +{ + %this.clear(); + %this.add( "Game", 1 ); + %this.add( "Email", 4 ); + %this.add( "Chat", 5 ); + %this.add( "Browser", 6 ); + %this.add( "Mod Browser", 7 ); +} + +//------------------------------------------------------------------------------ +function toggleInvertYAxis() +{ + // Catch the case where this is toggled in-game while in a vehicle: + if ( isObject( passengerKeys ) ) + { + %bind = passengerKeys.getBinding( pitch ); + if ( %bind !$= "" ) + { + %device = getField( %bind, 0 ); + %action = getField( %bind, 1 ); + %flags = $pref::Vehicle::InvertYAxis ? "SDI" : "SD"; + %deadZone = passengerKeys.getDeadZone( %device, %action ); + %scale = passengerKeys.getScale( %device, %action ); + passengerKeys.bind( %device, %action, %flags, %deadZone, %scale, pitch ); + } + } +} + +//------------------------------------------------------------------------------ +function toggleImmersion() +{ + MessageBoxOK( "Force Feedback", "This will take effect the next time you start Tribes 2." ); +} + +//------------------------------------------------------------------------------ +function toggleVehicleTeleportPref() +{ + // If we are in a game, let the server know we've changed; + if ( isObject( ServerConnection ) ) + commandToServer( 'EnableVehicleTeleport', $pref::Vehicle::pilotTeleport ); +} diff --git a/scripts/PracticeCTFGame.cs b/scripts/PracticeCTFGame.cs index cf9f35f..f69044f 100644 --- a/scripts/PracticeCTFGame.cs +++ b/scripts/PracticeCTFGame.cs @@ -1,3100 +1,3100 @@ -// DisplayName = Capture the Flag (Practice) - -//--- GAME RULES BEGIN --- -//Prevent enemy from capturing your flag -//Score one point for grabbing the enemy's flag -//To capture, your flag must be at its stand -//Score 100 points each time enemy flag is captured -//--- GAME RULES END --- - -//exec the AI scripts -exec("scripts/aiPracticeCtf.cs"); - -$InvBanList[PracticeCTF, "MiningTool"] = 1; - -//-- tracking --- -function PracticeCTFGame::initGameVars(%game) -{ - // z0dd - ZOD: Zero out Practice mode options - $TeamDeployableMin[TurretIndoorDeployable] = 4; - $TeamDeployableMin[TurretOutdoorDeployable] = 4; - - // z0dd - ZOD: We need only zero these when server comes up for first time. - if(!$pctfLoaded) - { - $PracticeCtf::SpawnFavs = 0; - $PracticeCtf::SpawnOnly = 0; - $PracticeCtf::AutoFlagReturn = 0; - $PracticeCtf::NoScoreLimit = 0; - $PracticeCtf::ProtectStatics = 0; - $PracticeCtf::UnlimAmmo = 0; - $pctfLoaded = 1; - } - %game.SCORE_PER_SUICIDE = 0; // z0dd - ZOD, 8/19/02. No penalty for suicide! Was -10 - %game.SCORE_PER_TEAMKILL = -10; - %game.SCORE_PER_DEATH = 0; - %game.SCORE_PER_TK_DESTROY = -10; // z0dd - ZOD, 10/03/02. Penalty for TKing equiptment. - - %game.SCORE_PER_KILL = 10; - %game.SCORE_PER_PLYR_FLAG_CAP = 30; - %game.SCORE_PER_PLYR_FLAG_TOUCH = 20; - %game.SCORE_PER_TEAM_FLAG_CAP = 100; - %game.SCORE_PER_TEAM_FLAG_TOUCH = 1; - %game.SCORE_PER_ESCORT_ASSIST = 5; - %game.SCORE_PER_HEADSHOT = 1; - %game.SCORE_PER_REARSHOT = 1; // z0dd - ZOD, 8/25/02. Rear Lance hits - - %game.SCORE_PER_TURRET_KILL = 10; // controlled - %game.SCORE_PER_TURRET_KILL_AUTO = 3; // uncontrolled - %game.SCORE_PER_FLAG_DEFEND = 5; - %game.SCORE_PER_CARRIER_KILL = 5; - %game.SCORE_PER_FLAG_RETURN = 10; - %game.SCORE_PER_STALEMATE_RETURN = 15; - %game.SCORE_PER_GEN_DEFEND = 5; - - %game.SCORE_PER_DESTROY_GEN = 10; - %game.SCORE_PER_DESTROY_SENSOR = 4; - %game.SCORE_PER_DESTROY_TURRET = 5; - %game.SCORE_PER_DESTROY_ISTATION = 2; - %game.SCORE_PER_DESTROY_VSTATION = 5; - %game.SCORE_PER_DESTROY_MPBTSTATION = 5; // z0dd - ZOD, 4/24/02. MPB Teleporter - %game.SCORE_PER_DESTROY_SOLAR = 5; - %game.SCORE_PER_DESTROY_SENTRY = 4; - %game.SCORE_PER_DESTROY_DEP_SENSOR = 1; - %game.SCORE_PER_DESTROY_DEP_INV = 2; - %game.SCORE_PER_DESTROY_DEP_TUR = 3; - - %game.SCORE_PER_DESTROY_SHRIKE = 5; - %game.SCORE_PER_DESTROY_BOMBER = 8; - %game.SCORE_PER_DESTROY_TRANSPORT = 5; - %game.SCORE_PER_DESTROY_WILDCAT = 5; - %game.SCORE_PER_DESTROY_TANK = 8; - %game.SCORE_PER_DESTROY_MPB = 12; - %game.SCORE_PER_PASSENGER = 2; - - %game.SCORE_PER_REPAIR_GEN = 8; - %game.SCORE_PER_REPAIR_SENSOR = 1; - %game.SCORE_PER_REPAIR_TURRET = 4; - %game.SCORE_PER_REPAIR_ISTATION = 2; - %game.SCORE_PER_REPAIR_VSTATION = 4; - %game.SCORE_PER_REPAIR_MPBTSTATION = 4; // z0dd - ZOD, 4/24/02. MPB Teleporter - %game.SCORE_PER_REPAIR_SOLAR = 4; - %game.SCORE_PER_REPAIR_SENTRY = 2; - %game.SCORE_PER_REPAIR_DEP_TUR = 3; - %game.SCORE_PER_REPAIR_DEP_INV = 2; - - %game.FLAG_RETURN_DELAY = 45 * 1000; //45 seconds - - %game.TIME_CONSIDERED_FLAGCARRIER_THREAT = 3 * 1000; //after damaging enemy flag carrier - %game.RADIUS_GEN_DEFENSE = 20; //meters - %game.RADIUS_FLAG_DEFENSE = 20; //meters - - %game.TOUCH_DELAY_MS = 20000; //20 secs - - %game.fadeTimeMS = 2000; - - %game.notifyMineDist = 7.5; - - %game.stalemate = false; - %game.stalemateObjsVisible = false; - %game.stalemateTimeMS = 60000; - %game.stalemateFreqMS = 15000; - %game.stalemateDurationMS = 6000; -} - -package PracticeCTFGame -{ - ///////////////////////////////////////////////////////////////////////////////////////// - // Practice Mode overloads ////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////// - - function ShapeBase::cleanNonType(%this, %type) - { - // z0dd - ZOD: If the map is multi mission type, need to make sure the CTF flags stay put - if(%type $= PracticeCTF) - { - for(%h = 0; (%typeList = getWord(%this.missionTypesList, %h)) !$= ""; %h++) - if(%typeList $= CTF) - return; - } - Parent::cleanNonType(%this, %type); - } - - //function ShapeBase::maxInventory(%this,%data) - //{ - // z0dd - ZOD, 6/04/02: Allow virtually unlimited ammo in practice mode - // if(($PracticeCtf::UnlimAmmo == 1) && (%data.getName() !$= "RepairKit" && $CurrentMissionType $= Practice)) - // return 999; - // else - // return %this.getDatablock().max[%data.getName()]; - //} - - function Player::maxInventory(%this, %data) - { - // z0dd - ZOD, 6/17/02: Allow virtually unlimited ammo in practice mode - if(($PracticeCtf::UnlimAmmo == 1) && (%data.getName() !$= "RepairKit" && Game.class $= "PracticeCTFGame")) - { - return 999; - } - else - { - %max = ShapeBase::maxInventory(%this,%data); - if (%this.getInventory(AmmoPack)) - %max += AmmoPack.max[%data.getName()]; - - return %max; - } - } - - function StaticShapeData::damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType) - { - // z0dd - ZOD, 5/04/02. Check to see if damage should be applied to all static team assets. - if($PracticeCtf::ProtectStatics == 1 && %targetObject.getDataBlock().getClassName() !$= "TurretData" && !%targetObject.getDataBlock().deployedObject) - return; - else - parent::damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType); - } - - function Observer::onTrigger(%data,%obj,%trigger,%state) - { - if (%state == 0 || %trigger >= 4) - return; - - %client = %obj.getControllingClient(); - if (%client == 0) - return; - // z0dd - ZOD: Check for client projectile observation - switch$ (%obj.mode) - { - case "observerFollow": - if(%obj.projectile !$= "") - { - if(%trigger == 3) - { - clearBottomPrint(%client); - %client.camera.setFlyMode(); - %client.setControlObject(%client.player); - %obj.projectile = ""; // Clear the projectile - } - else - return; - } - else - Parent::onTrigger(%data,%obj,%trigger,%state); - - case "observerFly": - if(%obj.projectile !$= "") - { - if(%trigger == 3) - { - clearBottomPrint(%client); - %client.setControlObject(%client.player); - %obj.projectile = ""; // Clear the projectile - } - else - return; - } - else - Parent::onTrigger(%data,%obj,%trigger,%state); - - default: - Parent::onTrigger(%data,%obj,%trigger,%state); - } - } - - function Observer::setMode(%data, %obj, %mode, %targetObj) - { - if(%mode $= "") - return; - - %client = %obj.getControllingClient(); - // z0dd - ZOD: Check for client projectile observation - switch$ (%mode) - { - case "observerFollow": - if(%obj.projectile !$= "") - { - bottomPrint(%targetObj.sourceObject.client, "Observing Projectile.\nPress your jet key to resume to player control.", 0, 2); - %transform = %targetObj.initialPosition; - %obj.setOrbitMode(%targetObj, %transform, 0.2, 12.0, 4.5); - } - else - Parent::setMode(%data, %obj, %mode, %targetObj); - - case "observerFly": - if(%obj.projectile !$= "") - { - %obj.setTransform(%obj.getTransform()); - %obj.setFlyMode(); - bottomPrint(%client, "Free Fly Mode.\nPress your jet key to resume player control.", 0, 2); - } - else - Parent::setMode(%data, %obj, %mode, %targetObj); - - default: - Parent::setMode(%data, %obj, %mode, %targetObj); - } - %obj.mode = %mode; - } - - function MortarImage::onFire(%data, %obj, %slot) - { - // --------------------------------------------------------------------------- - // z0dd - ZOD, 10/14/02. Anti rapid fire mortar/missile fix. - if (%obj.cantFire !$= "") - { - return 0; - } - - %wpnName = %data.getName(); - %obj.cantFire = 1; - %preventTime = %data.stateTimeoutValue[4]; - %obj.reloadSchedule = schedule(%preventTime * 1000, %obj, resetFire, %obj); - // --------------------------------------------------------------------------- - - // z0dd - ZOD: Check for client projectile observation - %data.lightStart = getSimTime(); - if(%obj.client.mortarObs) - %data.projectile = ObsMortarShot; - - %p = new (%data.projectileType)() { - dataBlock = %data.projectile; - initialDirection = %obj.getMuzzleVector(%slot); - initialPosition = %obj.getMuzzlePoint(%slot); - sourceObject = %obj; - sourceSlot = %slot; - }; - MissionCleanup.add(%p); - if(%obj.client) - %obj.client.projectile = %p; - - %obj.decInventory(%data.ammo,1); - AIGrenadeThrown(%p); - - if(%obj.client.mortarObs) - { - %obj.client.camera.projectile = %p; - %obj.client.camera.getDataBlock().setMode(%obj.client.camera, "observerFollow", %p); - %obj.client.setControlObject(%obj.client.camera); - } - return %p; - } - - function AssaultMortarTurretBarrel::onFire(%data, %obj, %slot) - { - // z0dd - ZOD: Check for client projectile observation - %client = %obj.getControllingClient(); - if(%client) - %obj.client = %client; - - %data.lightStart = getSimTime(); - %useEnergyObj = %obj.getObjectMount(); - if(!%useEnergyObj) - %useEnergyObj = %obj; - - %energy = %useEnergyObj.getEnergyLevel(); - %vehicle = %useEnergyObj; - if( %useEnergyObj.turretObject.getCapacitorLevel() < %data.minEnergy ) - return; - - if(%client.mortarObs) - %data.projectile = ObsAssaultMortar; - - %p = new (%data.projectileType)() { - dataBlock = %data.projectile; - initialDirection = %obj.getMuzzleVector(%slot); - initialPosition = %obj.getMuzzlePoint(%slot); - sourceObject = %obj; - sourceSlot = %slot; - vehicleObject = %vehicle; - }; - MissionCleanup.add(%p); - if(%client) - %client.projectile = %p; - - %vehicle.turretObject.setCapacitorLevel( %vehicle.turretObject.getCapacitorLevel() - %data.fireEnergy ); - AIGrenadeThrown(%p); - if(%client.mortarObs) - { - %client.camera.projectile = %p; - %client.camera.getDataBlock().setMode(%client.camera, "observerFollow", %p); - %client.setControlObject(%client.camera); - } - // Stop the onFire from looping - %obj.setImageTrigger(4, false); - return %p; - } - - function AssaultPlasmaTurretBarrel::onFire(%data, %obj, %slot) - { - // Function used to kill console spam because of client - // client value added to AssaultMortarTurretBarrel::onFire - %obj.client = ""; - parent::onFire(%data, %obj, %slot); - } - - function MissileLauncherImage::onFire(%data,%obj,%slot) - { - // --------------------------------------------------------------------------- - // z0dd - ZOD, 10/14/02. Anti rapid fire mortar/missile fix. - if (%obj.cantFire !$= "") - { - return 0; - } - - %wpnName = %data.getName(); - %obj.cantFire = 1; - %preventTime = %data.stateTimeoutValue[4]; - %obj.reloadSchedule = schedule(%preventTime * 1000, %obj, resetFire, %obj); - // --------------------------------------------------------------------------- - - // z0dd - ZOD: Check for client projectile observation - %data.lightStart = getSimTime(); - - if(%obj.client.missileObs) - %data.projectile = ObsShoulderMissile; - - %p = new (%data.projectileType)() { - dataBlock = %data.projectile; - initialDirection = %obj.getMuzzleVector(%slot); - initialPosition = %obj.getMuzzlePoint(%slot); - sourceObject = %obj; - sourceSlot = %slot; - }; - MissionCleanup.add(%p); - MissileSet.add(%p); - if(%obj.client) - %obj.client.projectile = %p; - - %obj.decInventory(%data.ammo,1); - if(%obj.client.missileObs) - { - %obj.client.camera.projectile = %p; - %obj.client.camera.getDataBlock().setMode(%obj.client.camera, "observerFollow", %p); - %obj.client.setControlObject(%obj.client.camera); - } - - %target = %obj.getLockedTarget(); - if(%target) - %p.setObjectTarget(%target); - else if(%obj.isLocked()) - %p.setPositionTarget(%obj.getLockedPosition()); - else - %p.setNoTarget(); - } - - function MissileLauncherImage::onWetFire(%data, %obj, %slot) - { - // z0dd - ZOD: Check for client projectile observation - %data.lightStart = getSimTime(); - - if(%obj.client.missileObs) - %data.projectile = ObsShoulderMissile; - - %p = new (%data.projectileType)() { - dataBlock = %data.projectile; - initialDirection = %obj.getMuzzleVector(%slot); - initialPosition = %obj.getMuzzlePoint(%slot); - sourceObject = %obj; - sourceSlot = %slot; - }; - MissionCleanup.add(%p); - MissileSet.add(%p); - if(%obj.client) - %obj.client.projectile = %p; - - %obj.decInventory(%data.ammo,1); - if(%obj.client.missileObs) - { - %obj.client.camera.projectile = %p; - %obj.client.camera.getDataBlock().setMode(%obj.client.camera, "observerFollow", %p); - %obj.client.setControlObject(%obj.client.camera); - } - %p.setObjectTarget(0); - } - - function GrenadeLauncherImage::onFire(%data, %obj, %slot) - { - // z0dd - ZOD: Check for client projectile observation - %data.lightStart = getSimTime(); - if( %obj.station $= "" && %obj.isCloaked() ) - { - if( %obj.respawnCloakThread !$= "" ) - { - Cancel(%obj.respawnCloakThread); - %obj.setCloaked( false ); - %obj.respawnCloakThread = ""; - } - else - { - if( %obj.getEnergyLevel() > 20 ) - { - %obj.setCloaked( false ); - %obj.reCloak = %obj.schedule( 500, "setCloaked", true ); - } - } - } - if( %obj.client > 0 ) - { - %obj.setInvincibleMode(0 ,0.00); - %obj.setInvincible( false ); - } - if(%obj.client.grenadeObs) - %data.projectile = ObsGrenade; - - %p = new (%data.projectileType)() { - dataBlock = %data.projectile; - initialDirection = %obj.getMuzzleVector(%slot); - initialPosition = %obj.getMuzzlePoint(%slot); - sourceObject = %obj; - sourceSlot = %slot; - }; - MissionCleanup.add(%p); - if(%obj.client) - %obj.client.projectile = %p; - - %obj.decInventory(%data.ammo,1); - AIGrenadeThrown(%p); - if(%obj.client.grenadeObs) - { - %obj.client.camera.projectile = %p; - %obj.client.camera.getDataBlock().setMode(%obj.client.camera, "observerFollow", %p); - %obj.client.setControlObject(%obj.client.camera); - } - return %p; - } - - function DiscImage::onFire(%data, %obj, %slot) - { - // z0dd - ZOD: Check for client projectile observation - %data.lightStart = getSimTime(); - if( %obj.station $= "" && %obj.isCloaked() ) - { - if( %obj.respawnCloakThread !$= "" ) - { - Cancel(%obj.respawnCloakThread); - %obj.setCloaked( false ); - %obj.respawnCloakThread = ""; - } - else - { - if( %obj.getEnergyLevel() > 20 ) - { - %obj.setCloaked( false ); - %obj.reCloak = %obj.schedule( 500, "setCloaked", true ); - } - } - } - if( %obj.client > 0 ) - { - %obj.setInvincibleMode(0 ,0.00); - %obj.setInvincible( false ); - } - if(%obj.client.discObs) - %data.projectile = ObsDiscProjectile; - - %p = new (%data.projectileType)() { - dataBlock = %data.projectile; - initialDirection = %obj.getMuzzleVector(%slot); - initialPosition = %obj.getMuzzlePoint(%slot); - sourceObject = %obj; - sourceSlot = %slot; - }; - MissionCleanup.add(%p); - if(%obj.client) - %obj.client.projectile = %p; - - %obj.decInventory(%data.ammo,1); - if(%obj.client.discObs) - { - %obj.client.camera.projectile = %p; - %obj.client.camera.getDataBlock().setMode(%obj.client.camera, "observerFollow", %p); - %obj.client.setControlObject(%obj.client.camera); - } - return %p; - } - - function ProjectileData::onExplode(%data, %proj, %pos, %mod) - { - // z0dd - ZOD: If client is observing this projectile, let client camera free fly - if(%proj.sourceObject.client !$="" && isObject(%proj.sourceObject)) - { - %client = %proj.sourceObject.client; - %camera = %proj.sourceObject.client.getControlObject(); - if(%camera == %client.camera && %proj == %camera.projectile) - { - clearBottomPrint(%client); - %client.camera.getDataBlock().setMode(%client.camera, "observerFly"); - } - } - Parent::onExplode(%data, %proj, %pos, %mod); - } - - function Beacon::onUse(%data, %obj) - { - if(%obj.client.transMode) - deployTransferPad(%data, %obj); - else - Parent::onUse(%data, %obj); - } - - function StationInventory::stationReady(%data, %obj) - { - //Display the Inventory Station GUI here - %obj.notReady = 1; - %obj.inUse = "Down"; - %obj.schedule(500,"playThread",$ActivateThread,"activate1"); - %player = %obj.triggeredBy; - %energy = %player.getEnergyLevel(); - %max = %player.getDatablock().maxEnergy; // z0dd - ZOD, 4/20/02. Inv energy bug fix - %player.setCloaked(true); - %player.schedule(500, "setCloaked", false); - if (!%player.client.isAIControlled()) - { - if($PracticeCtf::SpawnOnly) // z0dd - ZOD: Test for spawn only - getAmmoStationLovin(%player.client); - else - buyFavorites(%player.client); - } - %player.setEnergyLevel(mFloor(%player.getDatablock().maxEnergy * %energy / %max)); // z0dd - ZOD, 4/20/02. Inv energy bug fix - %data.schedule( 500, "beginPersonalInvEffect", %obj ); - } - - function MobileInvStation::stationReady(%data, %obj) - { - //Display the Inventory Station GUI here - %obj.notReady = 1; - %obj.inUse = "Down"; - %obj.schedule(200,"playThread",$ActivateThread,"activate1"); - %obj.getObjectMount().playThread($ActivateThread,"Activate"); - %player = %obj.triggeredBy; - %energy = %player.getEnergyLevel(); - %player.setCloaked(true); - %player.schedule(900, "setCloaked", false); - if (!%player.client.isAIControlled()) - { - if($PracticeCtf::SpawnOnly) // z0dd - ZOD: Test for spawn only - getAmmoStationLovin(%player.client); - else - buyFavorites(%player.client); - } - %player.setEnergyLevel(%energy); - } - - function DeployedStationInventory::stationReady(%data, %obj) - { - %obj.notReady = 1; - %player = %obj.triggeredBy; - %obj.playThread($ActivateThread,"activate1"); - if (!%player.client.isAIControlled()) - { - if($PracticeCtf::SpawnOnly) // z0dd - ZOD: Test for spawn only - getAmmoStationLovin(%player.client); - else - buyDeployableFavorites(%player.client); - } - } - - function Flag::onEnterLiquid(%data, %obj, %coverage, %type) - { - if(%type > 3) // 1-3 are water, 4+ is lava and quicksand(?) - { - //error("flag("@%obj@") is in liquid type" SPC %type); - if($PracticeCtf::AutoFlagReturn) // z0dd - ZOD: Test automatic flag returns - Game.flagReturn(%obj); - else - Game.schedule(3000, flagReturn, %obj); - } - } - ///////////////////////////////////////////////////////////////////////////////////////// - - function ShapeBaseData::onDestroyed(%data, %obj) - { - %scorer = %obj.lastDamagedBy; - if(!isObject(%scorer)) - return; - - if( (%scorer.getType() & $TypeMasks::GameBaseObjectType) && %scorer.getDataBlock().catagory $= "Vehicles" ) - { - // z0dd - ZOD, 6/18/02. %name was never defined. - %name = %scorer.getDatablock().getName(); - if(%name $= "BomberFlyer" || %name $= "AssaultVehicle") - %gunnerNode = 1; - else - %gunnerNode = 0; - - if(%scorer.getMountNodeObject(%gunnerNode)) - { - %destroyer = %scorer.getMountNodeObject(%gunnerNode).client; - %scorer = %destroyer; - %damagingTeam = %scorer.team; - } - } - else if(%scorer.getClassName() $= "Turret") - { - if(%scorer.getControllingClient()) - { - //manned turret - %destroyer = %scorer.getControllingClient(); - %scorer = %destroyer; - %damagingTeam = %scorer.team; - } - else - { - return; //unmanned turret - } - } - - if(!%damagingTeam) - %damagingTeam = %scorer.team; - - // z0dd - ZOD, 10/03/02. Total re-write from here down. - if(%damagingTeam == %obj.team) - { - if(!%obj.getDataBlock().deployedObject) - { - teamDestroyMessage(%scorer, 'msgTkDes', '\c5Teammate %1 destroyed your team\'s %2!', %scorer.name, Game.cleanWord(%obj.getDataBlock().targetTypeTag)); - Game.awardScoreTkDestroy(%scorer); - } - return; - } - - %objType = %obj.getDataBlock().getName(); - switch$ ( %objType ) - { - case "GeneratorLarge": - teamDestroyMessage(%scorer, 'msgGenDestroyed', '\c5%1 destroyed a %2 Generator!', %scorer.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - %score = game.awardScoreGenDestroy(%scorer); - - case "SolarPanel": - teamDestroyMessage(%scorer, 'msgSolarDestroyed', '\c5%1 destroyed a %2 Solar Panel!', %scorer.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - %score = game.awardScoreSolarDestroy(%scorer); - game.shareScore(%score, %score); - - case "SensorLargePulse": - teamDestroyMessage(%scorer, 'msgSensorDestroyed', '\c5%1 destroyed a %2 Sensor!', %scorer.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - %score = game.awardScoreSensorDestroy(%scorer); - - case "SensorMediumPulse": - teamDestroyMessage(%scorer, 'msgSensorDestroyed', '\c5%1 destroyed a %2 Sensor!', %scorer.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - %score = game.awardScoreSensorDestroy(%scorer); - - case "DeployedMotionSensor": - teamDestroyMessage(%scorer, 'msgDepSenDestroyed', '\c5%1 destroyed a Deployable Sensor!', %scorer.name); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - %score = game.awardScoreDepSensorDestroy(%scorer); - - case "DeployedPulseSensor": - teamDestroyMessage(%scorer, 'msgDepSenDestroyed', '\c5%1 destroyed a Deployable Sensor!', %scorer.name); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - %score = game.awardScoreDepSensorDestroy(%scorer); - - case "StationInventory": - teamDestroyMessage(%scorer, 'msgInvDestroyed', '\c5%1 destroyed a %2 Inventory Station!', %scorer.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - %score = game.awardScoreInvDestroy(%scorer); - - case "StationAmmo": - teamDestroyMessage(%scorer, 'msgInvDestroyed', '\c5%1 destroyed a %2 Ammo Station!', %scorer.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - %score = game.awardScoreInvDestroy(%scorer); - - case "StationVehicle": - teamDestroyMessage(%scorer, 'msgVehStationDestroyed', '\c5%1 destroyed a Vehicle Station!', %scorer.name); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - %score = game.awardScoreVehicleStationDestroy(%scorer); - - case "MPBTeleporter": // z0dd - ZOD, 4/24/02. MPB teleporter - teamDestroyMessage(%scorer, 'msgTeleporterDestroyed', '\c5%1 destroyed a MPB Teleport Station!', %scorer.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - %score = game.awardScoreMPBTeleporterDestroy(%scorer); - - case "DeployedStationInventory": - teamDestroyMessage(%scorer, 'msgDepInvDestroyed', '\c5%1 destroyed a Deployable Inventory!', %scorer.name); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - %score = game.awardScoreDepStationDestroy(%scorer); - - case "TurretBaseLarge": - teamDestroyMessage(%scorer, 'msgTurDestroyed', '\c5%1 destroyed a %2 Turret!', %scorer.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - %score = game.awardScoreTurretDestroy(%scorer); - - case "SentryTurret": - teamDestroyMessage(%scorer, 'msgSentryDestroyed', '\c5%1 destroyed a %2 Sentry Turret!', %scorer.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - %score = game.awardScoreSentryDestroy(%scorer); - - case "TurretDeployedFloorIndoor": - teamDestroyMessage(%scorer, 'msgDepTurDestroyed', '\c5%1 destroyed a Spider Clamp Turret!', %scorer.name); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - %score = game.awardScoreDepTurretDestroy(%scorer); - - case "TurretDeployedWallIndoor": - teamDestroyMessage(%scorer, 'msgDepTurDestroyed', '\c5%1 destroyed a Spider Clamp Turret!', %scorer.name); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - %score = game.awardScoreDepTurretDestroy(%scorer); - - case "TurretDeployedCeilingIndoor": - teamDestroyMessage(%scorer, 'msgDepTurDestroyed', '\c5%1 destroyed a Spider Clamp Turret!', %scorer.name); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - %score = game.awardScoreDepTurretDestroy(%scorer); - - case "TurretDeployedOutdoor": - teamDestroyMessage(%scorer, 'msgDepTurDestroyed', '\c5%1 destroyed a Landspike Turret!', %scorer.name); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - %score = game.awardScoreDepTurretDestroy(%scorer); - - default: - return; - } - - if(!%obj.soiledByEnemyRepair) - { - game.shareScore(%scorer, %score); - } - } - - function ShapeBaseData::onDisabled(%data, %obj) - { - %obj.wasDisabled = true; - Parent::onDisabled(%data, %obj); - } - - function RepairGunImage::onRepair(%this, %obj, %slot) - { - Parent::onRepair(%this, %obj, %slot); - %target = %obj.repairing; - if(%target && %target.team != %obj.team) - { - //error("Enemy stuff("@%obj@") is being repaired (by "@%target@")"); - %target.soiledByEnemyRepair = true; - } - } - - function Flag::objectiveInit(%data, %flag) - { - if (!%flag.isTeamSkinned) - { - %pos = %flag.getTransform(); - %group = %flag.getGroup(); - } - %flag.originalPosition = %flag.getTransform(); - $flagPos[%flag.team] = %flag.originalPosition; - %flag.isHome = true; - %flag.carrier = ""; - %flag.grabber = ""; - setTargetSkin(%flag.getTarget(), PracticeCTFGame::getTeamSkin(PracticeCTFGame, %flag.team)); - setTargetSensorGroup(%flag.getTarget(), %flag.team); - setTargetAlwaysVisMask(%flag.getTarget(), 0x7); - setTargetRenderMask(%flag.getTarget(), getTargetRenderMask(%flag.getTarget()) | 0x2); - %flag.scopeWhenSensorVisible(true); - $flagStatus[%flag.team] = ""; - - //Point the flag and stand at each other - %group = %flag.getGroup(); - %count = %group.getCount(); - %flag.stand = ""; - for(%i = 0; %i < %count; %i++) - { - %this = %group.getObject(%i); - //--------------------------------------------------------------------------------------------------------------------------- - // z0dd - ZOD: Added TSStatic, console spam fix - if(%this.getClassName() !$= "InteriorInstance" && %this.getClassName() !$= "SimGroup" && %this.getClassName() !$= "TSStatic") - { - if(%this.getDataBlock().getName() $= "ExteriorFlagStand") - { - %flag.stand = %this; - %this.flag = %flag; - } - } - } - // set the nametag on the target - setTargetName(%flag.getTarget(), PracticeCTFGame::getTeamName(PracticeCTFGame, %flag.team)); - - // create a marker on this guy - %flag.waypoint = new MissionMarker() { - position = %flag.getTransform(); - dataBlock = "FlagMarker"; - }; - MissionCleanup.add(%flag.waypoint); - - // create a target for this (there is no MissionMarker::onAdd script call) - %target = createTarget(%flag.waypoint, PracticeCTFGame::getTeamName( PracticeCTFGame, %flag.team), "", "", 'Base', %flag.team, 0); - setTargetAlwaysVisMask(%target, 0xffffffff); - - //store the flag in an array - $TeamFlag[%flag.team] = %flag; - - // -------------------------------------------------------- - // z0dd - ZOD, 5/26/02. Don't let flag hover over defenders - %flag.static = true; - - // ------------------------------------------------------------------------------------------- - // z0dd - ZOD, 10/03/02. Use triggers for flags that are at home, hack for flag collision bug. - %flag.trigger = new Trigger() - { - dataBlock = flagTrigger; - polyhedron = "-0.6 0.6 0.1 1.2 0.0 0.0 0.0 -1.2 0.0 0.0 0.0 2.5"; - position = %flag.position; - rotation = %flag.rotation; - }; - MissionCleanup.add(%flag.trigger); - %flag.trigger.flag = %flag; - // ------------------------------------------------------------------------------------------- - } -}; - -//-------------------------------------------------------------------------- - -function PracticeCTFGame::getTeamSkin(%game, %team) -{ - CTFGame::getTeamSkin(%game, %team); -} - -function PracticeCTFGame::getTeamName(%game, %team) -{ - CTFGame::getTeamName(%game, %team); -} - -//-------------------------------------------------------------------------- -function PracticeCTFGame::missionLoadDone(%game) -{ - //default version sets up teams - must be called first... - DefaultGame::missionLoadDone(%game); - - for(%i = 1; %i < (%game.numTeams + 1); %i++) - $teamScore[%i] = 0; - - // remove - MissionGroup.clearFlagWaypoints(); - - //reset some globals, just in case... - $dontScoreTimer[1] = false; - $dontScoreTimer[2] = false; - - echo( "starting camp thread..." ); - %game.campThread_1 = schedule( 1000, 0, "checkVehicleCamping", 1 ); - %game.campThread_2 = schedule( 1000, 0, "checkVehicleCamping", 2 ); - - // z0dd - ZOD: Need to save off turret barrels for practice mode reset - // Function allready exists in siege no need to duplicate. - SiegeGame::checkTurretBases(); -} - -function PracticeCTFGame::playerTouchFlag(%game, %player, %flag) -{ - %client = %player.client; - - if ((%flag.carrier $= "") && (%player.getState() !$= "Dead")) - { - //flag isn't held and has been touched by a live player - if (%client.team == %flag.team) - %game.playerTouchOwnFlag(%player, %flag); - else - %game.playerTouchEnemyFlag(%player, %flag); - - // SquirrelOfDeath, 10/02/02. moved searchSchedule cancel from here to playerTouchEnemyFlag. - } - - // toggle visibility of the flag - setTargetRenderMask(%flag.waypoint.getTarget(), %flag.isHome ? 0 : 1); -} - -function PracticeCTFGame::playerTouchOwnFlag(%game, %player, %flag) -{ - if(%flag.isHome) - { - if (%player.holdingFlag !$= "") - %game.flagCap(%player); - } - else - %game.flagReturn(%flag, %player); - - //call the AI function - %game.AIplayerTouchOwnFlag(%player, %flag); -} - -function PracticeCTFGame::playerTouchEnemyFlag(%game, %player, %flag) -{ - // --------------------------------------------------------------- - // z0dd, ZOD - 9/27/02. Player must wait to grab after throwing it - if((%player.flagTossWait !$= "") && %player.flagTossWait) - return; - // --------------------------------------------------------------- - - cancel(%flag.searchSchedule); // z0dd - ZOD, 9/28/02. Hack for flag collision bug. SquirrelOfDeath, 10/02/02: Moved from PlayerTouchFlag - - cancel(%game.updateFlagThread[%flag]); // z0dd - ZOD, 8/4/02. Cancel this flag's thread to KineticPoet's flag updater - %game.flagHeldTime[%flag] = getSimTime(); // z0dd - ZOD, 8/15/02. Store time player grabbed flag. - - %client = %player.client; - %player.holdingFlag = %flag; //%player has this flag - %flag.carrier = %player; //this %flag is carried by %player - - %player.mountImage(FlagImage, $FlagSlot, true, %game.getTeamSkin(%flag.team)); - - %game.playerGotFlagTarget(%player); - //only cancel the return timer if the player is in bounds... - if (!%client.outOfBounds) - { - cancel($FlagReturnTimer[%flag]); - $FlagReturnTimer[%flag] = ""; - } - - //if this flag was "at home", see if both flags have now been taken - if (%flag.isHome) - { - // tiebreaker score - game.awardScoreFlagTouch( %client, %flag ); - - %startStalemate = false; - if ($TeamFlag[1] == %flag) - %startStalemate = !$TeamFlag[2].isHome; - else - %startStalemate = !$TeamFlag[1].isHome; - - if (%startStalemate) - %game.stalemateSchedule = %game.schedule(%game.stalemateTimeMS, beginStalemate); - - } - - %flag.hide(true); - %flag.startFade(0, 0, false); - %flag.isHome = false; - if(%flag.stand) - %flag.stand.getDataBlock().onFlagTaken(%flag.stand);//animate, if exterior stand - - $flagStatus[%flag.team] = %client.nameBase; - %teamName = %game.getTeamName(%flag.team); - messageTeamExcept(%client, 'MsgCTFFlagTaken', '\c2Teammate %1 took the %2 flag.~wfx/misc/flag_snatch.wav', %client.name, %teamName, %flag.team, %client.nameBase); - messageTeam(%flag.team, 'MsgCTFFlagTaken', '\c2Your flag has been taken by %1!~wfx/misc/flag_taken.wav',%client.name, 0, %flag.team, %client.nameBase); - messageTeam(0, 'MsgCTFFlagTaken', '\c2%1 took the %2 flag.~wfx/misc/flag_snatch.wav', %client.name, %teamName, %flag.team, %client.nameBase); - messageClient(%client, 'MsgCTFFlagTaken', '\c2You took the %2 flag.~wfx/misc/flag_snatch.wav', %client.name, %teamName, %flag.team, %client.nameBase); - logEcho(%client.nameBase@" (pl "@%player@"/cl "@%client@") took team "@%flag.team@" flag"); - - //call the AI function - %game.AIplayerTouchEnemyFlag(%player, %flag); - - //if the player is out of bounds, then in 3 seconds, it should be thrown back towards the in bounds area... - if (%client.outOfBounds) - %game.schedule(3000, "boundaryLoseFlag", %player); -} - -function PracticeCTFGame::playerGotFlagTarget(%game, %player) -{ - %player.scopeWhenSensorVisible(true); - %target = %player.getTarget(); - setTargetRenderMask(%target, getTargetRenderMask(%target) | 0x2); - if(%game.stalemateObjsVisible) - setTargetAlwaysVisMask(%target, 0x7); -} - -function PracticeCTFGame::playerLostFlagTarget(%game, %player) -{ - %player.scopeWhenSensorVisible(false); - %target = %player.getTarget(); - setTargetRenderMask(%target, getTargetRenderMask(%target) & ~0x2); - // clear his always vis target mask - setTargetAlwaysVisMask(%target, (1 << getTargetSensorGroup(%target))); -} - -//---------------------------------------------------------------------------------------- -// z0dd - ZOD, 8/4/02: KineticPoet's flag updater code -function PracticeCTFGame::updateFlagTransform(%game, %flag) -{ - %flag.setTransform(%flag.getTransform()); - %game.updateFlagThread[%flag] = %game.schedule(100, "updateFlagTransform", %flag); -} -//---------------------------------------------------------------------------------------- - -function PracticeCTFGame::playerDroppedFlag(%game, %player) -{ - %client = %player.client; - %flag = %player.holdingFlag; - %game.updateFlagTransform(%flag); // z0dd - ZOD, 8/4/02, Call to KineticPoet's flag updater - %held = %game.formatTime(getSimTime() - %game.flagHeldTime[%flag], false); // z0dd - ZOD, 8/15/02. How long did player hold flag? - - %game.playerLostFlagTarget(%player); - - %player.holdingFlag = ""; //player isn't holding a flag anymore - %flag.carrier = ""; //flag isn't held anymore - $flagStatus[%flag.team] = ""; - - %player.unMountImage($FlagSlot); - %flag.hide(false); //Does the throwItem function handle this? - - %teamName = %game.getTeamName(%flag.team); - messageTeamExcept(%client, 'MsgCTFFlagDropped', '\c2Teammate %1 dropped the %2 flag. (Held: %4)~wfx/misc/flag_drop.wav', %client.name, %teamName, %flag.team, %held); // z0dd - ZOD, 8/15/02. How long flag was held - messageTeam(%flag.team, 'MsgCTFFlagDropped', '\c2Your flag has been dropped by %1! (Held: %4)~wfx/misc/flag_drop.wav', %client.name, 0, %flag.team, %held); // z0dd - ZOD, 8/15/02. How long flag was held - messageTeam(0, 'MsgCTFFlagDropped', '\c2%1 dropped the %2 flag. (Held: %4)~wfx/misc/flag_drop.wav', %client.name, %teamName, %flag.team, %held); // z0dd - ZOD, 8/15/02. How long flag was held - if(!%player.client.outOfBounds) - messageClient(%client, 'MsgCTFFlagDropped', '\c2You dropped the %2 flag. (Held: %4)~wfx/misc/flag_drop.wav', %client.name, %teamName, %flag.team, %held); // z0dd - ZOD, 8/15/02. How long flag was held - // Yogi, 8/18/02. 3rd param changed 0 -> %client.name - logEcho(%client.nameBase@" (pl "@%player@"/cl "@%client@") dropped team "@%flag.team@" flag"@" (Held: "@%held@")"); - - // z0dd - ZOD: Check for auto flag returns - if($PracticeCtf::AutoFlagReturn) - { - %game.flagReturnFade(%flag); - } - else - { - //don't duplicate the schedule if there's already one in progress... - if($FlagReturnTimer[%flag] <= 0) - $FlagReturnTimer[%flag] = %game.schedule(%game.FLAG_RETURN_DELAY - %game.fadeTimeMS, "flagReturnFade", %flag); - } - - //call the AI function - %game.AIplayerDroppedFlag(%player, %flag); -} - -function PracticeCTFGame::flagCap(%game, %player) -{ - %client = %player.client; - %flag = %player.holdingFlag; - %flag.carrier = ""; - - %held = %game.formatTime(getSimTime() - %game.flagHeldTime[%flag], false); // z0dd - ZOD, 8/15/02. How long did player hold flag? - - %game.playerLostFlagTarget(%player); - //award points to player and team - %teamName = %game.getTeamName(%flag.team); - messageTeamExcept(%client, 'MsgCTFFlagCapped', '\c2%1 captured the %2 flag! (Held: %5)~wfx/misc/flag_capture.wav', %client.name, %teamName, %flag.team, %client.team, %held); - messageTeam(%flag.team, 'MsgCTFFlagCapped', '\c2Your flag was captured by %1. (Held: %5)~wfx/misc/flag_lost.wav', %client.name, 0, %flag.team, %client.team, %held); - messageTeam(0, 'MsgCTFFlagCapped', '\c2%1 captured the %2 flag! (Held: %5)~wfx/misc/flag_capture.wav', %client.name, %teamName, %flag.team, %client.team, %held); - messageClient(%client, 'MsgCTFFlagCapped', '\c2You captured the %2 flag! (Held: %5)~wfx/misc/flag_capture.wav', %client.name, %teamName, %flag.team, %client.team, %held); // z0dd - ZOD, 8/19/02. Yogi. 3rd param changed from 0 to %client.name - - logEcho(%client.nameBase@" (pl "@%player@"/cl "@%client@") capped team "@%client.team@" flag"@" (Held: "@%held@")"); - %player.holdingFlag = ""; //no longer holding it. - %player.unMountImage($FlagSlot); - %game.awardScoreFlagCap(%client, %flag); - %game.flagReset(%flag); - - //call the AI function - %game.AIflagCap(%player, %flag); - - //if this cap didn't end the game, play the announcer... - if ($missionRunning) - { - if (%game.getTeamName(%client.team) $= 'Inferno') - messageAll("", '~wvoice/announcer/ann.infscores.wav'); - else if (%game.getTeamName(%client.team) $= 'Storm') - messageAll("", '~wvoice/announcer/ann.stoscores.wav'); - else if (%game.getTeamName(%client.team) $= 'Phoenix') - messageAll("", '~wvoice/announcer/ann.pxscore.wav'); - else if (%game.getTeamName(%client.team) $= 'Blood Eagle') - messageAll("", '~wvoice/announcer/ann.bescore.wav'); - else if (%game.getTeamName(%client.team) $= 'Diamond Sword') - messageAll("", '~wvoice/announcer/ann.dsscore.wav'); - else if (%game.getTeamName(%client.team) $= 'Starwolf') - messageAll("", '~wvoice/announcer/ann.swscore.wav'); - } -} - -function PracticeCTFGame::flagReturnFade(%game, %flag) -{ - $FlagReturnTimer[%flag] = %game.schedule(%game.fadeTimeMS, "flagReturn", %flag); - %flag.startFade(%game.fadeTimeMS, 0, true); -} - -function PracticeCTFGame::flagReturn(%game, %flag, %player) -{ - // z0dd - ZOD: Bug fix related to practice mode - if($FlagReturnTimer[%flag] !$= "") - { - cancel($FlagReturnTimer[%flag]); - $FlagReturnTimer[%flag] = ""; - } - - if(%flag.team == 1) - %otherTeam = 2; - else - %otherTeam = 1; - %teamName = %game.getTeamName(%flag.team); - if (%player !$= "") - { - //a player returned it - %client = %player.client; - messageTeamExcept(%client, 'MsgCTFFlagReturned', '\c2Teammate %1 returned your flag to base.~wfx/misc/flag_return.wav', %client.name, 0, %flag.team); - messageTeam(%otherTeam, 'MsgCTFFlagReturned', '\c2Enemy %1 returned the %2 flag.~wfx/misc/flag_return.wav', %client.name, %teamName, %flag.team); - messageTeam(0, 'MsgCTFFlagReturned', '\c2%1 returned the %2 flag.~wfx/misc/flag_return.wav', %client.name, %teamName, %flag.team); - messageClient(%client, 'MsgCTFFlagReturned', '\c2You returned your flag.~wfx/misc/flag_return.wav', %client.name, %teamName, %flag.team); // z0dd - ZOD, 8/19/02. Yogi. 3rd param changed from 0 to %client.name - logEcho(%client.nameBase@" (pl "@%player@"/cl "@%client@") returned team "@%flag.team@" flag"); - - // find out what type of return it is - // stalemate return? - - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - if(%game.stalemate) - { - //error("Stalemate return!!!"); - %game.awardScoreStalemateReturn(%player.client); - } - else // regular return - { - %enemyFlagDist = vectorDist($flagPos[%flag.team], $flagPos[%otherTeam]); - %dist = vectorDist(%flag.position, %flag.originalPosition); - - %rawRatio = %dist/%enemyFlagDist; - %ratio = %rawRatio < 1 ? %rawRatio : 1; - %percentage = mFloor( (%ratio) * 10 ) * 10; - %game.awardScoreFlagReturn(%player.client, %percentage); - } - // --------------------------------------------------- - } - else - { - //returned due to timer - messageTeam(%otherTeam, 'MsgCTFFlagReturned', '\c2The %2 flag was returned to base.~wfx/misc/flag_return.wav', 0, %teamName, %flag.team); //because it was dropped for too long - messageTeam(%flag.team, 'MsgCTFFlagReturned', '\c2Your flag was returned.~wfx/misc/flag_return.wav', 0, 0, %flag.team); - messageTeam(0, 'MsgCTFFlagReturned', '\c2The %2 flag was returned to base.~wfx/misc/flag_return.wav', 0, %teamName, %flag.team); - logEcho("team "@%flag.team@" flag returned (timeout)"); - } - - %game.flagReset(%flag); -} - -function PracticeCTFGame::showStalemateTargets(%game) -{ - cancel(%game.stalemateSchedule); - - //show the targets - for (%i = 1; %i <= 2; %i++) - { - %flag = $TeamFlag[%i]; - - //find the object to scope/waypoint.... - //render the target hud icon for slot 1 (a centermass flag) - //if we just set him as always sensor vis, it'll work fine. - if (isObject(%flag.carrier)) - setTargetAlwaysVisMask(%flag.carrier.getTarget(), 0x7); - } - - //schedule the targets to hide - %game.stalemateObjsVisible = true; - %game.stalemateSchedule = %game.schedule(%game.stalemateDurationMS, hideStalemateTargets); -} - -function PracticeCTFGame::hideStalemateTargets(%game) -{ - cancel(%game.stalemateSchedule); - - //hide the targets - for (%i = 1; %i <= 2; %i++) - { - %flag = $TeamFlag[%i]; - if (isObject(%flag.carrier)) - { - %target = %flag.carrier.getTarget(); - setTargetAlwaysVisMask(%target, (1 << getTargetSensorGroup(%target))); - } - } - - //schedule the targets to show again - %game.stalemateObjsVisible = false; - %game.stalemateSchedule = %game.schedule(%game.stalemateFreqMS, showStalemateTargets); -} - -function PracticeCTFGame::beginStalemate(%game) -{ - %game.stalemate = true; - %game.showStalemateTargets(); -} - -function PracticeCTFGame::endStalemate(%game) -{ - %game.stalemate = false; - %game.hideStalemateTargets(); - cancel(%game.stalemateSchedule); -} - -function PracticeCTFGame::flagReset(%game, %flag) -{ - cancel(%game.updateFlagThread[%flag]); // z0dd - ZOD, 8/4/02. Cancel this flag's thread to KineticPoet's flag updater - - //any time a flag is reset, kill the stalemate schedule - %game.endStalemate(); - - //make sure if there's a player carrying it (probably one out of bounds...), it is stripped first - if (isObject(%flag.carrier)) - { - //hide the target hud icon for slot 2 (a centermass flag - visible only as part of a teams sensor network) - %game.playerLostFlagTarget(%flag.carrier); - %flag.carrier.holdingFlag = ""; //no longer holding it. - %flag.carrier.unMountImage($FlagSlot); - } - - //fades, restore default position, home, velocity, general status, etc. - %flag.setVelocity("0 0 0"); - %flag.setTransform(%flag.originalPosition); - %flag.isHome = true; - %flag.carrier = ""; - %flag.grabber = ""; - $flagStatus[%flag.team] = ""; - %flag.hide(false); - if(%flag.stand) - %flag.stand.getDataBlock().onFlagReturn(%flag.stand);//animate, if exterior stand - - //fade the flag in... - %flag.startFade(%game.fadeTimeMS, 0, false); - - // dont render base target - setTargetRenderMask(%flag.waypoint.getTarget(), 0); - - //call the AI function - %game.AIflagReset(%flag); - - // -------------------------------------------------------- - // z0dd - ZOD, 5/26/02. Don't let flag hover over defenders - %flag.static = true; - - // -------------------------------------------------------------------------- - // z0dd - ZOD, 9/28/02. Hack for flag collision bug. - if(%flag.searchSchedule !$="") - { - cancel(%flag.searchSchedule); - } - // -------------------------------------------------------------------------- -} - -function PracticeCTFGame::timeLimitReached(%game) -{ - logEcho("game over (timelimit)"); - %game.gameOver(); - cycleMissions(); -} - -function PracticeCTFGame::scoreLimitReached(%game) -{ - logEcho("game over (scorelimit)"); - %game.gameOver(); - cycleMissions(); -} - -function PracticeCTFGame::notifyMineDeployed(%game, %mine) -{ - //see if the mine is within 5 meters of the flag stand... - %mineTeam = %mine.sourceObject.team; - %homeFlag = $TeamFlag[%mineTeam]; - if (isObject(%homeFlag)) - { - %dist = VectorDist(%homeFlag.originalPosition, %mine.position); - if (%dist <= %game.notifyMineDist) - { - messageTeam(%mineTeam, 'MsgCTFFlagMined', "The flag has been mined.~wvoice/announcer/flag_minedFem.wav" ); - } - } -} - -function PracticeCTFGame::gameOver(%game) -{ - // z0dd - ZOD, 9/28/02. Hack for flag collision bug. - for(%f = 1; %f <= %game.numTeams; %f++) - { - cancel($TeamFlag[%f].searchSchedule); - } - - // ------------------------------------------- - // z0dd - ZOD, 9/28/02. Cancel camp schedules. - if( Game.campThread_1 !$= "" ) - cancel(Game.campThread_1); - - if( Game.campThread_2 !$= "" ) - cancel(Game.campThread_2); - // ------------------------------------------- - - //call the default - DefaultGame::gameOver(%game); - - //send the winner message - %winner = ""; - if ($teamScore[1] > $teamScore[2]) - %winner = %game.getTeamName(1); - else if ($teamScore[2] > $teamScore[1]) - %winner = %game.getTeamName(2); - - if (%winner $= 'Storm') - messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.stowins.wav" ); - else if (%winner $= 'Inferno') - messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.infwins.wav" ); - else if (%winner $= 'Starwolf') - messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.swwin.wav" ); - else if (%winner $= 'Blood Eagle') - messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.bewin.wav" ); - else if (%winner $= 'Diamond Sword') - messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.dswin.wav" ); - else if (%winner $= 'Phoenix') - messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.pxwin.wav" ); - else - messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.gameover.wav" ); - - messageAll('MsgClearObjHud', ""); - for(%i = 0; %i < ClientGroup.getCount(); %i ++) - { - %client = ClientGroup.getObject(%i); - %game.resetScore(%client); - } - for(%j = 1; %j <= %game.numTeams; %j++) - $TeamScore[%j] = 0; -} - -function PracticeCTFGame::onClientDamaged(%game, %clVictim, %clAttacker, %damageType, %implement, %damageLoc) -{ - if(%clVictim.headshot && %damageType == $DamageType::Laser && %clVictim.team != %clAttacker.team) - { - %clAttacker.scoreHeadshot++; - if (%game.SCORE_PER_HEADSHOT != 0) - { - messageClient(%clAttacker, 'msgHeadshot', '\c0You received a %1 point bonus for a successful headshot.', %game.SCORE_PER_HEADSHOT); - messageTeamExcept(%clAttacker, 'msgHeadshot', '\c5%1 hit a sniper rifle headshot.', %clAttacker.name); // z0dd - ZOD, 8/15/02. Tell team - } - %game.recalcScore(%clAttacker); - } - - // ----------------------------------------------- - // z0dd - ZOD, 8/25/02. Rear Lance hits - if(%clVictim.rearshot && %damageType == $DamageType::ShockLance && %clVictim.team != %clAttacker.team) - { - %clAttacker.scoreRearshot++; - if (%game.SCORE_PER_REARSHOT != 0) - { - messageClient(%clAttacker, 'msgRearshot', '\c0You received a %1 point bonus for a successful rearshot.', %game.SCORE_PER_REARSHOT); - messageTeamExcept(%clAttacker, 'msgRearshot', '\c5%1 hit a shocklance rearshot.', %clAttacker.name); - } - %game.recalcScore(%clAttacker); - } - // ----------------------------------------------- - - //the DefaultGame will set some vars - DefaultGame::onClientDamaged(%game, %clVictim, %clAttacker, %damageType, %implement, %damageLoc); - - //if victim is carrying a flag and is not on the attackers team, mark the attacker as a threat for x seconds(for scoring purposes) - if ((%clVictim.holdingFlag !$= "") && (%clVictim.team != %clAttacker.team)) - { - %clAttacker.dmgdFlagCarrier = true; - cancel(%clAttacker.threatTimer); //restart timer - %clAttacker.threatTimer = schedule(%game.TIME_CONSIDERED_FLAGCARRIER_THREAT, %clAttacker.dmgdFlagCarrier = false); - } -} - -//////////////////////////////////////////////////////////////////////////////////////// -function PracticeCTFGame::clientMissionDropReady(%game, %client) -{ - messageClient(%client, 'MsgClientReady',"", %game.class); - %game.resetScore(%client); - for(%i = 1; %i <= %game.numTeams; %i++) - { - $Teams[%i].score = 0; - messageClient(%client, 'MsgCTFAddTeam', "", %i, %game.getTeamName(%i), $flagStatus[%i], $TeamScore[%i]); - } - //%game.populateTeamRankArray(%client); - - //messageClient(%client, 'MsgYourRankIs', "", -1); - - messageClient(%client, 'MsgMissionDropInfo', '\c0You are in mission %1 (%2).', $MissionDisplayName, $MissionTypeDisplayName, $ServerName ); - - DefaultGame::clientMissionDropReady(%game, %client); -} - -function PracticeCTFGame::assignClientTeam(%game, %client, %respawn) -{ - DefaultGame::assignClientTeam(%game, %client, %respawn); - // if player's team is not on top of objective hud, switch lines - messageClient(%client, 'MsgCheckTeamLines', "", %client.team); -} - -function PracticeCTFGame::recalcScore(%game, %cl) -{ - %killValue = %cl.kills * %game.SCORE_PER_KILL; - %deathValue = %cl.deaths * %game.SCORE_PER_DEATH; - - if (%killValue - %deathValue == 0) - %killPoints = 0; - else - %killPoints = (%killValue * %killValue) / (%killValue - %deathValue); - - %cl.offenseScore = %killPoints + - %cl.suicides * %game.SCORE_PER_SUICIDE + - %cl.escortAssists * %game.SCORE_PER_ESCORT_ASSIST + - %cl.teamKills * %game.SCORE_PER_TEAMKILL + - %cl.tkDestroys * %game.SCORE_PER_TK_DESTROY + // z0dd - ZOD, 10/03/02. Penalty for tking equiptment. - %cl.scoreHeadshot * %game.SCORE_PER_HEADSHOT + - %cl.scoreRearshot * %game.SCORE_PER_REARSHOT + // z0dd - ZOD, 8/25/02. Added Lance rear shot messages - %cl.flagCaps * %game.SCORE_PER_PLYR_FLAG_CAP + - %cl.flagGrabs * %game.SCORE_PER_PLYR_FLAG_TOUCH + - %cl.genDestroys * %game.SCORE_PER_DESTROY_GEN + - %cl.sensorDestroys * %game.SCORE_PER_DESTROY_SENSOR + - %cl.turretDestroys * %game.SCORE_PER_DESTROY_TURRET + - %cl.iStationDestroys * %game.SCORE_PER_DESTROY_ISTATION + - %cl.vstationDestroys * %game.SCORE_PER_DESTROY_VSTATION + - %cl.mpbtstationDestroys * %game.SCORE_PER_DESTROY_MPBTSTATION + // z0dd - ZOD 3/30/02. MPB Teleporter - %cl.solarDestroys * %game.SCORE_PER_DESTROY_SOLAR + - %cl.sentryDestroys * %game.SCORE_PER_DESTROY_SENTRY + - %cl.depSensorDestroys * %game.SCORE_PER_DESTROY_DEP_SENSOR + - %cl.depTurretDestroys * %game.SCORE_PER_DESTROY_DEP_TUR + - %cl.depStationDestroys * %game.SCORE_PER_DESTROY_DEP_INV + - %cl.vehicleScore + %cl.vehicleBonus; - - %cl.defenseScore = %cl.genDefends * %game.SCORE_PER_GEN_DEFEND + - %cl.flagDefends * %game.SCORE_PER_FLAG_DEFEND + - %cl.carrierKills * %game.SCORE_PER_CARRIER_KILL + - %cl.escortAssists * %game.SCORE_PER_ESCORT_ASSIST + - %cl.turretKills * %game.SCORE_PER_TURRET_KILL_AUTO + - %cl.mannedturretKills * %game.SCORE_PER_TURRET_KILL + - %cl.genRepairs * %game.SCORE_PER_REPAIR_GEN + - %cl.SensorRepairs * %game.SCORE_PER_REPAIR_SENSOR + - %cl.TurretRepairs * %game.SCORE_PER_REPAIR_TURRET + - %cl.StationRepairs * %game.SCORE_PER_REPAIR_ISTATION + - %cl.VStationRepairs * %game.SCORE_PER_REPAIR_VSTATION + - %cl.mpbtstationRepairs * %game.SCORE_PER_REPAIR_MPBTSTATION + // z0dd - ZOD 3/30/02. MPB Teleporter - %cl.solarRepairs * %game.SCORE_PER_REPAIR_SOLAR + - %cl.sentryRepairs * %game.SCORE_PER_REPAIR_SENTRY + - %cl.depInvRepairs * %game.SCORE_PER_REPAIR_DEP_INV + - %cl.depTurretRepairs * %game.SCORE_PER_REPAIR_DEP_TUR + - %cl.returnPts; - - %cl.score = mFloor(%cl.offenseScore + %cl.defenseScore); - %game.recalcTeamRanks(%cl); -} - -function PracticeCTFGame::updateKillScores(%game, %clVictim, %clKiller, %damageType, %implement) -{ -// is this a vehicle kill rather than a player kill - - // console error message suppression - if( isObject( %implement ) ) - { - if( %implement.getDataBlock().getName() $= "AssaultPlasmaTurret" || %implement.getDataBlock().getName() $= "BomberTurret" ) // gunner - %clKiller = %implement.vehicleMounted.getMountNodeObject(1).client; - else if(%implement.getDataBlock().catagory $= "Vehicles") // pilot - %clKiller = %implement.getMountNodeObject(0).client; - } - - if(%game.testTurretKill(%implement)) //check for turretkill before awarded a non client points for a kill - %game.awardScoreTurretKill(%clVictim, %implement); - else if (%game.testKill(%clVictim, %clKiller)) //verify victim was an enemy - { - %value = %game.awardScoreKill(%clKiller); - %game.shareScore(%clKiller, %value); - %game.awardScoreDeath(%clVictim); - - if (%game.testGenDefend(%clVictim, %clKiller)) - %game.awardScoreGenDefend(%clKiller); - - if(%game.testCarrierKill(%clVictim, %clKiller)) - %game.awardScoreCarrierKill(%clKiller); - else - { - if (%game.testFlagDefend(%clVictim, %clKiller)) - %game.awardScoreFlagDefend(%clKiller); - } - if (%game.testEscortAssist(%clVictim, %clKiller)) - %game.awardScoreEscortAssist(%clKiller); - } - else - { - if (%game.testSuicide(%clVictim, %clKiller, %damageType)) //otherwise test for suicide - { - %game.awardScoreSuicide(%clVictim); - } - else - { - if (%game.testTeamKill(%clVictim, %clKiller)) //otherwise test for a teamkill - %game.awardScoreTeamKill(%clVictim, %clKiller); - } - } -} - -function PracticeCTFGame::testFlagDefend(%game, %victimID, %killerID) -{ - InitContainerRadiusSearch(%victimID.plyrPointOfDeath, %game.RADIUS_FLAG_DEFENSE, $TypeMasks::ItemObjectType); - %objID = containerSearchNext(); - while(%objID != 0) - { - %objType = %objID.getDataBlock().getName(); - if ((%objType $= "Flag") && (%objID.team == %killerID.team)) - return true; //found the(a) killer's flag near the victim's point of death - else - %objID = containerSearchNext(); - } - return false; //didn't find a qualifying flag within required radius of victims point of death -} - -function PracticeCTFGame::testGenDefend(%game, %victimID, %killerID) -{ - InitContainerRadiusSearch(%victimID.plyrPointOfDeath, %game.RADIUS_GEN_DEFENSE, $TypeMasks::StaticShapeObjectType); - %objID = containerSearchNext(); - while(%objID != 0) - { - %objType = %objID.getDataBlock().ClassName; - if ((%objType $= "generator") && (%objID.team == %killerID.team)) - return true; //found a killer's generator within required radius of victim's death - else - %objID = containerSearchNext(); - } - return false; //didn't find a qualifying gen within required radius of victim's point of death -} - -function PracticeCTFGame::testCarrierKill(%game, %victimID, %killerID) -{ - %flag = %victimID.plyrDiedHoldingFlag; - return ((%flag !$= "") && (%flag.team == %killerID.team)); -} - -function PracticeCTFGame::testEscortAssist(%game, %victimID, %killerID) -{ - return (%victimID.dmgdFlagCarrier); -} - -function PracticeCTFGame::testValidRepair(%game, %obj) -{ - if(!%obj.wasDisabled) - { - //error(%obj SPC "was never disabled"); - return false; - } - else if(%obj.lastDamagedByTeam == %obj.team) - { - //error(%obj SPC "was last damaged by a friendly"); - return false; - } - else if(%obj.team != %obj.repairedBy.team) - { - //error(%obj SPC "was repaired by an enemy"); - return false; - } - else - { - if(%obj.soiledByEnemyRepair) - %obj.soiledByEnemyRepair = false; - return true; - } -} - -function PracticeCTFGame::awardScoreFlagCap(%game, %cl, %flag) -{ - %cl.flagCaps++; - $TeamScore[%cl.team] += %game.SCORE_PER_TEAM_FLAG_CAP; - messageAll('MsgTeamScoreIs', "", %cl.team, $TeamScore[%cl.team]); - - %flag.grabber.flagGrabs++; - - if (%game.SCORE_PER_TEAM_FLAG_CAP > 0) - { - %plural = (%game.SCORE_PER_PLYR_FLAG_CAP != 1 ? 's' : ""); - %plural2 = (%game.SCORE_PER_PLYR_FLAG_TOUCH != 1 ? 's' : ""); - - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - if(%cl == %flag.grabber) - { - messageClient(%cl, 'msgCTFFriendCap', '\c0You receive %1 point%2 for stealing and capturing the enemy flag!', %game.SCORE_PER_PLYR_FLAG_CAP+%game.SCORE_PER_PLYR_FLAG_TOUCH, %plural); - messageTeam(%flag.team, 'msgCTFEnemyCap', '\c0Enemy %1 received %2 point%3 for capturing your flag!', %cl.name, %game.SCORE_PER_PLYR_FLAG_CAP+%game.SCORE_PER_PLYR_FLAG_TOUCH, %plural); - //messageTeamExcept(%cl, 'msgCTFFriendCap', '\c0Teammate %1 receives %2 point%3 for capturing the enemy flag!', %cl.name, %game.SCORE_PER_PLYR_FLAG_CAP+%game.SCORE_PER_PLYR_FLAG_TOUCH, %plural); // z0dd - ZOD, 8/15/02. Message is pointless - } - else - { - if(isObject(%flag.grabber)) // is the grabber still here? - { - messageClient(%cl, 'msgCTFFriendCap', '\c0You receive %1 point%2 for capturing the enemy flag! %3 gets %4 point%5 for the steal assist.', %game.SCORE_PER_PLYR_FLAG_CAP, %plural, %flag.grabber.name, %game.SCORE_PER_PLYR_FLAG_TOUCH, %plural2); - messageClient(%flag.grabber, 'msgCTFFriendCap', '\c0You receive %1 point%2 for stealing a flag that was subsequently capped by %3.', %game.SCORE_PER_PLYR_FLAG_TOUCH, %plural2, %cl.name); - } - else - messageClient(%cl, 'msgCTFFriendCap', '\c0You receive %1 point%2 for capturing the enemy flag!', %game.SCORE_PER_PLYR_FLAG_CAP, %plural); - - //messageTeamExcept(%cl, 'msgCTFFriendCap', '\c0Teammate %1 receives %2 point%3 for capturing the enemy flag!', %cl.name, %game.SCORE_PER_PLYR_FLAG_CAP, %plural); // z0dd - ZOD, 8/15/02. Message is pointless - //messageTeam(%flag.team, 'msgCTFEnemyCap', '\c0Enemy %1 received %2 point%3 for capturing your flag!', %cl.name, %game.SCORE_PER_PLYR_FLAG_CAP, %plural); // z0dd - ZOD, 8/15/02. Message is pointless - } - // --------------------------------------------------- - } - - %game.recalcScore(%cl); - - if(isObject(%flag.grabber)) - %game.recalcScore(%flag.grabber); - - %game.checkScoreLimit(%cl.team); -} - - -function PracticeCTFGame::awardScoreFlagTouch(%game, %cl, %flag) -{ - - %flag.grabber = %cl; - %team = %cl.team; - if( $DontScoreTimer[%team] ) - return; - - $dontScoreTimer[%team] = true; - //tinman - needed to remove all game calls to "eval" for the PURE server... - %game.schedule(%game.TOUCH_DELAY_MS, resetDontScoreTimer, %team); - //schedule(%game.TOUCH_DELAY_MS, 0, eval, "$dontScoreTimer["@%team@"] = false;"); - schedule(%game.TOUCH_DELAY_MS, 0, eval, "$dontScoreTimer["@%team@"] = false;"); - $TeamScore[%team] += %game.SCORE_PER_TEAM_FLAG_TOUCH; - messageAll('MsgTeamScoreIs', "", %team, $TeamScore[%team]); - - if (%game.SCORE_PER_TEAM_FLAG_TOUCH > 0) - { - %plural = (%game.SCORE_PER_TEAM_FLAG_TOUCH != 1 ? 's' : ""); - messageTeam(%team, 'msgCTFFriendFlagTouch', '\c0Your team receives %1 point%2 for grabbing the enemy flag!', %game.SCORE_PER_TEAM_FLAG_TOUCH, %plural); - messageTeam(%flag.team, 'msgCTFEnemyFlagTouch', '\c0Enemy %1 receives %2 point%3 for grabbing your flag!', %cl.name, %game.SCORE_PER_TEAM_FLAG_TOUCH, %plural); - } - %game.recalcScore(%cl); - %game.checkScoreLimit(%team); -} - -function PracticeCTFGame::resetDontScoreTimer(%game, %team) -{ - $dontScoreTimer[%team] = false; -} - -function PracticeCTFGame::checkScoreLimit(%game, %team) -{ - // z0dd - ZOD, 5/12/02. Check for no score limit - if(!$PracticeCtf::NoScoreLimit) - { - %scoreLimit = MissionGroup.CTF_scoreLimit * %game.SCORE_PER_TEAM_FLAG_CAP; - // default of 5 if scoreLimit not defined - if(%scoreLimit $= "") - %scoreLimit = 5 * %game.SCORE_PER_TEAM_FLAG_CAP; - if($TeamScore[%team] >= %scoreLimit) - %game.scoreLimitReached(); - } - else - %scoreLimit = %scoreLimit = 999; -} - -function PracticeCTFGame::awardScoreFlagReturn(%game, %cl, %perc) -{ - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - if (%game.SCORE_PER_FLAG_RETURN != 0) - { - %pts = mfloor( %game.SCORE_PER_FLAG_RETURN * (%perc/100) ); - if(%perc == 100) - messageClient(%cl, 'scoreFlaRetMsg', 'Flag return - exceeded capping distance - %1 point bonus.', %pts, %perc); - else if(%perc == 0) - messageClient(%cl, 'scoreFlaRetMsg', 'You gently place the flag back on the stand.', %pts, %perc); - else - messageClient(%cl, 'scoreFlaRetMsg', '\c0Flag return from %2%% of capping distance - %1 point bonus.', %pts, %perc); - %cl.returnPts += %pts; - } - %game.recalcScore(%cl); - return %game.SCORE_PER_FLAG_RETURN; - // --------------------------------------------------- -} - -function PracticeCTFGame::awardScoreStalemateReturn(%game, %cl) -{ - if (%game.SCORE_PER_STALEMATE_RETURN != 0) - { - messageClient(%cl, 'scoreStaleRetMsg', '\c0You received a %1 point bonus for a stalemate-breaking, flag return.', %game.SCORE_PER_STALEMATE_RETURN); - %cl.returnPts += %game.SCORE_PER_STALEMATE_RETURN; - } - %game.recalcScore(%cl); - return %game.SCORE_PER_STALEMATE_RETURN; -} - -// Asset Destruction scoring -function PracticeCTFGame::awardScoreGenDestroy(%game,%cl) -{ - %cl.genDestroys++; - if (%game.SCORE_PER_DESTROY_GEN != 0) - { - messageClient(%cl, 'msgGenDes', '\c0You received a %1 point bonus for destroying an enemy generator.', %game.SCORE_PER_DESTROY_GEN); - //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); - } - %game.recalcScore(%cl); - return %game.SCORE_PER_DESTROY_GEN; -} - -function PracticeCTFGame::awardScoreSensorDestroy(%game,%cl) -{ - %cl.sensorDestroys++; - if (%game.SCORE_PER_DESTROY_SENSOR != 0) - { - messageClient(%cl, 'msgSensorDes', '\c0You received a %1 point bonus for destroying an enemy sensor.', %game.SCORE_PER_DESTROY_SENSOR); - //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); - } - %game.recalcScore(%cl); - return %game.SCORE_PER_DESTROY_SENSOR; -} - -function PracticeCTFGame::awardScoreTurretDestroy(%game,%cl) -{ - %cl.turretDestroys++; - if (%game.SCORE_PER_DESTROY_TURRET != 0) - { - messageClient(%cl, 'msgTurretDes', '\c0You received a %1 point bonus for destroying an enemy turret.', %game.SCORE_PER_DESTROY_TURRET); - //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); - } - %game.recalcScore(%cl); - return %game.SCORE_PER_DESTROY_TURRET; -} - -function PracticeCTFGame::awardScoreInvDestroy(%game,%cl) -{ - %cl.IStationDestroys++; - if (%game.SCORE_PER_DESTROY_ISTATION != 0) - { - messageClient(%cl, 'msgInvDes', '\c0You received a %1 point bonus for destroying an enemy inventory station.', %game.SCORE_PER_DESTROY_ISTATION); - //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); - } - %game.recalcScore(%cl); - return %game.SCORE_PER_DESTROY_ISTATION; -} - -function PracticeCTFGame::awardScoreVehicleStationDestroy(%game,%cl) -{ - %cl.VStationDestroys++; - if (%game.SCORE_PER_DESTROY_VSTATION != 0) - { - messageClient(%cl, 'msgVSDes', '\c0You received a %1 point bonus for destroying an enemy vehicle station.', %game.SCORE_PER_DESTROY_VSTATION); - //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); - } - %game.recalcScore(%cl); - return %game.SCORE_PER_DESTROY_VSTATION; -} - -// --------------------------------------------------------- -// z0dd - ZOD 3/30/02. MBP Teleporter -function PracticeCTFGame::awardScoreMPBTeleporterDestroy(%game,%cl) -{ - %cl.mpbtstationDestroys++; - if (%game.SCORE_PER_DESTROY_MPBTSTATION != 0) - { - messageClient(%cl, 'msgMPBTeleDes', '\c0You received a %1 point bonus for destroying an enemy MPB teleport station.', %game.SCORE_PER_DESTROY_MPBTSTATION); - //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); - } - %game.recalcScore(%cl); - return %game.SCORE_PER_DESTROY_MPBTSTATION; -} -// --------------------------------------------------------- - -function PracticeCTFGame::awardScoreSolarDestroy(%game,%cl) -{ - %cl.SolarDestroys++; - if (%game.SCORE_PER_DESTROY_SOLAR != 0) - { - messageClient(%cl, 'msgSolarDes', '\c0You received a %1 point bonus for destroying an enemy solar panel.', %game.SCORE_PER_DESTROY_SOLAR); - //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); - } - %game.recalcScore(%cl); - return %game.SCORE_PER_DESTROY_SOLAR; -} - -function PracticeCTFGame::awardScoreSentryDestroy(%game,%cl) -{ - %cl.sentryDestroys++; - if (%game.SCORE_PER_DESTROY_SENTRY != 0) - { - messageClient(%cl, 'msgSentryDes', '\c0You received a %1 point bonus for destroying an enemy sentry turret.', %game.SCORE_PER_DESTROY_SENTRY); - //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); - } - %game.recalcScore(%cl); - return %game.SCORE_PER_DESTROY_SENTRY; -} - -function PracticeCTFGame::awardScoreDepSensorDestroy(%game,%cl) -{ - %cl.depSensorDestroys++; - if (%game.SCORE_PER_DESTROY_DEP_SENSOR != 0) - { - messageClient(%cl, 'msgDepSensorDes', '\c0You received a %1 point bonus for destroying an enemy deployable sensor.', %game.SCORE_PER_DESTROY_DEP_SENSOR); // z0dd - ZOD, 8/15/02. Added "sensor" - //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); - } - %game.recalcScore(%cl); - return %game.SCORE_PER_DESTROY_DEP_SENSOR; -} - -function PracticeCTFGame::awardScoreDepTurretDestroy(%game,%cl) -{ - %cl.depTurretDestroys++; - if (%game.SCORE_PER_DESTROY_DEP_TUR != 0) - { - messageClient(%cl, 'msgDepTurDes', '\c0You received a %1 point bonus for destroying an enemy deployed turret.', %game.SCORE_PER_DESTROY_DEP_TUR); - //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); - } - %game.recalcScore(%cl); - return %game.SCORE_PER_DESTROY_DEP_TUR; -} - -function PracticeCTFGame::awardScoreDepStationDestroy(%game,%cl) -{ - %cl.depStationDestroys++; - if (%game.SCORE_PER_DESTROY_DEP_INV != 0) - { - messageClient(%cl, 'msgDepInvDes', '\c0You received a %1 point bonus for destroying an enemy deployed station.', %game.SCORE_PER_DESTROY_DEP_INV); - //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); - } - %game.recalcScore(%cl); - return %game.SCORE_PER_DESTROY_DEP_INV; -} - -// --------------------------------------------------------- -// z0dd - ZOD, 10/03/02. Penalty for TKing equiptment. -function PracticeCTFGame::awardScoreTkDestroy(%game, %cl) -{ - %cl.tkDestroys++; - if (%game.SCORE_PER_TK_DESTROY != 0) - { - messageClient(%cl, 'msgTkDes', '\c0You have been penalized %1 points for destroying your teams equiptment.', %game.SCORE_PER_TK_DESTROY); - } - %game.recalcScore(%cl); - return %game.SCORE_PER_TK_DESTROY; -} -// --------------------------------------------------------- - -function PracticeCTFGame::awardScoreGenDefend(%game, %killerID) -{ - %killerID.genDefends++; - if (%game.SCORE_PER_GEN_DEFEND != 0) - { - messageClient(%killerID, 'msgGenDef', '\c0You received a %1 point bonus for defending a generator.', %game.SCORE_PER_GEN_DEFEND); - messageTeamExcept(%killerID, 'msgGenDef', '\c2%1 defended our generator from an attack.', %killerID.name); // z0dd - ZOD, 8/15/02. Tell team - //messageTeamExcept(%killerID, 'msgGenDef', '\c0Teammate %1 received a %2 point bonus for defending a generator.', %killerID.name, %game.SCORE_PER_GEN_DEFEND); - } - %game.recalcScore(%cl); - return %game.SCORE_PER_GEN_DEFEND; -} - -function PracticeCTFGame::awardScoreCarrierKill(%game, %killerID) -{ - %killerID.carrierKills++; - if (%game.SCORE_PER_CARRIER_KILL != 0) - { - messageClient(%killerID, 'msgCarKill', '\c0You received a %1 point bonus for stopping the enemy flag carrier!', %game.SCORE_PER_CARRIER_KILL); - messageTeamExcept(%killerID, 'msgCarKill', '\c2%1 stopped the enemy flag carrier.', %killerID.name); // z0dd - ZOD, 8/15/02. Tell team - //messageTeamExcept(%killerID, 'msgCarKill', '\c0Teammate %1 received a %2 point bonus for stopping the enemy flag carrier!', %killerID.name, %game.SCORE_PER_CARRIER_KILL); - } - %game.recalcScore(%killerID); - return %game.SCORE_PER_CARRIER_KILL; -} - -function PracticeCTFGame::awardScoreFlagDefend(%game, %killerID) -{ - %killerID.flagDefends++; - if (%game.SCORE_PER_FLAG_DEFEND != 0) - { - messageClient(%killerID, 'msgFlagDef', '\c0You received a %1 point bonus for defending your flag!', %game.SCORE_PER_FLAG_DEFEND); - messageTeamExcept(%killerID, 'msgFlagDef', '\c2%1 defended our flag.', %killerID.name); // z0dd - ZOD, 8/15/02. Tell team - //messageTeamExcept(%killerID, 'msgFlagDef', '\c0Teammate %1 received a %2 point bonus for defending your flag!', %killerID.name, %game.SCORE_PER_FLAG_DEFEND); - } - %game.recalcScore(%killerID); - return %game.SCORE_PER_FLAG_DEFEND; -} - -function PracticeCTFGame::awardScoreEscortAssist(%game, %killerID) -{ - %killerID.escortAssists++; - if (%game.SCORE_PER_ESCORT_ASSIST != 0) - { - messageClient(%killerID, 'msgEscAsst', '\c0You received a %1 point bonus for protecting the flag carrier!', %game.SCORE_PER_ESCORT_ASSIST); - messageTeamExcept(%killerID, 'msgEscAsst', '\c2%1 protected our flag carrier.', %killerID.name); // z0dd - ZOD, 8/15/02. Tell team - //messageTeamExcept(%killerID, 'msgEscAsst', '\c0Teammate %1 received a %2 point bonus for protecting the flag carrier!', %killerID.name, %game.SCORE_PER_ESCORT_ASSIST); - } - %game.recalcScore(%killerID); - return %game.SCORE_PER_ESCORT_ASSIST; -} - -function PracticeCTFGame::resetScore(%game, %client) -{ - %client.offenseScore = 0; - %client.kills = 0; - %client.deaths = 0; - %client.suicides = 0; - %client.escortAssists = 0; - %client.teamKills = 0; - %client.tkDestroys = 0; // z0dd - ZOD, 10/03/02. Penalty for tking equiptment. - %client.flagCaps = 0; - %client.flagGrabs = 0; - %client.genDestroys = 0; - %client.sensorDestroys = 0; - %client.turretDestroys = 0; - %client.iStationDestroys = 0; - %client.vstationDestroys = 0; - %client.mpbtstationDestroys = 0; // z0dd - ZOD 3/30/02. MPB Teleporter - %client.solarDestroys = 0; - %client.sentryDestroys = 0; - %client.depSensorDestroys = 0; - %client.depTurretDestroys = 0; - %client.depStationDestroys = 0; - %client.vehicleScore = 0; - %client.vehicleBonus = 0; - - %client.flagDefends = 0; - %client.defenseScore = 0; - %client.genDefends = 0; - %client.carrierKills = 0; - %client.escortAssists = 0; - %client.turretKills = 0; - %client.mannedTurretKills = 0; - %client.flagReturns = 0; - %client.genRepairs = 0; - %client.SensorRepairs = 0; - %client.TurretRepairs = 0; - %client.StationRepairs = 0; - %client.VStationRepairs = 0; - %client.mpbtstationRepairs = 0; // z0dd - ZOD 3/30/02. MPB Teleporter - %client.solarRepairs = 0; - %client.sentryRepairs = 0; - %client.depInvRepairs = 0; - %client.depTurretRepairs = 0; - %client.returnPts = 0; - %client.score = 0; - - // z0dd - ZOD: Reset practice mode varibles - for(%i=0; %i < $Host::ClassicMaxTelepads; %i++) - { - %client.spawnPad[%i] = ""; - } - %client.transMode = ""; - %client.transPad = 1; - %client.camera.projectile = ""; - %client.mortarObs = ""; - %client.missileObs = ""; - %client.grenadeObs = ""; - %client.discObs = ""; -} - -function PracticeCTFGame::objectRepaired(%game, %obj, %objName) -{ - %item = %obj.getDataBlock().getName(); - switch$ (%item) - { - case generatorLarge : - %game.genOnRepaired(%obj, %objName); - case sensorMediumPulse : - %game.sensorOnRepaired(%obj, %objName); - case sensorLargePulse : - %game.sensorOnRepaired(%obj, %objName); - case stationInventory : - %game.stationOnRepaired(%obj, %objName); - case turretBaseLarge : - %game.turretOnRepaired(%obj, %objName); - case stationVehicle : - %game.vStationOnRepaired(%obj, %objName); - case MPBTeleporter : // z0dd - ZOD 3/30/02. MPB Teleporter - %game.mpbTStationOnRepaired(%obj, %objName); - case solarPanel : - %game.solarPanelOnRepaired(%obj, %objName); - case sentryTurret : - %game.sentryTurretOnRepaired(%obj, %objName); - case TurretDeployedWallIndoor: - %game.depTurretOnRepaired(%obj, %objName); - case TurretDeployedFloorIndoor: - %game.depTurretOnRepaired(%obj, %objName); - case TurretDeployedCeilingIndoor: - %game.depTurretOnRepaired(%obj, %objName); - case TurretDeployedOutdoor: - %game.depTurretOnRepaired(%obj, %objName); - } - %obj.wasDisabled = false; -} - -function PracticeCTFGame::genOnRepaired(%game, %obj, %objName) -{ - - if (%game.testValidRepair(%obj)) - { - %repairman = %obj.repairedBy; - teamRepairMessage(%repairman, 'msgGenRepaired', '\c0%1 repaired the %2 Generator!', %repairman.name, %obj.nameTag); - %game.awardScoreGenRepair(%obj.repairedBy); - } -} - -function PracticeCTFGame::stationOnRepaired(%game, %obj, %objName) -{ - if (%game.testValidRepair(%obj)) - { - %repairman = %obj.repairedBy; - teamRepairMessage(%repairman, 'msgStationRepaired', '\c0%1 repaired the %2 Inventory Station!', %repairman.name, %obj.nameTag); - %game.awardScoreStationRepair(%obj.repairedBy); - } -} - -function PracticeCTFGame::sensorOnRepaired(%game, %obj, %objName) -{ - if (%game.testValidRepair(%obj)) - { - %repairman = %obj.repairedBy; - teamRepairMessage(%repairman, 'msgSensorRepaired', '\c0%1 repaired the %2 Pulse Sensor!', %repairman.name, %obj.nameTag); - %game.awardScoreSensorRepair(%obj.repairedBy); - } -} - -function PracticeCTFGame::turretOnRepaired(%game, %obj, %objName) -{ - if (%game.testValidRepair(%obj)) - { - %repairman = %obj.repairedBy; - teamRepairMessage(%repairman, 'msgTurretRepaired', '\c0%1 repaired the %2 Turret!', %repairman.name, %obj.nameTag); - %game.awardScoreTurretRepair(%obj.repairedBy); - } -} - -function PracticeCTFGame::vStationOnRepaired(%game, %obj, %objName) -{ - if (%game.testValidRepair(%obj)) - { - %repairman = %obj.repairedBy; - teamRepairMessage(%repairman, 'msgvstationRepaired', '\c0%1 repaired the Vehicle Station!', %repairman.name); - %game.awardScoreVStationRepair(%obj.repairedBy); - } -} - -// z0dd - ZOD 3/17/02. Score for repairing MPB Teleporter station. -function PracticeCTFGame::mpbTStationOnRepaired(%game, %obj, %objName) -{ - if (%game.testValidRepair(%obj)) - { - %repairman = %obj.repairedBy; - teamRepairMessage(%repairman, 'msgTeleporterRepaired', '\c0%1 repaired the MPB Teleporter Station!', %repairman.name); - %game.awardScoreMpbTStationRepair(%obj.repairedBy); - } -} - -function PracticeCTFGame::solarPanelOnRepaired(%game, %obj, %objName) -{ - if (%game.testValidRepair(%obj)) - { - %repairman = %obj.repairedBy; - teamRepairMessage(%repairman, 'msgsolarRepaired', '\c0%1 repaired the %2 Solar Panel!', %repairman.name, %obj.nameTag); - %game.awardScoreSolarRepair(%obj.repairedBy); - } -} - -function PracticeCTFGame::sentryTurretOnRepaired(%game, %obj, %objName) -{ - if (%game.testValidRepair(%obj)) - { - %repairman = %obj.repairedBy; - teamRepairMessage(%repairman, 'msgsentryTurretRepaired', '\c0%1 repaired the %2 Sentry Turret!', %repairman.name, %obj.nameTag); - %game.awardScoreSentryRepair(%obj.repairedBy); - } -} - -function PracticeCTFGame::depTurretOnRepaired(%game, %obj, %objName) -{ - if (%game.testValidRepair(%obj)) - { - %repairman = %obj.repairedBy; - teamRepairMessage(%repairman, 'msgdepTurretRepaired', '\c4%1 repaired a %2 Deployable Turret!', %repairman.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Added this line - %game.awardScoreDepTurretRepair(%obj.repairedBy); - } -} - -function PracticeCTFGame::depInvOnRepaired(%game, %obj, %objName) -{ - if (%game.testValidRepair(%obj)) - { - %repairman = %obj.repairedBy; - teamRepairMessage(%repairman, 'msgdepInvRepaired', '\c4%1 repaired a %2 Deployable Inventory!', %repairman.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Added this line - %game.awardScoreDepInvRepair(%obj.repairedBy); - } -} - -function PracticeCTFGame::awardScoreGenRepair(%game, %cl) -{ - %cl.genRepairs++; - if (%game.SCORE_PER_REPAIR_GEN != 0) - { - messageClient(%cl, 'msgGenRep', '\c0You received a %1 point bonus for repairing a generator.', %game.SCORE_PER_REPAIR_GEN); - } - %game.recalcScore(%cl); -} - -function PracticeCTFGame::awardScoreStationRepair(%game, %cl) -{ - %cl.stationRepairs++; - if (%game.SCORE_PER_REPAIR_ISTATION != 0) - { - messageClient(%cl, 'msgIStationRep', '\c0You received a %1 point bonus for repairing a inventory station.', %game.SCORE_PER_REPAIR_ISTATION); - } - %game.recalcScore(%cl); -} - -function PracticeCTFGame::awardScoreSensorRepair(%game, %cl) -{ - %cl.sensorRepairs++; - if (%game.SCORE_PER_REPAIR_SENSOR != 0) - { - messageClient(%cl, 'msgSensorRep', '\c0You received a %1 point bonus for repairing a sensor.', %game.SCORE_PER_REPAIR_SENSOR); - } - %game.recalcScore(%cl); -} - -function PracticeCTFGame::awardScoreTurretRepair(%game, %cl) -{ - %cl.TurretRepairs++; - if (%game.SCORE_PER_REPAIR_TURRET != 0) - { - messageClient(%cl, 'msgTurretRep', '\c0You received a %1 point bonus for repairing a base turret.', %game.SCORE_PER_REPAIR_TURRET); - } - %game.recalcScore(%cl); -} - -function PracticeCTFGame::awardScoreVStationRepair(%game, %cl) -{ - %cl.VStationRepairs++; - if (%game.SCORE_PER_REPAIR_VSTATION != 0) - { - messageClient(%cl, 'msgVStationRep', '\c0You received a %1 point bonus for repairing a vehicle station.', %game.SCORE_PER_REPAIR_VSTATION); - } - %game.recalcScore(%cl); -} - -// z0dd - ZOD 3/17/02. Score for repairing MPB Teleporter station. -function PracticeCTFGame::awardScoreMpbTStationRepair(%game, %cl) -{ - %cl.mpbtstationRepairs++; - if (%game.SCORE_PER_REPAIR_MPBTSTATION != 0) - { - messageClient(%cl, 'msgVStationRep', '\c0You received a %1 point bonus for repairing a mpb teleporter station.', %game.SCORE_PER_REPAIR_TSTATION); - } - %game.recalcScore(%cl); -} - -function PracticeCTFGame::awardScoreSolarRepair(%game, %cl) -{ - %cl.solarRepairs++; - if (%game.SCORE_PER_REPAIR_SOLAR != 0) - { - messageClient(%cl, 'msgsolarRep', '\c0You received a %1 point bonus for repairing a solar panel.', %game.SCORE_PER_REPAIR_SOLAR); - } - %game.recalcScore(%cl); -} - -function PracticeCTFGame::awardScoreSentryRepair(%game, %cl) -{ - %cl.sentryRepairs++; - if (%game.SCORE_PER_REPAIR_SENTRY != 0) - { - messageClient(%cl, 'msgSentryRep', '\c0You received a %1 point bonus for repairing a sentry turret.', %game.SCORE_PER_REPAIR_SENTRY); - } - %game.recalcScore(%cl); -} - -function PracticeCTFGame::awardScoreDepTurretRepair(%game, %cl) -{ - %cl.depTurretRepairs++; - if (%game.SCORE_PER_REPAIR_DEP_TUR != 0) - { - messageClient(%cl, 'msgDepTurretRep', '\c0You received a %1 point bonus for repairing a deployed turret.', %game.SCORE_PER_REPAIR_DEP_TUR); - } - %game.recalcScore(%cl); -} - -function PracticeCTFGame::awardScoreDepInvRepair(%game, %cl) -{ - %cl.depInvRepairs++; - if (%game.SCORE_PER_REPAIR_DEP_INV != 0) - { - messageClient(%cl, 'msgDepInvRep', '\c0You received a %1 point bonus for repairing a deployed station.', %game.SCORE_PER_REPAIR_DEP_INV); - } - %game.recalcScore(%cl); -} - -function PracticeCTFGame::enterMissionArea(%game, %playerData, %player) -{ - if(%player.getState() $= "Dead") - return; - %player.client.outOfBounds = false; - messageClient(%player.client, 'EnterMissionArea', '\c1You are back in the mission area.'); - logEcho(%player.client.nameBase@" (pl "@%player@"/cl "@%player.client@") entered mission area"); - - //the instant a player leaves the mission boundary, the flag is dropped, and the return is scheduled... - if (%player.holdingFlag > 0) - { - cancel($FlagReturnTimer[%player.holdingFlag]); - $FlagReturnTimer[%player.holdingFlag] = ""; - } -} - -function PracticeCTFGame::leaveMissionArea(%game, %playerData, %player) -{ - if(%player.getState() $= "Dead") - return; - // maybe we'll do this just in case - %player.client.outOfBounds = true; - // if the player is holding a flag, strip it and throw it back into the mission area - // otherwise, just print a message - if(%player.holdingFlag > 0) - %game.boundaryLoseFlag(%player); - else - messageClient(%player.client, 'MsgLeaveMissionArea', '\c1You have left the mission area.~wfx/misc/warning_beep.wav'); - logEcho(%player.client.nameBase@" (pl "@%player@"/cl "@%player.client@") left mission area"); -} - -function PracticeCTFGame::boundaryLoseFlag(%game, %player) -{ - // this is called when a player goes out of the mission area while holding - // the enemy flag. - make sure the player is still out of bounds - if (!%player.client.outOfBounds || !isObject(%player.holdingFlag)) - return; - - // ------------------------------------------------------------------------------ - // z0dd - ZOD - SquirrelOfDeath, 9/27/02. Delay on grabbing flag after tossing it - %player.flagTossWait = true; - %player.schedule(1000, resetFlagTossWait); - // ------------------------------------------------------------------------------- - - %client = %player.client; - %flag = %player.holdingFlag; - %flag.setVelocity("0 0 0"); - %flag.setTransform(%player.getWorldBoxCenter()); - %flag.setCollisionTimeout(%player); - - %held = %game.formatTime(getSimTime() - %game.flagHeldTime[%flag], false); // z0dd - ZOD, 8/15/02. How long did player hold flag? - - %game.playerDroppedFlag(%player); - - // now for the tricky part -- throwing the flag back into the mission area - // let's try throwing it back towards its "home" - %home = %flag.originalPosition; - %vecx = firstWord(%home) - firstWord(%player.getWorldBoxCenter()); - %vecy = getWord(%home, 1) - getWord(%player.getWorldBoxCenter(), 1); - %vecz = getWord(%home, 2) - getWord(%player.getWorldBoxCenter(), 2); - %vec = %vecx SPC %vecy SPC %vecz; - - // normalize the vector, scale it, and add an extra "upwards" component - %vecNorm = VectorNormalize(%vec); - %vec = VectorScale(%vecNorm, 1500); - %vec = vectorAdd(%vec, "0 0 500"); - - // z0dd - ZOD, 6/09/02. Remove anti-hover so flag can be thrown properly - %flag.static = false; - - // z0dd - ZOD, 10/02/02. Hack for flag collision bug. - %flag.searchSchedule = %game.schedule(10, "startFlagCollisionSearch", %flag); - - // apply the impulse to the flag object - %flag.applyImpulse(%player.getWorldBoxCenter(), %vec); - - //don't forget to send the message - //messageClient(%player.client, 'MsgCTFFlagDropped', '\c1You have left the mission area and lost the flag.~wfx/misc/flag_drop.wav', 0, 0, %player.holdingFlag.team); - - // z0dd - ZOD 3/30/02. Above message was sending the wrong varible to objective hud. - messageClient(%player.client, 'MsgCTFFlagDropped', '\c1You have left the mission area and lost the flag. (Held: %4)~wfx/misc/flag_drop.wav', %client.name, 0, %flag.team, %held); // z0dd - ZOD, 8/19/02. yogi. 3rd param changed from 0 to %client.name - logEcho(%player.client.nameBase@" (pl "@%player@"/cl "@%player.client@") lost flag (out of bounds)"@" (Held: "@%held@")"); -} - -function PracticeCTFGame::dropFlag(%game, %player) -{ - if(%player.holdingFlag > 0) - { - if (!%player.client.outOfBounds) - %player.throwObject(%player.holdingFlag); - else - %game.boundaryLoseFlag(%player); - } -} - -function PracticeCTFGame::applyConcussion(%game, %player) -{ - %game.dropFlag( %player ); -} - -function PracticeCTFGame::vehicleDestroyed(%game, %vehicle, %destroyer) -{ - //vehicle name - %data = %vehicle.getDataBlock(); - //%vehicleType = getTaggedString(%data.targetNameTag) SPC getTaggedString(%data.targetTypeTag); - %vehicleType = getTaggedString(%data.targetTypeTag); - if(%vehicleType !$= "MPB") - %vehicleType = strlwr(%vehicleType); - - %enemyTeam = ( %destroyer.team == 1 ) ? 2 : 1; - - %scorer = 0; - %multiplier = 1; - - %passengers = 0; - for(%i = 0; %i < %data.numMountPoints; %i++) - if(%vehicle.getMountNodeObject(%i)) - %passengers++; - - //what destroyed this vehicle - if(%destroyer.client) - { - //it was a player, or his mine, satchel, whatever... - %destroyer = %destroyer.client; - %scorer = %destroyer; - - // determine if the object used was a mine - if(%vehicle.lastDamageType == $DamageType::Mine) - %multiplier = 2; - } - else if(%destroyer.getClassName() $= "Turret") - { - if(%destroyer.getControllingClient()) - { - //manned turret - %destroyer = %destroyer.getControllingClient(); - %scorer = %destroyer; - } - else - { - %destroyerName = "A turret"; - %multiplier = 0; - } - } - else if(%destroyer.getDataBlock().catagory $= "Vehicles") - { - // Vehicle vs vehicle kill! - if(%name $= "BomberFlyer" || %name $= "AssaultVehicle") - %gunnerNode = 1; - else - %gunnerNode = 0; - - if(%destroyer.getMountNodeObject(%gunnerNode)) - { - %destroyer = %destroyer.getMountNodeObject(%gunnerNode).client; - %scorer = %destroyer; - } - %multiplier = 3; - } - else // Is there anything else we care about? - return; - - - if(%destroyerName $= "") - %destroyerName = %destroyer.name; - - if(%vehicle.team == %destroyer.team) // team kill - { - %pref = (%vehicleType $= "Assault Tank") ? "an" : "a"; - messageAll( 'msgVehicleTeamDestroy', '\c0%1 TEAMKILLED %3 %2!', %destroyerName, %vehicleType, %pref); - } - - else // legit kill - { - //messageTeamExcept(%destroyer, 'msgVehicleDestroy', '\c0%1 destroyed an enemy %2.', %destroyerName, %vehicleType); // z0dd - ZOD, 8/20/02. not needed with new messenger on line below - teamDestroyMessage(%destroyer, 'msgVehDestroyed', '\c5%1 destroyed an enemy %2!', %destroyerName, %vehicleType); // z0dd - ZOD, 8/20/02. Send teammates a destroy message - messageTeam(%enemyTeam, 'msgVehicleDestroy', '\c0%1 destroyed your team\'s %2.', %destroyerName, %vehicleType); - //messageClient(%destroyer, 'msgVehicleDestroy', '\c0You destroyed an enemy %1.', %vehicleType); - - if(%scorer) - { - %value = %game.awardScoreVehicleDestroyed(%scorer, %vehicleType, %multiplier, %passengers); - %game.shareScore(%value); - } - } -} - -function PracticeCTFGame::awardScoreVehicleDestroyed(%game, %client, %vehicleType, %mult, %passengers) -{ - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - - if(%vehicleType $= "Grav Cycle") - %base = %game.SCORE_PER_DESTROY_WILDCAT; - else if(%vehicleType $= "Assault Tank") - %base = %game.SCORE_PER_DESTROY_TANK; - else if(%vehicleType $= "MPB") - %base = %game.SCORE_PER_DESTROY_MPB; - else if(%vehicleType $= "Turbograv") - %base = %game.SCORE_PER_DESTROY_SHRIKE; - else if(%vehicleType $= "Bomber") - %base = %game.SCORE_PER_DESTROY_BOMBER; - else if(%vehicleType $= "Heavy Transport") - %base = %game.SCORE_PER_DESTROY_TRANSPORT; - - %total = ( %base * %mult ) + ( %passengers * %game.SCORE_PER_PASSENGER ); - - %client.vehicleScore += %total; - - messageClient(%client, 'msgVehicleScore', '\c0You received a %1 point bonus for destroying an enemy %2.', %total, %vehicleType); - %game.recalcScore(%client); - return %total; -} - -function PracticeCTFGame::shareScore(%game, %client, %amount) -{ - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - - //error("share score of"SPC %amount SPC "from client:" SPC %client); - // all of the player in the bomber and tank share the points - // gained from any of the others - %vehicle = %client.vehicleMounted; - if(!%vehicle) - return 0; - %vehicleType = getTaggedString(%vehicle.getDataBlock().targetTypeTag); - if(%vehicleType $= "Bomber" || %vehicleType $= "Assault Tank") - { - for(%i = 0; %i < %vehicle.getDataBlock().numMountPoints; %i++) - { - %occupant = %vehicle.getMountNodeObject(%i); - if(%occupant) - { - %occCl = %occupant.client; - if(%occCl != %client && %occCl.team == %client.team) - { - // the vehicle has a valid teammate at this node - // share the score with them - %occCl.vehicleBonus += %amount; - %game.recalcScore(%occCl); - } - } - } - } -} - -function PracticeCTFGame::awardScoreTurretKill(%game, %victimID, %implement) -{ - if ((%killer = %implement.getControllingClient()) != 0) //award whoever might be controlling the turret - { - if (%killer == %victimID) - %game.awardScoreSuicide(%victimID); - else if (%killer.team == %victimID.team) //player controlling a turret killed a teammate - { - %killer.teamKills++; - %game.awardScoreTurretTeamKill(%victimID, %killer); - %game.awardScoreDeath(%victimID); - } - else - { - %killer.mannedturretKills++; - %game.recalcScore(%killer); - %game.awardScoreDeath(%victimID); - } - } - else if ((%killer = %implement.owner) != 0) //if it isn't controlled, award score to whoever deployed it - { - if (%killer.team == %victimID.team) - { - %game.awardScoreDeath(%victimID); - } - else - { - %killer.turretKills++; - %game.recalcScore(%killer); - %game.awardScoreDeath(%victimID); - } - } - //default is, no one was controlling it, no one owned it. No score given. -} - -function PracticeCTFGame::testKill(%game, %victimID, %killerID) -{ - return ((%killerID !=0) && (%victimID.team != %killerID.team)); -} - -function PracticeCTFGame::awardScoreKill(%game, %killerID) -{ - %killerID.kills++; - %game.recalcScore(%killerID); - return %game.SCORE_PER_KILL; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// z0dd - ZOD: Practice Mode functions ////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////// - -function PracticeCTFGame::onClientLeaveGame(%game, %client) -{ - // Clear out this clients transfer pads - for( %i = 0; %i < $Host::ClassicMaxTelepads; %i++ ) - { - if(isObject(%client.spawnPad[%i])) - %client.spawnPad[%i].setDamageState(Destroyed); - } - - // Call the default - DefaultGame::onClientLeaveGame(%game, %client); -} - -function PracticeCTFGame::clientChangeTeam(%game, %client, %team, %fromObs) -{ - // Clear out this clients transfer pads - for( %i = 0; %i < $Host::ClassicMaxTelepads; %i++ ) { - if(isObject(%client.spawnPad[%i])) - %client.spawnPad[%i].setDamageState(Destroyed); - } - - // Call the default - DefaultGame::clientChangeTeam(%game, %client, %team, %fromObs); -} - -function PracticeCTFGame::equip(%game, %player) -{ - for(%i =0; %i<$InventoryHudCount; %i++) - %player.client.setInventoryHudItem($InventoryHudData[%i, itemDataName], 0, 1); - %player.client.clearBackpackIcon(); - - if(!%player.client.isAIControlled() && $PracticeCtf::SpawnFavs && !$PracticeCtf::SpawnOnly) - { - buyFavorites(%player.client); - %player.setEnergyLevel(%player.getDataBlock().maxEnergy); - %player.selectWeaponSlot( 0 ); - } - else - { - %player.setInventory(Blaster,1); - %player.setInventory(Disc,1); - %player.setInventory(DiscAmmo, 999); - %player.setInventory(Chaingun, 1); - %player.setInventory(ChaingunAmmo, 999); - %player.setInventory(RepairKit,1); - %player.setInventory(Grenade, 30); - %player.setInventory(Beacon, 20); - %player.setInventory(TargetingLaser, 1); - %player.weaponCount = 3; - - %player.use("Blaster"); - } -} - -///////////////////////////////////////////////////////////////////////////////////////// -// z0dd - ZOD: Map Reset functions/////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////// - -function PracticeCTFGame::resetMission(%game) -{ - Cancel( %game.timeCheck ); - CancelCountdown(); - CancelEndCountdown(); - - //setup the second half... - // MES -- per MarkF, scheduling for 0 seconds will prevent player deletion-related crashes - %game.schedule(0, "refreshAll"); -} - -function PracticeCTFGame::refreshAll(%game) -{ - //stop the game and the bots - $MatchStarted = false; - $CountdownStarted = false; - AISystemEnabled(false); - - // Let everyone know what is going on - bottomPrintAll("\nYou are in observation mode while mission is resetting.\n", $Host::warmupTime, 3); - - // Return all flags that aren't home - for(%f = 1; %f <= %game.numTeams; %f++) - { - if(!$TeamFlag[%f].isHome) - { - %game.flagReturn($TeamFlag[%f]); - } - } - - //reset stations and vehicles that players were using - // Function exists in Siege, use it, no need to duplicate - SiegeGame::resetPlayers(%game); - - // zero out the counts for deployable items (found in defaultGame.cs) - %game.clearDeployableMaxes(); - - // Clean up deployables triggers - cleanTriggers(nameToID("MissionCleanup/Deployables")); - - // clean up the MissionCleanup group - note, this includes deleting all the player objects - %clean = nameToID("MissionCleanup"); - %clean.schedule(800, "housekeeping"); - //%clean.housekeeping(); // Function exists in Siege no need to duplicate - - // Vehicle objects placed in original position - // This apprently switches the vehicles team as well, not a good idea. - //resetNonStaticObjPositions(); - - // Restore static objects to their original condition - // Function exists in defaultGame.cs, in turn calls PracticeCTFGame::groupObjectRestore - %group = nameToID("MissionGroup/Teams"); - %group.objectRestore(); - - %count = ClientGroup.getCount(); - echo("-----------count=" @ %count); - for(%cl = 0; %cl < %count; %cl++) - { - %client = ClientGroup.getObject(%cl); - if( !%client.isAIControlled() ) - { - Game.forceObserver( %client, "playerChoose" ); - - // old code. wasn't working correctly for some reason - // Put everybody in observer mode: - //%client.camera.getDataBlock().setMode( %client.camera, "observerStaticNoNext" ); - //%client.setControlObject( %client.camera ); - - // This sets certain keybinds, usefull, lets keep it? - //commandToClient( %client, 'setHudMode', 'Standard' ); - //commandToClient( %client, 'ControlObjectReset' ); - - //clientResetTargets(%client, true); - //%client.notReady = true; - } - } - %game.schedule( $Host::warmupTime * 1000, "resetOver" ); -} - -function PracticeCTFGame::groupObjectRestore(%game, %this) -{ - for(%i = 0; %i < %this.getCount(); %i++) - %this.getObject(%i).objectRestore(); -} - -function PracticeCTFGame::shapeObjectRestore(%game, %object) -{ - if(%object.getDamageLevel()) - { - %object.setDamageLevel(0.0); - %object.setDamageState(Enabled); - } - if(%object.getDatablock().getName() $= "TurretBaseLarge") - { - // check to see if the turret base still has the same type of barrel it had - // at the beginning of the mission - if(%object.getMountedImage(0)) - { - if(%object.getMountedImage(0).getName() !$= %object.originalBarrel) - { - // pop the "new" barrel - %object.unmountImage(0); - // mount the original barrel - %object.mountImage(%object.initialBarrel, 0, false); - } - } - } -} - -function PracticeCTFGame::resetOver( %game ) -{ - // Reset the team scores - for(%j = 1; %j <= %game.numTeams; %j++) - $TeamScore[%j] = 0; - - // drop all players into mission - %game.dropPlayers(); - - //setup the AI for the second half - %game.aiHalfTime(); - - // start the mission again (release players) - %game.startupCountDown( $Host::warmupTime ); -} - -function PracticeCTFGame::dropPlayers( %game ) -{ - %count = ClientGroup.getCount(); - for(%cl = 0; %cl < %count; %cl++) - { - %client = ClientGroup.getObject(%cl); - - // Reset client score - %game.resetScore(%client); - - // Resend the scores and flag status - for(%i = 1; %i <= %game.numTeams; %i++) - messageClient(%client, 'MsgCTFAddTeam', "", %i, %game.getTeamName(%i), $flagStatus[%i], $TeamScore[%i]); - - if( !%client.isAIControlled() ) - { - // keep observers in observer mode - if(%client.team == 0) - %client.camera.getDataBlock().setMode(%client.camera, "justJoined"); - else - { - %game.spawnPlayer( %client, false ); - - %client.camera.getDataBlock().setMode( %client.camera, "pre-game", %client.player ); - %client.setControlObject( %client.camera ); - //%client.notReady = false; - } - } - } -} - -function PracticeCTFGame::startupCountDown(%game, %time) -{ - %game.startupCountDown = true; - $MatchStarted = false; - - %timeMS = %time * 1000; - %game.schedule(%timeMS, "startMap"); - notifyMatchStart(%timeMS); - - if(%timeMS > 30000) - schedule(%timeMS - 30000, 0, "notifyMatchStart", 30000); - if(%timeMS > 20000) - schedule(%timeMS - 20000, 0, "notifyMatchStart", 20000); - if(%timeMS > 10000) - schedule(%timeMS - 10000, 0, "notifyMatchStart", 10000); - if(%timeMS > 5000) - schedule(%timeMS - 5000, 0, "notifyMatchStart", 5000); - if(%timeMS > 4000) - schedule(%timeMS - 4000, 0, "notifyMatchStart", 4000); - if(%timeMS > 3000) - schedule(%timeMS - 3000, 0, "notifyMatchStart", 3000); - if(%timeMS > 2000) - schedule(%timeMS - 2000, 0, "notifyMatchStart", 2000); - if(%timeMS > 1000) - schedule(%timeMS - 1000, 0, "notifyMatchStart", 1000); -} - -function PracticeCTFGame::startMap(%game) -{ - $MatchStarted = true; - $CountdownStarted = true; - %game.startupCountDown = false; - - MessageAll('MsgMissionStart', "\c2Match started"); - - // reset the timelimit - %curTimeLeftMS = $Host::TimeLimit * 60 * 1000; - $missionStartTime = getSimTime(); - %game.timeCheck = %game.schedule(20000, "checkTimeLimit"); - - //schedule the end of match countdown - EndCountdown($Host::TimeLimit * 60 * 1000); - - // set all clients control to their player - %count = ClientGroup.getCount(); - for( %i = 0; %i < %count; %i++ ) - { - %cl = ClientGroup.getObject(%i); - - // Send clients the new clock - messageClient(%cl, 'MsgSystemClock', "", $Host::TimeLimit, %curTimeLeftMS); - - if (!isObject(%cl.player)) - commandToClient(%cl, 'setHudMode', 'Observer'); - else - { - %cl.observerMode = ""; - %cl.setControlObject( %cl.player ); - commandToClient(%cl, 'setHudMode', 'Standard'); - %client.notReady = false; - } - } - - //now synchronize everyone's clock - updateClientTimes(%curTimeLeftMS); - - //start the bots up again... - AISystemEnabled(true); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// z0dd - ZOD: Hud related Practice functions /////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////// - -function PracticeCTFGame::initPracticeHud(%game, %client, %val) -{ - commandToClient(%client, 'initializePracHud', "PracticeCTF"); - commandToClient(%client, 'practiceHudHead', "CTF Practice Config", "Server Settings", "Player Settings", "Projectile Observation", "Telepad Options", "Spawn Vehicle at Pad"); - - // Send admins full set of options. Edit, this was causing problems when client requires update. - //if(%client.isAdmin) - //{ - commandToClient(%client, 'practiceHudPopulate', "Minimum Turrets", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16"); - commandToClient(%client, 'practiceHudPopulate', "Return Flag", getTaggedString(Game.getTeamName(1)), getTaggedString(Game.getTeamName(2))); - //if(%client.isSuperAdmin) - //{ - commandToClient(%client, 'practiceHudPopulate', "Save Deployables", $MissionDisplayName @ " File 1", $MissionDisplayName @ " File 2", $MissionDisplayName @ " File 3", $MissionDisplayName @ " File 4", $MissionDisplayName @ " File 5", $MissionDisplayName @ " File 6"); - commandToClient(%client, 'practiceHudPopulate', "Load Deployables", $MissionDisplayName @ " File 1", $MissionDisplayName @ " File 2", $MissionDisplayName @ " File 3", $MissionDisplayName @ " File 4", $MissionDisplayName @ " File 5", $MissionDisplayName @ " File 6"); - //} - //} - commandToClient(%client, 'practiceHudDone'); -} - -function PracticeCTFGame::sendPracHudUpdate(%game, %client, %msg) -{ - %serverOptMask = 0; - if ($PracticeCtf::UnlimAmmo == 1) %serverOptMask += 1; - if ($PracticeCtf::AutoFlagReturn == 1) %serverOptMask += 2; - if ($PracticeCtf::SpawnFavs == 1) %serverOptMask += 4; - if ($PracticeCtf::SpawnOnly == 1) %serverOptMask += 8; - if ($PracticeCtf::NoScoreLimit == 1) %serverOptMask += 16; - if ($PracticeCtf::ProtectStatics == 1) %serverOptMask += 32; - - %clientOptMask = 0; - if (%client.discObs == 1) %clientOptMask += 1; - if (%client.grenadeObs == 1) %clientOptMask += 2; - if (%client.mortarObs == 1) %clientOptMask += 4; - if (%client.missileObs == 1) %clientOptMask += 8; - if (%client.transMode == 0) %clientOptMask += 16; - if (%client.transMode == 1) %clientOptMask += 32; - - messageClient(%client, 'UpdatePracHud', %msg, %serverOptMask, %clientOptMask, %client.isAdmin + %client.isSuperAdmin); -} - -function PracticeCTFGame::practiceBtnCmd(%game, %client, %btn, %val) -{ - // dont let non admins change practice mode server settings - if((mFloor(%btn/10) == 1) && (!%client.isAdmin) && (!%client.isSuperAdmin)) - { - messageClient(%client, 'MsgPracMode', '\c2Only admins can change that Server Setting.~wfx/misc/misc.error.wav'); - return; - } - if(!$MatchStarted) - { - messageClient( %client, 'MsgPracMode', '\c2You must wait for the match to start before using practice commands.~wfx/misc/misc.error.wav'); - return; - } - - %name = %client.nameBase; - %snd = "~wfx/misc/warning_beep.wav"; - - switch$ (%btn) - { - // GUI CONTROLS - - // SERVER BUTTONS - case 10: - $PracticeCtf::UnlimAmmo = !$PracticeCtf::UnlimAmmo; - sendAllPracHudUpdate(%game, "\c3" @ %name @ "\c2: 999 AMMO turned \c3" @ ($PracticeCtf::UnlimAmmo ? "ON" : "OFF") @ %snd); - - case 11: - $PracticeCtf::AutoFlagReturn = !$PracticeCtf::AutoFlagReturn; - sendAllPracHudUpdate(%game, "\c3" @ %name @ "\c2: AUTO-RETURN FLAGS turned \c3" @ ($PracticeCtf::AutoFlagReturn ? "ON" : "OFF") @ %snd); - - case 12: - $PracticeCtf::SpawnFavs = !$PracticeCtf::SpawnFavs; - sendAllPracHudUpdate(%game, "\c3" @ %name @ "\c2: SPAWN IN FAVORITE turned \c3" @ ($PracticeCtf::SpawnFavs ? "ON" : "OFF") @ %snd); - - case 13: - $PracticeCtf::SpawnOnly = !$PracticeCtf::SpawnOnly; - sendAllPracHudUpdate(%game, "\c3" @ %name @ "\c2: SPAWN ONLY turned \c3" @ ($PracticeCtf::SpawnOnly ? "ON" : "OFF") @ %snd); - - case 14: - $PracticeCtf::NoScoreLimit = !$PracticeCtf::NoScoreLimit; - sendAllPracHudUpdate(%game, "\c3" @ %name @ "\c2: NO SCORE LIMIT turned \c3" @ ($PracticeCtf::NoScoreLimit ? "ON" : "OFF") @ %snd); - for ( %team = 1; %team <= %game.numTeams; %team++ ) - %game.checkScoreLimit(%team); - - case 15: - $PracticeCtf::ProtectStatics = !$PracticeCtf::ProtectStatics; - sendAllPracHudUpdate(%game, "\c3" @ %name @ "\c2: PROTECT ASSESTS turned \c3" @ ($PracticeCtf::ProtectStatics ? "ON" : "OFF") @ %snd); - - case 16: - messageAll( 'MsgPracMode', '\c3%1\c2: Resetting map.%2', %client.name, %snd); - %game.resetMission(); - - // TELEPORT OPTIONS - case 20: - %client.transMode = 0; // beacon - //messageClient( %client, 'MsgPracMode', '\c2Beacon deploy mode: \c3Beacon\c2.%1', %snd); - - case 21: - %client.transMode = 1; // telepad - //messageClient( %client, 'MsgPracMode', '\c2Beacon deploy mode: \c3Transfer Pad\c2.%1', %snd); - - case 22: - selectPad(%client); - - case 23: - destroyPad(%client, 0); - - case 24: - teleportToPad(%client); - - // SPAWN VEHICLES - case 30: - spawnVehAtPad(%client, "ScoutVehicle"); - - case 31: - spawnVehAtPad(%client, "AssaultVehicle"); - - case 32: - spawnVehAtPad(%client, "MobileBaseVehicle"); - - case 33: - spawnVehAtPad(%client, "ScoutFlyer"); - - case 34: - spawnVehAtPad(%client, "BomberFlyer"); - - case 35: - spawnVehAtPad(%client, "HAPCFlyer"); - - // PROJECTILE OBSERVATION - case 40: - %client.discObs = %val; - - case 41: - %client.grenadeObs = %val; - - case 42: - %client.mortarObs = %val; - - case 43: - %client.missileObs = %val; - - default: - messageClient( %client, 'MsgError', '\c2Unknown values.%1', %snd); - } -} - -// Menu Submit handler -function PracticeCTFGame::updatePracticeHudSet(%game, %client, %opt, %val) -{ - // dont let non admins change practice mode server settings - if((%opt < 3) && ((!%client.isAdmin) || (!%client.isSuperAdmin))) - { - messageClient(%client, 'MsgError', '\c2Only admins can change that Server Setting.~wfx/misc/misc.error.wav'); - return; - } - else if((!%client.isSuperAdmin)) // dont let non SuperAdmins change SuperAdmin only practice mode server settings - { - messageClient(%client, 'MsgError', '\c2Only SuperAdmins can change that Server Setting.~wfx/misc/misc.error.wav'); - return; - } - if(!$MatchStarted) - { - messageClient( %client, 'MsgError', '\c2You must wait for the match to start before using practice commands.~wfx/misc/misc.error.wav'); - return; - } - - %snd = '~wfx/misc/warning_beep.wav'; - %adj = %val == 1 ? 1 : 0; // Convert index to only 1 or 0 to help keep function smaller - %detail = (%adj ? "On" : "Off"); - %name = %client.name; - - switch$ ( %opt ) - { - case 1: - %min = %val+3; - $TeamDeployableMin[TurretIndoorDeployable] = %min; - $TeamDeployableMin[TurretOutdoorDeployable] = %min; - %detail = %min; - messageAll( 'MsgPracMode', '\c3%5\c2: \"Minimum Turrets\" set to: \c3%4\c2.%1', %snd, %val, %adj, %detail, %name, $CurrentMission ); - - case 2: - if(!$TeamFlag[%val].isHome) - { - %game.flagReturn($TeamFlag[%val]); - messageAll( 'MsgPracMode', '\c3%5\c2: returned the flag.%1', %snd, %val, %adj, %detail, %name, $CurrentMission ); - } - else - messageClient( %client, 'MsgPracMode', '\c2Unknown values.', %snd, %val, %adj, %detail, %name, $CurrentMission ); - - case 3: - messageClient( %client, 'MsgPracMode', '\c2Attempting to save deployables to file: %6 %2.', %snd, %val, %adj, %detail, %name, $CurrentMission ); - %game.saveDeployables(%client, %val); - - case 4: - messageClient( %client, 'MsgPracMode', '\c2Attempting to load deployables from file: %6 %2.', %snd, %val, %adj, %detail, %name, $CurrentMission ); - %game.loadDeployables(%client, %val); - - default: - messageClient( %client, 'MsgError', '\c2Unknown values.', %snd, %val, %adj, %detail, %name, $CurrentMission ); - } -} - -// default to 0 -$DeployablesCount = 0; - -function PracticeCTFGame::loadDeployables(%game, %client, %val) -{ - if(%client.isSuperAdmin) - { - %filename = "prefs/" @ "DepSav" @ $CurrentMission @ %val @ ".cs"; - if(!isFile(%filename)) - { - messageClient(%client, 'MsgPracMode', '\c2File %6 %2 does not exist!', 0, %val, 0, 0, 0, $CurrentMission ); - return; - } - else - { - %group = nameToID("MissionCleanup/Deployables"); - %count = %group.getCount(); - for(%i = 0; %i < %count; %i++) - { - %obj = %group.getObject(%i); - %obj.setDamageState(Destroyed); - } - - %file = new FileObject(); - if(%file.openForRead(%filename)) - { - exec(%filename); - for(%i = 0; %i < $DeployablesCount; %i++) - { - %class = $DeployableClassName[%i]; - if(%class $= "TurretData") - %className = "Turret"; - else - %className = "StaticShape"; - - %deplObj = new (%className)() { - dataBlock = $DeployableDataBlockName[%i]; - }; - %deplObj.setTransform($DeployableTrans[%i]); - if(%deplObj.getDatablock().rechargeRate) - %deplObj.setRechargeRate(%deplObj.getDatablock().rechargeRate); - - %deplObj.team = $DeployableTeam[%i]; - %deplObj.owner = 0; - if(%deplObj.getTarget() != -1) - setTargetSensorGroup(%deplObj.getTarget(), $DeployableTeam[%i]); - - addToDeployGroup(%deplObj); - AIDeployObject(0, %deplObj); - $TeamDeployedCount[$DeployableTeam[%i], $DeployableItem[%i]]++; - %deplObj.deploy(); - } - } - %file.delete(); - messageClient(%client, 'MsgPracMode', '\c2Load file %6 %2 completed.', 0, %val, 0, 0, 0, $CurrentMission ); - } - } - else - messageClient(%client, 'MsgError', '\c2Only SuperAdmins can use this setting.~wfx/misc/misc.error.wav'); -} - -function PracticeCTFGame::saveDeployables(%game, %client, %val) -{ - if(%client.isSuperAdmin) - { - %filename = "prefs/" @ "DepSav" @ $CurrentMission @ %val @ ".cs"; - - // Check to see if theres anything to write first - %group = nameToID("MissionCleanup/Deployables"); - if (%group > 0) - %depCount = %group.getCount(); - else - return; - - if(isFile(%filename)) - deleteFile(%filename); - - %file = new fileObject(); - %file.openForWrite(%filename); - %count = 0; - for(%i = 0; %i < %depCount; %i++) - { - %deplObj = %group.getObject(%i); - if(isObject(%deplObj)) - { - %name = %deplObj.getDataBlock().getName(); - if(%name $= "DeployedStationInventory") - %item = "InventoryDeployable"; - else if(%name $= "DeployedMotionSensor") - %item = "MotionSensorDeployable"; - else if(%name $= "DeployedPulseSensor") - %item = "PulseSensorDeployable"; - else if(%name $= "TurretDeployedOutdoor") - %item = "TurretOutdoorDeployable"; - else if(%name $= "TurretDeployedFloorIndoor" || %name $= "TurretDeployedWallIndoor" || %name $= "TurretDeployedCeilingIndoor") - %item = "TurretIndoorDeployable"; - else if(%name $= "TurretDeployedCamera") - %item = "DeployedCamera"; - else - %item = ""; - - %file.writeLine("$DeployableDataBlockName[" @ %count @"] = " @ %name @ ";"); - %file.writeLine("$DeployableClassName[" @ %count @"] = " @ %deplObj.getDataBlock().getClassName() @ ";"); - %file.writeLine("$DeployableItem[" @ %count @"] = " @ %item @ ";"); - %file.writeLine("$DeployableTrans[" @ %count @"] = " @ "\"" @ %deplObj.getTransform() @ "\"" @ ";"); - %file.writeLine("$DeployableTeam[" @ %count @"] = " @ %deplObj.team @ ";"); - %count++; - } - } - %file.writeLine("$DeployablesCount = " @ %count @ ";"); - %file.close(); - %file.delete(); - messageClient(%client, 'MsgPracMode', '\c2Save file %6 %2 completed.', 0, %val, 0, 0, 0, $CurrentMission ); - } - else - messageClient(%client, 'MsgError', '\c2Only SuperAdmins can use this setting.~wfx/misc/misc.error.wav'); -} - -// z0dd - ZOD, 10/02/02. Hack for flag collision bug. -function CTFGame::startFlagCollisionSearch(%game, %flag) -{ - %flag.searchSchedule = %game.schedule(10, "startFlagCollisionSearch", %flag); // SquirrelOfDeath, 10/02/02. Moved from after the while loop - %pos = %flag.getWorldBoxCenter(); - InitContainerRadiusSearch( %pos, 1.0, $TypeMasks::VehicleObjectType | $TypeMasks::CorpseObjectType | $TypeMasks::PlayerObjectType ); - while((%found = containerSearchNext()) != 0) - { - %flag.getDataBlock().onCollision(%flag, %found); - // SquirrelOfDeath, 10/02/02. Removed break to catch all players possibly intersecting with flag - } -} +// DisplayName = Capture the Flag (Practice) + +//--- GAME RULES BEGIN --- +//Prevent enemy from capturing your flag +//Score one point for grabbing the enemy's flag +//To capture, your flag must be at its stand +//Score 100 points each time enemy flag is captured +//--- GAME RULES END --- + +//exec the AI scripts +exec("scripts/aiPracticeCtf.cs"); + +$InvBanList[PracticeCTF, "MiningTool"] = 1; + +//-- tracking --- +function PracticeCTFGame::initGameVars(%game) +{ + // z0dd - ZOD: Zero out Practice mode options + $TeamDeployableMin[TurretIndoorDeployable] = 4; + $TeamDeployableMin[TurretOutdoorDeployable] = 4; + + // z0dd - ZOD: We need only zero these when server comes up for first time. + if(!$pctfLoaded) + { + $PracticeCtf::SpawnFavs = 0; + $PracticeCtf::SpawnOnly = 0; + $PracticeCtf::AutoFlagReturn = 0; + $PracticeCtf::NoScoreLimit = 0; + $PracticeCtf::ProtectStatics = 0; + $PracticeCtf::UnlimAmmo = 0; + $pctfLoaded = 1; + } + %game.SCORE_PER_SUICIDE = 0; // z0dd - ZOD, 8/19/02. No penalty for suicide! Was -10 + %game.SCORE_PER_TEAMKILL = -10; + %game.SCORE_PER_DEATH = 0; + %game.SCORE_PER_TK_DESTROY = -10; // z0dd - ZOD, 10/03/02. Penalty for TKing equiptment. + + %game.SCORE_PER_KILL = 10; + %game.SCORE_PER_PLYR_FLAG_CAP = 30; + %game.SCORE_PER_PLYR_FLAG_TOUCH = 20; + %game.SCORE_PER_TEAM_FLAG_CAP = 100; + %game.SCORE_PER_TEAM_FLAG_TOUCH = 1; + %game.SCORE_PER_ESCORT_ASSIST = 5; + %game.SCORE_PER_HEADSHOT = 1; + %game.SCORE_PER_REARSHOT = 1; // z0dd - ZOD, 8/25/02. Rear Lance hits + + %game.SCORE_PER_TURRET_KILL = 10; // controlled + %game.SCORE_PER_TURRET_KILL_AUTO = 3; // uncontrolled + %game.SCORE_PER_FLAG_DEFEND = 5; + %game.SCORE_PER_CARRIER_KILL = 5; + %game.SCORE_PER_FLAG_RETURN = 10; + %game.SCORE_PER_STALEMATE_RETURN = 15; + %game.SCORE_PER_GEN_DEFEND = 5; + + %game.SCORE_PER_DESTROY_GEN = 10; + %game.SCORE_PER_DESTROY_SENSOR = 4; + %game.SCORE_PER_DESTROY_TURRET = 5; + %game.SCORE_PER_DESTROY_ISTATION = 2; + %game.SCORE_PER_DESTROY_VSTATION = 5; + %game.SCORE_PER_DESTROY_MPBTSTATION = 5; // z0dd - ZOD, 4/24/02. MPB Teleporter + %game.SCORE_PER_DESTROY_SOLAR = 5; + %game.SCORE_PER_DESTROY_SENTRY = 4; + %game.SCORE_PER_DESTROY_DEP_SENSOR = 1; + %game.SCORE_PER_DESTROY_DEP_INV = 2; + %game.SCORE_PER_DESTROY_DEP_TUR = 3; + + %game.SCORE_PER_DESTROY_SHRIKE = 5; + %game.SCORE_PER_DESTROY_BOMBER = 8; + %game.SCORE_PER_DESTROY_TRANSPORT = 5; + %game.SCORE_PER_DESTROY_WILDCAT = 5; + %game.SCORE_PER_DESTROY_TANK = 8; + %game.SCORE_PER_DESTROY_MPB = 12; + %game.SCORE_PER_PASSENGER = 2; + + %game.SCORE_PER_REPAIR_GEN = 8; + %game.SCORE_PER_REPAIR_SENSOR = 1; + %game.SCORE_PER_REPAIR_TURRET = 4; + %game.SCORE_PER_REPAIR_ISTATION = 2; + %game.SCORE_PER_REPAIR_VSTATION = 4; + %game.SCORE_PER_REPAIR_MPBTSTATION = 4; // z0dd - ZOD, 4/24/02. MPB Teleporter + %game.SCORE_PER_REPAIR_SOLAR = 4; + %game.SCORE_PER_REPAIR_SENTRY = 2; + %game.SCORE_PER_REPAIR_DEP_TUR = 3; + %game.SCORE_PER_REPAIR_DEP_INV = 2; + + %game.FLAG_RETURN_DELAY = 45 * 1000; //45 seconds + + %game.TIME_CONSIDERED_FLAGCARRIER_THREAT = 3 * 1000; //after damaging enemy flag carrier + %game.RADIUS_GEN_DEFENSE = 20; //meters + %game.RADIUS_FLAG_DEFENSE = 20; //meters + + %game.TOUCH_DELAY_MS = 20000; //20 secs + + %game.fadeTimeMS = 2000; + + %game.notifyMineDist = 7.5; + + %game.stalemate = false; + %game.stalemateObjsVisible = false; + %game.stalemateTimeMS = 60000; + %game.stalemateFreqMS = 15000; + %game.stalemateDurationMS = 6000; +} + +package PracticeCTFGame +{ + ///////////////////////////////////////////////////////////////////////////////////////// + // Practice Mode overloads ////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////////// + + function ShapeBase::cleanNonType(%this, %type) + { + // z0dd - ZOD: If the map is multi mission type, need to make sure the CTF flags stay put + if(%type $= PracticeCTF) + { + for(%h = 0; (%typeList = getWord(%this.missionTypesList, %h)) !$= ""; %h++) + if(%typeList $= CTF) + return; + } + Parent::cleanNonType(%this, %type); + } + + //function ShapeBase::maxInventory(%this,%data) + //{ + // z0dd - ZOD, 6/04/02: Allow virtually unlimited ammo in practice mode + // if(($PracticeCtf::UnlimAmmo == 1) && (%data.getName() !$= "RepairKit" && $CurrentMissionType $= Practice)) + // return 999; + // else + // return %this.getDatablock().max[%data.getName()]; + //} + + function Player::maxInventory(%this, %data) + { + // z0dd - ZOD, 6/17/02: Allow virtually unlimited ammo in practice mode + if(($PracticeCtf::UnlimAmmo == 1) && (%data.getName() !$= "RepairKit" && Game.class $= "PracticeCTFGame")) + { + return 999; + } + else + { + %max = ShapeBase::maxInventory(%this,%data); + if (%this.getInventory(AmmoPack)) + %max += AmmoPack.max[%data.getName()]; + + return %max; + } + } + + function StaticShapeData::damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType) + { + // z0dd - ZOD, 5/04/02. Check to see if damage should be applied to all static team assets. + if($PracticeCtf::ProtectStatics == 1 && %targetObject.getDataBlock().getClassName() !$= "TurretData" && !%targetObject.getDataBlock().deployedObject) + return; + else + parent::damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType); + } + + function Observer::onTrigger(%data,%obj,%trigger,%state) + { + if (%state == 0 || %trigger >= 4) + return; + + %client = %obj.getControllingClient(); + if (%client == 0) + return; + // z0dd - ZOD: Check for client projectile observation + switch$ (%obj.mode) + { + case "observerFollow": + if(%obj.projectile !$= "") + { + if(%trigger == 3) + { + clearBottomPrint(%client); + %client.camera.setFlyMode(); + %client.setControlObject(%client.player); + %obj.projectile = ""; // Clear the projectile + } + else + return; + } + else + Parent::onTrigger(%data,%obj,%trigger,%state); + + case "observerFly": + if(%obj.projectile !$= "") + { + if(%trigger == 3) + { + clearBottomPrint(%client); + %client.setControlObject(%client.player); + %obj.projectile = ""; // Clear the projectile + } + else + return; + } + else + Parent::onTrigger(%data,%obj,%trigger,%state); + + default: + Parent::onTrigger(%data,%obj,%trigger,%state); + } + } + + function Observer::setMode(%data, %obj, %mode, %targetObj) + { + if(%mode $= "") + return; + + %client = %obj.getControllingClient(); + // z0dd - ZOD: Check for client projectile observation + switch$ (%mode) + { + case "observerFollow": + if(%obj.projectile !$= "") + { + bottomPrint(%targetObj.sourceObject.client, "Observing Projectile.\nPress your jet key to resume to player control.", 0, 2); + %transform = %targetObj.initialPosition; + %obj.setOrbitMode(%targetObj, %transform, 0.2, 12.0, 4.5); + } + else + Parent::setMode(%data, %obj, %mode, %targetObj); + + case "observerFly": + if(%obj.projectile !$= "") + { + %obj.setTransform(%obj.getTransform()); + %obj.setFlyMode(); + bottomPrint(%client, "Free Fly Mode.\nPress your jet key to resume player control.", 0, 2); + } + else + Parent::setMode(%data, %obj, %mode, %targetObj); + + default: + Parent::setMode(%data, %obj, %mode, %targetObj); + } + %obj.mode = %mode; + } + + function MortarImage::onFire(%data, %obj, %slot) + { + // --------------------------------------------------------------------------- + // z0dd - ZOD, 10/14/02. Anti rapid fire mortar/missile fix. + if (%obj.cantFire !$= "") + { + return 0; + } + + %wpnName = %data.getName(); + %obj.cantFire = 1; + %preventTime = %data.stateTimeoutValue[4]; + %obj.reloadSchedule = schedule(%preventTime * 1000, %obj, resetFire, %obj); + // --------------------------------------------------------------------------- + + // z0dd - ZOD: Check for client projectile observation + %data.lightStart = getSimTime(); + if(%obj.client.mortarObs) + %data.projectile = ObsMortarShot; + + %p = new (%data.projectileType)() { + dataBlock = %data.projectile; + initialDirection = %obj.getMuzzleVector(%slot); + initialPosition = %obj.getMuzzlePoint(%slot); + sourceObject = %obj; + sourceSlot = %slot; + }; + MissionCleanup.add(%p); + if(%obj.client) + %obj.client.projectile = %p; + + %obj.decInventory(%data.ammo,1); + AIGrenadeThrown(%p); + + if(%obj.client.mortarObs) + { + %obj.client.camera.projectile = %p; + %obj.client.camera.getDataBlock().setMode(%obj.client.camera, "observerFollow", %p); + %obj.client.setControlObject(%obj.client.camera); + } + return %p; + } + + function AssaultMortarTurretBarrel::onFire(%data, %obj, %slot) + { + // z0dd - ZOD: Check for client projectile observation + %client = %obj.getControllingClient(); + if(%client) + %obj.client = %client; + + %data.lightStart = getSimTime(); + %useEnergyObj = %obj.getObjectMount(); + if(!%useEnergyObj) + %useEnergyObj = %obj; + + %energy = %useEnergyObj.getEnergyLevel(); + %vehicle = %useEnergyObj; + if( %useEnergyObj.turretObject.getCapacitorLevel() < %data.minEnergy ) + return; + + if(%client.mortarObs) + %data.projectile = ObsAssaultMortar; + + %p = new (%data.projectileType)() { + dataBlock = %data.projectile; + initialDirection = %obj.getMuzzleVector(%slot); + initialPosition = %obj.getMuzzlePoint(%slot); + sourceObject = %obj; + sourceSlot = %slot; + vehicleObject = %vehicle; + }; + MissionCleanup.add(%p); + if(%client) + %client.projectile = %p; + + %vehicle.turretObject.setCapacitorLevel( %vehicle.turretObject.getCapacitorLevel() - %data.fireEnergy ); + AIGrenadeThrown(%p); + if(%client.mortarObs) + { + %client.camera.projectile = %p; + %client.camera.getDataBlock().setMode(%client.camera, "observerFollow", %p); + %client.setControlObject(%client.camera); + } + // Stop the onFire from looping + %obj.setImageTrigger(4, false); + return %p; + } + + function AssaultPlasmaTurretBarrel::onFire(%data, %obj, %slot) + { + // Function used to kill console spam because of client + // client value added to AssaultMortarTurretBarrel::onFire + %obj.client = ""; + parent::onFire(%data, %obj, %slot); + } + + function MissileLauncherImage::onFire(%data,%obj,%slot) + { + // --------------------------------------------------------------------------- + // z0dd - ZOD, 10/14/02. Anti rapid fire mortar/missile fix. + if (%obj.cantFire !$= "") + { + return 0; + } + + %wpnName = %data.getName(); + %obj.cantFire = 1; + %preventTime = %data.stateTimeoutValue[4]; + %obj.reloadSchedule = schedule(%preventTime * 1000, %obj, resetFire, %obj); + // --------------------------------------------------------------------------- + + // z0dd - ZOD: Check for client projectile observation + %data.lightStart = getSimTime(); + + if(%obj.client.missileObs) + %data.projectile = ObsShoulderMissile; + + %p = new (%data.projectileType)() { + dataBlock = %data.projectile; + initialDirection = %obj.getMuzzleVector(%slot); + initialPosition = %obj.getMuzzlePoint(%slot); + sourceObject = %obj; + sourceSlot = %slot; + }; + MissionCleanup.add(%p); + MissileSet.add(%p); + if(%obj.client) + %obj.client.projectile = %p; + + %obj.decInventory(%data.ammo,1); + if(%obj.client.missileObs) + { + %obj.client.camera.projectile = %p; + %obj.client.camera.getDataBlock().setMode(%obj.client.camera, "observerFollow", %p); + %obj.client.setControlObject(%obj.client.camera); + } + + %target = %obj.getLockedTarget(); + if(%target) + %p.setObjectTarget(%target); + else if(%obj.isLocked()) + %p.setPositionTarget(%obj.getLockedPosition()); + else + %p.setNoTarget(); + } + + function MissileLauncherImage::onWetFire(%data, %obj, %slot) + { + // z0dd - ZOD: Check for client projectile observation + %data.lightStart = getSimTime(); + + if(%obj.client.missileObs) + %data.projectile = ObsShoulderMissile; + + %p = new (%data.projectileType)() { + dataBlock = %data.projectile; + initialDirection = %obj.getMuzzleVector(%slot); + initialPosition = %obj.getMuzzlePoint(%slot); + sourceObject = %obj; + sourceSlot = %slot; + }; + MissionCleanup.add(%p); + MissileSet.add(%p); + if(%obj.client) + %obj.client.projectile = %p; + + %obj.decInventory(%data.ammo,1); + if(%obj.client.missileObs) + { + %obj.client.camera.projectile = %p; + %obj.client.camera.getDataBlock().setMode(%obj.client.camera, "observerFollow", %p); + %obj.client.setControlObject(%obj.client.camera); + } + %p.setObjectTarget(0); + } + + function GrenadeLauncherImage::onFire(%data, %obj, %slot) + { + // z0dd - ZOD: Check for client projectile observation + %data.lightStart = getSimTime(); + if( %obj.station $= "" && %obj.isCloaked() ) + { + if( %obj.respawnCloakThread !$= "" ) + { + Cancel(%obj.respawnCloakThread); + %obj.setCloaked( false ); + %obj.respawnCloakThread = ""; + } + else + { + if( %obj.getEnergyLevel() > 20 ) + { + %obj.setCloaked( false ); + %obj.reCloak = %obj.schedule( 500, "setCloaked", true ); + } + } + } + if( %obj.client > 0 ) + { + %obj.setInvincibleMode(0 ,0.00); + %obj.setInvincible( false ); + } + if(%obj.client.grenadeObs) + %data.projectile = ObsGrenade; + + %p = new (%data.projectileType)() { + dataBlock = %data.projectile; + initialDirection = %obj.getMuzzleVector(%slot); + initialPosition = %obj.getMuzzlePoint(%slot); + sourceObject = %obj; + sourceSlot = %slot; + }; + MissionCleanup.add(%p); + if(%obj.client) + %obj.client.projectile = %p; + + %obj.decInventory(%data.ammo,1); + AIGrenadeThrown(%p); + if(%obj.client.grenadeObs) + { + %obj.client.camera.projectile = %p; + %obj.client.camera.getDataBlock().setMode(%obj.client.camera, "observerFollow", %p); + %obj.client.setControlObject(%obj.client.camera); + } + return %p; + } + + function DiscImage::onFire(%data, %obj, %slot) + { + // z0dd - ZOD: Check for client projectile observation + %data.lightStart = getSimTime(); + if( %obj.station $= "" && %obj.isCloaked() ) + { + if( %obj.respawnCloakThread !$= "" ) + { + Cancel(%obj.respawnCloakThread); + %obj.setCloaked( false ); + %obj.respawnCloakThread = ""; + } + else + { + if( %obj.getEnergyLevel() > 20 ) + { + %obj.setCloaked( false ); + %obj.reCloak = %obj.schedule( 500, "setCloaked", true ); + } + } + } + if( %obj.client > 0 ) + { + %obj.setInvincibleMode(0 ,0.00); + %obj.setInvincible( false ); + } + if(%obj.client.discObs) + %data.projectile = ObsDiscProjectile; + + %p = new (%data.projectileType)() { + dataBlock = %data.projectile; + initialDirection = %obj.getMuzzleVector(%slot); + initialPosition = %obj.getMuzzlePoint(%slot); + sourceObject = %obj; + sourceSlot = %slot; + }; + MissionCleanup.add(%p); + if(%obj.client) + %obj.client.projectile = %p; + + %obj.decInventory(%data.ammo,1); + if(%obj.client.discObs) + { + %obj.client.camera.projectile = %p; + %obj.client.camera.getDataBlock().setMode(%obj.client.camera, "observerFollow", %p); + %obj.client.setControlObject(%obj.client.camera); + } + return %p; + } + + function ProjectileData::onExplode(%data, %proj, %pos, %mod) + { + // z0dd - ZOD: If client is observing this projectile, let client camera free fly + if(%proj.sourceObject.client !$="" && isObject(%proj.sourceObject)) + { + %client = %proj.sourceObject.client; + %camera = %proj.sourceObject.client.getControlObject(); + if(%camera == %client.camera && %proj == %camera.projectile) + { + clearBottomPrint(%client); + %client.camera.getDataBlock().setMode(%client.camera, "observerFly"); + } + } + Parent::onExplode(%data, %proj, %pos, %mod); + } + + function Beacon::onUse(%data, %obj) + { + if(%obj.client.transMode) + deployTransferPad(%data, %obj); + else + Parent::onUse(%data, %obj); + } + + function StationInventory::stationReady(%data, %obj) + { + //Display the Inventory Station GUI here + %obj.notReady = 1; + %obj.inUse = "Down"; + %obj.schedule(500,"playThread",$ActivateThread,"activate1"); + %player = %obj.triggeredBy; + %energy = %player.getEnergyLevel(); + %max = %player.getDatablock().maxEnergy; // z0dd - ZOD, 4/20/02. Inv energy bug fix + %player.setCloaked(true); + %player.schedule(500, "setCloaked", false); + if (!%player.client.isAIControlled()) + { + if($PracticeCtf::SpawnOnly) // z0dd - ZOD: Test for spawn only + getAmmoStationLovin(%player.client); + else + buyFavorites(%player.client); + } + %player.setEnergyLevel(mFloor(%player.getDatablock().maxEnergy * %energy / %max)); // z0dd - ZOD, 4/20/02. Inv energy bug fix + %data.schedule( 500, "beginPersonalInvEffect", %obj ); + } + + function MobileInvStation::stationReady(%data, %obj) + { + //Display the Inventory Station GUI here + %obj.notReady = 1; + %obj.inUse = "Down"; + %obj.schedule(200,"playThread",$ActivateThread,"activate1"); + %obj.getObjectMount().playThread($ActivateThread,"Activate"); + %player = %obj.triggeredBy; + %energy = %player.getEnergyLevel(); + %player.setCloaked(true); + %player.schedule(900, "setCloaked", false); + if (!%player.client.isAIControlled()) + { + if($PracticeCtf::SpawnOnly) // z0dd - ZOD: Test for spawn only + getAmmoStationLovin(%player.client); + else + buyFavorites(%player.client); + } + %player.setEnergyLevel(%energy); + } + + function DeployedStationInventory::stationReady(%data, %obj) + { + %obj.notReady = 1; + %player = %obj.triggeredBy; + %obj.playThread($ActivateThread,"activate1"); + if (!%player.client.isAIControlled()) + { + if($PracticeCtf::SpawnOnly) // z0dd - ZOD: Test for spawn only + getAmmoStationLovin(%player.client); + else + buyDeployableFavorites(%player.client); + } + } + + function Flag::onEnterLiquid(%data, %obj, %coverage, %type) + { + if(%type > 3) // 1-3 are water, 4+ is lava and quicksand(?) + { + //error("flag("@%obj@") is in liquid type" SPC %type); + if($PracticeCtf::AutoFlagReturn) // z0dd - ZOD: Test automatic flag returns + Game.flagReturn(%obj); + else + Game.schedule(3000, flagReturn, %obj); + } + } + ///////////////////////////////////////////////////////////////////////////////////////// + + function ShapeBaseData::onDestroyed(%data, %obj) + { + %scorer = %obj.lastDamagedBy; + if(!isObject(%scorer)) + return; + + if( (%scorer.getType() & $TypeMasks::GameBaseObjectType) && %scorer.getDataBlock().catagory $= "Vehicles" ) + { + // z0dd - ZOD, 6/18/02. %name was never defined. + %name = %scorer.getDatablock().getName(); + if(%name $= "BomberFlyer" || %name $= "AssaultVehicle") + %gunnerNode = 1; + else + %gunnerNode = 0; + + if(%scorer.getMountNodeObject(%gunnerNode)) + { + %destroyer = %scorer.getMountNodeObject(%gunnerNode).client; + %scorer = %destroyer; + %damagingTeam = %scorer.team; + } + } + else if(%scorer.getClassName() $= "Turret") + { + if(%scorer.getControllingClient()) + { + //manned turret + %destroyer = %scorer.getControllingClient(); + %scorer = %destroyer; + %damagingTeam = %scorer.team; + } + else + { + return; //unmanned turret + } + } + + if(!%damagingTeam) + %damagingTeam = %scorer.team; + + // z0dd - ZOD, 10/03/02. Total re-write from here down. + if(%damagingTeam == %obj.team) + { + if(!%obj.getDataBlock().deployedObject) + { + teamDestroyMessage(%scorer, 'msgTkDes', '\c5Teammate %1 destroyed your team\'s %2!', %scorer.name, Game.cleanWord(%obj.getDataBlock().targetTypeTag)); + Game.awardScoreTkDestroy(%scorer); + } + return; + } + + %objType = %obj.getDataBlock().getName(); + switch$ ( %objType ) + { + case "GeneratorLarge": + teamDestroyMessage(%scorer, 'msgGenDestroyed', '\c5%1 destroyed a %2 Generator!', %scorer.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + %score = game.awardScoreGenDestroy(%scorer); + + case "SolarPanel": + teamDestroyMessage(%scorer, 'msgSolarDestroyed', '\c5%1 destroyed a %2 Solar Panel!', %scorer.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + %score = game.awardScoreSolarDestroy(%scorer); + game.shareScore(%score, %score); + + case "SensorLargePulse": + teamDestroyMessage(%scorer, 'msgSensorDestroyed', '\c5%1 destroyed a %2 Sensor!', %scorer.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + %score = game.awardScoreSensorDestroy(%scorer); + + case "SensorMediumPulse": + teamDestroyMessage(%scorer, 'msgSensorDestroyed', '\c5%1 destroyed a %2 Sensor!', %scorer.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + %score = game.awardScoreSensorDestroy(%scorer); + + case "DeployedMotionSensor": + teamDestroyMessage(%scorer, 'msgDepSenDestroyed', '\c5%1 destroyed a Deployable Sensor!', %scorer.name); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + %score = game.awardScoreDepSensorDestroy(%scorer); + + case "DeployedPulseSensor": + teamDestroyMessage(%scorer, 'msgDepSenDestroyed', '\c5%1 destroyed a Deployable Sensor!', %scorer.name); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + %score = game.awardScoreDepSensorDestroy(%scorer); + + case "StationInventory": + teamDestroyMessage(%scorer, 'msgInvDestroyed', '\c5%1 destroyed a %2 Inventory Station!', %scorer.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + %score = game.awardScoreInvDestroy(%scorer); + + case "StationAmmo": + teamDestroyMessage(%scorer, 'msgInvDestroyed', '\c5%1 destroyed a %2 Ammo Station!', %scorer.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + %score = game.awardScoreInvDestroy(%scorer); + + case "StationVehicle": + teamDestroyMessage(%scorer, 'msgVehStationDestroyed', '\c5%1 destroyed a Vehicle Station!', %scorer.name); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + %score = game.awardScoreVehicleStationDestroy(%scorer); + + case "MPBTeleporter": // z0dd - ZOD, 4/24/02. MPB teleporter + teamDestroyMessage(%scorer, 'msgTeleporterDestroyed', '\c5%1 destroyed a MPB Teleport Station!', %scorer.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + %score = game.awardScoreMPBTeleporterDestroy(%scorer); + + case "DeployedStationInventory": + teamDestroyMessage(%scorer, 'msgDepInvDestroyed', '\c5%1 destroyed a Deployable Inventory!', %scorer.name); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + %score = game.awardScoreDepStationDestroy(%scorer); + + case "TurretBaseLarge": + teamDestroyMessage(%scorer, 'msgTurDestroyed', '\c5%1 destroyed a %2 Turret!', %scorer.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + %score = game.awardScoreTurretDestroy(%scorer); + + case "SentryTurret": + teamDestroyMessage(%scorer, 'msgSentryDestroyed', '\c5%1 destroyed a %2 Sentry Turret!', %scorer.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + %score = game.awardScoreSentryDestroy(%scorer); + + case "TurretDeployedFloorIndoor": + teamDestroyMessage(%scorer, 'msgDepTurDestroyed', '\c5%1 destroyed a Spider Clamp Turret!', %scorer.name); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + %score = game.awardScoreDepTurretDestroy(%scorer); + + case "TurretDeployedWallIndoor": + teamDestroyMessage(%scorer, 'msgDepTurDestroyed', '\c5%1 destroyed a Spider Clamp Turret!', %scorer.name); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + %score = game.awardScoreDepTurretDestroy(%scorer); + + case "TurretDeployedCeilingIndoor": + teamDestroyMessage(%scorer, 'msgDepTurDestroyed', '\c5%1 destroyed a Spider Clamp Turret!', %scorer.name); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + %score = game.awardScoreDepTurretDestroy(%scorer); + + case "TurretDeployedOutdoor": + teamDestroyMessage(%scorer, 'msgDepTurDestroyed', '\c5%1 destroyed a Landspike Turret!', %scorer.name); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + %score = game.awardScoreDepTurretDestroy(%scorer); + + default: + return; + } + + if(!%obj.soiledByEnemyRepair) + { + game.shareScore(%scorer, %score); + } + } + + function ShapeBaseData::onDisabled(%data, %obj) + { + %obj.wasDisabled = true; + Parent::onDisabled(%data, %obj); + } + + function RepairGunImage::onRepair(%this, %obj, %slot) + { + Parent::onRepair(%this, %obj, %slot); + %target = %obj.repairing; + if(%target && %target.team != %obj.team) + { + //error("Enemy stuff("@%obj@") is being repaired (by "@%target@")"); + %target.soiledByEnemyRepair = true; + } + } + + function Flag::objectiveInit(%data, %flag) + { + if (!%flag.isTeamSkinned) + { + %pos = %flag.getTransform(); + %group = %flag.getGroup(); + } + %flag.originalPosition = %flag.getTransform(); + $flagPos[%flag.team] = %flag.originalPosition; + %flag.isHome = true; + %flag.carrier = ""; + %flag.grabber = ""; + setTargetSkin(%flag.getTarget(), PracticeCTFGame::getTeamSkin(PracticeCTFGame, %flag.team)); + setTargetSensorGroup(%flag.getTarget(), %flag.team); + setTargetAlwaysVisMask(%flag.getTarget(), 0x7); + setTargetRenderMask(%flag.getTarget(), getTargetRenderMask(%flag.getTarget()) | 0x2); + %flag.scopeWhenSensorVisible(true); + $flagStatus[%flag.team] = ""; + + //Point the flag and stand at each other + %group = %flag.getGroup(); + %count = %group.getCount(); + %flag.stand = ""; + for(%i = 0; %i < %count; %i++) + { + %this = %group.getObject(%i); + //--------------------------------------------------------------------------------------------------------------------------- + // z0dd - ZOD: Added TSStatic, console spam fix + if(%this.getClassName() !$= "InteriorInstance" && %this.getClassName() !$= "SimGroup" && %this.getClassName() !$= "TSStatic") + { + if(%this.getDataBlock().getName() $= "ExteriorFlagStand") + { + %flag.stand = %this; + %this.flag = %flag; + } + } + } + // set the nametag on the target + setTargetName(%flag.getTarget(), PracticeCTFGame::getTeamName(PracticeCTFGame, %flag.team)); + + // create a marker on this guy + %flag.waypoint = new MissionMarker() { + position = %flag.getTransform(); + dataBlock = "FlagMarker"; + }; + MissionCleanup.add(%flag.waypoint); + + // create a target for this (there is no MissionMarker::onAdd script call) + %target = createTarget(%flag.waypoint, PracticeCTFGame::getTeamName( PracticeCTFGame, %flag.team), "", "", 'Base', %flag.team, 0); + setTargetAlwaysVisMask(%target, 0xffffffff); + + //store the flag in an array + $TeamFlag[%flag.team] = %flag; + + // -------------------------------------------------------- + // z0dd - ZOD, 5/26/02. Don't let flag hover over defenders + %flag.static = true; + + // ------------------------------------------------------------------------------------------- + // z0dd - ZOD, 10/03/02. Use triggers for flags that are at home, hack for flag collision bug. + %flag.trigger = new Trigger() + { + dataBlock = flagTrigger; + polyhedron = "-0.6 0.6 0.1 1.2 0.0 0.0 0.0 -1.2 0.0 0.0 0.0 2.5"; + position = %flag.position; + rotation = %flag.rotation; + }; + MissionCleanup.add(%flag.trigger); + %flag.trigger.flag = %flag; + // ------------------------------------------------------------------------------------------- + } +}; + +//-------------------------------------------------------------------------- + +function PracticeCTFGame::getTeamSkin(%game, %team) +{ + CTFGame::getTeamSkin(%game, %team); +} + +function PracticeCTFGame::getTeamName(%game, %team) +{ + CTFGame::getTeamName(%game, %team); +} + +//-------------------------------------------------------------------------- +function PracticeCTFGame::missionLoadDone(%game) +{ + //default version sets up teams - must be called first... + DefaultGame::missionLoadDone(%game); + + for(%i = 1; %i < (%game.numTeams + 1); %i++) + $teamScore[%i] = 0; + + // remove + MissionGroup.clearFlagWaypoints(); + + //reset some globals, just in case... + $dontScoreTimer[1] = false; + $dontScoreTimer[2] = false; + + echo( "starting camp thread..." ); + %game.campThread_1 = schedule( 1000, 0, "checkVehicleCamping", 1 ); + %game.campThread_2 = schedule( 1000, 0, "checkVehicleCamping", 2 ); + + // z0dd - ZOD: Need to save off turret barrels for practice mode reset + // Function allready exists in siege no need to duplicate. + SiegeGame::checkTurretBases(); +} + +function PracticeCTFGame::playerTouchFlag(%game, %player, %flag) +{ + %client = %player.client; + + if ((%flag.carrier $= "") && (%player.getState() !$= "Dead")) + { + //flag isn't held and has been touched by a live player + if (%client.team == %flag.team) + %game.playerTouchOwnFlag(%player, %flag); + else + %game.playerTouchEnemyFlag(%player, %flag); + + // SquirrelOfDeath, 10/02/02. moved searchSchedule cancel from here to playerTouchEnemyFlag. + } + + // toggle visibility of the flag + setTargetRenderMask(%flag.waypoint.getTarget(), %flag.isHome ? 0 : 1); +} + +function PracticeCTFGame::playerTouchOwnFlag(%game, %player, %flag) +{ + if(%flag.isHome) + { + if (%player.holdingFlag !$= "") + %game.flagCap(%player); + } + else + %game.flagReturn(%flag, %player); + + //call the AI function + %game.AIplayerTouchOwnFlag(%player, %flag); +} + +function PracticeCTFGame::playerTouchEnemyFlag(%game, %player, %flag) +{ + // --------------------------------------------------------------- + // z0dd, ZOD - 9/27/02. Player must wait to grab after throwing it + if((%player.flagTossWait !$= "") && %player.flagTossWait) + return; + // --------------------------------------------------------------- + + cancel(%flag.searchSchedule); // z0dd - ZOD, 9/28/02. Hack for flag collision bug. SquirrelOfDeath, 10/02/02: Moved from PlayerTouchFlag + + cancel(%game.updateFlagThread[%flag]); // z0dd - ZOD, 8/4/02. Cancel this flag's thread to KineticPoet's flag updater + %game.flagHeldTime[%flag] = getSimTime(); // z0dd - ZOD, 8/15/02. Store time player grabbed flag. + + %client = %player.client; + %player.holdingFlag = %flag; //%player has this flag + %flag.carrier = %player; //this %flag is carried by %player + + %player.mountImage(FlagImage, $FlagSlot, true, %game.getTeamSkin(%flag.team)); + + %game.playerGotFlagTarget(%player); + //only cancel the return timer if the player is in bounds... + if (!%client.outOfBounds) + { + cancel($FlagReturnTimer[%flag]); + $FlagReturnTimer[%flag] = ""; + } + + //if this flag was "at home", see if both flags have now been taken + if (%flag.isHome) + { + // tiebreaker score + game.awardScoreFlagTouch( %client, %flag ); + + %startStalemate = false; + if ($TeamFlag[1] == %flag) + %startStalemate = !$TeamFlag[2].isHome; + else + %startStalemate = !$TeamFlag[1].isHome; + + if (%startStalemate) + %game.stalemateSchedule = %game.schedule(%game.stalemateTimeMS, beginStalemate); + + } + + %flag.hide(true); + %flag.startFade(0, 0, false); + %flag.isHome = false; + if(%flag.stand) + %flag.stand.getDataBlock().onFlagTaken(%flag.stand);//animate, if exterior stand + + $flagStatus[%flag.team] = %client.nameBase; + %teamName = %game.getTeamName(%flag.team); + messageTeamExcept(%client, 'MsgCTFFlagTaken', '\c2Teammate %1 took the %2 flag.~wfx/misc/flag_snatch.wav', %client.name, %teamName, %flag.team, %client.nameBase); + messageTeam(%flag.team, 'MsgCTFFlagTaken', '\c2Your flag has been taken by %1!~wfx/misc/flag_taken.wav',%client.name, 0, %flag.team, %client.nameBase); + messageTeam(0, 'MsgCTFFlagTaken', '\c2%1 took the %2 flag.~wfx/misc/flag_snatch.wav', %client.name, %teamName, %flag.team, %client.nameBase); + messageClient(%client, 'MsgCTFFlagTaken', '\c2You took the %2 flag.~wfx/misc/flag_snatch.wav', %client.name, %teamName, %flag.team, %client.nameBase); + logEcho(%client.nameBase@" (pl "@%player@"/cl "@%client@") took team "@%flag.team@" flag"); + + //call the AI function + %game.AIplayerTouchEnemyFlag(%player, %flag); + + //if the player is out of bounds, then in 3 seconds, it should be thrown back towards the in bounds area... + if (%client.outOfBounds) + %game.schedule(3000, "boundaryLoseFlag", %player); +} + +function PracticeCTFGame::playerGotFlagTarget(%game, %player) +{ + %player.scopeWhenSensorVisible(true); + %target = %player.getTarget(); + setTargetRenderMask(%target, getTargetRenderMask(%target) | 0x2); + if(%game.stalemateObjsVisible) + setTargetAlwaysVisMask(%target, 0x7); +} + +function PracticeCTFGame::playerLostFlagTarget(%game, %player) +{ + %player.scopeWhenSensorVisible(false); + %target = %player.getTarget(); + setTargetRenderMask(%target, getTargetRenderMask(%target) & ~0x2); + // clear his always vis target mask + setTargetAlwaysVisMask(%target, (1 << getTargetSensorGroup(%target))); +} + +//---------------------------------------------------------------------------------------- +// z0dd - ZOD, 8/4/02: KineticPoet's flag updater code +function PracticeCTFGame::updateFlagTransform(%game, %flag) +{ + %flag.setTransform(%flag.getTransform()); + %game.updateFlagThread[%flag] = %game.schedule(100, "updateFlagTransform", %flag); +} +//---------------------------------------------------------------------------------------- + +function PracticeCTFGame::playerDroppedFlag(%game, %player) +{ + %client = %player.client; + %flag = %player.holdingFlag; + %game.updateFlagTransform(%flag); // z0dd - ZOD, 8/4/02, Call to KineticPoet's flag updater + %held = %game.formatTime(getSimTime() - %game.flagHeldTime[%flag], false); // z0dd - ZOD, 8/15/02. How long did player hold flag? + + %game.playerLostFlagTarget(%player); + + %player.holdingFlag = ""; //player isn't holding a flag anymore + %flag.carrier = ""; //flag isn't held anymore + $flagStatus[%flag.team] = ""; + + %player.unMountImage($FlagSlot); + %flag.hide(false); //Does the throwItem function handle this? + + %teamName = %game.getTeamName(%flag.team); + messageTeamExcept(%client, 'MsgCTFFlagDropped', '\c2Teammate %1 dropped the %2 flag. (Held: %4)~wfx/misc/flag_drop.wav', %client.name, %teamName, %flag.team, %held); // z0dd - ZOD, 8/15/02. How long flag was held + messageTeam(%flag.team, 'MsgCTFFlagDropped', '\c2Your flag has been dropped by %1! (Held: %4)~wfx/misc/flag_drop.wav', %client.name, 0, %flag.team, %held); // z0dd - ZOD, 8/15/02. How long flag was held + messageTeam(0, 'MsgCTFFlagDropped', '\c2%1 dropped the %2 flag. (Held: %4)~wfx/misc/flag_drop.wav', %client.name, %teamName, %flag.team, %held); // z0dd - ZOD, 8/15/02. How long flag was held + if(!%player.client.outOfBounds) + messageClient(%client, 'MsgCTFFlagDropped', '\c2You dropped the %2 flag. (Held: %4)~wfx/misc/flag_drop.wav', %client.name, %teamName, %flag.team, %held); // z0dd - ZOD, 8/15/02. How long flag was held + // Yogi, 8/18/02. 3rd param changed 0 -> %client.name + logEcho(%client.nameBase@" (pl "@%player@"/cl "@%client@") dropped team "@%flag.team@" flag"@" (Held: "@%held@")"); + + // z0dd - ZOD: Check for auto flag returns + if($PracticeCtf::AutoFlagReturn) + { + %game.flagReturnFade(%flag); + } + else + { + //don't duplicate the schedule if there's already one in progress... + if($FlagReturnTimer[%flag] <= 0) + $FlagReturnTimer[%flag] = %game.schedule(%game.FLAG_RETURN_DELAY - %game.fadeTimeMS, "flagReturnFade", %flag); + } + + //call the AI function + %game.AIplayerDroppedFlag(%player, %flag); +} + +function PracticeCTFGame::flagCap(%game, %player) +{ + %client = %player.client; + %flag = %player.holdingFlag; + %flag.carrier = ""; + + %held = %game.formatTime(getSimTime() - %game.flagHeldTime[%flag], false); // z0dd - ZOD, 8/15/02. How long did player hold flag? + + %game.playerLostFlagTarget(%player); + //award points to player and team + %teamName = %game.getTeamName(%flag.team); + messageTeamExcept(%client, 'MsgCTFFlagCapped', '\c2%1 captured the %2 flag! (Held: %5)~wfx/misc/flag_capture.wav', %client.name, %teamName, %flag.team, %client.team, %held); + messageTeam(%flag.team, 'MsgCTFFlagCapped', '\c2Your flag was captured by %1. (Held: %5)~wfx/misc/flag_lost.wav', %client.name, 0, %flag.team, %client.team, %held); + messageTeam(0, 'MsgCTFFlagCapped', '\c2%1 captured the %2 flag! (Held: %5)~wfx/misc/flag_capture.wav', %client.name, %teamName, %flag.team, %client.team, %held); + messageClient(%client, 'MsgCTFFlagCapped', '\c2You captured the %2 flag! (Held: %5)~wfx/misc/flag_capture.wav', %client.name, %teamName, %flag.team, %client.team, %held); // z0dd - ZOD, 8/19/02. Yogi. 3rd param changed from 0 to %client.name + + logEcho(%client.nameBase@" (pl "@%player@"/cl "@%client@") capped team "@%client.team@" flag"@" (Held: "@%held@")"); + %player.holdingFlag = ""; //no longer holding it. + %player.unMountImage($FlagSlot); + %game.awardScoreFlagCap(%client, %flag); + %game.flagReset(%flag); + + //call the AI function + %game.AIflagCap(%player, %flag); + + //if this cap didn't end the game, play the announcer... + if ($missionRunning) + { + if (%game.getTeamName(%client.team) $= 'Inferno') + messageAll("", '~wvoice/announcer/ann.infscores.wav'); + else if (%game.getTeamName(%client.team) $= 'Storm') + messageAll("", '~wvoice/announcer/ann.stoscores.wav'); + else if (%game.getTeamName(%client.team) $= 'Phoenix') + messageAll("", '~wvoice/announcer/ann.pxscore.wav'); + else if (%game.getTeamName(%client.team) $= 'Blood Eagle') + messageAll("", '~wvoice/announcer/ann.bescore.wav'); + else if (%game.getTeamName(%client.team) $= 'Diamond Sword') + messageAll("", '~wvoice/announcer/ann.dsscore.wav'); + else if (%game.getTeamName(%client.team) $= 'Starwolf') + messageAll("", '~wvoice/announcer/ann.swscore.wav'); + } +} + +function PracticeCTFGame::flagReturnFade(%game, %flag) +{ + $FlagReturnTimer[%flag] = %game.schedule(%game.fadeTimeMS, "flagReturn", %flag); + %flag.startFade(%game.fadeTimeMS, 0, true); +} + +function PracticeCTFGame::flagReturn(%game, %flag, %player) +{ + // z0dd - ZOD: Bug fix related to practice mode + if($FlagReturnTimer[%flag] !$= "") + { + cancel($FlagReturnTimer[%flag]); + $FlagReturnTimer[%flag] = ""; + } + + if(%flag.team == 1) + %otherTeam = 2; + else + %otherTeam = 1; + %teamName = %game.getTeamName(%flag.team); + if (%player !$= "") + { + //a player returned it + %client = %player.client; + messageTeamExcept(%client, 'MsgCTFFlagReturned', '\c2Teammate %1 returned your flag to base.~wfx/misc/flag_return.wav', %client.name, 0, %flag.team); + messageTeam(%otherTeam, 'MsgCTFFlagReturned', '\c2Enemy %1 returned the %2 flag.~wfx/misc/flag_return.wav', %client.name, %teamName, %flag.team); + messageTeam(0, 'MsgCTFFlagReturned', '\c2%1 returned the %2 flag.~wfx/misc/flag_return.wav', %client.name, %teamName, %flag.team); + messageClient(%client, 'MsgCTFFlagReturned', '\c2You returned your flag.~wfx/misc/flag_return.wav', %client.name, %teamName, %flag.team); // z0dd - ZOD, 8/19/02. Yogi. 3rd param changed from 0 to %client.name + logEcho(%client.nameBase@" (pl "@%player@"/cl "@%client@") returned team "@%flag.team@" flag"); + + // find out what type of return it is + // stalemate return? + + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + if(%game.stalemate) + { + //error("Stalemate return!!!"); + %game.awardScoreStalemateReturn(%player.client); + } + else // regular return + { + %enemyFlagDist = vectorDist($flagPos[%flag.team], $flagPos[%otherTeam]); + %dist = vectorDist(%flag.position, %flag.originalPosition); + + %rawRatio = %dist/%enemyFlagDist; + %ratio = %rawRatio < 1 ? %rawRatio : 1; + %percentage = mFloor( (%ratio) * 10 ) * 10; + %game.awardScoreFlagReturn(%player.client, %percentage); + } + // --------------------------------------------------- + } + else + { + //returned due to timer + messageTeam(%otherTeam, 'MsgCTFFlagReturned', '\c2The %2 flag was returned to base.~wfx/misc/flag_return.wav', 0, %teamName, %flag.team); //because it was dropped for too long + messageTeam(%flag.team, 'MsgCTFFlagReturned', '\c2Your flag was returned.~wfx/misc/flag_return.wav', 0, 0, %flag.team); + messageTeam(0, 'MsgCTFFlagReturned', '\c2The %2 flag was returned to base.~wfx/misc/flag_return.wav', 0, %teamName, %flag.team); + logEcho("team "@%flag.team@" flag returned (timeout)"); + } + + %game.flagReset(%flag); +} + +function PracticeCTFGame::showStalemateTargets(%game) +{ + cancel(%game.stalemateSchedule); + + //show the targets + for (%i = 1; %i <= 2; %i++) + { + %flag = $TeamFlag[%i]; + + //find the object to scope/waypoint.... + //render the target hud icon for slot 1 (a centermass flag) + //if we just set him as always sensor vis, it'll work fine. + if (isObject(%flag.carrier)) + setTargetAlwaysVisMask(%flag.carrier.getTarget(), 0x7); + } + + //schedule the targets to hide + %game.stalemateObjsVisible = true; + %game.stalemateSchedule = %game.schedule(%game.stalemateDurationMS, hideStalemateTargets); +} + +function PracticeCTFGame::hideStalemateTargets(%game) +{ + cancel(%game.stalemateSchedule); + + //hide the targets + for (%i = 1; %i <= 2; %i++) + { + %flag = $TeamFlag[%i]; + if (isObject(%flag.carrier)) + { + %target = %flag.carrier.getTarget(); + setTargetAlwaysVisMask(%target, (1 << getTargetSensorGroup(%target))); + } + } + + //schedule the targets to show again + %game.stalemateObjsVisible = false; + %game.stalemateSchedule = %game.schedule(%game.stalemateFreqMS, showStalemateTargets); +} + +function PracticeCTFGame::beginStalemate(%game) +{ + %game.stalemate = true; + %game.showStalemateTargets(); +} + +function PracticeCTFGame::endStalemate(%game) +{ + %game.stalemate = false; + %game.hideStalemateTargets(); + cancel(%game.stalemateSchedule); +} + +function PracticeCTFGame::flagReset(%game, %flag) +{ + cancel(%game.updateFlagThread[%flag]); // z0dd - ZOD, 8/4/02. Cancel this flag's thread to KineticPoet's flag updater + + //any time a flag is reset, kill the stalemate schedule + %game.endStalemate(); + + //make sure if there's a player carrying it (probably one out of bounds...), it is stripped first + if (isObject(%flag.carrier)) + { + //hide the target hud icon for slot 2 (a centermass flag - visible only as part of a teams sensor network) + %game.playerLostFlagTarget(%flag.carrier); + %flag.carrier.holdingFlag = ""; //no longer holding it. + %flag.carrier.unMountImage($FlagSlot); + } + + //fades, restore default position, home, velocity, general status, etc. + %flag.setVelocity("0 0 0"); + %flag.setTransform(%flag.originalPosition); + %flag.isHome = true; + %flag.carrier = ""; + %flag.grabber = ""; + $flagStatus[%flag.team] = ""; + %flag.hide(false); + if(%flag.stand) + %flag.stand.getDataBlock().onFlagReturn(%flag.stand);//animate, if exterior stand + + //fade the flag in... + %flag.startFade(%game.fadeTimeMS, 0, false); + + // dont render base target + setTargetRenderMask(%flag.waypoint.getTarget(), 0); + + //call the AI function + %game.AIflagReset(%flag); + + // -------------------------------------------------------- + // z0dd - ZOD, 5/26/02. Don't let flag hover over defenders + %flag.static = true; + + // -------------------------------------------------------------------------- + // z0dd - ZOD, 9/28/02. Hack for flag collision bug. + if(%flag.searchSchedule !$="") + { + cancel(%flag.searchSchedule); + } + // -------------------------------------------------------------------------- +} + +function PracticeCTFGame::timeLimitReached(%game) +{ + logEcho("game over (timelimit)"); + %game.gameOver(); + cycleMissions(); +} + +function PracticeCTFGame::scoreLimitReached(%game) +{ + logEcho("game over (scorelimit)"); + %game.gameOver(); + cycleMissions(); +} + +function PracticeCTFGame::notifyMineDeployed(%game, %mine) +{ + //see if the mine is within 5 meters of the flag stand... + %mineTeam = %mine.sourceObject.team; + %homeFlag = $TeamFlag[%mineTeam]; + if (isObject(%homeFlag)) + { + %dist = VectorDist(%homeFlag.originalPosition, %mine.position); + if (%dist <= %game.notifyMineDist) + { + messageTeam(%mineTeam, 'MsgCTFFlagMined', "The flag has been mined.~wvoice/announcer/flag_minedFem.wav" ); + } + } +} + +function PracticeCTFGame::gameOver(%game) +{ + // z0dd - ZOD, 9/28/02. Hack for flag collision bug. + for(%f = 1; %f <= %game.numTeams; %f++) + { + cancel($TeamFlag[%f].searchSchedule); + } + + // ------------------------------------------- + // z0dd - ZOD, 9/28/02. Cancel camp schedules. + if( Game.campThread_1 !$= "" ) + cancel(Game.campThread_1); + + if( Game.campThread_2 !$= "" ) + cancel(Game.campThread_2); + // ------------------------------------------- + + //call the default + DefaultGame::gameOver(%game); + + //send the winner message + %winner = ""; + if ($teamScore[1] > $teamScore[2]) + %winner = %game.getTeamName(1); + else if ($teamScore[2] > $teamScore[1]) + %winner = %game.getTeamName(2); + + if (%winner $= 'Storm') + messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.stowins.wav" ); + else if (%winner $= 'Inferno') + messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.infwins.wav" ); + else if (%winner $= 'Starwolf') + messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.swwin.wav" ); + else if (%winner $= 'Blood Eagle') + messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.bewin.wav" ); + else if (%winner $= 'Diamond Sword') + messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.dswin.wav" ); + else if (%winner $= 'Phoenix') + messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.pxwin.wav" ); + else + messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.gameover.wav" ); + + messageAll('MsgClearObjHud', ""); + for(%i = 0; %i < ClientGroup.getCount(); %i ++) + { + %client = ClientGroup.getObject(%i); + %game.resetScore(%client); + } + for(%j = 1; %j <= %game.numTeams; %j++) + $TeamScore[%j] = 0; +} + +function PracticeCTFGame::onClientDamaged(%game, %clVictim, %clAttacker, %damageType, %implement, %damageLoc) +{ + if(%clVictim.headshot && %damageType == $DamageType::Laser && %clVictim.team != %clAttacker.team) + { + %clAttacker.scoreHeadshot++; + if (%game.SCORE_PER_HEADSHOT != 0) + { + messageClient(%clAttacker, 'msgHeadshot', '\c0You received a %1 point bonus for a successful headshot.', %game.SCORE_PER_HEADSHOT); + messageTeamExcept(%clAttacker, 'msgHeadshot', '\c5%1 hit a sniper rifle headshot.', %clAttacker.name); // z0dd - ZOD, 8/15/02. Tell team + } + %game.recalcScore(%clAttacker); + } + + // ----------------------------------------------- + // z0dd - ZOD, 8/25/02. Rear Lance hits + if(%clVictim.rearshot && %damageType == $DamageType::ShockLance && %clVictim.team != %clAttacker.team) + { + %clAttacker.scoreRearshot++; + if (%game.SCORE_PER_REARSHOT != 0) + { + messageClient(%clAttacker, 'msgRearshot', '\c0You received a %1 point bonus for a successful rearshot.', %game.SCORE_PER_REARSHOT); + messageTeamExcept(%clAttacker, 'msgRearshot', '\c5%1 hit a shocklance rearshot.', %clAttacker.name); + } + %game.recalcScore(%clAttacker); + } + // ----------------------------------------------- + + //the DefaultGame will set some vars + DefaultGame::onClientDamaged(%game, %clVictim, %clAttacker, %damageType, %implement, %damageLoc); + + //if victim is carrying a flag and is not on the attackers team, mark the attacker as a threat for x seconds(for scoring purposes) + if ((%clVictim.holdingFlag !$= "") && (%clVictim.team != %clAttacker.team)) + { + %clAttacker.dmgdFlagCarrier = true; + cancel(%clAttacker.threatTimer); //restart timer + %clAttacker.threatTimer = schedule(%game.TIME_CONSIDERED_FLAGCARRIER_THREAT, %clAttacker.dmgdFlagCarrier = false); + } +} + +//////////////////////////////////////////////////////////////////////////////////////// +function PracticeCTFGame::clientMissionDropReady(%game, %client) +{ + messageClient(%client, 'MsgClientReady',"", %game.class); + %game.resetScore(%client); + for(%i = 1; %i <= %game.numTeams; %i++) + { + $Teams[%i].score = 0; + messageClient(%client, 'MsgCTFAddTeam', "", %i, %game.getTeamName(%i), $flagStatus[%i], $TeamScore[%i]); + } + //%game.populateTeamRankArray(%client); + + //messageClient(%client, 'MsgYourRankIs', "", -1); + + messageClient(%client, 'MsgMissionDropInfo', '\c0You are in mission %1 (%2).', $MissionDisplayName, $MissionTypeDisplayName, $ServerName ); + + DefaultGame::clientMissionDropReady(%game, %client); +} + +function PracticeCTFGame::assignClientTeam(%game, %client, %respawn) +{ + DefaultGame::assignClientTeam(%game, %client, %respawn); + // if player's team is not on top of objective hud, switch lines + messageClient(%client, 'MsgCheckTeamLines', "", %client.team); +} + +function PracticeCTFGame::recalcScore(%game, %cl) +{ + %killValue = %cl.kills * %game.SCORE_PER_KILL; + %deathValue = %cl.deaths * %game.SCORE_PER_DEATH; + + if (%killValue - %deathValue == 0) + %killPoints = 0; + else + %killPoints = (%killValue * %killValue) / (%killValue - %deathValue); + + %cl.offenseScore = %killPoints + + %cl.suicides * %game.SCORE_PER_SUICIDE + + %cl.escortAssists * %game.SCORE_PER_ESCORT_ASSIST + + %cl.teamKills * %game.SCORE_PER_TEAMKILL + + %cl.tkDestroys * %game.SCORE_PER_TK_DESTROY + // z0dd - ZOD, 10/03/02. Penalty for tking equiptment. + %cl.scoreHeadshot * %game.SCORE_PER_HEADSHOT + + %cl.scoreRearshot * %game.SCORE_PER_REARSHOT + // z0dd - ZOD, 8/25/02. Added Lance rear shot messages + %cl.flagCaps * %game.SCORE_PER_PLYR_FLAG_CAP + + %cl.flagGrabs * %game.SCORE_PER_PLYR_FLAG_TOUCH + + %cl.genDestroys * %game.SCORE_PER_DESTROY_GEN + + %cl.sensorDestroys * %game.SCORE_PER_DESTROY_SENSOR + + %cl.turretDestroys * %game.SCORE_PER_DESTROY_TURRET + + %cl.iStationDestroys * %game.SCORE_PER_DESTROY_ISTATION + + %cl.vstationDestroys * %game.SCORE_PER_DESTROY_VSTATION + + %cl.mpbtstationDestroys * %game.SCORE_PER_DESTROY_MPBTSTATION + // z0dd - ZOD 3/30/02. MPB Teleporter + %cl.solarDestroys * %game.SCORE_PER_DESTROY_SOLAR + + %cl.sentryDestroys * %game.SCORE_PER_DESTROY_SENTRY + + %cl.depSensorDestroys * %game.SCORE_PER_DESTROY_DEP_SENSOR + + %cl.depTurretDestroys * %game.SCORE_PER_DESTROY_DEP_TUR + + %cl.depStationDestroys * %game.SCORE_PER_DESTROY_DEP_INV + + %cl.vehicleScore + %cl.vehicleBonus; + + %cl.defenseScore = %cl.genDefends * %game.SCORE_PER_GEN_DEFEND + + %cl.flagDefends * %game.SCORE_PER_FLAG_DEFEND + + %cl.carrierKills * %game.SCORE_PER_CARRIER_KILL + + %cl.escortAssists * %game.SCORE_PER_ESCORT_ASSIST + + %cl.turretKills * %game.SCORE_PER_TURRET_KILL_AUTO + + %cl.mannedturretKills * %game.SCORE_PER_TURRET_KILL + + %cl.genRepairs * %game.SCORE_PER_REPAIR_GEN + + %cl.SensorRepairs * %game.SCORE_PER_REPAIR_SENSOR + + %cl.TurretRepairs * %game.SCORE_PER_REPAIR_TURRET + + %cl.StationRepairs * %game.SCORE_PER_REPAIR_ISTATION + + %cl.VStationRepairs * %game.SCORE_PER_REPAIR_VSTATION + + %cl.mpbtstationRepairs * %game.SCORE_PER_REPAIR_MPBTSTATION + // z0dd - ZOD 3/30/02. MPB Teleporter + %cl.solarRepairs * %game.SCORE_PER_REPAIR_SOLAR + + %cl.sentryRepairs * %game.SCORE_PER_REPAIR_SENTRY + + %cl.depInvRepairs * %game.SCORE_PER_REPAIR_DEP_INV + + %cl.depTurretRepairs * %game.SCORE_PER_REPAIR_DEP_TUR + + %cl.returnPts; + + %cl.score = mFloor(%cl.offenseScore + %cl.defenseScore); + %game.recalcTeamRanks(%cl); +} + +function PracticeCTFGame::updateKillScores(%game, %clVictim, %clKiller, %damageType, %implement) +{ +// is this a vehicle kill rather than a player kill + + // console error message suppression + if( isObject( %implement ) ) + { + if( %implement.getDataBlock().getName() $= "AssaultPlasmaTurret" || %implement.getDataBlock().getName() $= "BomberTurret" ) // gunner + %clKiller = %implement.vehicleMounted.getMountNodeObject(1).client; + else if(%implement.getDataBlock().catagory $= "Vehicles") // pilot + %clKiller = %implement.getMountNodeObject(0).client; + } + + if(%game.testTurretKill(%implement)) //check for turretkill before awarded a non client points for a kill + %game.awardScoreTurretKill(%clVictim, %implement); + else if (%game.testKill(%clVictim, %clKiller)) //verify victim was an enemy + { + %value = %game.awardScoreKill(%clKiller); + %game.shareScore(%clKiller, %value); + %game.awardScoreDeath(%clVictim); + + if (%game.testGenDefend(%clVictim, %clKiller)) + %game.awardScoreGenDefend(%clKiller); + + if(%game.testCarrierKill(%clVictim, %clKiller)) + %game.awardScoreCarrierKill(%clKiller); + else + { + if (%game.testFlagDefend(%clVictim, %clKiller)) + %game.awardScoreFlagDefend(%clKiller); + } + if (%game.testEscortAssist(%clVictim, %clKiller)) + %game.awardScoreEscortAssist(%clKiller); + } + else + { + if (%game.testSuicide(%clVictim, %clKiller, %damageType)) //otherwise test for suicide + { + %game.awardScoreSuicide(%clVictim); + } + else + { + if (%game.testTeamKill(%clVictim, %clKiller)) //otherwise test for a teamkill + %game.awardScoreTeamKill(%clVictim, %clKiller); + } + } +} + +function PracticeCTFGame::testFlagDefend(%game, %victimID, %killerID) +{ + InitContainerRadiusSearch(%victimID.plyrPointOfDeath, %game.RADIUS_FLAG_DEFENSE, $TypeMasks::ItemObjectType); + %objID = containerSearchNext(); + while(%objID != 0) + { + %objType = %objID.getDataBlock().getName(); + if ((%objType $= "Flag") && (%objID.team == %killerID.team)) + return true; //found the(a) killer's flag near the victim's point of death + else + %objID = containerSearchNext(); + } + return false; //didn't find a qualifying flag within required radius of victims point of death +} + +function PracticeCTFGame::testGenDefend(%game, %victimID, %killerID) +{ + InitContainerRadiusSearch(%victimID.plyrPointOfDeath, %game.RADIUS_GEN_DEFENSE, $TypeMasks::StaticShapeObjectType); + %objID = containerSearchNext(); + while(%objID != 0) + { + %objType = %objID.getDataBlock().ClassName; + if ((%objType $= "generator") && (%objID.team == %killerID.team)) + return true; //found a killer's generator within required radius of victim's death + else + %objID = containerSearchNext(); + } + return false; //didn't find a qualifying gen within required radius of victim's point of death +} + +function PracticeCTFGame::testCarrierKill(%game, %victimID, %killerID) +{ + %flag = %victimID.plyrDiedHoldingFlag; + return ((%flag !$= "") && (%flag.team == %killerID.team)); +} + +function PracticeCTFGame::testEscortAssist(%game, %victimID, %killerID) +{ + return (%victimID.dmgdFlagCarrier); +} + +function PracticeCTFGame::testValidRepair(%game, %obj) +{ + if(!%obj.wasDisabled) + { + //error(%obj SPC "was never disabled"); + return false; + } + else if(%obj.lastDamagedByTeam == %obj.team) + { + //error(%obj SPC "was last damaged by a friendly"); + return false; + } + else if(%obj.team != %obj.repairedBy.team) + { + //error(%obj SPC "was repaired by an enemy"); + return false; + } + else + { + if(%obj.soiledByEnemyRepair) + %obj.soiledByEnemyRepair = false; + return true; + } +} + +function PracticeCTFGame::awardScoreFlagCap(%game, %cl, %flag) +{ + %cl.flagCaps++; + $TeamScore[%cl.team] += %game.SCORE_PER_TEAM_FLAG_CAP; + messageAll('MsgTeamScoreIs', "", %cl.team, $TeamScore[%cl.team]); + + %flag.grabber.flagGrabs++; + + if (%game.SCORE_PER_TEAM_FLAG_CAP > 0) + { + %plural = (%game.SCORE_PER_PLYR_FLAG_CAP != 1 ? 's' : ""); + %plural2 = (%game.SCORE_PER_PLYR_FLAG_TOUCH != 1 ? 's' : ""); + + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + if(%cl == %flag.grabber) + { + messageClient(%cl, 'msgCTFFriendCap', '\c0You receive %1 point%2 for stealing and capturing the enemy flag!', %game.SCORE_PER_PLYR_FLAG_CAP+%game.SCORE_PER_PLYR_FLAG_TOUCH, %plural); + messageTeam(%flag.team, 'msgCTFEnemyCap', '\c0Enemy %1 received %2 point%3 for capturing your flag!', %cl.name, %game.SCORE_PER_PLYR_FLAG_CAP+%game.SCORE_PER_PLYR_FLAG_TOUCH, %plural); + //messageTeamExcept(%cl, 'msgCTFFriendCap', '\c0Teammate %1 receives %2 point%3 for capturing the enemy flag!', %cl.name, %game.SCORE_PER_PLYR_FLAG_CAP+%game.SCORE_PER_PLYR_FLAG_TOUCH, %plural); // z0dd - ZOD, 8/15/02. Message is pointless + } + else + { + if(isObject(%flag.grabber)) // is the grabber still here? + { + messageClient(%cl, 'msgCTFFriendCap', '\c0You receive %1 point%2 for capturing the enemy flag! %3 gets %4 point%5 for the steal assist.', %game.SCORE_PER_PLYR_FLAG_CAP, %plural, %flag.grabber.name, %game.SCORE_PER_PLYR_FLAG_TOUCH, %plural2); + messageClient(%flag.grabber, 'msgCTFFriendCap', '\c0You receive %1 point%2 for stealing a flag that was subsequently capped by %3.', %game.SCORE_PER_PLYR_FLAG_TOUCH, %plural2, %cl.name); + } + else + messageClient(%cl, 'msgCTFFriendCap', '\c0You receive %1 point%2 for capturing the enemy flag!', %game.SCORE_PER_PLYR_FLAG_CAP, %plural); + + //messageTeamExcept(%cl, 'msgCTFFriendCap', '\c0Teammate %1 receives %2 point%3 for capturing the enemy flag!', %cl.name, %game.SCORE_PER_PLYR_FLAG_CAP, %plural); // z0dd - ZOD, 8/15/02. Message is pointless + //messageTeam(%flag.team, 'msgCTFEnemyCap', '\c0Enemy %1 received %2 point%3 for capturing your flag!', %cl.name, %game.SCORE_PER_PLYR_FLAG_CAP, %plural); // z0dd - ZOD, 8/15/02. Message is pointless + } + // --------------------------------------------------- + } + + %game.recalcScore(%cl); + + if(isObject(%flag.grabber)) + %game.recalcScore(%flag.grabber); + + %game.checkScoreLimit(%cl.team); +} + + +function PracticeCTFGame::awardScoreFlagTouch(%game, %cl, %flag) +{ + + %flag.grabber = %cl; + %team = %cl.team; + if( $DontScoreTimer[%team] ) + return; + + $dontScoreTimer[%team] = true; + //tinman - needed to remove all game calls to "eval" for the PURE server... + %game.schedule(%game.TOUCH_DELAY_MS, resetDontScoreTimer, %team); + //schedule(%game.TOUCH_DELAY_MS, 0, eval, "$dontScoreTimer["@%team@"] = false;"); + schedule(%game.TOUCH_DELAY_MS, 0, eval, "$dontScoreTimer["@%team@"] = false;"); + $TeamScore[%team] += %game.SCORE_PER_TEAM_FLAG_TOUCH; + messageAll('MsgTeamScoreIs', "", %team, $TeamScore[%team]); + + if (%game.SCORE_PER_TEAM_FLAG_TOUCH > 0) + { + %plural = (%game.SCORE_PER_TEAM_FLAG_TOUCH != 1 ? 's' : ""); + messageTeam(%team, 'msgCTFFriendFlagTouch', '\c0Your team receives %1 point%2 for grabbing the enemy flag!', %game.SCORE_PER_TEAM_FLAG_TOUCH, %plural); + messageTeam(%flag.team, 'msgCTFEnemyFlagTouch', '\c0Enemy %1 receives %2 point%3 for grabbing your flag!', %cl.name, %game.SCORE_PER_TEAM_FLAG_TOUCH, %plural); + } + %game.recalcScore(%cl); + %game.checkScoreLimit(%team); +} + +function PracticeCTFGame::resetDontScoreTimer(%game, %team) +{ + $dontScoreTimer[%team] = false; +} + +function PracticeCTFGame::checkScoreLimit(%game, %team) +{ + // z0dd - ZOD, 5/12/02. Check for no score limit + if(!$PracticeCtf::NoScoreLimit) + { + %scoreLimit = MissionGroup.CTF_scoreLimit * %game.SCORE_PER_TEAM_FLAG_CAP; + // default of 5 if scoreLimit not defined + if(%scoreLimit $= "") + %scoreLimit = 5 * %game.SCORE_PER_TEAM_FLAG_CAP; + if($TeamScore[%team] >= %scoreLimit) + %game.scoreLimitReached(); + } + else + %scoreLimit = %scoreLimit = 999; +} + +function PracticeCTFGame::awardScoreFlagReturn(%game, %cl, %perc) +{ + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + if (%game.SCORE_PER_FLAG_RETURN != 0) + { + %pts = mfloor( %game.SCORE_PER_FLAG_RETURN * (%perc/100) ); + if(%perc == 100) + messageClient(%cl, 'scoreFlaRetMsg', 'Flag return - exceeded capping distance - %1 point bonus.', %pts, %perc); + else if(%perc == 0) + messageClient(%cl, 'scoreFlaRetMsg', 'You gently place the flag back on the stand.', %pts, %perc); + else + messageClient(%cl, 'scoreFlaRetMsg', '\c0Flag return from %2%% of capping distance - %1 point bonus.', %pts, %perc); + %cl.returnPts += %pts; + } + %game.recalcScore(%cl); + return %game.SCORE_PER_FLAG_RETURN; + // --------------------------------------------------- +} + +function PracticeCTFGame::awardScoreStalemateReturn(%game, %cl) +{ + if (%game.SCORE_PER_STALEMATE_RETURN != 0) + { + messageClient(%cl, 'scoreStaleRetMsg', '\c0You received a %1 point bonus for a stalemate-breaking, flag return.', %game.SCORE_PER_STALEMATE_RETURN); + %cl.returnPts += %game.SCORE_PER_STALEMATE_RETURN; + } + %game.recalcScore(%cl); + return %game.SCORE_PER_STALEMATE_RETURN; +} + +// Asset Destruction scoring +function PracticeCTFGame::awardScoreGenDestroy(%game,%cl) +{ + %cl.genDestroys++; + if (%game.SCORE_PER_DESTROY_GEN != 0) + { + messageClient(%cl, 'msgGenDes', '\c0You received a %1 point bonus for destroying an enemy generator.', %game.SCORE_PER_DESTROY_GEN); + //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); + } + %game.recalcScore(%cl); + return %game.SCORE_PER_DESTROY_GEN; +} + +function PracticeCTFGame::awardScoreSensorDestroy(%game,%cl) +{ + %cl.sensorDestroys++; + if (%game.SCORE_PER_DESTROY_SENSOR != 0) + { + messageClient(%cl, 'msgSensorDes', '\c0You received a %1 point bonus for destroying an enemy sensor.', %game.SCORE_PER_DESTROY_SENSOR); + //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); + } + %game.recalcScore(%cl); + return %game.SCORE_PER_DESTROY_SENSOR; +} + +function PracticeCTFGame::awardScoreTurretDestroy(%game,%cl) +{ + %cl.turretDestroys++; + if (%game.SCORE_PER_DESTROY_TURRET != 0) + { + messageClient(%cl, 'msgTurretDes', '\c0You received a %1 point bonus for destroying an enemy turret.', %game.SCORE_PER_DESTROY_TURRET); + //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); + } + %game.recalcScore(%cl); + return %game.SCORE_PER_DESTROY_TURRET; +} + +function PracticeCTFGame::awardScoreInvDestroy(%game,%cl) +{ + %cl.IStationDestroys++; + if (%game.SCORE_PER_DESTROY_ISTATION != 0) + { + messageClient(%cl, 'msgInvDes', '\c0You received a %1 point bonus for destroying an enemy inventory station.', %game.SCORE_PER_DESTROY_ISTATION); + //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); + } + %game.recalcScore(%cl); + return %game.SCORE_PER_DESTROY_ISTATION; +} + +function PracticeCTFGame::awardScoreVehicleStationDestroy(%game,%cl) +{ + %cl.VStationDestroys++; + if (%game.SCORE_PER_DESTROY_VSTATION != 0) + { + messageClient(%cl, 'msgVSDes', '\c0You received a %1 point bonus for destroying an enemy vehicle station.', %game.SCORE_PER_DESTROY_VSTATION); + //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); + } + %game.recalcScore(%cl); + return %game.SCORE_PER_DESTROY_VSTATION; +} + +// --------------------------------------------------------- +// z0dd - ZOD 3/30/02. MBP Teleporter +function PracticeCTFGame::awardScoreMPBTeleporterDestroy(%game,%cl) +{ + %cl.mpbtstationDestroys++; + if (%game.SCORE_PER_DESTROY_MPBTSTATION != 0) + { + messageClient(%cl, 'msgMPBTeleDes', '\c0You received a %1 point bonus for destroying an enemy MPB teleport station.', %game.SCORE_PER_DESTROY_MPBTSTATION); + //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); + } + %game.recalcScore(%cl); + return %game.SCORE_PER_DESTROY_MPBTSTATION; +} +// --------------------------------------------------------- + +function PracticeCTFGame::awardScoreSolarDestroy(%game,%cl) +{ + %cl.SolarDestroys++; + if (%game.SCORE_PER_DESTROY_SOLAR != 0) + { + messageClient(%cl, 'msgSolarDes', '\c0You received a %1 point bonus for destroying an enemy solar panel.', %game.SCORE_PER_DESTROY_SOLAR); + //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); + } + %game.recalcScore(%cl); + return %game.SCORE_PER_DESTROY_SOLAR; +} + +function PracticeCTFGame::awardScoreSentryDestroy(%game,%cl) +{ + %cl.sentryDestroys++; + if (%game.SCORE_PER_DESTROY_SENTRY != 0) + { + messageClient(%cl, 'msgSentryDes', '\c0You received a %1 point bonus for destroying an enemy sentry turret.', %game.SCORE_PER_DESTROY_SENTRY); + //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); + } + %game.recalcScore(%cl); + return %game.SCORE_PER_DESTROY_SENTRY; +} + +function PracticeCTFGame::awardScoreDepSensorDestroy(%game,%cl) +{ + %cl.depSensorDestroys++; + if (%game.SCORE_PER_DESTROY_DEP_SENSOR != 0) + { + messageClient(%cl, 'msgDepSensorDes', '\c0You received a %1 point bonus for destroying an enemy deployable sensor.', %game.SCORE_PER_DESTROY_DEP_SENSOR); // z0dd - ZOD, 8/15/02. Added "sensor" + //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); + } + %game.recalcScore(%cl); + return %game.SCORE_PER_DESTROY_DEP_SENSOR; +} + +function PracticeCTFGame::awardScoreDepTurretDestroy(%game,%cl) +{ + %cl.depTurretDestroys++; + if (%game.SCORE_PER_DESTROY_DEP_TUR != 0) + { + messageClient(%cl, 'msgDepTurDes', '\c0You received a %1 point bonus for destroying an enemy deployed turret.', %game.SCORE_PER_DESTROY_DEP_TUR); + //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); + } + %game.recalcScore(%cl); + return %game.SCORE_PER_DESTROY_DEP_TUR; +} + +function PracticeCTFGame::awardScoreDepStationDestroy(%game,%cl) +{ + %cl.depStationDestroys++; + if (%game.SCORE_PER_DESTROY_DEP_INV != 0) + { + messageClient(%cl, 'msgDepInvDes', '\c0You received a %1 point bonus for destroying an enemy deployed station.', %game.SCORE_PER_DESTROY_DEP_INV); + //messageTeamExcept(%cl, 'msgGenDes', '\c0Teammate %1 received a %2 point bonus for destroying an enemy generator.', %cl.name, %game.SCORE_PER_GEN_DESTROY); + } + %game.recalcScore(%cl); + return %game.SCORE_PER_DESTROY_DEP_INV; +} + +// --------------------------------------------------------- +// z0dd - ZOD, 10/03/02. Penalty for TKing equiptment. +function PracticeCTFGame::awardScoreTkDestroy(%game, %cl) +{ + %cl.tkDestroys++; + if (%game.SCORE_PER_TK_DESTROY != 0) + { + messageClient(%cl, 'msgTkDes', '\c0You have been penalized %1 points for destroying your teams equiptment.', %game.SCORE_PER_TK_DESTROY); + } + %game.recalcScore(%cl); + return %game.SCORE_PER_TK_DESTROY; +} +// --------------------------------------------------------- + +function PracticeCTFGame::awardScoreGenDefend(%game, %killerID) +{ + %killerID.genDefends++; + if (%game.SCORE_PER_GEN_DEFEND != 0) + { + messageClient(%killerID, 'msgGenDef', '\c0You received a %1 point bonus for defending a generator.', %game.SCORE_PER_GEN_DEFEND); + messageTeamExcept(%killerID, 'msgGenDef', '\c2%1 defended our generator from an attack.', %killerID.name); // z0dd - ZOD, 8/15/02. Tell team + //messageTeamExcept(%killerID, 'msgGenDef', '\c0Teammate %1 received a %2 point bonus for defending a generator.', %killerID.name, %game.SCORE_PER_GEN_DEFEND); + } + %game.recalcScore(%cl); + return %game.SCORE_PER_GEN_DEFEND; +} + +function PracticeCTFGame::awardScoreCarrierKill(%game, %killerID) +{ + %killerID.carrierKills++; + if (%game.SCORE_PER_CARRIER_KILL != 0) + { + messageClient(%killerID, 'msgCarKill', '\c0You received a %1 point bonus for stopping the enemy flag carrier!', %game.SCORE_PER_CARRIER_KILL); + messageTeamExcept(%killerID, 'msgCarKill', '\c2%1 stopped the enemy flag carrier.', %killerID.name); // z0dd - ZOD, 8/15/02. Tell team + //messageTeamExcept(%killerID, 'msgCarKill', '\c0Teammate %1 received a %2 point bonus for stopping the enemy flag carrier!', %killerID.name, %game.SCORE_PER_CARRIER_KILL); + } + %game.recalcScore(%killerID); + return %game.SCORE_PER_CARRIER_KILL; +} + +function PracticeCTFGame::awardScoreFlagDefend(%game, %killerID) +{ + %killerID.flagDefends++; + if (%game.SCORE_PER_FLAG_DEFEND != 0) + { + messageClient(%killerID, 'msgFlagDef', '\c0You received a %1 point bonus for defending your flag!', %game.SCORE_PER_FLAG_DEFEND); + messageTeamExcept(%killerID, 'msgFlagDef', '\c2%1 defended our flag.', %killerID.name); // z0dd - ZOD, 8/15/02. Tell team + //messageTeamExcept(%killerID, 'msgFlagDef', '\c0Teammate %1 received a %2 point bonus for defending your flag!', %killerID.name, %game.SCORE_PER_FLAG_DEFEND); + } + %game.recalcScore(%killerID); + return %game.SCORE_PER_FLAG_DEFEND; +} + +function PracticeCTFGame::awardScoreEscortAssist(%game, %killerID) +{ + %killerID.escortAssists++; + if (%game.SCORE_PER_ESCORT_ASSIST != 0) + { + messageClient(%killerID, 'msgEscAsst', '\c0You received a %1 point bonus for protecting the flag carrier!', %game.SCORE_PER_ESCORT_ASSIST); + messageTeamExcept(%killerID, 'msgEscAsst', '\c2%1 protected our flag carrier.', %killerID.name); // z0dd - ZOD, 8/15/02. Tell team + //messageTeamExcept(%killerID, 'msgEscAsst', '\c0Teammate %1 received a %2 point bonus for protecting the flag carrier!', %killerID.name, %game.SCORE_PER_ESCORT_ASSIST); + } + %game.recalcScore(%killerID); + return %game.SCORE_PER_ESCORT_ASSIST; +} + +function PracticeCTFGame::resetScore(%game, %client) +{ + %client.offenseScore = 0; + %client.kills = 0; + %client.deaths = 0; + %client.suicides = 0; + %client.escortAssists = 0; + %client.teamKills = 0; + %client.tkDestroys = 0; // z0dd - ZOD, 10/03/02. Penalty for tking equiptment. + %client.flagCaps = 0; + %client.flagGrabs = 0; + %client.genDestroys = 0; + %client.sensorDestroys = 0; + %client.turretDestroys = 0; + %client.iStationDestroys = 0; + %client.vstationDestroys = 0; + %client.mpbtstationDestroys = 0; // z0dd - ZOD 3/30/02. MPB Teleporter + %client.solarDestroys = 0; + %client.sentryDestroys = 0; + %client.depSensorDestroys = 0; + %client.depTurretDestroys = 0; + %client.depStationDestroys = 0; + %client.vehicleScore = 0; + %client.vehicleBonus = 0; + + %client.flagDefends = 0; + %client.defenseScore = 0; + %client.genDefends = 0; + %client.carrierKills = 0; + %client.escortAssists = 0; + %client.turretKills = 0; + %client.mannedTurretKills = 0; + %client.flagReturns = 0; + %client.genRepairs = 0; + %client.SensorRepairs = 0; + %client.TurretRepairs = 0; + %client.StationRepairs = 0; + %client.VStationRepairs = 0; + %client.mpbtstationRepairs = 0; // z0dd - ZOD 3/30/02. MPB Teleporter + %client.solarRepairs = 0; + %client.sentryRepairs = 0; + %client.depInvRepairs = 0; + %client.depTurretRepairs = 0; + %client.returnPts = 0; + %client.score = 0; + + // z0dd - ZOD: Reset practice mode varibles + for(%i=0; %i < $Host::ClassicMaxTelepads; %i++) + { + %client.spawnPad[%i] = ""; + } + %client.transMode = ""; + %client.transPad = 1; + %client.camera.projectile = ""; + %client.mortarObs = ""; + %client.missileObs = ""; + %client.grenadeObs = ""; + %client.discObs = ""; +} + +function PracticeCTFGame::objectRepaired(%game, %obj, %objName) +{ + %item = %obj.getDataBlock().getName(); + switch$ (%item) + { + case generatorLarge : + %game.genOnRepaired(%obj, %objName); + case sensorMediumPulse : + %game.sensorOnRepaired(%obj, %objName); + case sensorLargePulse : + %game.sensorOnRepaired(%obj, %objName); + case stationInventory : + %game.stationOnRepaired(%obj, %objName); + case turretBaseLarge : + %game.turretOnRepaired(%obj, %objName); + case stationVehicle : + %game.vStationOnRepaired(%obj, %objName); + case MPBTeleporter : // z0dd - ZOD 3/30/02. MPB Teleporter + %game.mpbTStationOnRepaired(%obj, %objName); + case solarPanel : + %game.solarPanelOnRepaired(%obj, %objName); + case sentryTurret : + %game.sentryTurretOnRepaired(%obj, %objName); + case TurretDeployedWallIndoor: + %game.depTurretOnRepaired(%obj, %objName); + case TurretDeployedFloorIndoor: + %game.depTurretOnRepaired(%obj, %objName); + case TurretDeployedCeilingIndoor: + %game.depTurretOnRepaired(%obj, %objName); + case TurretDeployedOutdoor: + %game.depTurretOnRepaired(%obj, %objName); + } + %obj.wasDisabled = false; +} + +function PracticeCTFGame::genOnRepaired(%game, %obj, %objName) +{ + + if (%game.testValidRepair(%obj)) + { + %repairman = %obj.repairedBy; + teamRepairMessage(%repairman, 'msgGenRepaired', '\c0%1 repaired the %2 Generator!', %repairman.name, %obj.nameTag); + %game.awardScoreGenRepair(%obj.repairedBy); + } +} + +function PracticeCTFGame::stationOnRepaired(%game, %obj, %objName) +{ + if (%game.testValidRepair(%obj)) + { + %repairman = %obj.repairedBy; + teamRepairMessage(%repairman, 'msgStationRepaired', '\c0%1 repaired the %2 Inventory Station!', %repairman.name, %obj.nameTag); + %game.awardScoreStationRepair(%obj.repairedBy); + } +} + +function PracticeCTFGame::sensorOnRepaired(%game, %obj, %objName) +{ + if (%game.testValidRepair(%obj)) + { + %repairman = %obj.repairedBy; + teamRepairMessage(%repairman, 'msgSensorRepaired', '\c0%1 repaired the %2 Pulse Sensor!', %repairman.name, %obj.nameTag); + %game.awardScoreSensorRepair(%obj.repairedBy); + } +} + +function PracticeCTFGame::turretOnRepaired(%game, %obj, %objName) +{ + if (%game.testValidRepair(%obj)) + { + %repairman = %obj.repairedBy; + teamRepairMessage(%repairman, 'msgTurretRepaired', '\c0%1 repaired the %2 Turret!', %repairman.name, %obj.nameTag); + %game.awardScoreTurretRepair(%obj.repairedBy); + } +} + +function PracticeCTFGame::vStationOnRepaired(%game, %obj, %objName) +{ + if (%game.testValidRepair(%obj)) + { + %repairman = %obj.repairedBy; + teamRepairMessage(%repairman, 'msgvstationRepaired', '\c0%1 repaired the Vehicle Station!', %repairman.name); + %game.awardScoreVStationRepair(%obj.repairedBy); + } +} + +// z0dd - ZOD 3/17/02. Score for repairing MPB Teleporter station. +function PracticeCTFGame::mpbTStationOnRepaired(%game, %obj, %objName) +{ + if (%game.testValidRepair(%obj)) + { + %repairman = %obj.repairedBy; + teamRepairMessage(%repairman, 'msgTeleporterRepaired', '\c0%1 repaired the MPB Teleporter Station!', %repairman.name); + %game.awardScoreMpbTStationRepair(%obj.repairedBy); + } +} + +function PracticeCTFGame::solarPanelOnRepaired(%game, %obj, %objName) +{ + if (%game.testValidRepair(%obj)) + { + %repairman = %obj.repairedBy; + teamRepairMessage(%repairman, 'msgsolarRepaired', '\c0%1 repaired the %2 Solar Panel!', %repairman.name, %obj.nameTag); + %game.awardScoreSolarRepair(%obj.repairedBy); + } +} + +function PracticeCTFGame::sentryTurretOnRepaired(%game, %obj, %objName) +{ + if (%game.testValidRepair(%obj)) + { + %repairman = %obj.repairedBy; + teamRepairMessage(%repairman, 'msgsentryTurretRepaired', '\c0%1 repaired the %2 Sentry Turret!', %repairman.name, %obj.nameTag); + %game.awardScoreSentryRepair(%obj.repairedBy); + } +} + +function PracticeCTFGame::depTurretOnRepaired(%game, %obj, %objName) +{ + if (%game.testValidRepair(%obj)) + { + %repairman = %obj.repairedBy; + teamRepairMessage(%repairman, 'msgdepTurretRepaired', '\c4%1 repaired a %2 Deployable Turret!', %repairman.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Added this line + %game.awardScoreDepTurretRepair(%obj.repairedBy); + } +} + +function PracticeCTFGame::depInvOnRepaired(%game, %obj, %objName) +{ + if (%game.testValidRepair(%obj)) + { + %repairman = %obj.repairedBy; + teamRepairMessage(%repairman, 'msgdepInvRepaired', '\c4%1 repaired a %2 Deployable Inventory!', %repairman.name, %obj.nameTag); // z0dd - ZOD, 8/20/02. Added this line + %game.awardScoreDepInvRepair(%obj.repairedBy); + } +} + +function PracticeCTFGame::awardScoreGenRepair(%game, %cl) +{ + %cl.genRepairs++; + if (%game.SCORE_PER_REPAIR_GEN != 0) + { + messageClient(%cl, 'msgGenRep', '\c0You received a %1 point bonus for repairing a generator.', %game.SCORE_PER_REPAIR_GEN); + } + %game.recalcScore(%cl); +} + +function PracticeCTFGame::awardScoreStationRepair(%game, %cl) +{ + %cl.stationRepairs++; + if (%game.SCORE_PER_REPAIR_ISTATION != 0) + { + messageClient(%cl, 'msgIStationRep', '\c0You received a %1 point bonus for repairing a inventory station.', %game.SCORE_PER_REPAIR_ISTATION); + } + %game.recalcScore(%cl); +} + +function PracticeCTFGame::awardScoreSensorRepair(%game, %cl) +{ + %cl.sensorRepairs++; + if (%game.SCORE_PER_REPAIR_SENSOR != 0) + { + messageClient(%cl, 'msgSensorRep', '\c0You received a %1 point bonus for repairing a sensor.', %game.SCORE_PER_REPAIR_SENSOR); + } + %game.recalcScore(%cl); +} + +function PracticeCTFGame::awardScoreTurretRepair(%game, %cl) +{ + %cl.TurretRepairs++; + if (%game.SCORE_PER_REPAIR_TURRET != 0) + { + messageClient(%cl, 'msgTurretRep', '\c0You received a %1 point bonus for repairing a base turret.', %game.SCORE_PER_REPAIR_TURRET); + } + %game.recalcScore(%cl); +} + +function PracticeCTFGame::awardScoreVStationRepair(%game, %cl) +{ + %cl.VStationRepairs++; + if (%game.SCORE_PER_REPAIR_VSTATION != 0) + { + messageClient(%cl, 'msgVStationRep', '\c0You received a %1 point bonus for repairing a vehicle station.', %game.SCORE_PER_REPAIR_VSTATION); + } + %game.recalcScore(%cl); +} + +// z0dd - ZOD 3/17/02. Score for repairing MPB Teleporter station. +function PracticeCTFGame::awardScoreMpbTStationRepair(%game, %cl) +{ + %cl.mpbtstationRepairs++; + if (%game.SCORE_PER_REPAIR_MPBTSTATION != 0) + { + messageClient(%cl, 'msgVStationRep', '\c0You received a %1 point bonus for repairing a mpb teleporter station.', %game.SCORE_PER_REPAIR_TSTATION); + } + %game.recalcScore(%cl); +} + +function PracticeCTFGame::awardScoreSolarRepair(%game, %cl) +{ + %cl.solarRepairs++; + if (%game.SCORE_PER_REPAIR_SOLAR != 0) + { + messageClient(%cl, 'msgsolarRep', '\c0You received a %1 point bonus for repairing a solar panel.', %game.SCORE_PER_REPAIR_SOLAR); + } + %game.recalcScore(%cl); +} + +function PracticeCTFGame::awardScoreSentryRepair(%game, %cl) +{ + %cl.sentryRepairs++; + if (%game.SCORE_PER_REPAIR_SENTRY != 0) + { + messageClient(%cl, 'msgSentryRep', '\c0You received a %1 point bonus for repairing a sentry turret.', %game.SCORE_PER_REPAIR_SENTRY); + } + %game.recalcScore(%cl); +} + +function PracticeCTFGame::awardScoreDepTurretRepair(%game, %cl) +{ + %cl.depTurretRepairs++; + if (%game.SCORE_PER_REPAIR_DEP_TUR != 0) + { + messageClient(%cl, 'msgDepTurretRep', '\c0You received a %1 point bonus for repairing a deployed turret.', %game.SCORE_PER_REPAIR_DEP_TUR); + } + %game.recalcScore(%cl); +} + +function PracticeCTFGame::awardScoreDepInvRepair(%game, %cl) +{ + %cl.depInvRepairs++; + if (%game.SCORE_PER_REPAIR_DEP_INV != 0) + { + messageClient(%cl, 'msgDepInvRep', '\c0You received a %1 point bonus for repairing a deployed station.', %game.SCORE_PER_REPAIR_DEP_INV); + } + %game.recalcScore(%cl); +} + +function PracticeCTFGame::enterMissionArea(%game, %playerData, %player) +{ + if(%player.getState() $= "Dead") + return; + %player.client.outOfBounds = false; + messageClient(%player.client, 'EnterMissionArea', '\c1You are back in the mission area.'); + logEcho(%player.client.nameBase@" (pl "@%player@"/cl "@%player.client@") entered mission area"); + + //the instant a player leaves the mission boundary, the flag is dropped, and the return is scheduled... + if (%player.holdingFlag > 0) + { + cancel($FlagReturnTimer[%player.holdingFlag]); + $FlagReturnTimer[%player.holdingFlag] = ""; + } +} + +function PracticeCTFGame::leaveMissionArea(%game, %playerData, %player) +{ + if(%player.getState() $= "Dead") + return; + // maybe we'll do this just in case + %player.client.outOfBounds = true; + // if the player is holding a flag, strip it and throw it back into the mission area + // otherwise, just print a message + if(%player.holdingFlag > 0) + %game.boundaryLoseFlag(%player); + else + messageClient(%player.client, 'MsgLeaveMissionArea', '\c1You have left the mission area.~wfx/misc/warning_beep.wav'); + logEcho(%player.client.nameBase@" (pl "@%player@"/cl "@%player.client@") left mission area"); +} + +function PracticeCTFGame::boundaryLoseFlag(%game, %player) +{ + // this is called when a player goes out of the mission area while holding + // the enemy flag. - make sure the player is still out of bounds + if (!%player.client.outOfBounds || !isObject(%player.holdingFlag)) + return; + + // ------------------------------------------------------------------------------ + // z0dd - ZOD - SquirrelOfDeath, 9/27/02. Delay on grabbing flag after tossing it + %player.flagTossWait = true; + %player.schedule(1000, resetFlagTossWait); + // ------------------------------------------------------------------------------- + + %client = %player.client; + %flag = %player.holdingFlag; + %flag.setVelocity("0 0 0"); + %flag.setTransform(%player.getWorldBoxCenter()); + %flag.setCollisionTimeout(%player); + + %held = %game.formatTime(getSimTime() - %game.flagHeldTime[%flag], false); // z0dd - ZOD, 8/15/02. How long did player hold flag? + + %game.playerDroppedFlag(%player); + + // now for the tricky part -- throwing the flag back into the mission area + // let's try throwing it back towards its "home" + %home = %flag.originalPosition; + %vecx = firstWord(%home) - firstWord(%player.getWorldBoxCenter()); + %vecy = getWord(%home, 1) - getWord(%player.getWorldBoxCenter(), 1); + %vecz = getWord(%home, 2) - getWord(%player.getWorldBoxCenter(), 2); + %vec = %vecx SPC %vecy SPC %vecz; + + // normalize the vector, scale it, and add an extra "upwards" component + %vecNorm = VectorNormalize(%vec); + %vec = VectorScale(%vecNorm, 1500); + %vec = vectorAdd(%vec, "0 0 500"); + + // z0dd - ZOD, 6/09/02. Remove anti-hover so flag can be thrown properly + %flag.static = false; + + // z0dd - ZOD, 10/02/02. Hack for flag collision bug. + %flag.searchSchedule = %game.schedule(10, "startFlagCollisionSearch", %flag); + + // apply the impulse to the flag object + %flag.applyImpulse(%player.getWorldBoxCenter(), %vec); + + //don't forget to send the message + //messageClient(%player.client, 'MsgCTFFlagDropped', '\c1You have left the mission area and lost the flag.~wfx/misc/flag_drop.wav', 0, 0, %player.holdingFlag.team); + + // z0dd - ZOD 3/30/02. Above message was sending the wrong varible to objective hud. + messageClient(%player.client, 'MsgCTFFlagDropped', '\c1You have left the mission area and lost the flag. (Held: %4)~wfx/misc/flag_drop.wav', %client.name, 0, %flag.team, %held); // z0dd - ZOD, 8/19/02. yogi. 3rd param changed from 0 to %client.name + logEcho(%player.client.nameBase@" (pl "@%player@"/cl "@%player.client@") lost flag (out of bounds)"@" (Held: "@%held@")"); +} + +function PracticeCTFGame::dropFlag(%game, %player) +{ + if(%player.holdingFlag > 0) + { + if (!%player.client.outOfBounds) + %player.throwObject(%player.holdingFlag); + else + %game.boundaryLoseFlag(%player); + } +} + +function PracticeCTFGame::applyConcussion(%game, %player) +{ + %game.dropFlag( %player ); +} + +function PracticeCTFGame::vehicleDestroyed(%game, %vehicle, %destroyer) +{ + //vehicle name + %data = %vehicle.getDataBlock(); + //%vehicleType = getTaggedString(%data.targetNameTag) SPC getTaggedString(%data.targetTypeTag); + %vehicleType = getTaggedString(%data.targetTypeTag); + if(%vehicleType !$= "MPB") + %vehicleType = strlwr(%vehicleType); + + %enemyTeam = ( %destroyer.team == 1 ) ? 2 : 1; + + %scorer = 0; + %multiplier = 1; + + %passengers = 0; + for(%i = 0; %i < %data.numMountPoints; %i++) + if(%vehicle.getMountNodeObject(%i)) + %passengers++; + + //what destroyed this vehicle + if(%destroyer.client) + { + //it was a player, or his mine, satchel, whatever... + %destroyer = %destroyer.client; + %scorer = %destroyer; + + // determine if the object used was a mine + if(%vehicle.lastDamageType == $DamageType::Mine) + %multiplier = 2; + } + else if(%destroyer.getClassName() $= "Turret") + { + if(%destroyer.getControllingClient()) + { + //manned turret + %destroyer = %destroyer.getControllingClient(); + %scorer = %destroyer; + } + else + { + %destroyerName = "A turret"; + %multiplier = 0; + } + } + else if(%destroyer.getDataBlock().catagory $= "Vehicles") + { + // Vehicle vs vehicle kill! + if(%name $= "BomberFlyer" || %name $= "AssaultVehicle") + %gunnerNode = 1; + else + %gunnerNode = 0; + + if(%destroyer.getMountNodeObject(%gunnerNode)) + { + %destroyer = %destroyer.getMountNodeObject(%gunnerNode).client; + %scorer = %destroyer; + } + %multiplier = 3; + } + else // Is there anything else we care about? + return; + + + if(%destroyerName $= "") + %destroyerName = %destroyer.name; + + if(%vehicle.team == %destroyer.team) // team kill + { + %pref = (%vehicleType $= "Assault Tank") ? "an" : "a"; + messageAll( 'msgVehicleTeamDestroy', '\c0%1 TEAMKILLED %3 %2!', %destroyerName, %vehicleType, %pref); + } + + else // legit kill + { + //messageTeamExcept(%destroyer, 'msgVehicleDestroy', '\c0%1 destroyed an enemy %2.', %destroyerName, %vehicleType); // z0dd - ZOD, 8/20/02. not needed with new messenger on line below + teamDestroyMessage(%destroyer, 'msgVehDestroyed', '\c5%1 destroyed an enemy %2!', %destroyerName, %vehicleType); // z0dd - ZOD, 8/20/02. Send teammates a destroy message + messageTeam(%enemyTeam, 'msgVehicleDestroy', '\c0%1 destroyed your team\'s %2.', %destroyerName, %vehicleType); + //messageClient(%destroyer, 'msgVehicleDestroy', '\c0You destroyed an enemy %1.', %vehicleType); + + if(%scorer) + { + %value = %game.awardScoreVehicleDestroyed(%scorer, %vehicleType, %multiplier, %passengers); + %game.shareScore(%value); + } + } +} + +function PracticeCTFGame::awardScoreVehicleDestroyed(%game, %client, %vehicleType, %mult, %passengers) +{ + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + + if(%vehicleType $= "Grav Cycle") + %base = %game.SCORE_PER_DESTROY_WILDCAT; + else if(%vehicleType $= "Assault Tank") + %base = %game.SCORE_PER_DESTROY_TANK; + else if(%vehicleType $= "MPB") + %base = %game.SCORE_PER_DESTROY_MPB; + else if(%vehicleType $= "Turbograv") + %base = %game.SCORE_PER_DESTROY_SHRIKE; + else if(%vehicleType $= "Bomber") + %base = %game.SCORE_PER_DESTROY_BOMBER; + else if(%vehicleType $= "Heavy Transport") + %base = %game.SCORE_PER_DESTROY_TRANSPORT; + + %total = ( %base * %mult ) + ( %passengers * %game.SCORE_PER_PASSENGER ); + + %client.vehicleScore += %total; + + messageClient(%client, 'msgVehicleScore', '\c0You received a %1 point bonus for destroying an enemy %2.', %total, %vehicleType); + %game.recalcScore(%client); + return %total; +} + +function PracticeCTFGame::shareScore(%game, %client, %amount) +{ + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + + //error("share score of"SPC %amount SPC "from client:" SPC %client); + // all of the player in the bomber and tank share the points + // gained from any of the others + %vehicle = %client.vehicleMounted; + if(!%vehicle) + return 0; + %vehicleType = getTaggedString(%vehicle.getDataBlock().targetTypeTag); + if(%vehicleType $= "Bomber" || %vehicleType $= "Assault Tank") + { + for(%i = 0; %i < %vehicle.getDataBlock().numMountPoints; %i++) + { + %occupant = %vehicle.getMountNodeObject(%i); + if(%occupant) + { + %occCl = %occupant.client; + if(%occCl != %client && %occCl.team == %client.team) + { + // the vehicle has a valid teammate at this node + // share the score with them + %occCl.vehicleBonus += %amount; + %game.recalcScore(%occCl); + } + } + } + } +} + +function PracticeCTFGame::awardScoreTurretKill(%game, %victimID, %implement) +{ + if ((%killer = %implement.getControllingClient()) != 0) //award whoever might be controlling the turret + { + if (%killer == %victimID) + %game.awardScoreSuicide(%victimID); + else if (%killer.team == %victimID.team) //player controlling a turret killed a teammate + { + %killer.teamKills++; + %game.awardScoreTurretTeamKill(%victimID, %killer); + %game.awardScoreDeath(%victimID); + } + else + { + %killer.mannedturretKills++; + %game.recalcScore(%killer); + %game.awardScoreDeath(%victimID); + } + } + else if ((%killer = %implement.owner) != 0) //if it isn't controlled, award score to whoever deployed it + { + if (%killer.team == %victimID.team) + { + %game.awardScoreDeath(%victimID); + } + else + { + %killer.turretKills++; + %game.recalcScore(%killer); + %game.awardScoreDeath(%victimID); + } + } + //default is, no one was controlling it, no one owned it. No score given. +} + +function PracticeCTFGame::testKill(%game, %victimID, %killerID) +{ + return ((%killerID !=0) && (%victimID.team != %killerID.team)); +} + +function PracticeCTFGame::awardScoreKill(%game, %killerID) +{ + %killerID.kills++; + %game.recalcScore(%killerID); + return %game.SCORE_PER_KILL; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// z0dd - ZOD: Practice Mode functions ////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// + +function PracticeCTFGame::onClientLeaveGame(%game, %client) +{ + // Clear out this clients transfer pads + for( %i = 0; %i < $Host::ClassicMaxTelepads; %i++ ) + { + if(isObject(%client.spawnPad[%i])) + %client.spawnPad[%i].setDamageState(Destroyed); + } + + // Call the default + DefaultGame::onClientLeaveGame(%game, %client); +} + +function PracticeCTFGame::clientChangeTeam(%game, %client, %team, %fromObs) +{ + // Clear out this clients transfer pads + for( %i = 0; %i < $Host::ClassicMaxTelepads; %i++ ) { + if(isObject(%client.spawnPad[%i])) + %client.spawnPad[%i].setDamageState(Destroyed); + } + + // Call the default + DefaultGame::clientChangeTeam(%game, %client, %team, %fromObs); +} + +function PracticeCTFGame::equip(%game, %player) +{ + for(%i =0; %i<$InventoryHudCount; %i++) + %player.client.setInventoryHudItem($InventoryHudData[%i, itemDataName], 0, 1); + %player.client.clearBackpackIcon(); + + if(!%player.client.isAIControlled() && $PracticeCtf::SpawnFavs && !$PracticeCtf::SpawnOnly) + { + buyFavorites(%player.client); + %player.setEnergyLevel(%player.getDataBlock().maxEnergy); + %player.selectWeaponSlot( 0 ); + } + else + { + %player.setInventory(Blaster,1); + %player.setInventory(Disc,1); + %player.setInventory(DiscAmmo, 999); + %player.setInventory(Chaingun, 1); + %player.setInventory(ChaingunAmmo, 999); + %player.setInventory(RepairKit,1); + %player.setInventory(Grenade, 30); + %player.setInventory(Beacon, 20); + %player.setInventory(TargetingLaser, 1); + %player.weaponCount = 3; + + %player.use("Blaster"); + } +} + +///////////////////////////////////////////////////////////////////////////////////////// +// z0dd - ZOD: Map Reset functions/////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// + +function PracticeCTFGame::resetMission(%game) +{ + Cancel( %game.timeCheck ); + CancelCountdown(); + CancelEndCountdown(); + + //setup the second half... + // MES -- per MarkF, scheduling for 0 seconds will prevent player deletion-related crashes + %game.schedule(0, "refreshAll"); +} + +function PracticeCTFGame::refreshAll(%game) +{ + //stop the game and the bots + $MatchStarted = false; + $CountdownStarted = false; + AISystemEnabled(false); + + // Let everyone know what is going on + bottomPrintAll("\nYou are in observation mode while mission is resetting.\n", $Host::warmupTime, 3); + + // Return all flags that aren't home + for(%f = 1; %f <= %game.numTeams; %f++) + { + if(!$TeamFlag[%f].isHome) + { + %game.flagReturn($TeamFlag[%f]); + } + } + + //reset stations and vehicles that players were using + // Function exists in Siege, use it, no need to duplicate + SiegeGame::resetPlayers(%game); + + // zero out the counts for deployable items (found in defaultGame.cs) + %game.clearDeployableMaxes(); + + // Clean up deployables triggers + cleanTriggers(nameToID("MissionCleanup/Deployables")); + + // clean up the MissionCleanup group - note, this includes deleting all the player objects + %clean = nameToID("MissionCleanup"); + %clean.schedule(800, "housekeeping"); + //%clean.housekeeping(); // Function exists in Siege no need to duplicate + + // Vehicle objects placed in original position + // This apprently switches the vehicles team as well, not a good idea. + //resetNonStaticObjPositions(); + + // Restore static objects to their original condition + // Function exists in defaultGame.cs, in turn calls PracticeCTFGame::groupObjectRestore + %group = nameToID("MissionGroup/Teams"); + %group.objectRestore(); + + %count = ClientGroup.getCount(); + echo("-----------count=" @ %count); + for(%cl = 0; %cl < %count; %cl++) + { + %client = ClientGroup.getObject(%cl); + if( !%client.isAIControlled() ) + { + Game.forceObserver( %client, "playerChoose" ); + + // old code. wasn't working correctly for some reason + // Put everybody in observer mode: + //%client.camera.getDataBlock().setMode( %client.camera, "observerStaticNoNext" ); + //%client.setControlObject( %client.camera ); + + // This sets certain keybinds, usefull, lets keep it? + //commandToClient( %client, 'setHudMode', 'Standard' ); + //commandToClient( %client, 'ControlObjectReset' ); + + //clientResetTargets(%client, true); + //%client.notReady = true; + } + } + %game.schedule( $Host::warmupTime * 1000, "resetOver" ); +} + +function PracticeCTFGame::groupObjectRestore(%game, %this) +{ + for(%i = 0; %i < %this.getCount(); %i++) + %this.getObject(%i).objectRestore(); +} + +function PracticeCTFGame::shapeObjectRestore(%game, %object) +{ + if(%object.getDamageLevel()) + { + %object.setDamageLevel(0.0); + %object.setDamageState(Enabled); + } + if(%object.getDatablock().getName() $= "TurretBaseLarge") + { + // check to see if the turret base still has the same type of barrel it had + // at the beginning of the mission + if(%object.getMountedImage(0)) + { + if(%object.getMountedImage(0).getName() !$= %object.originalBarrel) + { + // pop the "new" barrel + %object.unmountImage(0); + // mount the original barrel + %object.mountImage(%object.initialBarrel, 0, false); + } + } + } +} + +function PracticeCTFGame::resetOver( %game ) +{ + // Reset the team scores + for(%j = 1; %j <= %game.numTeams; %j++) + $TeamScore[%j] = 0; + + // drop all players into mission + %game.dropPlayers(); + + //setup the AI for the second half + %game.aiHalfTime(); + + // start the mission again (release players) + %game.startupCountDown( $Host::warmupTime ); +} + +function PracticeCTFGame::dropPlayers( %game ) +{ + %count = ClientGroup.getCount(); + for(%cl = 0; %cl < %count; %cl++) + { + %client = ClientGroup.getObject(%cl); + + // Reset client score + %game.resetScore(%client); + + // Resend the scores and flag status + for(%i = 1; %i <= %game.numTeams; %i++) + messageClient(%client, 'MsgCTFAddTeam', "", %i, %game.getTeamName(%i), $flagStatus[%i], $TeamScore[%i]); + + if( !%client.isAIControlled() ) + { + // keep observers in observer mode + if(%client.team == 0) + %client.camera.getDataBlock().setMode(%client.camera, "justJoined"); + else + { + %game.spawnPlayer( %client, false ); + + %client.camera.getDataBlock().setMode( %client.camera, "pre-game", %client.player ); + %client.setControlObject( %client.camera ); + //%client.notReady = false; + } + } + } +} + +function PracticeCTFGame::startupCountDown(%game, %time) +{ + %game.startupCountDown = true; + $MatchStarted = false; + + %timeMS = %time * 1000; + %game.schedule(%timeMS, "startMap"); + notifyMatchStart(%timeMS); + + if(%timeMS > 30000) + schedule(%timeMS - 30000, 0, "notifyMatchStart", 30000); + if(%timeMS > 20000) + schedule(%timeMS - 20000, 0, "notifyMatchStart", 20000); + if(%timeMS > 10000) + schedule(%timeMS - 10000, 0, "notifyMatchStart", 10000); + if(%timeMS > 5000) + schedule(%timeMS - 5000, 0, "notifyMatchStart", 5000); + if(%timeMS > 4000) + schedule(%timeMS - 4000, 0, "notifyMatchStart", 4000); + if(%timeMS > 3000) + schedule(%timeMS - 3000, 0, "notifyMatchStart", 3000); + if(%timeMS > 2000) + schedule(%timeMS - 2000, 0, "notifyMatchStart", 2000); + if(%timeMS > 1000) + schedule(%timeMS - 1000, 0, "notifyMatchStart", 1000); +} + +function PracticeCTFGame::startMap(%game) +{ + $MatchStarted = true; + $CountdownStarted = true; + %game.startupCountDown = false; + + MessageAll('MsgMissionStart', "\c2Match started"); + + // reset the timelimit + %curTimeLeftMS = $Host::TimeLimit * 60 * 1000; + $missionStartTime = getSimTime(); + %game.timeCheck = %game.schedule(20000, "checkTimeLimit"); + + //schedule the end of match countdown + EndCountdown($Host::TimeLimit * 60 * 1000); + + // set all clients control to their player + %count = ClientGroup.getCount(); + for( %i = 0; %i < %count; %i++ ) + { + %cl = ClientGroup.getObject(%i); + + // Send clients the new clock + messageClient(%cl, 'MsgSystemClock', "", $Host::TimeLimit, %curTimeLeftMS); + + if (!isObject(%cl.player)) + commandToClient(%cl, 'setHudMode', 'Observer'); + else + { + %cl.observerMode = ""; + %cl.setControlObject( %cl.player ); + commandToClient(%cl, 'setHudMode', 'Standard'); + %client.notReady = false; + } + } + + //now synchronize everyone's clock + updateClientTimes(%curTimeLeftMS); + + //start the bots up again... + AISystemEnabled(true); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// z0dd - ZOD: Hud related Practice functions /////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// + +function PracticeCTFGame::initPracticeHud(%game, %client, %val) +{ + commandToClient(%client, 'initializePracHud', "PracticeCTF"); + commandToClient(%client, 'practiceHudHead', "CTF Practice Config", "Server Settings", "Player Settings", "Projectile Observation", "Telepad Options", "Spawn Vehicle at Pad"); + + // Send admins full set of options. Edit, this was causing problems when client requires update. + //if(%client.isAdmin) + //{ + commandToClient(%client, 'practiceHudPopulate', "Minimum Turrets", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16"); + commandToClient(%client, 'practiceHudPopulate', "Return Flag", getTaggedString(Game.getTeamName(1)), getTaggedString(Game.getTeamName(2))); + //if(%client.isSuperAdmin) + //{ + commandToClient(%client, 'practiceHudPopulate', "Save Deployables", $MissionDisplayName @ " File 1", $MissionDisplayName @ " File 2", $MissionDisplayName @ " File 3", $MissionDisplayName @ " File 4", $MissionDisplayName @ " File 5", $MissionDisplayName @ " File 6"); + commandToClient(%client, 'practiceHudPopulate', "Load Deployables", $MissionDisplayName @ " File 1", $MissionDisplayName @ " File 2", $MissionDisplayName @ " File 3", $MissionDisplayName @ " File 4", $MissionDisplayName @ " File 5", $MissionDisplayName @ " File 6"); + //} + //} + commandToClient(%client, 'practiceHudDone'); +} + +function PracticeCTFGame::sendPracHudUpdate(%game, %client, %msg) +{ + %serverOptMask = 0; + if ($PracticeCtf::UnlimAmmo == 1) %serverOptMask += 1; + if ($PracticeCtf::AutoFlagReturn == 1) %serverOptMask += 2; + if ($PracticeCtf::SpawnFavs == 1) %serverOptMask += 4; + if ($PracticeCtf::SpawnOnly == 1) %serverOptMask += 8; + if ($PracticeCtf::NoScoreLimit == 1) %serverOptMask += 16; + if ($PracticeCtf::ProtectStatics == 1) %serverOptMask += 32; + + %clientOptMask = 0; + if (%client.discObs == 1) %clientOptMask += 1; + if (%client.grenadeObs == 1) %clientOptMask += 2; + if (%client.mortarObs == 1) %clientOptMask += 4; + if (%client.missileObs == 1) %clientOptMask += 8; + if (%client.transMode == 0) %clientOptMask += 16; + if (%client.transMode == 1) %clientOptMask += 32; + + messageClient(%client, 'UpdatePracHud', %msg, %serverOptMask, %clientOptMask, %client.isAdmin + %client.isSuperAdmin); +} + +function PracticeCTFGame::practiceBtnCmd(%game, %client, %btn, %val) +{ + // dont let non admins change practice mode server settings + if((mFloor(%btn/10) == 1) && (!%client.isAdmin) && (!%client.isSuperAdmin)) + { + messageClient(%client, 'MsgPracMode', '\c2Only admins can change that Server Setting.~wfx/misc/misc.error.wav'); + return; + } + if(!$MatchStarted) + { + messageClient( %client, 'MsgPracMode', '\c2You must wait for the match to start before using practice commands.~wfx/misc/misc.error.wav'); + return; + } + + %name = %client.nameBase; + %snd = "~wfx/misc/warning_beep.wav"; + + switch$ (%btn) + { + // GUI CONTROLS + + // SERVER BUTTONS + case 10: + $PracticeCtf::UnlimAmmo = !$PracticeCtf::UnlimAmmo; + sendAllPracHudUpdate(%game, "\c3" @ %name @ "\c2: 999 AMMO turned \c3" @ ($PracticeCtf::UnlimAmmo ? "ON" : "OFF") @ %snd); + + case 11: + $PracticeCtf::AutoFlagReturn = !$PracticeCtf::AutoFlagReturn; + sendAllPracHudUpdate(%game, "\c3" @ %name @ "\c2: AUTO-RETURN FLAGS turned \c3" @ ($PracticeCtf::AutoFlagReturn ? "ON" : "OFF") @ %snd); + + case 12: + $PracticeCtf::SpawnFavs = !$PracticeCtf::SpawnFavs; + sendAllPracHudUpdate(%game, "\c3" @ %name @ "\c2: SPAWN IN FAVORITE turned \c3" @ ($PracticeCtf::SpawnFavs ? "ON" : "OFF") @ %snd); + + case 13: + $PracticeCtf::SpawnOnly = !$PracticeCtf::SpawnOnly; + sendAllPracHudUpdate(%game, "\c3" @ %name @ "\c2: SPAWN ONLY turned \c3" @ ($PracticeCtf::SpawnOnly ? "ON" : "OFF") @ %snd); + + case 14: + $PracticeCtf::NoScoreLimit = !$PracticeCtf::NoScoreLimit; + sendAllPracHudUpdate(%game, "\c3" @ %name @ "\c2: NO SCORE LIMIT turned \c3" @ ($PracticeCtf::NoScoreLimit ? "ON" : "OFF") @ %snd); + for ( %team = 1; %team <= %game.numTeams; %team++ ) + %game.checkScoreLimit(%team); + + case 15: + $PracticeCtf::ProtectStatics = !$PracticeCtf::ProtectStatics; + sendAllPracHudUpdate(%game, "\c3" @ %name @ "\c2: PROTECT ASSESTS turned \c3" @ ($PracticeCtf::ProtectStatics ? "ON" : "OFF") @ %snd); + + case 16: + messageAll( 'MsgPracMode', '\c3%1\c2: Resetting map.%2', %client.name, %snd); + %game.resetMission(); + + // TELEPORT OPTIONS + case 20: + %client.transMode = 0; // beacon + //messageClient( %client, 'MsgPracMode', '\c2Beacon deploy mode: \c3Beacon\c2.%1', %snd); + + case 21: + %client.transMode = 1; // telepad + //messageClient( %client, 'MsgPracMode', '\c2Beacon deploy mode: \c3Transfer Pad\c2.%1', %snd); + + case 22: + selectPad(%client); + + case 23: + destroyPad(%client, 0); + + case 24: + teleportToPad(%client); + + // SPAWN VEHICLES + case 30: + spawnVehAtPad(%client, "ScoutVehicle"); + + case 31: + spawnVehAtPad(%client, "AssaultVehicle"); + + case 32: + spawnVehAtPad(%client, "MobileBaseVehicle"); + + case 33: + spawnVehAtPad(%client, "ScoutFlyer"); + + case 34: + spawnVehAtPad(%client, "BomberFlyer"); + + case 35: + spawnVehAtPad(%client, "HAPCFlyer"); + + // PROJECTILE OBSERVATION + case 40: + %client.discObs = %val; + + case 41: + %client.grenadeObs = %val; + + case 42: + %client.mortarObs = %val; + + case 43: + %client.missileObs = %val; + + default: + messageClient( %client, 'MsgError', '\c2Unknown values.%1', %snd); + } +} + +// Menu Submit handler +function PracticeCTFGame::updatePracticeHudSet(%game, %client, %opt, %val) +{ + // dont let non admins change practice mode server settings + if((%opt < 3) && ((!%client.isAdmin) || (!%client.isSuperAdmin))) + { + messageClient(%client, 'MsgError', '\c2Only admins can change that Server Setting.~wfx/misc/misc.error.wav'); + return; + } + else if((!%client.isSuperAdmin)) // dont let non SuperAdmins change SuperAdmin only practice mode server settings + { + messageClient(%client, 'MsgError', '\c2Only SuperAdmins can change that Server Setting.~wfx/misc/misc.error.wav'); + return; + } + if(!$MatchStarted) + { + messageClient( %client, 'MsgError', '\c2You must wait for the match to start before using practice commands.~wfx/misc/misc.error.wav'); + return; + } + + %snd = '~wfx/misc/warning_beep.wav'; + %adj = %val == 1 ? 1 : 0; // Convert index to only 1 or 0 to help keep function smaller + %detail = (%adj ? "On" : "Off"); + %name = %client.name; + + switch$ ( %opt ) + { + case 1: + %min = %val+3; + $TeamDeployableMin[TurretIndoorDeployable] = %min; + $TeamDeployableMin[TurretOutdoorDeployable] = %min; + %detail = %min; + messageAll( 'MsgPracMode', '\c3%5\c2: \"Minimum Turrets\" set to: \c3%4\c2.%1', %snd, %val, %adj, %detail, %name, $CurrentMission ); + + case 2: + if(!$TeamFlag[%val].isHome) + { + %game.flagReturn($TeamFlag[%val]); + messageAll( 'MsgPracMode', '\c3%5\c2: returned the flag.%1', %snd, %val, %adj, %detail, %name, $CurrentMission ); + } + else + messageClient( %client, 'MsgPracMode', '\c2Unknown values.', %snd, %val, %adj, %detail, %name, $CurrentMission ); + + case 3: + messageClient( %client, 'MsgPracMode', '\c2Attempting to save deployables to file: %6 %2.', %snd, %val, %adj, %detail, %name, $CurrentMission ); + %game.saveDeployables(%client, %val); + + case 4: + messageClient( %client, 'MsgPracMode', '\c2Attempting to load deployables from file: %6 %2.', %snd, %val, %adj, %detail, %name, $CurrentMission ); + %game.loadDeployables(%client, %val); + + default: + messageClient( %client, 'MsgError', '\c2Unknown values.', %snd, %val, %adj, %detail, %name, $CurrentMission ); + } +} + +// default to 0 +$DeployablesCount = 0; + +function PracticeCTFGame::loadDeployables(%game, %client, %val) +{ + if(%client.isSuperAdmin) + { + %filename = "prefs/" @ "DepSav" @ $CurrentMission @ %val @ ".cs"; + if(!isFile(%filename)) + { + messageClient(%client, 'MsgPracMode', '\c2File %6 %2 does not exist!', 0, %val, 0, 0, 0, $CurrentMission ); + return; + } + else + { + %group = nameToID("MissionCleanup/Deployables"); + %count = %group.getCount(); + for(%i = 0; %i < %count; %i++) + { + %obj = %group.getObject(%i); + %obj.setDamageState(Destroyed); + } + + %file = new FileObject(); + if(%file.openForRead(%filename)) + { + exec(%filename); + for(%i = 0; %i < $DeployablesCount; %i++) + { + %class = $DeployableClassName[%i]; + if(%class $= "TurretData") + %className = "Turret"; + else + %className = "StaticShape"; + + %deplObj = new (%className)() { + dataBlock = $DeployableDataBlockName[%i]; + }; + %deplObj.setTransform($DeployableTrans[%i]); + if(%deplObj.getDatablock().rechargeRate) + %deplObj.setRechargeRate(%deplObj.getDatablock().rechargeRate); + + %deplObj.team = $DeployableTeam[%i]; + %deplObj.owner = 0; + if(%deplObj.getTarget() != -1) + setTargetSensorGroup(%deplObj.getTarget(), $DeployableTeam[%i]); + + addToDeployGroup(%deplObj); + AIDeployObject(0, %deplObj); + $TeamDeployedCount[$DeployableTeam[%i], $DeployableItem[%i]]++; + %deplObj.deploy(); + } + } + %file.delete(); + messageClient(%client, 'MsgPracMode', '\c2Load file %6 %2 completed.', 0, %val, 0, 0, 0, $CurrentMission ); + } + } + else + messageClient(%client, 'MsgError', '\c2Only SuperAdmins can use this setting.~wfx/misc/misc.error.wav'); +} + +function PracticeCTFGame::saveDeployables(%game, %client, %val) +{ + if(%client.isSuperAdmin) + { + %filename = "prefs/" @ "DepSav" @ $CurrentMission @ %val @ ".cs"; + + // Check to see if theres anything to write first + %group = nameToID("MissionCleanup/Deployables"); + if (%group > 0) + %depCount = %group.getCount(); + else + return; + + if(isFile(%filename)) + deleteFile(%filename); + + %file = new fileObject(); + %file.openForWrite(%filename); + %count = 0; + for(%i = 0; %i < %depCount; %i++) + { + %deplObj = %group.getObject(%i); + if(isObject(%deplObj)) + { + %name = %deplObj.getDataBlock().getName(); + if(%name $= "DeployedStationInventory") + %item = "InventoryDeployable"; + else if(%name $= "DeployedMotionSensor") + %item = "MotionSensorDeployable"; + else if(%name $= "DeployedPulseSensor") + %item = "PulseSensorDeployable"; + else if(%name $= "TurretDeployedOutdoor") + %item = "TurretOutdoorDeployable"; + else if(%name $= "TurretDeployedFloorIndoor" || %name $= "TurretDeployedWallIndoor" || %name $= "TurretDeployedCeilingIndoor") + %item = "TurretIndoorDeployable"; + else if(%name $= "TurretDeployedCamera") + %item = "DeployedCamera"; + else + %item = ""; + + %file.writeLine("$DeployableDataBlockName[" @ %count @"] = " @ %name @ ";"); + %file.writeLine("$DeployableClassName[" @ %count @"] = " @ %deplObj.getDataBlock().getClassName() @ ";"); + %file.writeLine("$DeployableItem[" @ %count @"] = " @ %item @ ";"); + %file.writeLine("$DeployableTrans[" @ %count @"] = " @ "\"" @ %deplObj.getTransform() @ "\"" @ ";"); + %file.writeLine("$DeployableTeam[" @ %count @"] = " @ %deplObj.team @ ";"); + %count++; + } + } + %file.writeLine("$DeployablesCount = " @ %count @ ";"); + %file.close(); + %file.delete(); + messageClient(%client, 'MsgPracMode', '\c2Save file %6 %2 completed.', 0, %val, 0, 0, 0, $CurrentMission ); + } + else + messageClient(%client, 'MsgError', '\c2Only SuperAdmins can use this setting.~wfx/misc/misc.error.wav'); +} + +// z0dd - ZOD, 10/02/02. Hack for flag collision bug. +function CTFGame::startFlagCollisionSearch(%game, %flag) +{ + %flag.searchSchedule = %game.schedule(10, "startFlagCollisionSearch", %flag); // SquirrelOfDeath, 10/02/02. Moved from after the while loop + %pos = %flag.getWorldBoxCenter(); + InitContainerRadiusSearch( %pos, 1.0, $TypeMasks::VehicleObjectType | $TypeMasks::CorpseObjectType | $TypeMasks::PlayerObjectType ); + while((%found = containerSearchNext()) != 0) + { + %flag.getDataBlock().onCollision(%flag, %found); + // SquirrelOfDeath, 10/02/02. Removed break to catch all players possibly intersecting with flag + } +} diff --git a/scripts/RPGGame.cs b/scripts/RPGGame.cs index d223c64..6668332 100644 --- a/scripts/RPGGame.cs +++ b/scripts/RPGGame.cs @@ -1,726 +1,324 @@ -// DisplayName = Birth of Legend - -//--- GAME RULES BEGIN --- -// There are none, the gameMode conforms itself towards what you do. -//--- GAME RULES END --- - -// Notes: -// In Role Playing, you select your race (at the warrior pane), join an RPG server and your -// character is setup (specifically to that server). From there, you can start clans, build -// bases, and war with each other. Basically, it's a freeMode sort of thing. - -//exec the AI scripts -exec("scripts/aiRPG.cs"); - -$RequiresClient[RPG] = true; -$InvBanList[RPG, "C4Charge"] = 1; - -//-- tracking --- -function RPGGame::initGameVars(%game) -{ - //%game. = ""; //I guess I'll eventually set some, but most are loaded via BASIC files -} - -package RPGGame -{ -function blah(){} //Eh.. -}; - -function RPGGame::setUpTeams(%game) -{ - defaultGame::setUpTeams(%game); - %game.numTeams = 1; - setSensorGroupCount(4); - $TeamDamage = true; //Allow team Damage -} - -function RPGGame::getTeamSkin(%game, %team) -{ - if($host::tournamentMode) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - { - return $teamSkin[%team]; - } - - else - { - //error("CTFGame::getTeamSkin"); - if(!$host::useCustomSkins) - { - %terrain = MissionGroup.musicTrack; - //error("Terrain type is: " SPC %terrain); - switch$(%terrain) - { - case "lush": - if(%team == 1) - %skin = 'beagle'; - else if(%team == 2) - %skin = 'dsword'; - else %skin = 'base'; - - case "badlands": - if(%team == 1) - %skin = 'swolf'; - else if(%team == 2) - %skin = 'dsword'; - else %skin = 'base'; - - case "ice": - if(%team == 1) - %skin = 'swolf'; - else if(%team == 2) - %skin = 'beagle'; - else %skin = 'base'; - - case "desert": - if(%team == 1) - %skin = 'cotp'; - else if(%team == 2) - %skin = 'beagle'; - else %skin = 'base'; - - case "Volcanic": - if(%team == 1) - %skin = 'dsword'; - else if(%team == 2) - %skin = 'cotp'; - else %skin = 'base'; - - default: - if(%team == 2) - %skin = 'baseb'; - else %skin = 'base'; - } - } - else %skin = $teamSkin[%team]; - - //error("%skin = " SPC getTaggedString(%skin)); - return %skin; -} -} - -function RPGGame::getTeamName(%game, %team) -{ - // --------------------------------------------------- - // z0dd - ZOD 3/30/02. Only display default team names - //if ( isDemo() || $host::tournamentMode) - return $TeamName[%team]; - // --------------------------------------------------- -} - -//-------------------------------------------------------------------------- -function RPGGame::missionLoadDone(%game) -{ - //default version sets up teams - must be called first... - DefaultGame::missionLoadDone(%game); -} - -function RPGGame::showStalemateTargets(%game) -{ - cancel(%game.stalemateSchedule); - - //show the targets - for (%i = 1; %i <= 2; %i++) - { - %flag = $TeamFlag[%i]; - - //find the object to scope/waypoint.... - //render the target hud icon for slot 1 (a centermass flag) - //if we just set him as always sensor vis, it'll work fine. - if (isObject(%flag.carrier)) - setTargetAlwaysVisMask(%flag.carrier.getTarget(), 0x7); - } - //schedule the targets to hide - %game.stalemateObjsVisible = true; - %game.stalemateSchedule = %game.schedule(%game.stalemateDurationMS, hideStalemateTargets); -} - -function RPGGame::timeLimitReached(%game) -{ - logEcho("game over (timelimit)"); - %game.gameOver(); - cycleMissions(); -} - -function RPGGame::scoreLimitReached(%game) -{ - logEcho("game over (scorelimit)"); - %game.gameOver(); - cycleMissions(); -} - -function RPGGame::gameOver(%game) -{ - //call the default - DefaultGame::gameOver(%game); - messageAll('MsgClearObjHud', ""); -} - -function RPGGame::onClientDamaged(%game, %clVictim, %clAttacker, %damageType, %implement, %damageLoc) -{ - if(%clVictim.headshot && %damageType == $DamageType::Laser && %clVictim.team != %clAttacker.team) - { - %clAttacker.scoreHeadshot++; - if (%game.SCORE_PER_HEADSHOT != 0) - { - messageClient(%clAttacker, 'msgHeadshot', '\c0You received a %1 point bonus for a successful headshot.', %game.SCORE_PER_HEADSHOT); - messageTeamExcept(%clAttacker, 'msgHeadshot', '\c5%1 hit a sniper rifle headshot.', %clAttacker.name); // z0dd - ZOD, 8/15/02. Tell team - } - %game.recalcScore(%clAttacker); - } - - // ----------------------------------------------- - // z0dd - ZOD, 8/25/02. Rear Lance hits - if(%clVictim.rearshot && %damageType == $DamageType::ShockLance && %clVictim.team != %clAttacker.team) - { - %clAttacker.scoreRearshot++; - if (%game.SCORE_PER_REARSHOT != 0) - { - messageClient(%clAttacker, 'msgRearshot', '\c0You received a %1 point bonus for a successful rearshot.', %game.SCORE_PER_REARSHOT); - messageTeamExcept(%clAttacker, 'msgRearshot', '\c5%1 hit a shocklance rearshot.', %clAttacker.name); - } - %game.recalcScore(%clAttacker); - } - // ----------------------------------------------- - - //the DefaultGame will set some vars - DefaultGame::onClientDamaged(%game, %clVictim, %clAttacker, %damageType, %implement, %damageLoc); - - //if victim is carrying a flag and is not on the attackers team, mark the attacker as a threat for x seconds(for scoring purposes) - if ((%clVictim.holdingFlag !$= "") && (%clVictim.team != %clAttacker.team)) - { - %clAttacker.dmgdFlagCarrier = true; - cancel(%clAttacker.threatTimer); //restart timer - %clAttacker.threatTimer = schedule(%game.TIME_CONSIDERED_FLAGCARRIER_THREAT, %clAttacker.dmgdFlagCarrier = false); - } -} - -//////////////////////////////////////////////////////////////////////////////////////// -function RPGGame::clientMissionDropReady(%game, %client) -{ - messageClient(%client, 'MsgClientReady',"", "SinglePlayerGame"); //Force the SP game objective hud to setup - %game.resetScore(%client); - - messageClient(%client, 'MsgMissionDropInfo', '\c0You are in mission %1 (%2).', $MissionDisplayName, $MissionTypeDisplayName, $ServerName ); - - DefaultGame::clientMissionDropReady(%game, %client); - - //Force client Spawn since we're ready now - schedule(1000,0,"forceClientSpawn",%client,true); - - %client.setControlObject(%client.player); - commandToClient(%client,'bottomPrint',"Try not to die.",3); - - //Since this is an RPG gamemode, be sure some things are correct. (May have been a mission switch from CTF or some other gamemode) - commandToClient(%client,'SetScoreText',"PDA - Personal Data Assistant"); - //Make sure the data hud is working. - messageClient(%client,'MsgSPCurrentObjective1',"",'Location: Unknown.'); - messageClient(%client,'MsgSPCurrentObjective2',"",'Money: $%1.',%client.money); -} - -function RPGGame::assignClientTeam(%game, %client, %respawn) -{ - DefaultGame::assignClientTeam(%game, %client, %respawn); - // if player's team is not on top of objective hud, switch lines - messageClient(%client, 'MsgCheckTeamLines', "", %client.team); -} - -function RPGGame::applyConcussion(%game, %player) -{ -} - -function RPGGame::vehicleDestroyed(%game, %vehicle, %destroyer) -{ -} - -function RPGGame::onClientKilled(%game, %clVictim, %clKiller, %damageType, %implement, %damageLocation) -{ - defaultGame::onClientKilled(%game, %clVictim, %clKiller, %damageType, %implement, %damageLocation); - commandToClient(%clVictim,'HandleScriptedCommand',2); - //commandToClient(%clVictim,'alxPlayMusic',"T2BOL/Music/TribesHymn.mp3"); //Add a little music that becomes audible if the player idles in death for a bit.. - //No, play this epic audio: - schedule(2000,0,"messageClient",%clVictim,'MsgDeath',"~wfx/Lose.wav"); - forceScoreScreenOpen(%clVictim,"DEATH"); - $Data::ShouldApply[%clVictim.GUID] = false; - - if (%clVictim.isAIControlled()) - %clVictim.drop(); -} - -//...very very messy PDA code below!! - -function RPGGame::updateScoreHud(%game, %client, %tag) //This is just here for when the PDA is first opened. -{ - if (%client.PDAPage $= "") - { - messageClient( %client, 'ClearHud', "", 'scoreScreen', 0 ); - - messageClient( %client, 'SetScoreHudHeader', "", 'Main Page'); - messageClient( %client, 'SetScoreHudSubheader', "", "Please select a command."); - - %index = 0; - messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Command List:"); - %index++; - messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "-Self Statistics"); - %index++; - messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "-Electronic Mail"); - %index++; - messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "-View Inventory"); - %index++; - messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "-Clan Management"); - %index++; - messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "-Save Game"); - - %client.PDAPage = "MAIN"; - } -} -function RPGGame::createPlayer(%game, %client, %spawnLoc, %respawn) -{ -DefaultGame::createPlayer(%game, %client, %spawnLoc, %respawn); -commandToClient(%client,'HandleScriptedCommand',9,formatTimeString("HHnn") SPC "Hrs."); -} - -function RPGGame::processGameLink(%game, %client, %arg1, %arg2, %arg3, %arg4, %arg5) -{ -messageClient( %client, 'ClearHud', "", 'scoreScreen', 0 ); - -//Special handles here.. -if (getSubStr(%arg1,0,5) $= "EMAIL" && getSubStr(%arg1,5,1) !$= "" && isNumber(getSubStr(%arg1,5,1))) -{ -%id = getSubStr(%arg1,5,strLen(%arg1)); -%client.email = %id; -messageClient( %client, 'SetScoreHudHeader', "", 'Electronic MailClose'); -messageClient( %client, 'SetScoreHudSubheader', "", "Delete E-Mail "@$Data::EMail::Date[%client.GUID,%i]@"Reply"); -%index = 0; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'From %1:',$Data::EMail::Sender[%client.GUID,%i]); -%index++; -%count = getSubStrOccurance($Data::EMail::Content[%client.GUID,%id],"\t"); -echo(%count); - -if (%count != 0) -for (%i = 0; %i < %count; %i++) -{ -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, '%1',getField($Data::EMail::Contents[%client.GUID,%id],%i)); -%index++; -} -else -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, '%1',$Data::EMail::Contents[%client.GUID,%id]); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Back To Listing"); -return; -} -else if (getSubStr(%arg1,0,7) $= "EMAILID" && isNumber(getSubStr(%arg1,7,strLen(%arg1)))) -{ -%id = getSubStr(%arg1,7,strLen(%arg1)); -%guid = $Data::Client[%id]; -%count = $Data::EMail::Count[%guid]; -%name = $Data::ClientName[%id]; -%clid = plNameToCid(%name); -if (checkEmails(%guid,%client.emailTitle)) -return; -messageClient( %client, 'SetScoreHudHeader', "", 'Electronic MailClose'); -messageClient( %client, 'SetScoreHudSubheader', "", 'E-Mail sent to %1.',%name); -messageClient( %client, 'SetLineHud', "", 'scoreScreen', 1, 'Back to Listing'); -$Data::EMail::Title[%guid,%count] = %client.emailTitle; -$Data::EMail::Sender[%guid,%count] = %client.namebase; -$Data::EMail::Contents[%guid,%count] = %client.emailCont; -$Data::EMail::Date[%guid,%count] = formatTimeString("DD, MM dd, yy @ hh:nn A"); -$Data::EMail::Count[%guid]++; -if (IsObject(%clid)) -messageClient(%clid,'msgClient','\c3Received an E-Mail from %1. ~wfx/misc/warning_beep.wav',%client.namebase); -return; -} - -switch$ (%arg1) -{ -case "CLOSE": -closeScoreScreen(%client); -case "BACK": //Resets you to the main menu -messageClient( %client, 'SetScoreHudHeader', "", 'Main PageClose'); -messageClient( %client, 'SetScoreHudSubheader', "", "Please select a command."); - - %index = 0; - messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Command List:"); - %index++; - messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "-Self Statistics"); - %index++; - messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "-Electronic Mail"); - %index++; - messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "-View Inventory"); - %index++; - messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "-Clan Management"); - %index++; - messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "-Save Game"); - -%client.PDAPage = "MAIN"; - -case "CLNSTP": -messageClient( %client, 'SetScoreHudHeader', "", 'Clan ManagementClose'); -messageClient( %client, 'SetScoreHudSubheader', "", "Showing clan setup."); -%index = 0; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Clan Name: %1 [Change]',%client.clanN); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Clan Tag: %1 [Change]',%client.clanT); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Short Description: %1 [Change]',%client.description); -%index++; - -if (%client.clanN !$= "" && %client.clanT !$= "") -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Done'); -%index++; - -%client.PDAPage = "CLNSTP"; - -case "EMAIL": -messageClient( %client, 'SetScoreHudHeader', "", 'Electronic MailClose'); -messageClient( %client, 'SetScoreHudSubheader', "", "Showing E-Mails in sequential order."); - -%index = 0; -%count = $Data::EMail::Count[%client.GUID]; -for (%i = 0; %i <= %count; %i++) -{ - if ($Data::EMail::Title[%client.GUID,%i] !$= "") - { - messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, '%2 - %3',%i,$Data::EMail::Sender[%client.GUID,%i],$Data::EMail::Title[%client.GUID,%i]); - %index++; - } -} - -if (%index == 0) -{ -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "There are no E-Mails to show."); -%index++; -} - -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "[Compose an E-Mail]"); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Back To Main Menu"); -%index++; - -case "EMAILSEND": -messageClient( %client, 'SetScoreHudHeader', "", 'Electronic MailClose'); -messageClient( %client, 'SetScoreHudSubheader', "", "New E-Mail"); - -%index = 0; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Title: %1 [Change]',%client.emailTitle); -%index++; - -%count = getSubStrOccurance(%client.emailCont,"\t"); - -if (%count != 0) -for (%i = 0; %i < %count; %i++) -{ -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Contents: %1 [Change]',%client.emailCont); -} -else -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Contents: %1 [Change]',%client.emailCont); -%index++; -if (%client.emailTitle !$= "" && %client.emailcont !$= "") -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Select Receptiant'); - -case "RECPT": -messageClient( %client, 'SetScoreHudHeader', "", 'Electronic MailClose'); -messageClient( %client, 'SetScoreHudSubheader', "", "Select Receptiant"); - -%count = $Data::ClientCount; -%index = 0; -for (%i = 0; %i < %count; %i++) -{ - messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, '%2',%i,$Data::ClientName[%i]); - %index++; -} - -case "CLNFN": -if ($Data::IsInClan[%client.GUID]) -{ -%ID = $Data::ClanID[%client.GUID]; - if ($Data::ClanLeaderGUID[%ID] == %client.GUID) - { - $Data::ClanName[%ID] = %client.clanN; - $Data::ClanTag[%ID] = %client.clanT; - $Data::ClanDesc[%ID] = %client.description; - forceScoreScreenOpen(%client,"CLNMG"); - } -} -else -{ -$Data::IsInCLan[%client.GUID] = true; - -if ($Data::ClanCount $= "") -$Data::ClanCount = 0; - -$Data::ClanName[$Data::ClanCount] = %client.clanN; -$Data::ClanTag[$Data::ClanCount] = %client.clanT; -$Data::ClanDesc[$Data::ClanCount] = %client.desc; -$Data::ClanLeader[$Data::ClanCount] = %client.namebase; -$Data::ClanLeaderGUID[$Data::ClanCount] = %client.GUID; -$Data::ClanMember[$Data::ClanCount, 0] = %client.GUID; -$Data::ClanID[%client.GUID] = $Data::ClanCount; -$Data::ClanCount++; -setName(%client,"\cp\c7" @ %client.clanT @ "\c6" @ %client.namebase @ "\co"); -saveGame(); -forceScoreScreenOpen(%client,"CLNMG"); -} - -%client.PDAPage = "MAIN"; - -case "CLNMG": -messageClient( %client, 'SetScoreHudHeader', "", 'Clan ManagementClose'); -messageClient( %client, 'SetScoreHudSubheader', "", "Showing clan management."); -%index = 0; - -if (!$Data::IsInClan[%client.GUID]) -{ -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'You are not in a clan. Try creating a [New Clan].'); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Or view the [List] of clans.'); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Back To Main Menu"); -} -else -{ -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Clan Name: %1',$Data::ClanName[$Data::ClanID[%client.GUID]]); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Clan Tag: %1', $Data::ClanTag[$Data::ClanID[%client.GUID]]); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Short Description: %1',%client.description); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, ''); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, '[View] member list.'); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, '[View] other clans.'); -if ($Data::IsInClan[%client.GUID] && $Data::ClanLeaderGUID[$Data::ClanID[%client.GUID]] == %client.GUID) -{ -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, '[Edit] Clan.'); -} -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Back To Main Menu"); -} - -%client.PDAPage = "CLNMG"; - -case "CLNMBR": -%client.PDAPage = "CLNMBR"; - -messageClient( %client, 'SetScoreHudHeader', "", 'Clan ManagementClose'); -messageClient( %client, 'SetScoreHudSubheader', "", "Showing member list."); -%index = 0; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Name: %1',%client.namebase); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Back To Previous Page'); -%index++; - - -case "SLFSTS": //Self Statistics -messageClient( %client, 'SetScoreHudHeader', "", 'Self StatisticsClose'); -messageClient( %client, 'SetScoreHudSubheader', "", "Showing your stats."); -%index = 0; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Name: %1',%client.namebase); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Race: %1',%client.race); -%index++; - -if (%client.money $= "") -%client.money = 0; //You got zilch. - -%trans = %client.player.getTransform(); -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Cash: $%1',%client.money); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'GPS Coordinates: %1 %2 %3',getWord(%trans,0),getWord(%trans,1),getWord(%trans,2)); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, ''); -%index++; - -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Refresh'); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Back To Main Menu"); -%client.PDAPage = "SLFSTS"; - -case "INVENTORY": //View Inventory -messageClient( %client, 'SetScoreHudHeader', "", 'Show InventoryClose'); -messageClient( %client, 'SetScoreHudSubheader', "", "Showing your inventory."); -%index = 0; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Minerals--'); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Steel: %1 units.', %client.units["Steel"]); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Back To Main Menu"); -%client.PDAPage = "INVENTORY"; - -case "DEATH": -if (isObject(%client.player) && %client.player.getState() $= "Move") -return; - -messageClient( %client, 'SetScoreHudHeader', "", 'Death'); -messageClient( %client, 'SetScoreHudSubheader', "", "You have died."); - -messageClient( %client, 'SetLineHud', "", 'scoreScreen', 0, "Respawn"); -%client.PDAPage = "DEATH"; - -case "DELETE": -messageClient( %client, 'SetScoreHudHeader', "", 'Electronic MailClose'); -messageClient( %client, 'SetScoreHudSubheader', "", "E-Mail deleted."); -messageClient( %client, 'SetLineHud', "", 'scoreScreen', 0, 'Back to Listing'); -$Data::EMail::Title[%client.GUID,%client.email] = ""; - -case "SAVE": -saveGame(); -closeScoreScreen(%client); -messageClient(%client,'msgSaveSuccess',"\c3Game successfully saved."); - -case "RESPAWN": -if (isObject(%client.player) && %client.player.getState() $= "Move") -return; - -%client.PDAPage = "MAIN"; -forceClientSpawn(%client); - -case "SLFSTS": //Self Statistics -messageClient( %client, 'SetScoreHudHeader', "", 'Self StatisticsClose'); -messageClient( %client, 'SetScoreHudSubheader', "", "Showing your stats."); -%index = 0; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Name: %1',%client.namebase); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Race: %1',%client.race); -%index++; - -if (%client.race $= "Draakan") -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Type: %1',%client.sex); -else -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Sex: %1',%client.sex); -%index++; - -if (%client.money $= "") -%client.money = 0; //You got zilch. - -%trans = %client.player.getTransform(); -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Cash: $%1',%client.money); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'GPS Coordinates: %1 %2 %3',getWord(%trans,0),getWord(%trans,1),getWord(%trans,2)); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, ''); -%index++; - -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, 'Refresh'); -%index++; -messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Back To Main Menu"); -%client.PDAPage = "SLFSTS"; - -default: //If something fails, return to the main menu. -serverCmdProcessGameLink(%client,"BACK"); -} -} - -function checkEmails(%guid,%title) -{ - for (%i = 0; %i < $Data::EMail::Count[%GUID]; %i++) - { - if ($Data::EMail::Title[%guid,%i] $= %title) - return true; - } -return false; -} - -function plnametocid(%name) -{ - %count = ClientGroup.getCount(); //counts total clients - for(%i = 0; %i < %count; %i++) //loops till all clients are accounted for - { - %obj = ClientGroup.getObject(%i); //gets the clientid based on the ordering hes in on the list - %nametest=%obj.namebase; //pointless step but i didnt feel like removing it.... - %nametest=strlwr(%nametest); //make name lowercase - %name=strlwr(%name); //same as above, for the other name - if(strstr(%nametest,%name) != -1) //is all of name test used in name - return %obj; //if so return the clientid and stop the function - } - return 0; //if none fits return 0 and end function -} - - -function RPGGame::onEnterTrigger(%game, %name, %data, %obj, %colObj) -{ -switch$(%obj.type) -{ - case "Transport": if (%obj.targetTransform $= "") return; - %Colobj.setTransform(%obj.targetTransform); - if (%Colobj.Usewhiteout) %Obj.setWhiteout(0.8); - case "Territory": if (%obj.race $= "") return; - %obj.client.isOnTerritory[%Colobj.race] = true; - setClientTeam(%Colobj.client,getRaceTeam(%Obj.race)); - if (%obj.location $= "") - { - messageClient(%Colobj.client,'MsgSPCurrentObjective1',"",'Location: %1.', %obj.race SPC "Territory"); - messageClient(%colObj.client,'msgEnteredRaceTerritory','\c3You have entered %1 territory.',%obj.race); - } - else - { - messageClient(%colObj.client,'msgEnteredRaceTerritory','\c3You have entered %1.',%obj.location); - messageClient(%Colobj.client,'MsgSPCurrentObjective1',"",'Location: %1.', %obj.location); - } - case "Damage": //Will add lots o' vars onto it.. - %obj.damage[%colobj] = true; - %colObj.isinLava = true; - - -} -if (%Colobj.message $= "" && %Colobj.type !$= "Territory") -messageClient(%Colobj.client,'MsgTrigger',%obj.message); -} - -function RPGGame::onLeaveTrigger(%game, %name, %data, %obj, %colObj) -{ - switch$(%obj.type) - { - case "Territory": if (%obj.race $= "") return; - - if (%obj.location $= "") - messageClient(%Colobj.client,'MsgExitedRaceTerritory',"\c3You have exited "@%obj.race@" territory. Your sensor data is now undetectable."); - else - messageClient(%Colobj.client,'MsgExitedRaceTerritory',"\c3You have exited "@%obj.location@"."); - %Colobj.client.isOnTerritory[%obj.race] = false; - messageClient(%colObj.client,'MsgSPCurrentObjective1',"",'Location: Unknown.'); - setClientTeam(%Colobj.client,0); //Not on the sensor, I think - case "Damage": - %obj.damage[%obj] = false; - %colObj.isInLava = true; - } -} - -function RPGGame::onTickTrigger(%game, %name, %data, %obj) -{ - switch(%obj.type) - { - case "Damage": - for (%i = 0; %i < MissionCleanup.getCount(); %i++) - { - %objT = MissionCleanup.getObject(%i); - if (%objt.getClassName() $= "Player" && %objt.getState() $= "move") - { - if (%obj.damage[%objT] && %objT.isInLava) - %objT.damage(0, %objT.getPosition(), %obj.damage, %obj,damageType); - } - } - } -} - -function serverCmdShowHud(%client, %tag) -{ - - %tagName = getWord(%tag, 1); - %tag = getWord(%tag, 0); - - if (%tag $= 'scoreScreen') - serverCmdProcessGameLink(%client,%client.PDAPage); - - messageClient(%client, 'OpenHud', "", %tag); - switch$ (%tagname) - { - case "vehicleHud": - vehicleHud::updateHud(1,%client,%tag); - case "scoreScreen": - updateScoreHudThread(%client, %tag); - - } -} - +// DisplayName = Birth of Legend + +//--- GAME RULES BEGIN --- +// There are none, the gameMode conforms itself towards what you do. +//--- GAME RULES END --- + +// Notes: +// In Role Playing, you select your race (at the warrior pane), join an RPG server and your +// character is setup (specifically to that server). From there, you can start clans, build +// bases, and war with each other. Basically, it's a freeMode sort of thing. + +//exec the AI scripts +exec("scripts/aiRPG.cs"); + +// exec a bunch of dependencies +exec("scripts/modScripts/server/RPG/initialise.cs"); + +$InvBanList[RPG, "C4Charge"] = 1; + +//-- tracking --- +function RPGGame::initGameVars(%game) +{ + //%game. = ""; //I guess I'll eventually set some, but most are loaded via BASIC files +} + +package RPGGame +{ + function notifyMatchStart(%time){} + function notifyMatchEnd(%time){} + + // FIXME: I have no idea where to find this serverCmd so here's quick hack + function serverCmdResetControlObject(%client) + { + parent::serverCmdResetControlObject(%client); + if ($CurrentMissionType $= "RPG" && isObject(%client.player) && %client.player.getState() $= "move") + %client.setControlObject(%client.player); + } +}; +function RPGGame::timeLimitReached(%game){} +function RPGGame::scoreLimitReached(%game){} +function RPGGame::gameOver(%game){} +function RPGGame::checkTimeLimit(%game, %forced){} +function RPGGame::leaveMissionArea(%game, %playerData, %player){} +function RPGGame::enterMissionArea(%game, %playerData, %player){} + +function RPGGame::setUpTeams(%game) +{ + defaultGame::setUpTeams(%game); + %game.numTeams = 1; + setSensorGroupCount(4); + $TeamDamage = true; //Allow team Damage +} + +function RPGGame::getTeamSkin(%game, %team) +{ + if($host::tournamentMode) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + { + return $teamSkin[%team]; + } + + else + { + //error("CTFGame::getTeamSkin"); + if(!$host::useCustomSkins) + { + %terrain = MissionGroup.musicTrack; + //error("Terrain type is: " SPC %terrain); + switch$(%terrain) + { + case "lush": + if(%team == 1) + %skin = 'beagle'; + else if(%team == 2) + %skin = 'dsword'; + else %skin = 'base'; + + case "badlands": + if(%team == 1) + %skin = 'swolf'; + else if(%team == 2) + %skin = 'dsword'; + else %skin = 'base'; + + case "ice": + if(%team == 1) + %skin = 'swolf'; + else if(%team == 2) + %skin = 'beagle'; + else %skin = 'base'; + + case "desert": + if(%team == 1) + %skin = 'cotp'; + else if(%team == 2) + %skin = 'beagle'; + else %skin = 'base'; + + case "Volcanic": + if(%team == 1) + %skin = 'dsword'; + else if(%team == 2) + %skin = 'cotp'; + else %skin = 'base'; + + default: + if(%team == 2) + %skin = 'baseb'; + else %skin = 'base'; + } + } + else %skin = $teamSkin[%team]; + + //error("%skin = " SPC getTaggedString(%skin)); + return %skin; +} +} + +function RPGGame::getTeamName(%game, %team) +{ + // --------------------------------------------------- + // z0dd - ZOD 3/30/02. Only display default team names + //if ( isDemo() || $host::tournamentMode) + return $TeamName[%team]; + // --------------------------------------------------- +} + +//-------------------------------------------------------------------------- +function RPGGame::missionLoadDone(%game) +{ + //default version sets up teams - must be called first... + DefaultGame::missionLoadDone(%game); +} + +function RPGGame::showStalemateTargets(%game) +{ + cancel(%game.stalemateSchedule); + + //show the targets + for (%i = 1; %i <= 2; %i++) + { + %flag = $TeamFlag[%i]; + + //find the object to scope/waypoint.... + //render the target hud icon for slot 1 (a centermass flag) + //if we just set him as always sensor vis, it'll work fine. + if (isObject(%flag.carrier)) + setTargetAlwaysVisMask(%flag.carrier.getTarget(), 0x7); + } + //schedule the targets to hide + %game.stalemateObjsVisible = true; + %game.stalemateSchedule = %game.schedule(%game.stalemateDurationMS, hideStalemateTargets); +} + +function RPGGame::onClientDamaged(%game, %clVictim, %clAttacker, %damageType, %implement, %damageLoc) +{ + if(%clVictim.headshot && %damageType == $DamageType::Laser && %clVictim.team != %clAttacker.team) + { + %clAttacker.scoreHeadshot++; + if (%game.SCORE_PER_HEADSHOT != 0) + { + messageClient(%clAttacker, 'msgHeadshot', '\c0You received a %1 point bonus for a successful headshot.', %game.SCORE_PER_HEADSHOT); + messageTeamExcept(%clAttacker, 'msgHeadshot', '\c5%1 hit a sniper rifle headshot.', %clAttacker.name); // z0dd - ZOD, 8/15/02. Tell team + } + %game.recalcScore(%clAttacker); + } + + // ----------------------------------------------- + // z0dd - ZOD, 8/25/02. Rear Lance hits + if(%clVictim.rearshot && %damageType == $DamageType::ShockLance && %clVictim.team != %clAttacker.team) + { + %clAttacker.scoreRearshot++; + if (%game.SCORE_PER_REARSHOT != 0) + { + messageClient(%clAttacker, 'msgRearshot', '\c0You received a %1 point bonus for a successful rearshot.', %game.SCORE_PER_REARSHOT); + messageTeamExcept(%clAttacker, 'msgRearshot', '\c5%1 hit a shocklance rearshot.', %clAttacker.name); + } + %game.recalcScore(%clAttacker); + } + // ----------------------------------------------- + + //the DefaultGame will set some vars + DefaultGame::onClientDamaged(%game, %clVictim, %clAttacker, %damageType, %implement, %damageLoc); + + //if victim is carrying a flag and is not on the attackers team, mark the attacker as a threat for x seconds(for scoring purposes) + if ((%clVictim.holdingFlag !$= "") && (%clVictim.team != %clAttacker.team)) + { + %clAttacker.dmgdFlagCarrier = true; + cancel(%clAttacker.threatTimer); //restart timer + %clAttacker.threatTimer = schedule(%game.TIME_CONSIDERED_FLAGCARRIER_THREAT, %clAttacker.dmgdFlagCarrier = false); + } +} + +//////////////////////////////////////////////////////////////////////////////////////// +function RPGGame::clientMissionDropReady(%game, %client) +{ + messageClient(%client, 'MsgClientReady',"", "SinglePlayerGame"); //Force the SP game objective hud to setup + %game.resetScore(%client); + + messageClient(%client, 'MsgMissionDropInfo', '\c0You are in mission %1 (%2).', $MissionDisplayName, $MissionTypeDisplayName, $ServerName ); + + DefaultGame::clientMissionDropReady(%game, %client); + + //Force client Spawn since we're ready now + %client.schedule(100,"spawn"); + //%client.setControlObject(%client.player); + commandToClient(%client,'bottomPrint',"Try not to die.",3); + + // FIXME: Always assigns radio access for now + %client.hasRadio = 1; + %client.radioFrequency = 1; + + // Since this is an RPG gamemode, be sure some things are correct. (May have been a mission switch from CTF or some other gamemode) + commandToClient(%client,'SetScoreText',"PDA - Personal Data Assistant"); + //Make sure the data hud is working. + messageClient(%client,'MsgSPCurrentObjective1',"",'Location: Unknown.'); + messageClient(%client,'MsgSPCurrentObjective2',"",'Money: $%1.',%client.money); +} + +function RPGGame::assignClientTeam(%game, %client, %respawn) +{ + DefaultGame::assignClientTeam(%game, %client, %respawn); + // if player's team is not on top of objective hud, switch lines + messageClient(%client, 'MsgCheckTeamLines', "", %client.team); +} + +function RPGGame::applyConcussion(%game, %player) +{ +} + +function RPGGame::vehicleDestroyed(%game, %vehicle, %destroyer) +{ +} + +function RPGGame::onClientKilled(%game, %clVictim, %clKiller, %damageType, %implement, %damageLocation) +{ + defaultGame::onClientKilled(%game, %clVictim, %clKiller, %damageType, %implement, %damageLocation); + commandToClient(%clVictim,'HandleScriptedCommand',2); + //No, play this epic audio: + schedule(2000,0,"messageClient",%clVictim,'MsgDeath',"~wfx/Lose.wav"); + forceScoreScreenOpen(%clVictim,"DEATH"); + $Data::ShouldApply[%clVictim.GUID] = false; + + if (%clVictim.isAIControlled()) + %clVictim.drop(); +} + +function RPGGame::createPlayer(%game, %client, %spawnLoc, %respawn) +{ + DefaultGame::createPlayer(%game, %client, %spawnLoc, %respawn); + %client.observerMode = ""; + commandToClient(%client, 'setHudMode', 'Standard'); + %client.setControlObject(%client.player); +} + +function RPGGame::startMatch(%game) +{ + echo("START MATCH"); + //the match has been started, clear the team rank array, and repopulate it... + for (%i = 0; %i < 32; %i++) + %game.clearTeamRankArray(%i); + + //used in BountyGame, prolly in a few others as well... + $matchStarted = true; + + %game.clearDeployableMaxes(); + + $missionStartTime = getSimTime(); + %curTimeLeftMS = ($Host::TimeLimit * 60 * 1000); + + // schedule first timeLimit check for 20 seconds + if(%game.class !$= "SiegeGame") + { + %game.timeCheck = %game.schedule(20000, "checkTimeLimit"); + } + + //schedule the end of match countdown + EndCountdown($Host::TimeLimit * 60 * 1000); + + //reset everyone's score and add them to the team rank array + for (%i = 0; %i < ClientGroup.getCount(); %i++) + { + %cl = ClientGroup.getObject(%i); + %game.resetScore(%cl); + %game.populateTeamRankArray(%cl); + } + + // set all clients control to their player + %count = ClientGroup.getCount(); + for( %i = 0; %i < %count; %i++ ) + { + %cl = ClientGroup.getObject(%i); + + // Siege game will set the clock differently + if(%game.class !$= "SiegeGame") + messageClient(%cl, 'MsgSystemClock', "", $Host::TimeLimit, %curTimeLeftMS); + + if( !$Host::TournamentMode && %cl.matchStartReady && %cl.camera.mode $= "pre-game") + { + commandToClient(%cl, 'setHudMode', 'Standard'); + %cl.setControlObject( %cl.player ); + } + else + { + if( %cl.matchStartReady ) + { + if(%cl.camera.mode $= "pre-game") + { + %cl.observerMode = ""; + commandToClient(%cl, 'setHudMode', 'Standard'); + + if(isObject(%cl.player)) + %cl.setControlObject( %cl.player ); + else + echo("can't set control for client: " @ %cl @ ", no player object found!"); + } + else + %cl.observerMode = "observerFly"; + } + } + } + + // on with the show this is it! + AISystemEnabled( true ); +} \ No newline at end of file diff --git a/scripts/SVGame.cs b/scripts/SVGame.cs index c3c1a8a..7e18ef3 100644 --- a/scripts/SVGame.cs +++ b/scripts/SVGame.cs @@ -1,748 +1,748 @@ -// -------------------------------------------------------- -// Survival Mission Type -// -------------------------------------------------------- - -// DisplayName = Survival - -//--- GAME RULES BEGIN --- -//Survive as many waves of enemies as possible. -//The bot count increments by one each round. -//If progressive mode is enabled, bots are spawned every thirty seconds. -//--- GAME RULES END --- - -$InvBanList[SV, "MiningTool"] = 1; - -exec("scripts/aiSurvival.cs"); - -package SVGame -{ - function UpdateClientTimes(%time) //Used for initial countdown if needed - { - %secondsLeft = %time / 1000; - messageAll('MsgSystemClock', "", (%secondsLeft / 60), %time); - return true; - } - - function notifyMatchEnd(%time){ return true; } //Survival has NO end - - - function Disconnect() //Package this function so we can disable the schedules on disconnect - { - parent::Disconnect(); - - cancel(Game.helper); - cancel(Game.roundStart); - cancel(Game.roundMessage[0]); - cancel(Game.roundMessage[1]); - cancel(Game.roundMessage[2]); - cancel(Game.roundMessage[3]); - cancel(Game.roundMessage[4]); - cancel(Game.roundMessage[5]); - cancel(Game.BotWave); - return true; - } -}; - -function SVGame::initGameVars(%game) -{ - %game.SCORE_PER_KILL = 1; - %game.SCORE_PER_DEATH = -1; - %game.SCORE_PER_SUICIDE = -1; - - //SV Vars - %game.rounds = 1; - %game.playerCount = 0; - %game.botCount = 0; - %game.shouldSpawn = 0; - %game.start = 0; - %game.AIWon = 0; - - %prefs = new ScriptObject(){ class = "BasicDataParser"; }; - %prefs.load("prefs/Survival.conf"); - %config = %prefs.get("Config",0); - %area = %prefs.get("MissionArea",0); - - // Load configuration - %game.maxBots = %config.element("MaxBots"); - %game.difficultyIncrement = %config.element("difficultyIncrement"); - %game.fastDifficultyIncrement = %config.element("fastDifficultyIncrement"); - %game.startDifficulty = %config.element("startDifficulty"); - %game.enableGodbot = %config.element("enableGodbot"); - %game.godBotFrequency = %config.element("godBotFrequency"); - %game.hintsEnabled = %config.element("hintsEnabled"); - %game.hintTimeMS = %config.element("hintTimeMS"); - %game.allowSetup = %config.element("allowSetup"); - %game.setupTimeMS = %config.element("setupTimeMS"); - - %prefs.empty(); - %prefs.delete(); - %area.empty(); - %area.delete(); - return true; -} - -function SVGame::missionLoadDone(%game) -{ - //default version sets up teams - must be called first... - DefaultGame::missionLoadDone(%game); - - //Ok.. for some odd reason the AI grenade Set isn't created for this gamemode. - //Without it, the bots don't function very well at all. - //Make sure it exists when the game starts - if (!IsObject($AIGrenadeSet)) - AIObjectives.add($AIGrenadeSet = new Simgroup(AIGrenadeSet)); - //Remove console spam.. - if (!IsObject($AIRemoteTurretSet)) - AIObjectives.add($AIRemoteTurretSet = new Simgroup(AIRemoteTurretSet)); - if (!IsObject($ObjectiveQ[2])) - $ObjectiveQ[2] = new simSet(); - return true; -} - -function SVGame::setUpTeams(%game) -{ - DefaultGame::setUpTeams(%game); - %game.numTeams = 1; //Players cannot switch teams - setSensorGroupCount(3); //Team 0, 1, and 2 - return true; -} - -function SVGame::RoundStart(%game) -{ - if (%game.playerCount <= 0) - { - messageAll('MsgAll',"\c2The round cannot start untill someone spawns! ~wfx/misc/misc.error.wav"); - Game.shouldSpawn = 1; //Tell the game to start a 10 sec countdown now - return; - } - - %game.start = 1; - %game.AIWon = 0; - messageAll('MsgSystemClock',"\c2The round has started! ~wfx/misc/red_alert.wav",1,120000); //Start "Player Help" countdown - Game.lockDeadClients(); - Game.spawnAI(); - Game.helper = Game.schedule(120000,"PlayerHelp"); - //Ok.. bots spawn every 30 secs - if ($Host::ProgressiveMode) - Game.BotWave = Game.schedule(180000,"SpawnAI",true); - return true; -} - -function SVGame::checkTimeLimit(%game, %forced){} - -function SVGame::freeDeadClients(%game) -{ - for (%i = 0; %i < ClientGroup.getCount(); %i++) - { - %cl = ClientGroup.getObject(%i); - %cl.isDead = false; - %cl.kills = 0; //Since this is called every round, might as well reset the kill count for this round - } - return true; -} - -function SVGame::lockDeadClients(%game) -{ - for (%i = 0; %i < ClientGroup.getCount(); %i++) - { - %cl = ClientGroup.getObject(%i); - %cl.isDead = true; //Doesn't matter if the dude is alive -- when he dies the flag is set. - } - return true; -} - -function SVGame::startMatch(%game) -{ - DefaultGame::startMatch(%game); - - if (!$Host::ProgressiveMode) - messageAll('MsgSystemClock',"\c2The first round will start in one minute.",1,60000); - else - messageAll('MsgSystemClock',"\c2The attack will start in one minute!",1,60000); - - Game.roundMessage[0] = schedule(50000,0,"messageAll",'msgAll',"\c2Round starts in ten seconds.~wfx/misc/hunters_10.wav"); - Game.roundMessage[1] = schedule(55000,0,"messageAll",'msgAll',"\c2Round starts in five seconds.~wfx/misc/hunters_5.wav"); - Game.roundMessage[2] = schedule(56000,0,"messageAll",'msgAll',"\c2Round starts in four seconds.~wfx/misc/hunters_4.wav"); - Game.roundMessage[3] = schedule(57000,0,"messageAll",'msgAll',"\c2Round starts in three seconds.~wfx/misc/hunters_3.wav"); - Game.roundMessage[4] = schedule(58000,0,"messageAll",'msgAll',"\c2Round starts in two seconds.~wfx/misc/hunters_2.wav"); - Game.roundMessage[5] = schedule(59000,0,"messageAll",'msgAll',"\c2Round starts in one second.~wfx/misc/hunters_1.wav"); - Game.roundStart = Game.schedule(60000,"RoundStart"); - Game.freeDeadClients(); - return true; -} - -function SVGame::checkRounds(%game) -{ - if (%game.start) - return false; - - for (%i = 0; %i < ClientGroup.getCount(); %i++) - { - %cl = ClientGroup.getObject(%i); - if (IsObject(%cl.player) && %cl.player.getState() $= "move") - { - %cl.streak++; - if(%cl.streak > $Data::Rounds[%cl.GUID,$MissionName]) - { - messageClient(%cl,'MsgClient','\c2Congratulations, you broke your old Round record of %1!',%cl.streak--); - $Data::Rounds[%cl.GUID,$MissionName]++; - } - } - } - return true; -} - -function SVGame::onClientKilled(%game, %clVictim, %clKiller, %damageType, %implement, %damageLoc) -{ - cancel(%clVictim.player.alertThread); - DefaultGame::onClientKilled(%game, %clVictim, %clKiller, %damageType, %implement, %damageLoc); - - if (IsObject(%clVictim) && !%clVictim.isAIControlled()) - { - %game.playerCount--; //May be someone switching to observer - if (%game.start) - %clVictim.isDead = true; - %clVictim.streak = 0; //Moved from SVGame::CheckRounds to fix .streak being reset for some reason - } - - if (%game.playerCount <= 0 && %game.start) - { - messageAll('MsgSystemClock',"\c2Round "@%game.rounds@" belongs to the Artificial Intelligance! The game will now restart back at round 1. ~wfx/misc/flag_return.wav",1,60000); - %game.rounds = 1; - %game.start = 0; - %game.AIWon = 1; //Tell the game the b0ts won, or else when they disconnect, it'll be counted as a player win - cancel(Game.helper); - messageAll('MsgSPCurrentObjective1',"",'Current round: 1'); - Game.roundMessage[0] = schedule(50000,0,"messageAll",'msgAll',"\c2Round starts in ten seconds.~wfx/misc/hunters_10.wav"); - Game.roundMessage[1] = schedule(55000,0,"messageAll",'msgAll',"\c2Round starts in five seconds.~wfx/misc/hunters_5.wav"); - Game.roundMessage[2] = schedule(56000,0,"messageAll",'msgAll',"\c2Round starts in four seconds.~wfx/misc/hunters_4.wav"); - Game.roundMessage[3] = schedule(57000,0,"messageAll",'msgAll',"\c2Round starts in three seconds.~wfx/misc/hunters_3.wav"); - Game.roundMessage[4] = schedule(58000,0,"messageAll",'msgAll',"\c2Round starts in two seconds.~wfx/misc/hunters_2.wav"); - Game.roundMessage[5] = schedule(59000,0,"messageAll",'msgAll',"\c2Round starts in one second.~wfx/misc/hunters_1.wav"); - Game.roundStart = Game.schedule(60000,"RoundStart"); - //disconnectAllBots(); - Game.freeDeadClients(); - - %bots = Array.create(); - %count = HiddenClientGroup.getCount(); - for (%i = 0; %i < %count; %i++) - { - %cl = HiddenClientGroup.getObject(%i); - if (%cl.isAIControlled()) - %bots.setElement(%i, %cl); - } - - - // For the lulz - %damageCount = 8; - %damageType[0] = $DamageType::Suicide; - %damageType[1] = $DamageType::Lava; - %damageType[2] = $DamageType::Ground; - %damageType[3] = $DamageType::Impact; - %damageType[4] = $DamageType::OutOfBounds; - %damageType[5] = $DamageType::ForceFieldPowerup; - %damageType[6] = $DamageType::Lightning; - %damageType[7] = $DamageType::NexusCamping; - - // Now to kill them - for (%i = 0; %i < %count; %i++) - { - %bot = %bots.element(%i); - %death = getRandom(0,2); - if (%death == 0) // Explode - { - %bot.player.blowup(); - %bot.player.schedule(100,"setPosition","0 0 -99999"); - %bot.player.schedule(110,"scriptKill",%damageType[getRandom(0,%damageCount)]); - } - else if (%death == 1) // Fade - { - %bot.player.setCloaked(true); - %bot.player.schedule(100,"setPosition","0 0 -99999"); - %bot.player.schedule(110,"scriptKill",%damageType[getRandom(0,%damageCount)]); - } - else - %bot.player.scriptKill(%damageType[getRandom(0,%damageCount)]); - } - %bots.delete(); - - Game.botCount = 0; - } - return true; -} - -function SVGame::spawnPlayer( %game, %client, %respawn ) -{ - if (%client.isDead) - return commandToClient(%client, 'CenterPrint', "You will respawn next round.",2); - else if (!%client.isAIControlled()) - { - %client.team = 1; - DefaultGame::spawnPlayer(%game, %client, %respawn); - Game.playerCount++; - commandToClient(%client,'bottomPrint',"Try not to die.",3); - if (%game.shouldSpawn) - { - %game.shouldSpawn = 0; - messageAll('MsgSystemClock',"\c2Round starts in ten seconds.~wfx/misc/hunters_10.wav",1,10000); - Game.roundMessage[0] = schedule(5000,0,"messageAll",'msgAll',"\c2Round starts in five seconds.~wfx/misc/hunters_5.wav"); - Game.roundMessage[1] = schedule(6000,0,"messageAll",'msgAll',"\c2Round starts in four seconds.~wfx/misc/hunters_4.wav"); - Game.roundMessage[2] = schedule(7000,0,"messageAll",'msgAll',"\c2Round starts in three seconds.~wfx/misc/hunters_3.wav"); - Game.roundMessage[3] = schedule(8000,0,"messageAll",'msgAll',"\c2Round starts in two seconds.~wfx/misc/hunters_2.wav"); - Game.roundMessage[4] = schedule(9000,0,"messageAll",'msgAll',"\c2Round starts in one second.~wfx/misc/hunters_1.wav"); - Game.roundStart = Game.schedule(10000,"RoundStart"); - } - } - return true; -} - -function SVGame::onAIKilled(%game, %clVictim, %clAttacker, %damageType, %implement) -{ - DefaultGame::onAIKilled(%game, %clVictim, %clAttacker, %damageType, %implement); - - if (IsObject(%clVictim) && %clVictim.isAIControlled()) - { - if (%game.botCount != 0) - %game.botCount--; - messageAll('MsgSPCurrentObjective2',"",'Number of bots: %1',Game.botCount); - HiddenClientGroup.remove(%clVictim); - %clVictim.drop(); - } - - if (%game.botCount <= 0 && !$Host::ProgressiveMode && !%game.AIWon) //There are no rounds.. - { - messageAll('MsgSystemClock',"\c2Round "@%game.rounds@" belongs to the players! They have thirty seconds to get ready. ~wfx/misc/flag_return.wav",1,30000); - %game.rounds++; - %game.start = 0; - cancel(Game.helper); - messageAll('MsgSPCurrentObjective1',"",'Current Round: %1',Game.rounds); - Game.roundMessage[0] = schedule(20000,0,"messageAll",'msgAll',"\c2Round starts in ten seconds.~wfx/misc/hunters_10.wav"); - Game.roundMessage[1] = schedule(25000,0,"messageAll",'msgAll',"\c2Round starts in five seconds.~wfx/misc/hunters_5.wav"); - Game.roundMessage[2] = schedule(26000,0,"messageAll",'msgAll',"\c2Round starts in four seconds.~wfx/misc/hunters_4.wav"); - Game.roundMessage[3] = schedule(27000,0,"messageAll",'msgAll',"\c2Round starts in three seconds.~wfx/misc/hunters_3.wav"); - Game.roundMessage[4] = schedule(28000,0,"messageAll",'msgAll',"\c2Round starts in two seconds.~wfx/misc/hunters_2.wav"); - Game.roundMessage[5] = schedule(29000,0,"messageAll",'msgAll',"\c2Round starts in one second.~wfx/misc/hunters_1.wav"); - - //Award a client's ROUNDs if he beat his old round record - Game.checkRounds(); - //Allow dead peeps to rejoin - Game.freeDeadClients(); - Game.roundStart = Game.schedule(30000,"RoundStart"); - } - return true; -} - -function SVGame::PlayerHelp(%game) //Is called after 2 minutes in each round; tells where the b0ts are -{ - if (%game.start) - { - messageAll('MsgSystemClock',"\c2Good hunting! ~wvoice/Training/Any/ANY.hunting.wav",1,120000); - for (%i = 0; %i < HiddenClientGroup.getcount(); %i++) - { - %cl = HiddenClientGroup.getObject(%i); - if (%cl.isAIControlled() && %cl.team == 2) - { - %wp = new Waypoint() - { - Datablock = "WayPointMarker"; - Position = %cl.player.getPosition(); - Name = %cl.namebase; - Team = 2; - }; - %wp.schedule(3000,"Delete"); - } - } - Game.helper = Game.schedule(120000,"PlayerHelp"); - } -} - -function SVGame::SpawnAI(%game,%val) -{ - if (%val && !$Host::ProgressiveMode) - return; - - if (Game.rounds == 90) - { - messageAll('msgAll',"\c3The Godbot is here! ~wfx/misc/red_alert.wav"); - for (%i = 0; %i < 6; %i++) - { - %bot = aiConnectByName("Godbot",2); - %bot.setSkillLevel(1); - %bot.player.clearInventory(); - %bot.player.setArmor("TR2Heavy"); - %bot.player.setInventory("TR2EnergyPack",1,true); - %bot.player.setInventory("Disc",1,true); - %bot.player.setInventory("DiscAmmo",900,true); - // %bot.player.setInventory("Chaingun",1,true); - //%bot.player.setInventory("ChaingunAmmo",999,true); - %bot.player.setInventory("GrenadeLauncher",1,true); - %bot.player.setInventory("GrenadeLauncherAmmo",999,true); - %bot.player.setInventory("Shocklance",1,true); - %bot.player.setInventory("Mortar",1,true); - %bot.player.setInventory("MortarAmmo",999,true); - %bot.player.use("Disc"); - %game.botCount = 5; - hideClient(%bot); - } - return; - } - %playerCount = clientGroup.getCount() - 1; - - for (%i = 0; %i < 2 + Game.rounds+1; %i++) - { - %bot = aiConnectByIndex(getRandom(0,$BotProfile::Count),2); //Choose random b0ts by Index - //Alright -- this'll make the game a bit harder -- depending on the rounds, the bots will have random armors. - %chance = getRandom(1,5 + Game.rounds); - %bot.player.clearInventory(); - - if (%chance > 6) //Medium Armor - { - %bot.player.setArmor("Medium"); - // %bot.player.setInventory("Chaingun",1,1); - //%bot.player.setInventory("ChaingunAmmo",500,1); - %bot.player.setInventory("GrenadeLauncher",1,1); - %bot.player.setInventory("GrenadeLauncherAmmo",999,1); - %bot.player.setInventory("Disc",1,1); - %bot.player.setInventory("DiscAmmo",30,1); - %bot.player.setInventory("Shoklance",1,1); - %bot.player.setInventory("MissileLauncher",1,1); - %bot.player.setInventory("MissileLauncherAmmo",50); - %bot.player.use("Chaingun"); - } - else if (%chance > 10) //JUGGY - { - %bot.player.setArmor("Heavy"); - %bot.player.setInventory("GrenadeLauncher",1,1); - %bot.player.setInventory("GrenadeLauncherAmmo",999,1); - // %bot.player.setInventory("Chaingun",1,1); - // %bot.player.setInventory("ChaingunAmmo",500,1); - %bot.player.setInventory("Disc",1,1); - %bot.player.setInventory("DiscAmmo",30,1); - %bot.player.setInventory("Shoklance",1,1); - %bot.player.use("Chaingun"); - } - else //Light - { - %bot.player.setArmor("Light"); - %bot.player.setInventory("GrenadeLauncher",1,1); - %bot.player.setInventory("GrenadeLauncherAmmo",999,1); - // %bot.player.setInventory("Chaingun",1,1); - // %bot.player.setInventory("ChaingunAmmo",500,1); - %bot.player.setInventory("Disc",1,1); - %bot.player.setInventory("DiscAmmo",30,1); - %bot.player.setInventory("Shoklance",1,1); - %bot.player.use("Chaingun"); - } - hideClient(%bot); - %random = getRandom(0,%playerCount); - // %client = clientGroup.getObject(%random); - // %bot.stepEscort(%client.player); - %bot.player.setInventory("AmmoPack",1,1); - setTeam(%bot,2); - %bot.setSkillLevel(99); - // %bot.stepEngage(clientGroup.getObject(%random)); - } - - if ($Host::ProgressiveMode && %val) - { - %game.rounds++; //So we increment every time -- I should put a limit to the bots.. - Game.BotWave = Game.schedule(180000,"SpawnAI",true); - } - -messageAll('MsgSPCurrentObjective2',"",'Number of bots: %1',Game.botCount); -} - -function SVGame::allowsProtectedStatics(%game) -{ - return true; -} - -function SVGame::equip(%game, %player) -{ - for(%i =0; %i<$InventoryHudCount; %i++) - %player.client.setInventoryHudItem($InventoryHudData[%i, itemDataName], 0, 1); - %player.client.clearBackpackIcon(); - - //%player.setArmor("Light"); - %player.setInventory(RepairKit, 1); - %player.setInventory("Disc", 1); - %player.setInventory("DiscAmmo", 15); - %player.setInventory("TargetingLaser", 1); - %player.weaponCount = 1; - - if (%player.client.race $= "Draakan") //Also defined in DefaultGame.cs, but this overrides it. - %player.setInventory(Flamer,1); - - // do we want to give players a disc launcher instead? GJL: Yes we do! - %player.use("Disc"); - - return true; -} - -function SVGame::pickPlayerSpawn(%game, %client, %respawn) -{ - // if the client is a bot and on team 2, use team 2 -- otherwise we're always team 1 - if (%client.isAIControlled() && %client.team == 2) - return %game.pickTeamSpawn(2); - else - return %game.pickTeamSpawn(1); - return false; -} - -function SVGame::clientJoinTeam( %game, %client, %team, %respawn ) -{ - %game.assignClientTeam( %client ); - - // Spawn the player: - %game.spawnPlayer( %client, %respawn ); - return true; -} - -function SVGame::assignClientTeam(%game, %client, %respawn) -{ - DefaultGame::assignClientTeam(%game, %client, %respawn); - // if player's team is not on top of objective hud, switch lines - messageClient(%client, 'MsgCheckTeamLines', "", %client.team); - return true; -} - -function SVGame::clientMissionDropReady(%game, %client) -{ - messageClient(%client, 'MsgClientReady',"", "SinglePlayerGame"); //Force the client to set up the SP game objective HUD - %game.resetScore(%client); - - //Setup the client's objective hud - messageClient(%client,'MsgSPCurrentObjective1',"",'Current round: 1'); - messageClient(%client,'MsgSPCurrentObjective2',"",'Number of bots: 0'); //Should update as soon as our player joins - - messageClient(%client, 'MsgMissionDropInfo', '\c0You are in mission %1 (%2).', $MissionDisplayName, $MissionTypeDisplayName, $ServerName ); - - DefaultGame::clientMissionDropReady(%game, %client); - return true; -} - -function SVGame::AIHasJoined(%game, %client) -{ - %game.botCount++; - return true; -} - -function SVGame::checkScoreLimit(%game, %client) -{ - //there's no score limit in DM -} - -function SVGame::createPlayer(%game, %client, %spawnLoc, %respawn) -{ - DefaultGame::createPlayer(%game, %client, %spawnLoc, %respawn); - %client.setSensorGroup(%client.team); - return true; -} - -function SVGame::resetScore(%game, %client) -{ - %client.deaths = 0; - %client.kills = 0; - %client.score = 0; - %client.efficiency = 0.0; - %client.suicides = 0; - return true; -} - -function SVGame::assignClientTeam(%game, %client, %respawn ) -{ - if (!%client.isDead) - DefaultGame::assignClientTeam(%game, %client, %respawn); - else - return true; - return false; -} - -function SVGame::updateKillScores(%game, %clVictim, %clKiller, %damageType, %implement) -{ - if (%game.testKill(%clVictim, %clKiller)) //verify victim was an enemy - { - %game.awardScoreKill(%clKiller); - messageClient(%clKiller, 'MsgDMKill', "", %clKiller.kills); - %game.awardScoreDeath(%clVictim); - } - else if (%game.testSuicide(%clVictim, %clKiller, %damageType)) //otherwise test for suicide - %game.awardScoreSuicide(%clVictim); - return true; -} - -function SVGame::recalcScore(%game, %client) -{ - %killValue = %client.kills * %game.SCORE_PER_KILL; - %deathValue = %client.deaths * %game.SCORE_PER_DEATH; - %suicideValue = %client.suicides * %game.SCORE_PER_SUICIDE; - - if (%killValue - %deathValue == 0) - %client.efficiency = %suicideValue; - else - %client.efficiency = ((%killValue * %killValue) / (%killValue - %deathValue)) + %suicideValue; - - %client.score = mFloatLength(%client.efficiency, 1); - messageClient(%client, 'MsgYourScoreIs', "", %client.score); - %game.recalcTeamRanks(%client); - %game.checkScoreLimit(%client); - return true; -} - -function SVGame::timeLimitReached(%game) -{ - logEcho("game over (timelimit)"); - %game.gameOver(); - cycleMissions(); - return true; -} - -function SVGame::scoreLimitReached(%game) -{ - logEcho("game over (scorelimit)"); - %game.gameOver(); - cycleMissions(); - return true; -} - -function SVGame::gameOver(%game) -{ - //call the default - DefaultGame::gameOver(%game); - Game.GameEnded = true; - - messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.gameover.wav" ); - - //cancel the schedules.. - cancel(Game.helper); - cancel(Game.roundStart); - cancel(Game.roundMessage[0]); - cancel(Game.roundMessage[1]); - cancel(Game.roundMessage[2]); - cancel(Game.roundMessage[3]); - cancel(Game.roundMessage[4]); - cancel(Game.roundMessage[5]); - cancel(Game.BotWave); - - cancel(%game.timeThread); - messageAll('MsgClearObjHud', ""); - for(%i = 0; %i < ClientGroup.getCount(); %i ++) - { - %client = ClientGroup.getObject(%i); - %game.resetScore(%client); - } - return true; -} - -function SVGame::enterMissionArea(%game, %playerData, %player) -{ - %player.client.outOfBounds = false; - messageClient(%player.client, 'EnterMissionArea', '\c1You are back in the mission area.'); - logEcho(%player.client.nameBase@" (pl "@%player@"/cl "@%player.client@") entered mission area"); - cancel(%player.alertThread); - return true; -} - -function SVGame::leaveMissionArea(%game, %playerData, %player) -{ - if(%player.getState() $= "Dead") - return false; - - %player.client.outOfBounds = true; - %player.setDamageFlash(0.3); - messageClient(%player.client, 'LeaveMissionArea', '\c1You have left the mission area. Return or die.~wfx/misc/warning_beep.wav'); - logEcho(%player.client.nameBase@" (pl "@%player@"/cl "@%player.client@") left mission area"); - %player.alertThread = %game.schedule(200, "DMAlertPlayer", 3, %player); - return true; -} - -function SVGame::DMAlertPlayer(%game, %count, %player) -{ - // MES - I commented below line out because it prints a blank line to chat window - //messageClient(%player.client, 'MsgDMLeftMisAreaWarn', '~wfx/misc/red_alert.wav'); - if(%count > 1) - %player.alertThread = %game.schedule(1000, "DMAlertPlayer", %count - 1, %player); - else - %player.alertThread = %game.schedule(1000, "MissionAreaDamage", %player); - return true; -} - -function SVGame::MissionAreaDamage(%game, %player) -{ - %player.setWhiteout(%player.getWhiteout()+0.027); - %player.alertThread = %game.schedule(100, "MissionAreaDamage", %player); - if (%player.getWhiteout() >= 1) - %player.schedule(400,"scriptKill",$DamageType::OutOfBounds); - return true; -} - -function SVGame::updateScoreHud(%game, %client, %tag) -{ - // Clear the header: - messageClient( %client, 'SetScoreHudHeader', "", "" ); - - if ($Data::Rounds[%client.GUID,$MissionName] $= "") - $Data::Rounds[%client.GUID,$MissionName] = 0; - - // Send the subheader: - messageClient(%client, 'SetScoreHudSubheader', "", '\tPLAYER\tRACE\tKILLS\tROUNDS'); - - for (%index = 0; %index < ClientGroup.getCount(); %index++) - { - //get the client info - %cl = ClientGroup.getObject(%index); - - //get the score - %clScore = mFloatLength( %cl.efficiency, 1 ); - - %clKills = mFloatLength( %cl.kills, 0 ); - %clDeaths = mFloatLength( %cl.deaths + %cl.suicides, 0 ); - %clStyle = %cl == %client ? "" : ""; - - //if the client is not an observer, send the message - if (%client.team != 0) - { - if (%client.race !$= "Draakan") //The type will make some difference someday.. lol - messageClient( %client, 'SetLineHud', "", %tag, %index, '%6\t%1%2%3%4', %cl.name, %cl.race, %clKills, $Data::Rounds[%client.GUID,$MissionName], %clDeaths, %clStyle ); - else - messageClient( %client, 'SetLineHud', "", %tag, %index, '%6\t%1%2 (%7)%3%4', %cl.name, %cl.race, %clKills, $Data::Rounds[%client.GUID,$MissionName], %clDeaths, %clStyle, %cl.sex ); - } - } - - // Tack on the list of observers: - %observerCount = 0; - for (%i = 0; %i < ClientGroup.getCount(); %i++) - { - %cl = ClientGroup.getObject(%i); - if (%cl.team == 0) - %observerCount++; - } - - if (%observerCount > 0) - { - messageClient( %client, 'SetLineHud', "", %tag, %index, ""); - %index++; - messageClient(%client, 'SetLineHud', "", %tag, %index, '\tOBSERVERS (%1)TIME', %observerCount); - %index++; - for (%i = 0; %i < ClientGroup.getCount(); %i++) - { - %cl = ClientGroup.getObject(%i); - //if this is an observer - if (%cl.team == 0) - { - %obsTime = getSimTime() - %cl.observerStartTime; - %obsTimeStr = %game.formatTime(%obsTime, false); - messageClient( %client, 'SetLineHud', "", %tag, %index, '\t%1%2', - %cl.name, %obsTimeStr ); - %index++; - } - } - } - - //clear the rest of Hud so we don't get old lines hanging around... - messageClient( %client, 'ClearHud', "", %tag, %index ); -} - -function SVGame::applyConcussion(%game, %player) -{ +// -------------------------------------------------------- +// Survival Mission Type +// -------------------------------------------------------- + +// DisplayName = Survival + +//--- GAME RULES BEGIN --- +//Survive as many waves of enemies as possible. +//The bot count increments by one each round. +//If progressive mode is enabled, bots are spawned every thirty seconds. +//--- GAME RULES END --- + +$InvBanList[SV, "MiningTool"] = 1; + +exec("scripts/aiSurvival.cs"); + +package SVGame +{ + function UpdateClientTimes(%time) //Used for initial countdown if needed + { + %secondsLeft = %time / 1000; + messageAll('MsgSystemClock', "", (%secondsLeft / 60), %time); + return true; + } + + function notifyMatchEnd(%time){ return true; } //Survival has NO end + + + function Disconnect() //Package this function so we can disable the schedules on disconnect + { + parent::Disconnect(); + + cancel(Game.helper); + cancel(Game.roundStart); + cancel(Game.roundMessage[0]); + cancel(Game.roundMessage[1]); + cancel(Game.roundMessage[2]); + cancel(Game.roundMessage[3]); + cancel(Game.roundMessage[4]); + cancel(Game.roundMessage[5]); + cancel(Game.BotWave); + return true; + } +}; + +function SVGame::initGameVars(%game) +{ + %game.SCORE_PER_KILL = 1; + %game.SCORE_PER_DEATH = -1; + %game.SCORE_PER_SUICIDE = -1; + + //SV Vars + %game.rounds = 1; + %game.playerCount = 0; + %game.botCount = 0; + %game.shouldSpawn = 0; + %game.start = 0; + %game.AIWon = 0; + + %prefs = new ScriptObject(){ class = "BasicDataParser"; }; + %prefs.load("prefs/Survival.conf"); + %config = %prefs.get("Config",0); + %area = %prefs.get("MissionArea",0); + + // Load configuration + %game.maxBots = %config.element("MaxBots"); + %game.difficultyIncrement = %config.element("difficultyIncrement"); + %game.fastDifficultyIncrement = %config.element("fastDifficultyIncrement"); + %game.startDifficulty = %config.element("startDifficulty"); + %game.enableGodbot = %config.element("enableGodbot"); + %game.godBotFrequency = %config.element("godBotFrequency"); + %game.hintsEnabled = %config.element("hintsEnabled"); + %game.hintTimeMS = %config.element("hintTimeMS"); + %game.allowSetup = %config.element("allowSetup"); + %game.setupTimeMS = %config.element("setupTimeMS"); + + %prefs.empty(); + %prefs.delete(); + %area.empty(); + %area.delete(); + return true; +} + +function SVGame::missionLoadDone(%game) +{ + //default version sets up teams - must be called first... + DefaultGame::missionLoadDone(%game); + + //Ok.. for some odd reason the AI grenade Set isn't created for this gamemode. + //Without it, the bots don't function very well at all. + //Make sure it exists when the game starts + if (!IsObject($AIGrenadeSet)) + AIObjectives.add($AIGrenadeSet = new Simgroup(AIGrenadeSet)); + //Remove console spam.. + if (!IsObject($AIRemoteTurretSet)) + AIObjectives.add($AIRemoteTurretSet = new Simgroup(AIRemoteTurretSet)); + if (!IsObject($ObjectiveQ[2])) + $ObjectiveQ[2] = new simSet(); + return true; +} + +function SVGame::setUpTeams(%game) +{ + DefaultGame::setUpTeams(%game); + %game.numTeams = 1; //Players cannot switch teams + setSensorGroupCount(3); //Team 0, 1, and 2 + return true; +} + +function SVGame::RoundStart(%game) +{ + if (%game.playerCount <= 0) + { + messageAll('MsgAll',"\c2The round cannot start untill someone spawns! ~wfx/misc/misc.error.wav"); + Game.shouldSpawn = 1; //Tell the game to start a 10 sec countdown now + return; + } + + %game.start = 1; + %game.AIWon = 0; + messageAll('MsgSystemClock',"\c2The round has started! ~wfx/misc/red_alert.wav",1,120000); //Start "Player Help" countdown + Game.lockDeadClients(); + Game.spawnAI(); + Game.helper = Game.schedule(120000,"PlayerHelp"); + //Ok.. bots spawn every 30 secs + if ($Host::ProgressiveMode) + Game.BotWave = Game.schedule(180000,"SpawnAI",true); + return true; +} + +function SVGame::checkTimeLimit(%game, %forced){} + +function SVGame::freeDeadClients(%game) +{ + for (%i = 0; %i < ClientGroup.getCount(); %i++) + { + %cl = ClientGroup.getObject(%i); + %cl.isDead = false; + %cl.kills = 0; //Since this is called every round, might as well reset the kill count for this round + } + return true; +} + +function SVGame::lockDeadClients(%game) +{ + for (%i = 0; %i < ClientGroup.getCount(); %i++) + { + %cl = ClientGroup.getObject(%i); + %cl.isDead = true; //Doesn't matter if the dude is alive -- when he dies the flag is set. + } + return true; +} + +function SVGame::startMatch(%game) +{ + DefaultGame::startMatch(%game); + + if (!$Host::ProgressiveMode) + messageAll('MsgSystemClock',"\c2The first round will start in one minute.",1,60000); + else + messageAll('MsgSystemClock',"\c2The attack will start in one minute!",1,60000); + + Game.roundMessage[0] = schedule(50000,0,"messageAll",'msgAll',"\c2Round starts in ten seconds.~wfx/misc/hunters_10.wav"); + Game.roundMessage[1] = schedule(55000,0,"messageAll",'msgAll',"\c2Round starts in five seconds.~wfx/misc/hunters_5.wav"); + Game.roundMessage[2] = schedule(56000,0,"messageAll",'msgAll',"\c2Round starts in four seconds.~wfx/misc/hunters_4.wav"); + Game.roundMessage[3] = schedule(57000,0,"messageAll",'msgAll',"\c2Round starts in three seconds.~wfx/misc/hunters_3.wav"); + Game.roundMessage[4] = schedule(58000,0,"messageAll",'msgAll',"\c2Round starts in two seconds.~wfx/misc/hunters_2.wav"); + Game.roundMessage[5] = schedule(59000,0,"messageAll",'msgAll',"\c2Round starts in one second.~wfx/misc/hunters_1.wav"); + Game.roundStart = Game.schedule(60000,"RoundStart"); + Game.freeDeadClients(); + return true; +} + +function SVGame::checkRounds(%game) +{ + if (%game.start) + return false; + + for (%i = 0; %i < ClientGroup.getCount(); %i++) + { + %cl = ClientGroup.getObject(%i); + if (IsObject(%cl.player) && %cl.player.getState() $= "move") + { + %cl.streak++; + if(%cl.streak > $Data::Rounds[%cl.GUID,$MissionName]) + { + messageClient(%cl,'MsgClient','\c2Congratulations, you broke your old Round record of %1!',%cl.streak--); + $Data::Rounds[%cl.GUID,$MissionName]++; + } + } + } + return true; +} + +function SVGame::onClientKilled(%game, %clVictim, %clKiller, %damageType, %implement, %damageLoc) +{ + cancel(%clVictim.player.alertThread); + DefaultGame::onClientKilled(%game, %clVictim, %clKiller, %damageType, %implement, %damageLoc); + + if (IsObject(%clVictim) && !%clVictim.isAIControlled()) + { + %game.playerCount--; //May be someone switching to observer + if (%game.start) + %clVictim.isDead = true; + %clVictim.streak = 0; //Moved from SVGame::CheckRounds to fix .streak being reset for some reason + } + + if (%game.playerCount <= 0 && %game.start) + { + messageAll('MsgSystemClock',"\c2Round "@%game.rounds@" belongs to the Artificial Intelligance! The game will now restart back at round 1. ~wfx/misc/flag_return.wav",1,60000); + %game.rounds = 1; + %game.start = 0; + %game.AIWon = 1; //Tell the game the b0ts won, or else when they disconnect, it'll be counted as a player win + cancel(Game.helper); + messageAll('MsgSPCurrentObjective1',"",'Current round: 1'); + Game.roundMessage[0] = schedule(50000,0,"messageAll",'msgAll',"\c2Round starts in ten seconds.~wfx/misc/hunters_10.wav"); + Game.roundMessage[1] = schedule(55000,0,"messageAll",'msgAll',"\c2Round starts in five seconds.~wfx/misc/hunters_5.wav"); + Game.roundMessage[2] = schedule(56000,0,"messageAll",'msgAll',"\c2Round starts in four seconds.~wfx/misc/hunters_4.wav"); + Game.roundMessage[3] = schedule(57000,0,"messageAll",'msgAll',"\c2Round starts in three seconds.~wfx/misc/hunters_3.wav"); + Game.roundMessage[4] = schedule(58000,0,"messageAll",'msgAll',"\c2Round starts in two seconds.~wfx/misc/hunters_2.wav"); + Game.roundMessage[5] = schedule(59000,0,"messageAll",'msgAll',"\c2Round starts in one second.~wfx/misc/hunters_1.wav"); + Game.roundStart = Game.schedule(60000,"RoundStart"); + //disconnectAllBots(); + Game.freeDeadClients(); + + %bots = Array.create(); + %count = HiddenClientGroup.getCount(); + for (%i = 0; %i < %count; %i++) + { + %cl = HiddenClientGroup.getObject(%i); + if (%cl.isAIControlled()) + %bots.setElement(%i, %cl); + } + + + // For the lulz + %damageCount = 8; + %damageType[0] = $DamageType::Suicide; + %damageType[1] = $DamageType::Lava; + %damageType[2] = $DamageType::Ground; + %damageType[3] = $DamageType::Impact; + %damageType[4] = $DamageType::OutOfBounds; + %damageType[5] = $DamageType::ForceFieldPowerup; + %damageType[6] = $DamageType::Lightning; + %damageType[7] = $DamageType::NexusCamping; + + // Now to kill them + for (%i = 0; %i < %count; %i++) + { + %bot = %bots.element(%i); + %death = getRandom(0,2); + if (%death == 0) // Explode + { + %bot.player.blowup(); + %bot.player.schedule(100,"setPosition","0 0 -99999"); + %bot.player.schedule(110,"scriptKill",%damageType[getRandom(0,%damageCount)]); + } + else if (%death == 1) // Fade + { + %bot.player.setCloaked(true); + %bot.player.schedule(100,"setPosition","0 0 -99999"); + %bot.player.schedule(110,"scriptKill",%damageType[getRandom(0,%damageCount)]); + } + else + %bot.player.scriptKill(%damageType[getRandom(0,%damageCount)]); + } + %bots.delete(); + + Game.botCount = 0; + } + return true; +} + +function SVGame::spawnPlayer( %game, %client, %respawn ) +{ + if (%client.isDead) + return commandToClient(%client, 'CenterPrint', "You will respawn next round.",2); + else if (!%client.isAIControlled()) + { + %client.team = 1; + DefaultGame::spawnPlayer(%game, %client, %respawn); + Game.playerCount++; + commandToClient(%client,'bottomPrint',"Try not to die.",3); + if (%game.shouldSpawn) + { + %game.shouldSpawn = 0; + messageAll('MsgSystemClock',"\c2Round starts in ten seconds.~wfx/misc/hunters_10.wav",1,10000); + Game.roundMessage[0] = schedule(5000,0,"messageAll",'msgAll',"\c2Round starts in five seconds.~wfx/misc/hunters_5.wav"); + Game.roundMessage[1] = schedule(6000,0,"messageAll",'msgAll',"\c2Round starts in four seconds.~wfx/misc/hunters_4.wav"); + Game.roundMessage[2] = schedule(7000,0,"messageAll",'msgAll',"\c2Round starts in three seconds.~wfx/misc/hunters_3.wav"); + Game.roundMessage[3] = schedule(8000,0,"messageAll",'msgAll',"\c2Round starts in two seconds.~wfx/misc/hunters_2.wav"); + Game.roundMessage[4] = schedule(9000,0,"messageAll",'msgAll',"\c2Round starts in one second.~wfx/misc/hunters_1.wav"); + Game.roundStart = Game.schedule(10000,"RoundStart"); + } + } + return true; +} + +function SVGame::onAIKilled(%game, %clVictim, %clAttacker, %damageType, %implement) +{ + DefaultGame::onAIKilled(%game, %clVictim, %clAttacker, %damageType, %implement); + + if (IsObject(%clVictim) && %clVictim.isAIControlled()) + { + if (%game.botCount != 0) + %game.botCount--; + messageAll('MsgSPCurrentObjective2',"",'Number of bots: %1',Game.botCount); + HiddenClientGroup.remove(%clVictim); + %clVictim.drop(); + } + + if (%game.botCount <= 0 && !$Host::ProgressiveMode && !%game.AIWon) //There are no rounds.. + { + messageAll('MsgSystemClock',"\c2Round "@%game.rounds@" belongs to the players! They have thirty seconds to get ready. ~wfx/misc/flag_return.wav",1,30000); + %game.rounds++; + %game.start = 0; + cancel(Game.helper); + messageAll('MsgSPCurrentObjective1',"",'Current Round: %1',Game.rounds); + Game.roundMessage[0] = schedule(20000,0,"messageAll",'msgAll',"\c2Round starts in ten seconds.~wfx/misc/hunters_10.wav"); + Game.roundMessage[1] = schedule(25000,0,"messageAll",'msgAll',"\c2Round starts in five seconds.~wfx/misc/hunters_5.wav"); + Game.roundMessage[2] = schedule(26000,0,"messageAll",'msgAll',"\c2Round starts in four seconds.~wfx/misc/hunters_4.wav"); + Game.roundMessage[3] = schedule(27000,0,"messageAll",'msgAll',"\c2Round starts in three seconds.~wfx/misc/hunters_3.wav"); + Game.roundMessage[4] = schedule(28000,0,"messageAll",'msgAll',"\c2Round starts in two seconds.~wfx/misc/hunters_2.wav"); + Game.roundMessage[5] = schedule(29000,0,"messageAll",'msgAll',"\c2Round starts in one second.~wfx/misc/hunters_1.wav"); + + //Award a client's ROUNDs if he beat his old round record + Game.checkRounds(); + //Allow dead peeps to rejoin + Game.freeDeadClients(); + Game.roundStart = Game.schedule(30000,"RoundStart"); + } + return true; +} + +function SVGame::PlayerHelp(%game) //Is called after 2 minutes in each round; tells where the b0ts are +{ + if (%game.start) + { + messageAll('MsgSystemClock',"\c2Good hunting! ~wvoice/Training/Any/ANY.hunting.wav",1,120000); + for (%i = 0; %i < HiddenClientGroup.getcount(); %i++) + { + %cl = HiddenClientGroup.getObject(%i); + if (%cl.isAIControlled() && %cl.team == 2) + { + %wp = new Waypoint() + { + Datablock = "WayPointMarker"; + Position = %cl.player.getPosition(); + Name = %cl.namebase; + Team = 2; + }; + %wp.schedule(3000,"Delete"); + } + } + Game.helper = Game.schedule(120000,"PlayerHelp"); + } +} + +function SVGame::SpawnAI(%game,%val) +{ + if (%val && !$Host::ProgressiveMode) + return; + + if (Game.rounds == 90) + { + messageAll('msgAll',"\c3The Godbot is here! ~wfx/misc/red_alert.wav"); + for (%i = 0; %i < 6; %i++) + { + %bot = aiConnectByName("Godbot",2); + %bot.setSkillLevel(1); + %bot.player.clearInventory(); + %bot.player.setArmor("TR2Heavy"); + %bot.player.setInventory("TR2EnergyPack",1,true); + %bot.player.setInventory("Disc",1,true); + %bot.player.setInventory("DiscAmmo",900,true); + // %bot.player.setInventory("Chaingun",1,true); + //%bot.player.setInventory("ChaingunAmmo",999,true); + %bot.player.setInventory("GrenadeLauncher",1,true); + %bot.player.setInventory("GrenadeLauncherAmmo",999,true); + %bot.player.setInventory("Shocklance",1,true); + %bot.player.setInventory("Mortar",1,true); + %bot.player.setInventory("MortarAmmo",999,true); + %bot.player.use("Disc"); + %game.botCount = 5; + hideClient(%bot); + } + return; + } + %playerCount = clientGroup.getCount() - 1; + + for (%i = 0; %i < 2 + Game.rounds+1; %i++) + { + %bot = aiConnectByIndex(getRandom(0,$BotProfile::Count),2); //Choose random b0ts by Index + //Alright -- this'll make the game a bit harder -- depending on the rounds, the bots will have random armors. + %chance = getRandom(1,5 + Game.rounds); + %bot.player.clearInventory(); + + if (%chance > 6) //Medium Armor + { + %bot.player.setArmor("Medium"); + // %bot.player.setInventory("Chaingun",1,1); + //%bot.player.setInventory("ChaingunAmmo",500,1); + %bot.player.setInventory("GrenadeLauncher",1,1); + %bot.player.setInventory("GrenadeLauncherAmmo",999,1); + %bot.player.setInventory("Disc",1,1); + %bot.player.setInventory("DiscAmmo",30,1); + %bot.player.setInventory("Shoklance",1,1); + %bot.player.setInventory("MissileLauncher",1,1); + %bot.player.setInventory("MissileLauncherAmmo",50); + %bot.player.use("Chaingun"); + } + else if (%chance > 10) //JUGGY + { + %bot.player.setArmor("Heavy"); + %bot.player.setInventory("GrenadeLauncher",1,1); + %bot.player.setInventory("GrenadeLauncherAmmo",999,1); + // %bot.player.setInventory("Chaingun",1,1); + // %bot.player.setInventory("ChaingunAmmo",500,1); + %bot.player.setInventory("Disc",1,1); + %bot.player.setInventory("DiscAmmo",30,1); + %bot.player.setInventory("Shoklance",1,1); + %bot.player.use("Chaingun"); + } + else //Light + { + %bot.player.setArmor("Light"); + %bot.player.setInventory("GrenadeLauncher",1,1); + %bot.player.setInventory("GrenadeLauncherAmmo",999,1); + // %bot.player.setInventory("Chaingun",1,1); + // %bot.player.setInventory("ChaingunAmmo",500,1); + %bot.player.setInventory("Disc",1,1); + %bot.player.setInventory("DiscAmmo",30,1); + %bot.player.setInventory("Shoklance",1,1); + %bot.player.use("Chaingun"); + } + hideClient(%bot); + %random = getRandom(0,%playerCount); + // %client = clientGroup.getObject(%random); + // %bot.stepEscort(%client.player); + %bot.player.setInventory("AmmoPack",1,1); + setTeam(%bot,2); + %bot.setSkillLevel(99); + // %bot.stepEngage(clientGroup.getObject(%random)); + } + + if ($Host::ProgressiveMode && %val) + { + %game.rounds++; //So we increment every time -- I should put a limit to the bots.. + Game.BotWave = Game.schedule(180000,"SpawnAI",true); + } + + messageAll('MsgSPCurrentObjective2',"",'Number of bots: %1',Game.botCount); +} + +function SVGame::allowsProtectedStatics(%game) +{ + return true; +} + +function SVGame::equip(%game, %player) +{ + for(%i =0; %i<$InventoryHudCount; %i++) + %player.client.setInventoryHudItem($InventoryHudData[%i, itemDataName], 0, 1); + %player.client.clearBackpackIcon(); + + //%player.setArmor("Light"); + %player.setInventory(RepairKit, 1); + %player.setInventory("Disc", 1); + %player.setInventory("DiscAmmo", 15); + %player.setInventory("TargetingLaser", 1); + %player.weaponCount = 1; + + if (%player.client.race $= "Draakan") //Also defined in DefaultGame.cs, but this overrides it. + %player.setInventory(Flamer,1); + + // do we want to give players a disc launcher instead? GJL: Yes we do! + %player.use("Disc"); + + return true; +} + +function SVGame::pickPlayerSpawn(%game, %client, %respawn) +{ + // if the client is a bot and on team 2, use team 2 -- otherwise we're always team 1 + if (%client.isAIControlled() && %client.team == 2) + return %game.pickTeamSpawn(2); + else + return %game.pickTeamSpawn(1); + return false; +} + +function SVGame::clientJoinTeam( %game, %client, %team, %respawn ) +{ + %game.assignClientTeam( %client ); + + // Spawn the player: + %game.spawnPlayer( %client, %respawn ); + return true; +} + +function SVGame::assignClientTeam(%game, %client, %respawn) +{ + DefaultGame::assignClientTeam(%game, %client, %respawn); + // if player's team is not on top of objective hud, switch lines + messageClient(%client, 'MsgCheckTeamLines', "", %client.team); + return true; +} + +function SVGame::clientMissionDropReady(%game, %client) +{ + messageClient(%client, 'MsgClientReady',"", "SinglePlayerGame"); //Force the client to set up the SP game objective HUD + %game.resetScore(%client); + + //Setup the client's objective hud + messageClient(%client,'MsgSPCurrentObjective1',"",'Current round: 1'); + messageClient(%client,'MsgSPCurrentObjective2',"",'Number of bots: 0'); //Should update as soon as our player joins + + messageClient(%client, 'MsgMissionDropInfo', '\c0You are in mission %1 (%2).', $MissionDisplayName, $MissionTypeDisplayName, $ServerName ); + + DefaultGame::clientMissionDropReady(%game, %client); + return true; +} + +function SVGame::AIHasJoined(%game, %client) +{ + %game.botCount++; + return true; +} + +function SVGame::checkScoreLimit(%game, %client) +{ + //there's no score limit in DM +} + +function SVGame::createPlayer(%game, %client, %spawnLoc, %respawn) +{ + DefaultGame::createPlayer(%game, %client, %spawnLoc, %respawn); + %client.setSensorGroup(%client.team); + return true; +} + +function SVGame::resetScore(%game, %client) +{ + %client.deaths = 0; + %client.kills = 0; + %client.score = 0; + %client.efficiency = 0.0; + %client.suicides = 0; + return true; +} + +function SVGame::assignClientTeam(%game, %client, %respawn ) +{ + if (!%client.isDead) + DefaultGame::assignClientTeam(%game, %client, %respawn); + else + return true; + return false; +} + +function SVGame::updateKillScores(%game, %clVictim, %clKiller, %damageType, %implement) +{ + if (%game.testKill(%clVictim, %clKiller)) //verify victim was an enemy + { + %game.awardScoreKill(%clKiller); + messageClient(%clKiller, 'MsgDMKill', "", %clKiller.kills); + %game.awardScoreDeath(%clVictim); + } + else if (%game.testSuicide(%clVictim, %clKiller, %damageType)) //otherwise test for suicide + %game.awardScoreSuicide(%clVictim); + return true; +} + +function SVGame::recalcScore(%game, %client) +{ + %killValue = %client.kills * %game.SCORE_PER_KILL; + %deathValue = %client.deaths * %game.SCORE_PER_DEATH; + %suicideValue = %client.suicides * %game.SCORE_PER_SUICIDE; + + if (%killValue - %deathValue == 0) + %client.efficiency = %suicideValue; + else + %client.efficiency = ((%killValue * %killValue) / (%killValue - %deathValue)) + %suicideValue; + + %client.score = mFloatLength(%client.efficiency, 1); + messageClient(%client, 'MsgYourScoreIs', "", %client.score); + %game.recalcTeamRanks(%client); + %game.checkScoreLimit(%client); + return true; +} + +function SVGame::timeLimitReached(%game) +{ + logEcho("game over (timelimit)"); + %game.gameOver(); + cycleMissions(); + return true; +} + +function SVGame::scoreLimitReached(%game) +{ + logEcho("game over (scorelimit)"); + %game.gameOver(); + cycleMissions(); + return true; +} + +function SVGame::gameOver(%game) +{ + //call the default + DefaultGame::gameOver(%game); + Game.GameEnded = true; + + messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.gameover.wav" ); + + //cancel the schedules.. + cancel(Game.helper); + cancel(Game.roundStart); + cancel(Game.roundMessage[0]); + cancel(Game.roundMessage[1]); + cancel(Game.roundMessage[2]); + cancel(Game.roundMessage[3]); + cancel(Game.roundMessage[4]); + cancel(Game.roundMessage[5]); + cancel(Game.BotWave); + + cancel(%game.timeThread); + messageAll('MsgClearObjHud', ""); + for(%i = 0; %i < ClientGroup.getCount(); %i ++) + { + %client = ClientGroup.getObject(%i); + %game.resetScore(%client); + } + return true; +} + +function SVGame::enterMissionArea(%game, %playerData, %player) +{ + %player.client.outOfBounds = false; + messageClient(%player.client, 'EnterMissionArea', '\c1You are back in the mission area.'); + logEcho(%player.client.nameBase@" (pl "@%player@"/cl "@%player.client@") entered mission area"); + cancel(%player.alertThread); + return true; +} + +function SVGame::leaveMissionArea(%game, %playerData, %player) +{ + if(%player.getState() $= "Dead") + return false; + + %player.client.outOfBounds = true; + %player.setDamageFlash(0.3); + messageClient(%player.client, 'LeaveMissionArea', '\c1You have left the mission area. Return or die.~wfx/misc/warning_beep.wav'); + logEcho(%player.client.nameBase@" (pl "@%player@"/cl "@%player.client@") left mission area"); + %player.alertThread = %game.schedule(200, "DMAlertPlayer", 3, %player); + return true; +} + +function SVGame::DMAlertPlayer(%game, %count, %player) +{ + // MES - I commented below line out because it prints a blank line to chat window + //messageClient(%player.client, 'MsgDMLeftMisAreaWarn', '~wfx/misc/red_alert.wav'); + if(%count > 1) + %player.alertThread = %game.schedule(1000, "DMAlertPlayer", %count - 1, %player); + else + %player.alertThread = %game.schedule(1000, "MissionAreaDamage", %player); + return true; +} + +function SVGame::MissionAreaDamage(%game, %player) +{ + %player.setWhiteout(%player.getWhiteout()+0.027); + %player.alertThread = %game.schedule(100, "MissionAreaDamage", %player); + if (%player.getWhiteout() >= 1) + %player.schedule(400,"scriptKill",$DamageType::OutOfBounds); + return true; +} + +function SVGame::updateScoreHud(%game, %client, %tag) +{ + // Clear the header: + messageClient( %client, 'SetScoreHudHeader', "", "" ); + + if ($Data::Rounds[%client.GUID,$MissionName] $= "") + $Data::Rounds[%client.GUID,$MissionName] = 0; + + // Send the subheader: + messageClient(%client, 'SetScoreHudSubheader', "", '\tPLAYER\tRACE\tKILLS\tROUNDS'); + + for (%index = 0; %index < ClientGroup.getCount(); %index++) + { + //get the client info + %cl = ClientGroup.getObject(%index); + + //get the score + %clScore = mFloatLength( %cl.efficiency, 1 ); + + %clKills = mFloatLength( %cl.kills, 0 ); + %clDeaths = mFloatLength( %cl.deaths + %cl.suicides, 0 ); + %clStyle = %cl == %client ? "" : ""; + + //if the client is not an observer, send the message + if (%client.team != 0) + { + if (%client.race !$= "Draakan") //The type will make some difference someday.. lol + messageClient( %client, 'SetLineHud', "", %tag, %index, '%6\t%1%2%3%4', %cl.name, %cl.race, %clKills, $Data::Rounds[%client.GUID,$MissionName], %clDeaths, %clStyle ); + else + messageClient( %client, 'SetLineHud', "", %tag, %index, '%6\t%1%2 (%7)%3%4', %cl.name, %cl.race, %clKills, $Data::Rounds[%client.GUID,$MissionName], %clDeaths, %clStyle, %cl.sex ); + } + } + + // Tack on the list of observers: + %observerCount = 0; + for (%i = 0; %i < ClientGroup.getCount(); %i++) + { + %cl = ClientGroup.getObject(%i); + if (%cl.team == 0) + %observerCount++; + } + + if (%observerCount > 0) + { + messageClient( %client, 'SetLineHud', "", %tag, %index, ""); + %index++; + messageClient(%client, 'SetLineHud', "", %tag, %index, '\tOBSERVERS (%1)TIME', %observerCount); + %index++; + for (%i = 0; %i < ClientGroup.getCount(); %i++) + { + %cl = ClientGroup.getObject(%i); + //if this is an observer + if (%cl.team == 0) + { + %obsTime = getSimTime() - %cl.observerStartTime; + %obsTimeStr = %game.formatTime(%obsTime, false); + messageClient( %client, 'SetLineHud', "", %tag, %index, '\t%1%2', + %cl.name, %obsTimeStr ); + %index++; + } + } + } + + //clear the rest of Hud so we don't get old lines hanging around... + messageClient( %client, 'ClearHud', "", %tag, %index ); +} + +function SVGame::applyConcussion(%game, %player) +{ } \ No newline at end of file diff --git a/scripts/SiegeGame.cs b/scripts/SiegeGame.cs index 1cd4154..f65d9a6 100644 --- a/scripts/SiegeGame.cs +++ b/scripts/SiegeGame.cs @@ -1,1224 +1,1224 @@ -//--- GAME RULES BEGIN --- -//One team defends base, other team tries to conquer it as quickly as possible -//Game has two rounds: Round 1 ends when base is conquered or time runs out -//Round 2: Teams switch sides, play again -- to win, attackers MUST beat the time set by the attackers in Round 1 -//Touching base switch conquers base -//--- GAME RULES END --- - -//Siege type script for TRIBES 2 -// -//The two teams each take a turn at defense and offense. -// -//If initial defending team's objective is captured, then roles switch -//and new offense team gets same amount of time to attempt to capture the -//objective. -// -//If time runs out before initial defending team's objective is captured, -//then roles switch and new offense team has to try to capture the -//objective before time runs out. -// -//The winner is either the team who captures the objective in least amount of time. -// -// In the mission file, Team 1 will be offense team, and team 2 will be the defense team. -// When the game actually starts, either team could start on offense, and the objects must -// have their team designation set accordingly. -// -// This mission type doesn't have a scoreLimit because, well, it really doesn't -// need one or lend itself to one. - -// ai support -exec("scripts/aiSiege.cs"); - -$InvBanList[Siege, "MiningTool"] = 1; - -package SiegeGame { - -function FlipFlop::objectiveInit(%data, %flipflop) -{ - Game.regObjective(%flipflop); - setTargetSkin(%flipflop.getTarget(), $teamSkin[0]); -} - -function SiegeGame::regObjective(%game, %object) -{ - %objSet = nameToID("MissionCleanup/Objectives"); - if(!isObject(%objSet)) - { - %objSet = new SimSet("Objectives"); - MissionCleanup.add(%objSet); - } - %objSet.add(%object); -} - -function FlipFlop::playerTouch(%data, %flipflop, %player) -{ - if(%player.team != Game.offenseTeam) - return; - - %defTeam = Game.offenseTeam == 1 ? 2 : 1; - Game.capPlayer[Game.offenseTeam] = stripChars( getTaggedString( %player.client.name ), "\cp\co\c6\c7\c8\c9" ); - - // Let the observers know: - messageTeam( 0, 'MsgSiegeTouchFlipFlop', '\c2%1 captured the %2 base!~wfx/misc/flipflop_taken.wav', %player.client.name, $TeamName[%defTeam] ); - // Let the teammates know: - messageTeam( %player.team, 'MsgSiegeTouchFlipFlop', '\c2%1 captured the %2 base!~wfx/misc/flipflop_taken.wav', %player.client.name, $TeamName[%defTeam] ); - // Let the other team know: - %losers = %player.team == 1 ? 2 : 1; - messageTeam( %losers, 'MsgSiegeTouchFlipFlop', '\c2%1 captured the %2 base!~wfx/misc/flipflop_lost.wav', %player.client.name, $TeamName[%defTeam]); - - logEcho(%player.client.nameBase@" (pl "@%player@"/cl "@%player.client@") captured team "@%defTeam@" base"); - Game.allObjectivesCompleted(); -} - -//-------------------------------------------------------------------------------- -function StaticShapeData::onDisabled(%data, %obj, %prevState) -{ - Parent::onDisabled(%data, %obj, %prevState); - - if(%obj.waypoint) - game.switchWaypoint(%obj.waypoint); -} - -//-------------------------------------------------------------------------------- -function StaticShapeData::onEnabled(%data, %obj, %prevState) -{ - if(%obj.waypoint) - game.switchWaypoint(%obj.waypoint); - - if(%obj.isPowered()) - %data.onGainPowerEnabled(%obj); - Parent::onEnabled(%data, %obj, %prevState); -} - -}; - -//--------- Siege SCORING INIT ------------------ -function SiegeGame::initGameVars(%game) -{ - %game.SCORE_PER_SUICIDE = 0; - %game.SCORE_PER_TEAMKILL = 0; - %game.SCORE_PER_DEATH = 0; - - %game.SCORE_PER_KILL = 0; - - %game.SCORE_PER_TURRET_KILL = 0; -} - -function SiegeGame::claimFlipflopResources(%game, %flipflop, %team) -{ - // equipment shouldn't switch teams when flipflop is touched -} - -function SiegeGame::missionLoadDone(%game) -{ - if( $Host::timeLimit == 0 ) - $Host::timeLimit = 999; - - //default version sets up teams - must be called first... - DefaultGame::missionLoadDone(%game); - - //clear the scores - $teamScore[1] = 0; - $teamScore[2] = 0; - - //decide which team is starting first - if (getRandom() > 0.5) - { - %game.offenseTeam = 1; - %defenseTeam = 2; - } - else - { - %game.offenseTeam = 2; - %defenseTeam = 1; - } - - //send the message - messageAll('MsgSiegeStart', '\c2Team %1 is starting on offense', $teamName[%game.offenseTeam]); - - //if the first offense team is team2, switch the object team designation - if (%game.offenseTeam == 2) - { - %group = nameToID("MissionGroup/Teams"); - %group.swapTeams(); - // search for vehicle pads also - %mcg = nameToID("MissionCleanup"); - %mcg.swapVehiclePads(); - } - - //also ensure the objectives are all on the defending team - %objSet = nameToId("MissionCleanup/Objectives"); - for(%j = 0; %j < %objSet.getCount(); %j++) - { - %obj = %objSet.getObject(%j); - %obj.team = %defenseTeam; - setTargetSensorGroup(%obj.getTarget(), %defenseTeam); - } - - //indicate we're starting the game from the beginning... - %game.firstHalf = true; - %game.timeLimitMS = $Host::TimeLimit * 60 * 1000; - %game.secondHalfCountDown = false; - %game.capPlayer[1] = ""; - %game.capPlayer[2] = ""; - - // save off turret bases' original barrels - %game.checkTurretBases(); - - // add objective waypoints - %game.findObjectiveWaypoints(); - - MissionGroup.setupPositionMarkers(true); -} - -function SiegeGame::checkTurretBases(%game) -{ - %mGroup = nameToID("MissionGroup/Teams"); - %mGroup.findTurretBase(); -} - -function SimGroup::findTurretBase(%this) -{ - for (%i = 0; %i < %this.getCount(); %i++) - %this.getObject(%i).findTurretBase(); -} - -function InteriorInstance::findTurretBase(%this) -{ - // sorry, we're not looking for interiors -} - -function AIObjective::findTurretBase(%this) -{ - // prevent console error spam -} - -function TSStatic::findTurretBase(%this) -{ - // prevent console error spam -} - -function GameBase::findTurretBase(%this) -{ - // apparently, the initialBarrel attribute gets overwritten whenever the - // barrel gets replaced. :( So we have to save it again under "originalBarrel". - if(%this.getDatablock().getName() $= "TurretBaseLarge") - %this.originalBarrel = %this.initialBarrel; -} - -function TSStatic::findTurretBase(%this) -{ - // prevent console error spam -} - -function SiegeGame::selectSpawnSphere(%game, %team) -{ - //for siege, the team1 drops are offense, team2 drops are defense - %sphereTeam = %game.offenseTeam == %team ? 1 : 2; - - return DefaultGame::selectSpawnSphere(%game, %sphereTeam); -} - -function SiegeGame::startMatch(%game) -{ - DefaultGame::startMatch( %game ); - - %game.startTimeMS = getSimTime(); - - // schedule first timeLimit check for 20 seconds - %game.timeSync = %game.schedule( 20000, "checkTimeLimit"); - %game.timeThread = %game.schedule( %game.timeLimitMS, "timeLimitReached"); - //updateClientTimes(%game.timeLimitMS); - messageAll('MsgSystemClock', "", $Host::TimeLimit, %game.timeLimitMS); - -// %count = ClientGroup.getCount(); -// for ( %i = 0; %i < %count; %i++ ) -// { -// %cl = ClientGroup.getObject( %i ); -// if ( %cl.team == %game.offenseTeam ) -// centerPrint( %cl, "\nTouch the enemy control switch to capture their base!", 5, 3 ); -// else -// centerPrint( %cl, "\nPrevent the enemy from touching your control switch!", 5, 3 ); -// } - - //make sure the AI is started - AISystemEnabled(true); -} - -function SiegeGame::allObjectivesCompleted(%game) -{ - Cancel( %game.timeSync ); - Cancel( %game.timeThread ); - cancelEndCountdown(); - - //store the elapsed time in the teamScore array... - $teamScore[%game.offenseTeam] = getSimTime() - %game.startTimeMS; - messageAll('MsgSiegeCaptured', '\c2Team %1 captured the base in %2!', $teamName[%game.offenseTeam], %game.formatTime($teamScore[%game.offenseTeam], true)); - - //set the new timelimit - %game.timeLimitMS = $teamScore[%game.offenseTeam]; - - if (%game.firstHalf) - { - // it's halftime, let everyone know - messageAll( 'MsgSiegeHalftime' ); - } - else - { - // game is over - messageAll('MsgSiegeMisDone', '\c2Mission complete.'); - } - logEcho("objective completed in "@%game.timeLimitMS); - - //setup the second half... - // MES -- per MarkF, scheduling for 0 seconds will prevent player deletion-related crashes - %game.schedule(0, halftime, 'objectives'); -} - -function SiegeGame::timeLimitReached(%game) -{ - cancel( %game.timeThread ); - cancel( %game.timeSync ); - - // if time has run out, the offense team gets no score (note, %game.timeLimitMS doesn't change) - $teamScore[%game.offenseTeam] = 0; - messageAll('MsgSiegeFailed', '\c2Team %1 failed to capture the base.', $teamName[%game.offenseTeam]); - - if (%game.firstHalf) - { - // it's halftime, let everyone know - messageAll( 'MsgSiegeHalftime' ); - } - else - { - // game is over - messageAll('MsgSiegeMisDone', '\c2Mission complete.'); - } - - logEcho("time limit reached"); - %game.halftime('time'); -} - -function SiegeGame::checkTimeLimit(%game) -{ - //if we're counting down to the beginning of the second half, check back in - if (%game.secondHalfCountDown) - { - %game.timeSync = %game.schedule(1000, "checkTimeLimit"); - return; - } - - %timeElapsedMS = getSimTime() - %game.startTimeMS; - %curTimeLeftMS = %game.timeLimitMS - %timeElapsedMS; - - if (%curTimeLeftMS <= 0) - { - // time's up, put down your pencils - %game.timeLimitReached(); - } - else - { - if(%curTimeLeftMS >= 20000) - %game.timeSync = %game.schedule( 20000, "checkTimeLimit" ); - else - %game.timeSync = %game.schedule( %curTimeLeftMS + 1, "checkTimeLimit" ); - - //now synchronize everyone's clock - messageAll('MsgSystemClock', "", $Host::TimeLimit, %curTimeLeftMS); - } -} - -function SiegeGame::startSecondHalf(%game) -{ - $MatchStarted = true; - %game.secondHalfCountDown = false; - - MessageAll('MsgMissionStart', "\c2Match started"); - - // set the start time. - //the new %game.timeLimitMS would have been set by timeLimitReached() or allObjectivesCompleted() - %game.startTimeMS = getSimTime(); - - %game.timeThread = %game.schedule(%game.timeLimitMS, "timeLimitReached"); - if (%game.timeLimitMS > 20000) - %game.timeSync = %game.schedule(20000, "checkTimeLimit"); - else - %game.timeSync = %game.schedule(%game.timeLimitMS, "checkTimeLimit"); - logEcho("start second half"); - - EndCountdown(%game.timeLimitMS); - - // set all clients control to their player - %count = ClientGroup.getCount(); - for( %i = 0; %i < %count; %i++ ) - { - %cl = ClientGroup.getObject(%i); - if (!isObject(%cl.player)) - commandToClient(%cl, 'setHudMode', 'Observer'); - else - { - %cl.observerMode = ""; - %cl.setControlObject( %cl.player ); - commandToClient(%cl, 'setHudMode', 'Standard'); -// if ( %client.team == %game.offenseTeam ) -// centerPrint( %cl, "\nTouch the enemy control switch to capture their base!", 5, 3 ); -// else -// centerPrint( %cl, "\nPrevent the enemy from touching your control switch!", 5, 3 ); - } - } - - //now synchronize everyone's clock - updateClientTimes(%game.timeLimitMS); - - //start the bots up again... - AISystemEnabled(true); -} - -function SiegeGame::halftime(%game, %reason) -{ - //stop the game and the bots - $MatchStarted = false; - AISystemEnabled(false); - - if (%game.firstHalf) - { - //switch the game variables - %game.firstHalf = false; - %oldOffenseTeam = %game.offenseTeam; - if (%game.offenseTeam == 1) - %game.offenseTeam = 2; - else - %game.offenseTeam = 1; - - //send the message - messageAll('MsgSiegeRolesSwitched', '\c2Team %1 is now on offense.', $teamName[%game.offenseTeam], %game.offenseTeam); - - //reset stations and vehicles that players were using - %game.resetPlayers(); - // zero out the counts for deployable items (found in defaultGame.cs) - %game.clearDeployableMaxes(); - - // z0dd - ZOD, 5/17/02. Clean up deployables triggers, function in supportClassic.cs - cleanTriggers(nameToID("MissionCleanup/Deployables")); - - // clean up the MissionCleanup group - note, this includes deleting all the player objects - %clean = nameToID("MissionCleanup"); - %clean.housekeeping(); - - // Non static objects placed in original position - resetNonStaticObjPositions(); - - // switch the teams for objects belonging to the teams - %group = nameToID("MissionGroup/Teams"); - %group.swapTeams(); - // search for vehicle pads also - %mcg = nameToID("MissionCleanup"); - %mcg.swapVehiclePads(); - - //restore the objects - %game.restoreObjects(); - - %count = ClientGroup.getCount(); - for(%cl = 0; %cl < %count; %cl++) - { - %client = ClientGroup.getObject(%cl); - if( !%client.isAIControlled() ) - { - // Put everybody in observer mode: - %client.camera.getDataBlock().setMode( %client.camera, "observerStaticNoNext" ); - %client.setControlObject( %client.camera ); - - // Send the halftime result info: - if ( %client.team == %oldOffenseTeam ) - { - if ( $teamScore[%oldOffenseTeam] > 0 ) - messageClient( %client, 'MsgSiegeResult', "", '%1 captured the %2 base in %3!', %game.capPlayer[%oldOffenseTeam], $teamName[%game.offenseTeam], %game.formatTime( $teamScore[%oldOffenseTeam], true ) ); - else - messageClient( %client, 'MsgSiegeResult', "", 'Your team failed to capture the %1 base.', $teamName[%game.offenseTeam] ); - } - else if ( $teamScore[%oldOffenseTeam] > 0 ) - messageClient( %client, 'MsgSiegeResult', "", '%1 captured your base in %3!', %game.capPlayer[%oldOffenseTeam], %game.formatTime( $teamScore[%oldOffenseTeam], true ) ); - else - messageClient( %client, 'MsgSiegeResult', "", 'Your team successfully held off team %1!', $teamName[%oldOffenseTeam] ); - - // List out the team rosters: - messageClient( %client, 'MsgSiegeAddLine', "", '%1%2', $TeamName[1], $TeamName[2] ); - %max = $TeamRank[1, count] > $TeamRank[2, count] ? $TeamRank[1, count] : $TeamRank[2, count]; - for ( %line = 0; %line < %max; %line++ ) - { - %plyr1 = $TeamRank[1, %line] $= "" ? "" : $TeamRank[1, %line].name; - %plyr2 = $TeamRank[2, %line] $= "" ? "" : $TeamRank[2, %line].name; - messageClient( %client, 'MsgSiegeAddLine', "", ' %1 %2', %plyr1, %plyr2 ); - } - - // Show observers: - %header = false; - for ( %i = 0; %i < %count; %i++ ) - { - %obs = ClientGroup.getObject( %i ); - if ( %obs.team <= 0 ) - { - if ( !%header ) - { - messageClient( %client, 'MsgSiegeAddLine', "", '\nOBSERVERS' ); - %header = true; - } - - messageClient( %client, 'MsgSiegeAddLine', "", ' %1', %obs.name ); - } - } - - commandToClient( %client, 'SetHalftimeClock', $Host::Siege::Halftime / 60000 ); - - // Get the HUDs right: - commandToClient( %client, 'setHudMode', 'SiegeHalftime' ); - commandToClient( %client, 'ControlObjectReset' ); - - clientResetTargets(%client, true); - %client.notReady = true; - } - } - - %game.schedule( $Host::Siege::Halftime, halftimeOver ); - } - else - { - // let's wrap it all up - %game.gameOver(); - cycleMissions(); - } -} - -function SiegeGame::halftimeOver( %game ) -{ - // drop all players into mission - %game.dropPlayers(); - - //setup the AI for the second half - %game.aiHalfTime(); - - // start the mission again (release players) - %game.halfTimeCountDown( $Host::warmupTime ); - - //redo the objective waypoints - %game.findObjectiveWaypoints(); -} - -function SiegeGame::dropPlayers( %game ) -{ - %count = ClientGroup.getCount(); - for(%cl = 0; %cl < %count; %cl++) - { - %client = ClientGroup.getObject(%cl); - if( !%client.isAIControlled() ) - { - // keep observers in observer mode - if(%client.team == 0) - %client.camera.getDataBlock().setMode(%client.camera, "justJoined"); - else - { - %game.spawnPlayer( %client, false ); - - %client.camera.getDataBlock().setMode( %client.camera, "pre-game", %client.player ); - %client.setControlObject( %client.camera ); - %client.notReady = false; - } - } - } -} - -function SiegeGame::resetPlayers(%game) -{ - // go through the client group and reset anything the players were using - // is most of this stuff really necessary? - %count = ClientGroup.getCount(); - for(%cl = 0; %cl < %count; %cl++) - { - %client = ClientGroup.getObject(%cl); - %player = %client.player; - - // clear the pack icon - messageClient(%client, 'msgPackIconOff', ""); - // if player was firing, stop firing - if(%player.getImageTrigger($WeaponSlot)) - %player.setImageTrigger($WeaponSlot, false); - - // if player had pack activated, deactivate it - if(%player.getImageTrigger($BackpackSlot)) - %player.setImageTrigger($BackpackSlot, false); - - // if player was in a vehicle, get rid of vehicle hud - commandToClient(%client, 'setHudMode', 'Standard', "", 0); - - // clear player's weapons and inventory huds - %client.SetWeaponsHudClearAll(); - %client.SetInventoryHudClearAll(); - - // if player was at a station, deactivate it - if(%player.station) - { - %player.station.triggeredBy = ""; - %player.station.getDataBlock().stationTriggered(%player.station, 0); - if(%player.armorSwitchSchedule) - cancel(%player.armorSwitchSchedule); - } - - // if piloting a vehicle, reset it (assuming it doesn't get deleted) - if(%player.lastVehicle.lastPilot) - %player.lastVehicle.lastPilot = ""; - } -} - -function SimGroup::housekeeping(%this) -{ - // delete selectively in the MissionCleanup group - %count = %this.getCount(); - // have to do this backwards or only half the objects will be deleted - for(%i = (%count - 1); %i > -1; %i--) - { - %detritus = %this.getObject(%i); - if(%detritus.getClassName() $= "SimSet") - { - // I don't think there are any simsets we want to delete - } - else if(%detritus.getName() $= "PZones") - { - // simgroup of physical zones for force fields - // don't delete them - } - //else if (%detritus.getClassName() $= "ScriptObject") - //{ - // // this will be the game type object. - // // DEFINITELY don't want to delete this. - //} - else if(%detritus.getName() $= PosMarker) - { - //Needed to reset non static objects... - } - else if((%detritus.getName() $= "TeamDrops1") || (%detritus.getName() $= "TeamDrops2")) - { - // this will actually be a SimSet named TeamDropsN (1 or 2) - // don't want to delete the spawn sphere groups, so do nothing - } - else if (%detritus.getName() $= "PlayerListGroup") - { - // we don't want to delete PlayerListGroup (SimGroup) - } - else if (%detritus.getDatablock().getName() $= "stationTrigger") - { - //we don't want to delete triggers for stations - } - else if (%detritus.getDatablock().getName() $= "StationVehicle") - { - // vehicle stations automatically get placed in MissionCleanup in a - // position near the vehicle pad. Don't delete it. - } - else if (%detritus.getClassName() $= "Camera") - { - // Cameras should NOT be deleted - } - else - { - // this group of stuff to be deleted should include: - // mines, deployed objects, projectiles, explosions, corpses, - // players, and the like. - %detritus.delete(); - } - } -} - -function SiegeGame::groupSwapTeams(%game, %this) -{ - for(%i = 0; %i < %this.getCount(); %i++) - %this.getObject(%i).swapTeams(); -} - -function SiegeGame::objectSwapTeams(%game, %this) -{ - %defTeam = %game.offenseTeam == 1 ? 2 : 1; - - if(%this.getDatablock().getName() $= "Flipflop") - { - if(getTargetSensorGroup(%this.getTarget()) != %defTeam) - { - setTargetSensorGroup(%this.getTarget(), %defTeam); - %this.team = %defTeam; - } - } - else - { - if(%this.getTarget() != -1) - { - if(getTargetSensorGroup(%this.getTarget()) == %game.offenseTeam) - { - setTargetSensorGroup(%this.getTarget(), %defTeam); - %this.team = %defTeam; - } - else if(getTargetSensorGroup(%this.getTarget()) == %defTeam) - { - setTargetSensorGroup(%this.getTarget(), %game.offenseTeam); - %this.team = %game.offenseTeam; - } - } - if(%this.getClassName() $= "Waypoint") - { - if(%this.team == %defTeam) - %this.team = %game.offenseTeam; - else if(%this.team == %game.offenseTeam) - %this.team = %defTeam; - } - } -} - -function SiegeGame::groupSwapVehiclePads(%game, %this) -{ - for(%i = 0; %i < %this.getCount(); %i++) - %this.getObject(%i).swapVehiclePads(); -} - -function SiegeGame::objectSwapVehiclePads(%game, %this) -{ - %defTeam = %game.offenseTeam == 1 ? 2 : 1; - - if(%this.getDatablock().getName() $= "StationVehicle") - { - if(%this.getTarget() != -1) - { - // swap the teams of both the vehicle pad and the vehicle station - if(getTargetSensorGroup(%this.getTarget()) == %game.offenseTeam) - { - setTargetSensorGroup(%this.getTarget(), %defTeam); - %this.team = %defTeam; - setTargetSensorGroup(%this.pad.getTarget(), %defTeam); - %this.pad.team = %defTeam; - // z0dd - ZOD, 4/20/02. Switch the teleporter too. - setTargetSensorGroup(%this.teleporter.getTarget(), %defTeam); - %this.teleporter.team = %defTeam; - } - else if(getTargetSensorGroup(%this.getTarget()) == %defTeam) - { - setTargetSensorGroup(%this.getTarget(), %game.offenseTeam); - %this.team = %game.offenseTeam; - setTargetSensorGroup(%this.pad.getTarget(), %game.offenseTeam); - %this.pad.team = %game.offenseTeam; - // z0dd - ZOD, 4/20/02. Switch the teleporter too. - setTargetSensorGroup(%this.teleporter.getTarget(), %game.offenseTeam); - %this.teleporter.team = %game.offenseTeam; - } - } - } -} - -function SiegeGame::restoreObjects(%game) -{ - // restore all the "permanent" mission objects to undamaged state - %group = nameToID("MissionGroup/Teams"); - // SimGroup::objectRestore is defined in DefaultGame.cs -- it simply calls - // %game.groupObjectRestore - %group.objectRestore(); -} - -function SiegeGame::groupObjectRestore(%game, %this) -{ - for(%i = 0; %i < %this.getCount(); %i++) - %this.getObject(%i).objectRestore(); -} - -function SiegeGame::shapeObjectRestore(%game, %object) -{ - //if(%object.getDatablock().getName() $= FlipFlop) - //{ - // messageAll('MsgSiegeObjRestore', "", %object.number, true); - //} - //else if(%object.getDamageLevel()) - if(%object.getDamageLevel()) - { - %object.setDamageLevel(0.0); - %object.setDamageState(Enabled); - } - if(%object.getDatablock().getName() $= "TurretBaseLarge") - { - // check to see if the turret base still has the same type of barrel it had - // at the beginning of the mission - if(%object.getMountedImage(0)) - if(%object.getMountedImage(0).getName() !$= %object.originalBarrel) - { - // pop the "new" barrel - %object.unmountImage(0); - // mount the original barrel - %object.mountImage(%object.originalBarrel, 0, false); - } - } -} - -function InteriorInstance::objectRestore(%this) -{ - // avoid console error spam -} - -function Trigger::objectRestore(%this) -{ - // avoid console error spam -} - -function TSStatic::objectRestore(%this) -{ - // avoid console error spam -} - -function ForceFieldBare::objectRestore(%this) -{ - // avoid console error spam -} - -// ------------------------------------------------------------------------ -// Waypoint managing - -function siegeGame::findObjectiveWaypoints(%game, %group) -{ - if(!%group) - %group = nameToId("MissionGroup/Teams"); - - for (%i = 0; %i < %group.getCount(); %i++) - { - %obj = %group.getObject(%i); - if(%obj.getClassName() $= SimGroup) - { - %game.findObjectiveWaypoints(%obj); - } - else if(%obj.needsObjectiveWaypoint) - { - %game.initializeWaypointAtObjective(%obj); - } - } -} - -function siegeGame::initializeWaypointAtObjective(%game, %object) -{ - // out with the old...jic - if ( %object.waypoint ) - { - if ( isObject( %object.waypoint ) ) - %object.waypoint.delete(); - else - %object.waypoint = ""; - } - - if(%object.team == %game.offenseTeam) - %team = %game.offenseTeam; - else - %team = (%game.offenseTeam == 1 ? 2 : 1); - - // to make the waypoint look a little prettier we are using the z from - // position and the x and y from worldBoxCenter - %posX = getWord(%object.getWorldBoxCenter(), 0); - %posY = getWord(%object.getWorldBoxCenter(), 1); - %posZ = getWord(%object.position, 2); - - %append = getTaggedString(%object.getDataBlock().targetTypeTag); - - %object.waypoint = new WayPoint() { - position = %posX SPC %posY SPC %posZ; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "WayPointMarker"; - team = %team; - name = getTaggedString(%object.nameTag) SPC %append; - }; - MissionCleanup.add(%object.waypoint); -} - -function siegeGame::switchWaypoint(%game, %waypoint) -{ - %team = %waypoint.team; - %newTeam = (%team == 1 ? 2 : 1); - - %waypoint.team = %newTeam; -} - - -function SiegeGame::gameOver(%game) -{ - //call the default - DefaultGame::gameOver(%game); - - cancel(%game.timeThread); - - messageAll('MsgClearObjHud', ""); -} - -function SiegeGame::sendDebriefing( %game, %client ) -{ - //if neither team captured - %winnerName = ""; - if ( $teamScore[1] == 0 && $teamScore[2] == 0 ) - %winner = -1; - - //else see if team1 won - else if ( $teamScore[1] > 0 && ( $teamScore[2] == 0 || $teamScore[1] < $teamScore[2] ) ) - { - %winner = 1; - %winnerName = $teamName[1]; - } - - //else see if team2 won - else if ($teamScore[2] > 0 && ($teamScore[1] == 0 || $teamScore[2] < $teamScore[1])) - { - %winner = 2; - %winnerName = $teamName[2]; - } - - //else see if it was a tie (right down to the millisecond - doubtful) - else if ($teamScore[1] == $teamScore[2]) - %winner = 0; - - //send the winner message - if (%winnerName $= 'Storm') - messageClient( %client, 'MsgGameOver', "Match has ended.~wvoice/announcer/ann.stowins.wav" ); - else if (%winnerName $= 'Inferno') - messageClient( %client, 'MsgGameOver', "Match has ended.~wvoice/announcer/ann.infwins.wav" ); - else - messageClient( %client, 'MsgGameOver', "Match has ended.~wvoice/announcer/ann.gameover.wav" ); - - // Mission result: - if (%winner > 0) - { - if (%winner == 1) - { - if ($teamScore[2] == 0) - messageClient(%client, 'MsgDebriefResult', "", 'Team %1 wins!', $TeamName[1]); - else - { - %timeDiffMS = $teamScore[2] - $teamScore[1]; - messageClient(%client, 'MsgDebriefResult', "", 'Team %1 won by capturing the base %2 faster!', $TeamName[1], %game.formatTime(%timeDiffMS, true)); - } - } - else - { - if ($teamScore[1] == 0) - messageClient(%client, 'MsgDebriefResult', "", 'Team %1 wins!', $TeamName[2]); - else - { - %timeDiffMS = $teamScore[1] - $teamScore[2]; - messageClient(%client, 'MsgDebriefResult', "", 'Team %1 won by capturing the base %2 faster!', $TeamName[2], %game.formatTime(%timeDiffMS, true)); - } - } - } - else - messageClient( %client, 'MsgDebriefResult', "", 'The mission ended in a tie.' ); - - // Game summary: - messageClient( %client, 'MsgDebriefAddLine', "", 'SUMMARY:' ); - %team1 = %game.offenseTeam == 1 ? 2 : 1; - %team2 = %game.offenseTeam; - if ( $teamScore[%team1] > 0 ) - { - %timeStr = %game.formatTime($teamScore[%team1], true); - messageClient( %client, 'MsgDebriefAddLine', "", '%1 captured the %2 base for Team %3 in %4.', %game.capPlayer[%team1], $TeamName[%team2], $TeamName[%team1], %timeStr); - } - else - messageClient( %client, 'MsgDebriefAddLine', "", 'Team %1 failed to capture the base.', $TeamName[%team1]); - - if ( $teamScore[%team2] > 0 ) - { - %timeStr = %game.formatTime($teamScore[%team2], true); - messageClient( %client, 'MsgDebriefAddLine', "", '%1 captured the %2 base for Team %3 in %4.', %game.capPlayer[%team2], $TeamName[%team1], $TeamName[%team2], %timeStr); - } - else - messageClient( %client, 'MsgDebriefAddLine', "", 'Team %1 failed to capture the base.', $TeamName[%team2]); - - // List out the team rosters: - messageClient( %client, 'MsgDebriefAddLine', "", '\n%1%2', $TeamName[1], $TeamName[2] ); - %max = $TeamRank[1, count] > $TeamRank[2, count] ? $TeamRank[1, count] : $TeamRank[2, count]; - for ( %line = 0; %line < %max; %line++ ) - { - %plyr1 = $TeamRank[1, %line] $= "" ? "" : $TeamRank[1, %line].name; - %plyr2 = $TeamRank[2, %line] $= "" ? "" : $TeamRank[2, %line].name; - messageClient( %client, 'MsgDebriefAddLine', "", ' %1 %2', %plyr1, %plyr2 ); - } - - // Show observers: - %count = ClientGroup.getCount(); - %header = false; - for ( %i = 0; %i < %count; %i++ ) - { - %cl = ClientGroup.getObject( %i ); - if ( %cl.team <= 0 ) - { - if ( !%header ) - { - messageClient( %client, 'MsgDebriefAddLine', "", '\nOBSERVERS' ); - %header = true; - } - - messageClient( %client, 'MsgDebriefAddLine', "", ' %1', %cl.name ); - } - } -} - -function SiegeGame::clientMissionDropReady(%game, %client) -{ - messageClient(%client, 'MsgClientReady', "", %game.class); - - for(%i = 1; %i <= %game.numTeams; %i++) - { - %isOffense = (%i == %game.offenseTeam); - messageClient(%client, 'MsgSiegeAddTeam', "", %i, $teamName[%i], %isOffense); - } - - messageClient(%client, 'MsgMissionDropInfo', '\c0You are in mission %1 (%2).', $MissionDisplayName, $MissionTypeDisplayName, $ServerName ); - DefaultGame::clientMissionDropReady(%game, %client); -} - -function SiegeGame::assignClientTeam(%game, %client, %respawn) -{ - DefaultGame::assignClientTeam(%game, %client, %respawn); - - // if player's team is not on top of objective hud, switch lines - messageClient(%client, 'MsgCheckTeamLines', "", %client.team); -} - -function SiegeGame::resetScore(%game, %client) -{ - %client.score = 0; - %client.kills = 0; - %client.deaths = 0; - %client.suicides = 0; - %client.objScore = 0; - %client.teamKills = 0; - %client.turretKills = 0; - %client.offenseScore = 0; - %client.defenseScore = 0; -} - -//--------------- Scoring functions ----------------- -function SiegeGame::recalcScore(%game, %cl) -{ - %killValue = %cl.kills * %game.SCORE_PER_KILL; - %deathValue = %cl.deaths * %game.SCORE_PER_DEATH; - - if (%killValue - %deathValue == 0) - %killPoints = 0; - else - %killPoints = (%killValue * %killValue) / (%killValue - %deathValue); - - %cl.offenseScore = %killPoints; - %cl.offenseScore += %cl.teamKills * %game.SCORE_PER_TEAMKILL; // -1 - %cl.offenseScore += %cl.objScore; - - %cl.defenseScore = %cl.turretKills * %game.SCORE_PER_TURRET_KILL; // 1 - - %cl.score = %cl.offenseScore + %cl.defenseScore; - %cl.score = mFloor(%cl.score); - %game.recalcTeamRanks(%cl); -} - -function SiegeGame::updateKillScores(%game, %clVictim, %clKiller, %damageType, %implement) -{ - if(%game.testTurretKill(%implement)) //check for turretkill before awarded a non client points for a kill - { - %game.awardScoreTurretKill(%clVictim, %implement); - } - else if (%game.testKill(%clVictim, %clKiller)) //verify victim was an enemy - { - %game.awardScoreKill(%clKiller); - %game.awardScoreDeath(%clVictim); - } - else - { - if (%game.testSuicide(%clVictim, %clKiller, %damageType)) //otherwise test for suicide - { - %game.awardScoreSuicide(%clVictim); - } - else - { - if (%game.testTeamKill(%clVictim, %clKiller)) //otherwise test for a teamkill - %game.awardScoreTeamKill(%clVictim, %clKiller); - } - } -} - -function SiegeGame::testValidRepair(%game, %obj) -{ - return ((%obj.lastDamagedByTeam != %obj.team) && (%obj.repairedBy.team == %obj.team)); -} - -function SiegeGame::genOnRepaired(%game, %obj, %objName) -{ - - if (%game.testValidRepair(%obj)) - { - %repairman = %obj.repairedBy; - messageTeam(%repairman.team, 'msgGenRepaired', '\c0%1 repaired the %2 generator!', %repairman.name, %obj.nameTag); - } -} - -function SiegeGame::stationOnRepaired(%game, %obj, %objName) -{ - if (%game.testValidRepair(%obj)) - { - %repairman = %obj.repairedBy; - messageTeam(%repairman.team, 'msgStationRepaired', '\c0%1 repaired the %2 inventory station!', %repairman.name, %obj.nameTag); - } -} - -function SiegeGame::sensorOnRepaired(%game, %obj, %objName) -{ - if (%game.testValidRepair(%obj)) - { - %repairman = %obj.repairedBy; - messageTeam(%repairman.team, 'msgSensorRepaired', '\c0%1 repaired the %2 pulse sensor!', %repairman.name, %obj.nameTag); - } -} - -function SiegeGame::turretOnRepaired(%game, %obj, %objName) -{ - if (%game.testValidRepair(%obj)) - { - %repairman = %obj.repairedBy; - messageTeam(%repairman.team, 'msgTurretRepaired', '\c0%1 repaired the %2 turret!', %repairman.name, %obj.nameTag); - } -} - -function SiegeGame::vStationOnRepaired(%game, %obj, %objName) -{ - if (%game.testValidRepair(%obj)) - { - %repairman = %obj.repairedBy; - messageTeam(%repairman.team, 'msgTurretRepaired', '\c0%1 repaired the %2 vehicle station!', %repairman.name, %obj.nameTag); - } -} - -function SiegeGame::halfTimeCountDown(%game, %time) -{ - %game.secondHalfCountDown = true; - $MatchStarted = false; - - %timeMS = %time * 1000; - %game.schedule(%timeMS, "startSecondHalf"); - notifyMatchStart(%timeMS); - - if(%timeMS > 30000) - schedule(%timeMS - 30000, 0, "notifyMatchStart", 30000); - if(%timeMS > 20000) - schedule(%timeMS - 20000, 0, "notifyMatchStart", 20000); - if(%timeMS > 10000) - schedule(%timeMS - 10000, 0, "notifyMatchStart", 10000); - if(%timeMS > 5000) - schedule(%timeMS - 5000, 0, "notifyMatchStart", 5000); - if(%timeMS > 4000) - schedule(%timeMS - 4000, 0, "notifyMatchStart", 4000); - if(%timeMS > 3000) - schedule(%timeMS - 3000, 0, "notifyMatchStart", 3000); - if(%timeMS > 2000) - schedule(%timeMS - 2000, 0, "notifyMatchStart", 2000); - if(%timeMS > 1000) - schedule(%timeMS - 1000, 0, "notifyMatchStart", 1000); -} - -function SiegeGame::applyConcussion(%game, %player) -{ -} - -function SiegeGame::updateScoreHud(%game, %client, %tag) -{ - %timeElapsedMS = getSimTime() - %game.startTimeMS; - %curTimeLeftMS = %game.timeLimitMS - %timeElapsedMS; - - if (!$MatchStarted) - %curTimeLeftStr = %game.formatTime(%game.timelimitMS, false); - else - %curTimeLeftStr = %game.formatTime(%curTimeLeftMS, false); - - // Send header: - if (%game.firstHalf) - messageClient( %client, 'SetScoreHudHeader', "", 'Team %1 has %2 to capture the base.', - $teamName[%game.offenseTeam], %curTimeLeftStr ); - else - messageClient( %client, 'SetScoreHudHeader', "", 'Team %1 must capture the base within %2 to win.', - $teamName[%game.offenseTeam], %curTimeLeftStr ); - - // Send subheader: - messageClient( %client, 'SetScoreHudSubheader', "", '\t%1 (%2)\t%3 (%4)', - $TeamName[1], $TeamRank[1, count], $TeamName[2], $TeamRank[2, count] ); - - %index = 0; - while (true) - { - if (%index >= $TeamRank[1, count] && %index >= $TeamRank[2, count]) - break; - - //get the team1 client info - %team1Client = ""; - %team1ClientScore = ""; - %col1Style = ""; - if (%index < $TeamRank[1, count]) - { - %team1Client = $TeamRank[1, %index]; - %team1ClientScore = %team1Client.score $= "" ? 0 : %team1Client.score; - if ( %team1Client == %client ) - %col1Style = ""; - } - - //get the team2 client info - %team2Client = ""; - %team2ClientScore = ""; - %col2Style = ""; - if (%index < $TeamRank[2, count]) - { - %team2Client = $TeamRank[2, %index]; - %team2ClientScore = %team2Client.score $= "" ? 0 : %team2Client.score; - if ( %team2Client == %client ) - %col2Style = ""; - } - - - //if the client is not an observer, send the message - if (%client.team != 0) - { - messageClient( %client, 'SetLineHud', "", %tag, %index, '\t%3%1\t%4%2', - %team1Client.name, %team2Client.name, %col1Style, %col2Style ); - } - //else for observers, create an anchor around the player name so they can be observed - else - { - messageClient( %client, 'SetLineHud', "", %tag, %index, '\t%3%1\t%4%2', - %team1Client.name, %team2Client.name, %col1Style, %col2Style, %team1Client, %team2Client ); - } - - %index++; - } - - // Tack on the list of observers: - %observerCount = 0; - for (%i = 0; %i < ClientGroup.getCount(); %i++) - { - %cl = ClientGroup.getObject(%i); - if (%cl.team == 0) - %observerCount++; - } - - if (%observerCount > 0) - { - messageClient( %client, 'SetLineHud', "", %tag, %index, ""); - %index++; - messageClient(%client, 'SetLineHud', "", %tag, %index, '\tOBSERVERS (%1)TIME', %observerCount); - %index++; - for (%i = 0; %i < ClientGroup.getCount(); %i++) - { - %cl = ClientGroup.getObject(%i); - //if this is an observer - if (%cl.team == 0) - { - %obsTime = getSimTime() - %cl.observerStartTime; - %obsTimeStr = %game.formatTime(%obsTime, false); - messageClient( %client, 'SetLineHud', "", %tag, %index, '\t%1%2', - %cl.name, %obsTimeStr ); - %index++; - } - } - } - - //clear the rest of Hud so we don't get old lines hanging around... - messageClient( %client, 'ClearHud', "", %tag, %index ); -} +//--- GAME RULES BEGIN --- +//One team defends base, other team tries to conquer it as quickly as possible +//Game has two rounds: Round 1 ends when base is conquered or time runs out +//Round 2: Teams switch sides, play again -- to win, attackers MUST beat the time set by the attackers in Round 1 +//Touching base switch conquers base +//--- GAME RULES END --- + +//Siege type script for TRIBES 2 +// +//The two teams each take a turn at defense and offense. +// +//If initial defending team's objective is captured, then roles switch +//and new offense team gets same amount of time to attempt to capture the +//objective. +// +//If time runs out before initial defending team's objective is captured, +//then roles switch and new offense team has to try to capture the +//objective before time runs out. +// +//The winner is either the team who captures the objective in least amount of time. +// +// In the mission file, Team 1 will be offense team, and team 2 will be the defense team. +// When the game actually starts, either team could start on offense, and the objects must +// have their team designation set accordingly. +// +// This mission type doesn't have a scoreLimit because, well, it really doesn't +// need one or lend itself to one. + +// ai support +exec("scripts/aiSiege.cs"); + +$InvBanList[Siege, "MiningTool"] = 1; + +package SiegeGame { + +function FlipFlop::objectiveInit(%data, %flipflop) +{ + Game.regObjective(%flipflop); + setTargetSkin(%flipflop.getTarget(), $teamSkin[0]); +} + +function SiegeGame::regObjective(%game, %object) +{ + %objSet = nameToID("MissionCleanup/Objectives"); + if(!isObject(%objSet)) + { + %objSet = new SimSet("Objectives"); + MissionCleanup.add(%objSet); + } + %objSet.add(%object); +} + +function FlipFlop::playerTouch(%data, %flipflop, %player) +{ + if(%player.team != Game.offenseTeam) + return; + + %defTeam = Game.offenseTeam == 1 ? 2 : 1; + Game.capPlayer[Game.offenseTeam] = stripChars( getTaggedString( %player.client.name ), "\cp\co\c6\c7\c8\c9" ); + + // Let the observers know: + messageTeam( 0, 'MsgSiegeTouchFlipFlop', '\c2%1 captured the %2 base!~wfx/misc/flipflop_taken.wav', %player.client.name, $TeamName[%defTeam] ); + // Let the teammates know: + messageTeam( %player.team, 'MsgSiegeTouchFlipFlop', '\c2%1 captured the %2 base!~wfx/misc/flipflop_taken.wav', %player.client.name, $TeamName[%defTeam] ); + // Let the other team know: + %losers = %player.team == 1 ? 2 : 1; + messageTeam( %losers, 'MsgSiegeTouchFlipFlop', '\c2%1 captured the %2 base!~wfx/misc/flipflop_lost.wav', %player.client.name, $TeamName[%defTeam]); + + logEcho(%player.client.nameBase@" (pl "@%player@"/cl "@%player.client@") captured team "@%defTeam@" base"); + Game.allObjectivesCompleted(); +} + +//-------------------------------------------------------------------------------- +function StaticShapeData::onDisabled(%data, %obj, %prevState) +{ + Parent::onDisabled(%data, %obj, %prevState); + + if(%obj.waypoint) + game.switchWaypoint(%obj.waypoint); +} + +//-------------------------------------------------------------------------------- +function StaticShapeData::onEnabled(%data, %obj, %prevState) +{ + if(%obj.waypoint) + game.switchWaypoint(%obj.waypoint); + + if(%obj.isPowered()) + %data.onGainPowerEnabled(%obj); + Parent::onEnabled(%data, %obj, %prevState); +} + +}; + +//--------- Siege SCORING INIT ------------------ +function SiegeGame::initGameVars(%game) +{ + %game.SCORE_PER_SUICIDE = 0; + %game.SCORE_PER_TEAMKILL = 0; + %game.SCORE_PER_DEATH = 0; + + %game.SCORE_PER_KILL = 0; + + %game.SCORE_PER_TURRET_KILL = 0; +} + +function SiegeGame::claimFlipflopResources(%game, %flipflop, %team) +{ + // equipment shouldn't switch teams when flipflop is touched +} + +function SiegeGame::missionLoadDone(%game) +{ + if( $Host::timeLimit == 0 ) + $Host::timeLimit = 999; + + //default version sets up teams - must be called first... + DefaultGame::missionLoadDone(%game); + + //clear the scores + $teamScore[1] = 0; + $teamScore[2] = 0; + + //decide which team is starting first + if (getRandom() > 0.5) + { + %game.offenseTeam = 1; + %defenseTeam = 2; + } + else + { + %game.offenseTeam = 2; + %defenseTeam = 1; + } + + //send the message + messageAll('MsgSiegeStart', '\c2Team %1 is starting on offense', $teamName[%game.offenseTeam]); + + //if the first offense team is team2, switch the object team designation + if (%game.offenseTeam == 2) + { + %group = nameToID("MissionGroup/Teams"); + %group.swapTeams(); + // search for vehicle pads also + %mcg = nameToID("MissionCleanup"); + %mcg.swapVehiclePads(); + } + + //also ensure the objectives are all on the defending team + %objSet = nameToId("MissionCleanup/Objectives"); + for(%j = 0; %j < %objSet.getCount(); %j++) + { + %obj = %objSet.getObject(%j); + %obj.team = %defenseTeam; + setTargetSensorGroup(%obj.getTarget(), %defenseTeam); + } + + //indicate we're starting the game from the beginning... + %game.firstHalf = true; + %game.timeLimitMS = $Host::TimeLimit * 60 * 1000; + %game.secondHalfCountDown = false; + %game.capPlayer[1] = ""; + %game.capPlayer[2] = ""; + + // save off turret bases' original barrels + %game.checkTurretBases(); + + // add objective waypoints + %game.findObjectiveWaypoints(); + + MissionGroup.setupPositionMarkers(true); +} + +function SiegeGame::checkTurretBases(%game) +{ + %mGroup = nameToID("MissionGroup/Teams"); + %mGroup.findTurretBase(); +} + +function SimGroup::findTurretBase(%this) +{ + for (%i = 0; %i < %this.getCount(); %i++) + %this.getObject(%i).findTurretBase(); +} + +function InteriorInstance::findTurretBase(%this) +{ + // sorry, we're not looking for interiors +} + +function AIObjective::findTurretBase(%this) +{ + // prevent console error spam +} + +function TSStatic::findTurretBase(%this) +{ + // prevent console error spam +} + +function GameBase::findTurretBase(%this) +{ + // apparently, the initialBarrel attribute gets overwritten whenever the + // barrel gets replaced. :( So we have to save it again under "originalBarrel". + if(%this.getDatablock().getName() $= "TurretBaseLarge") + %this.originalBarrel = %this.initialBarrel; +} + +function TSStatic::findTurretBase(%this) +{ + // prevent console error spam +} + +function SiegeGame::selectSpawnSphere(%game, %team) +{ + //for siege, the team1 drops are offense, team2 drops are defense + %sphereTeam = %game.offenseTeam == %team ? 1 : 2; + + return DefaultGame::selectSpawnSphere(%game, %sphereTeam); +} + +function SiegeGame::startMatch(%game) +{ + DefaultGame::startMatch( %game ); + + %game.startTimeMS = getSimTime(); + + // schedule first timeLimit check for 20 seconds + %game.timeSync = %game.schedule( 20000, "checkTimeLimit"); + %game.timeThread = %game.schedule( %game.timeLimitMS, "timeLimitReached"); + //updateClientTimes(%game.timeLimitMS); + messageAll('MsgSystemClock', "", $Host::TimeLimit, %game.timeLimitMS); + +// %count = ClientGroup.getCount(); +// for ( %i = 0; %i < %count; %i++ ) +// { +// %cl = ClientGroup.getObject( %i ); +// if ( %cl.team == %game.offenseTeam ) +// centerPrint( %cl, "\nTouch the enemy control switch to capture their base!", 5, 3 ); +// else +// centerPrint( %cl, "\nPrevent the enemy from touching your control switch!", 5, 3 ); +// } + + //make sure the AI is started + AISystemEnabled(true); +} + +function SiegeGame::allObjectivesCompleted(%game) +{ + Cancel( %game.timeSync ); + Cancel( %game.timeThread ); + cancelEndCountdown(); + + //store the elapsed time in the teamScore array... + $teamScore[%game.offenseTeam] = getSimTime() - %game.startTimeMS; + messageAll('MsgSiegeCaptured', '\c2Team %1 captured the base in %2!', $teamName[%game.offenseTeam], %game.formatTime($teamScore[%game.offenseTeam], true)); + + //set the new timelimit + %game.timeLimitMS = $teamScore[%game.offenseTeam]; + + if (%game.firstHalf) + { + // it's halftime, let everyone know + messageAll( 'MsgSiegeHalftime' ); + } + else + { + // game is over + messageAll('MsgSiegeMisDone', '\c2Mission complete.'); + } + logEcho("objective completed in "@%game.timeLimitMS); + + //setup the second half... + // MES -- per MarkF, scheduling for 0 seconds will prevent player deletion-related crashes + %game.schedule(0, halftime, 'objectives'); +} + +function SiegeGame::timeLimitReached(%game) +{ + cancel( %game.timeThread ); + cancel( %game.timeSync ); + + // if time has run out, the offense team gets no score (note, %game.timeLimitMS doesn't change) + $teamScore[%game.offenseTeam] = 0; + messageAll('MsgSiegeFailed', '\c2Team %1 failed to capture the base.', $teamName[%game.offenseTeam]); + + if (%game.firstHalf) + { + // it's halftime, let everyone know + messageAll( 'MsgSiegeHalftime' ); + } + else + { + // game is over + messageAll('MsgSiegeMisDone', '\c2Mission complete.'); + } + + logEcho("time limit reached"); + %game.halftime('time'); +} + +function SiegeGame::checkTimeLimit(%game) +{ + //if we're counting down to the beginning of the second half, check back in + if (%game.secondHalfCountDown) + { + %game.timeSync = %game.schedule(1000, "checkTimeLimit"); + return; + } + + %timeElapsedMS = getSimTime() - %game.startTimeMS; + %curTimeLeftMS = %game.timeLimitMS - %timeElapsedMS; + + if (%curTimeLeftMS <= 0) + { + // time's up, put down your pencils + %game.timeLimitReached(); + } + else + { + if(%curTimeLeftMS >= 20000) + %game.timeSync = %game.schedule( 20000, "checkTimeLimit" ); + else + %game.timeSync = %game.schedule( %curTimeLeftMS + 1, "checkTimeLimit" ); + + //now synchronize everyone's clock + messageAll('MsgSystemClock', "", $Host::TimeLimit, %curTimeLeftMS); + } +} + +function SiegeGame::startSecondHalf(%game) +{ + $MatchStarted = true; + %game.secondHalfCountDown = false; + + MessageAll('MsgMissionStart', "\c2Match started"); + + // set the start time. + //the new %game.timeLimitMS would have been set by timeLimitReached() or allObjectivesCompleted() + %game.startTimeMS = getSimTime(); + + %game.timeThread = %game.schedule(%game.timeLimitMS, "timeLimitReached"); + if (%game.timeLimitMS > 20000) + %game.timeSync = %game.schedule(20000, "checkTimeLimit"); + else + %game.timeSync = %game.schedule(%game.timeLimitMS, "checkTimeLimit"); + logEcho("start second half"); + + EndCountdown(%game.timeLimitMS); + + // set all clients control to their player + %count = ClientGroup.getCount(); + for( %i = 0; %i < %count; %i++ ) + { + %cl = ClientGroup.getObject(%i); + if (!isObject(%cl.player)) + commandToClient(%cl, 'setHudMode', 'Observer'); + else + { + %cl.observerMode = ""; + %cl.setControlObject( %cl.player ); + commandToClient(%cl, 'setHudMode', 'Standard'); +// if ( %client.team == %game.offenseTeam ) +// centerPrint( %cl, "\nTouch the enemy control switch to capture their base!", 5, 3 ); +// else +// centerPrint( %cl, "\nPrevent the enemy from touching your control switch!", 5, 3 ); + } + } + + //now synchronize everyone's clock + updateClientTimes(%game.timeLimitMS); + + //start the bots up again... + AISystemEnabled(true); +} + +function SiegeGame::halftime(%game, %reason) +{ + //stop the game and the bots + $MatchStarted = false; + AISystemEnabled(false); + + if (%game.firstHalf) + { + //switch the game variables + %game.firstHalf = false; + %oldOffenseTeam = %game.offenseTeam; + if (%game.offenseTeam == 1) + %game.offenseTeam = 2; + else + %game.offenseTeam = 1; + + //send the message + messageAll('MsgSiegeRolesSwitched', '\c2Team %1 is now on offense.', $teamName[%game.offenseTeam], %game.offenseTeam); + + //reset stations and vehicles that players were using + %game.resetPlayers(); + // zero out the counts for deployable items (found in defaultGame.cs) + %game.clearDeployableMaxes(); + + // z0dd - ZOD, 5/17/02. Clean up deployables triggers, function in supportClassic.cs + cleanTriggers(nameToID("MissionCleanup/Deployables")); + + // clean up the MissionCleanup group - note, this includes deleting all the player objects + %clean = nameToID("MissionCleanup"); + %clean.housekeeping(); + + // Non static objects placed in original position + resetNonStaticObjPositions(); + + // switch the teams for objects belonging to the teams + %group = nameToID("MissionGroup/Teams"); + %group.swapTeams(); + // search for vehicle pads also + %mcg = nameToID("MissionCleanup"); + %mcg.swapVehiclePads(); + + //restore the objects + %game.restoreObjects(); + + %count = ClientGroup.getCount(); + for(%cl = 0; %cl < %count; %cl++) + { + %client = ClientGroup.getObject(%cl); + if( !%client.isAIControlled() ) + { + // Put everybody in observer mode: + %client.camera.getDataBlock().setMode( %client.camera, "observerStaticNoNext" ); + %client.setControlObject( %client.camera ); + + // Send the halftime result info: + if ( %client.team == %oldOffenseTeam ) + { + if ( $teamScore[%oldOffenseTeam] > 0 ) + messageClient( %client, 'MsgSiegeResult', "", '%1 captured the %2 base in %3!', %game.capPlayer[%oldOffenseTeam], $teamName[%game.offenseTeam], %game.formatTime( $teamScore[%oldOffenseTeam], true ) ); + else + messageClient( %client, 'MsgSiegeResult', "", 'Your team failed to capture the %1 base.', $teamName[%game.offenseTeam] ); + } + else if ( $teamScore[%oldOffenseTeam] > 0 ) + messageClient( %client, 'MsgSiegeResult', "", '%1 captured your base in %3!', %game.capPlayer[%oldOffenseTeam], %game.formatTime( $teamScore[%oldOffenseTeam], true ) ); + else + messageClient( %client, 'MsgSiegeResult', "", 'Your team successfully held off team %1!', $teamName[%oldOffenseTeam] ); + + // List out the team rosters: + messageClient( %client, 'MsgSiegeAddLine', "", '%1%2', $TeamName[1], $TeamName[2] ); + %max = $TeamRank[1, count] > $TeamRank[2, count] ? $TeamRank[1, count] : $TeamRank[2, count]; + for ( %line = 0; %line < %max; %line++ ) + { + %plyr1 = $TeamRank[1, %line] $= "" ? "" : $TeamRank[1, %line].name; + %plyr2 = $TeamRank[2, %line] $= "" ? "" : $TeamRank[2, %line].name; + messageClient( %client, 'MsgSiegeAddLine', "", ' %1 %2', %plyr1, %plyr2 ); + } + + // Show observers: + %header = false; + for ( %i = 0; %i < %count; %i++ ) + { + %obs = ClientGroup.getObject( %i ); + if ( %obs.team <= 0 ) + { + if ( !%header ) + { + messageClient( %client, 'MsgSiegeAddLine', "", '\nOBSERVERS' ); + %header = true; + } + + messageClient( %client, 'MsgSiegeAddLine', "", ' %1', %obs.name ); + } + } + + commandToClient( %client, 'SetHalftimeClock', $Host::Siege::Halftime / 60000 ); + + // Get the HUDs right: + commandToClient( %client, 'setHudMode', 'SiegeHalftime' ); + commandToClient( %client, 'ControlObjectReset' ); + + clientResetTargets(%client, true); + %client.notReady = true; + } + } + + %game.schedule( $Host::Siege::Halftime, halftimeOver ); + } + else + { + // let's wrap it all up + %game.gameOver(); + cycleMissions(); + } +} + +function SiegeGame::halftimeOver( %game ) +{ + // drop all players into mission + %game.dropPlayers(); + + //setup the AI for the second half + %game.aiHalfTime(); + + // start the mission again (release players) + %game.halfTimeCountDown( $Host::warmupTime ); + + //redo the objective waypoints + %game.findObjectiveWaypoints(); +} + +function SiegeGame::dropPlayers( %game ) +{ + %count = ClientGroup.getCount(); + for(%cl = 0; %cl < %count; %cl++) + { + %client = ClientGroup.getObject(%cl); + if( !%client.isAIControlled() ) + { + // keep observers in observer mode + if(%client.team == 0) + %client.camera.getDataBlock().setMode(%client.camera, "justJoined"); + else + { + %game.spawnPlayer( %client, false ); + + %client.camera.getDataBlock().setMode( %client.camera, "pre-game", %client.player ); + %client.setControlObject( %client.camera ); + %client.notReady = false; + } + } + } +} + +function SiegeGame::resetPlayers(%game) +{ + // go through the client group and reset anything the players were using + // is most of this stuff really necessary? + %count = ClientGroup.getCount(); + for(%cl = 0; %cl < %count; %cl++) + { + %client = ClientGroup.getObject(%cl); + %player = %client.player; + + // clear the pack icon + messageClient(%client, 'msgPackIconOff', ""); + // if player was firing, stop firing + if(%player.getImageTrigger($WeaponSlot)) + %player.setImageTrigger($WeaponSlot, false); + + // if player had pack activated, deactivate it + if(%player.getImageTrigger($BackpackSlot)) + %player.setImageTrigger($BackpackSlot, false); + + // if player was in a vehicle, get rid of vehicle hud + commandToClient(%client, 'setHudMode', 'Standard', "", 0); + + // clear player's weapons and inventory huds + %client.SetWeaponsHudClearAll(); + %client.SetInventoryHudClearAll(); + + // if player was at a station, deactivate it + if(%player.station) + { + %player.station.triggeredBy = ""; + %player.station.getDataBlock().stationTriggered(%player.station, 0); + if(%player.armorSwitchSchedule) + cancel(%player.armorSwitchSchedule); + } + + // if piloting a vehicle, reset it (assuming it doesn't get deleted) + if(%player.lastVehicle.lastPilot) + %player.lastVehicle.lastPilot = ""; + } +} + +function SimGroup::housekeeping(%this) +{ + // delete selectively in the MissionCleanup group + %count = %this.getCount(); + // have to do this backwards or only half the objects will be deleted + for(%i = (%count - 1); %i > -1; %i--) + { + %detritus = %this.getObject(%i); + if(%detritus.getClassName() $= "SimSet") + { + // I don't think there are any simsets we want to delete + } + else if(%detritus.getName() $= "PZones") + { + // simgroup of physical zones for force fields + // don't delete them + } + //else if (%detritus.getClassName() $= "ScriptObject") + //{ + // // this will be the game type object. + // // DEFINITELY don't want to delete this. + //} + else if(%detritus.getName() $= PosMarker) + { + //Needed to reset non static objects... + } + else if((%detritus.getName() $= "TeamDrops1") || (%detritus.getName() $= "TeamDrops2")) + { + // this will actually be a SimSet named TeamDropsN (1 or 2) + // don't want to delete the spawn sphere groups, so do nothing + } + else if (%detritus.getName() $= "PlayerListGroup") + { + // we don't want to delete PlayerListGroup (SimGroup) + } + else if (%detritus.getDatablock().getName() $= "stationTrigger") + { + //we don't want to delete triggers for stations + } + else if (%detritus.getDatablock().getName() $= "StationVehicle") + { + // vehicle stations automatically get placed in MissionCleanup in a + // position near the vehicle pad. Don't delete it. + } + else if (%detritus.getClassName() $= "Camera") + { + // Cameras should NOT be deleted + } + else + { + // this group of stuff to be deleted should include: + // mines, deployed objects, projectiles, explosions, corpses, + // players, and the like. + %detritus.delete(); + } + } +} + +function SiegeGame::groupSwapTeams(%game, %this) +{ + for(%i = 0; %i < %this.getCount(); %i++) + %this.getObject(%i).swapTeams(); +} + +function SiegeGame::objectSwapTeams(%game, %this) +{ + %defTeam = %game.offenseTeam == 1 ? 2 : 1; + + if(%this.getDatablock().getName() $= "Flipflop") + { + if(getTargetSensorGroup(%this.getTarget()) != %defTeam) + { + setTargetSensorGroup(%this.getTarget(), %defTeam); + %this.team = %defTeam; + } + } + else + { + if(%this.getTarget() != -1) + { + if(getTargetSensorGroup(%this.getTarget()) == %game.offenseTeam) + { + setTargetSensorGroup(%this.getTarget(), %defTeam); + %this.team = %defTeam; + } + else if(getTargetSensorGroup(%this.getTarget()) == %defTeam) + { + setTargetSensorGroup(%this.getTarget(), %game.offenseTeam); + %this.team = %game.offenseTeam; + } + } + if(%this.getClassName() $= "Waypoint") + { + if(%this.team == %defTeam) + %this.team = %game.offenseTeam; + else if(%this.team == %game.offenseTeam) + %this.team = %defTeam; + } + } +} + +function SiegeGame::groupSwapVehiclePads(%game, %this) +{ + for(%i = 0; %i < %this.getCount(); %i++) + %this.getObject(%i).swapVehiclePads(); +} + +function SiegeGame::objectSwapVehiclePads(%game, %this) +{ + %defTeam = %game.offenseTeam == 1 ? 2 : 1; + + if(%this.getDatablock().getName() $= "StationVehicle") + { + if(%this.getTarget() != -1) + { + // swap the teams of both the vehicle pad and the vehicle station + if(getTargetSensorGroup(%this.getTarget()) == %game.offenseTeam) + { + setTargetSensorGroup(%this.getTarget(), %defTeam); + %this.team = %defTeam; + setTargetSensorGroup(%this.pad.getTarget(), %defTeam); + %this.pad.team = %defTeam; + // z0dd - ZOD, 4/20/02. Switch the teleporter too. + setTargetSensorGroup(%this.teleporter.getTarget(), %defTeam); + %this.teleporter.team = %defTeam; + } + else if(getTargetSensorGroup(%this.getTarget()) == %defTeam) + { + setTargetSensorGroup(%this.getTarget(), %game.offenseTeam); + %this.team = %game.offenseTeam; + setTargetSensorGroup(%this.pad.getTarget(), %game.offenseTeam); + %this.pad.team = %game.offenseTeam; + // z0dd - ZOD, 4/20/02. Switch the teleporter too. + setTargetSensorGroup(%this.teleporter.getTarget(), %game.offenseTeam); + %this.teleporter.team = %game.offenseTeam; + } + } + } +} + +function SiegeGame::restoreObjects(%game) +{ + // restore all the "permanent" mission objects to undamaged state + %group = nameToID("MissionGroup/Teams"); + // SimGroup::objectRestore is defined in DefaultGame.cs -- it simply calls + // %game.groupObjectRestore + %group.objectRestore(); +} + +function SiegeGame::groupObjectRestore(%game, %this) +{ + for(%i = 0; %i < %this.getCount(); %i++) + %this.getObject(%i).objectRestore(); +} + +function SiegeGame::shapeObjectRestore(%game, %object) +{ + //if(%object.getDatablock().getName() $= FlipFlop) + //{ + // messageAll('MsgSiegeObjRestore', "", %object.number, true); + //} + //else if(%object.getDamageLevel()) + if(%object.getDamageLevel()) + { + %object.setDamageLevel(0.0); + %object.setDamageState(Enabled); + } + if(%object.getDatablock().getName() $= "TurretBaseLarge") + { + // check to see if the turret base still has the same type of barrel it had + // at the beginning of the mission + if(%object.getMountedImage(0)) + if(%object.getMountedImage(0).getName() !$= %object.originalBarrel) + { + // pop the "new" barrel + %object.unmountImage(0); + // mount the original barrel + %object.mountImage(%object.originalBarrel, 0, false); + } + } +} + +function InteriorInstance::objectRestore(%this) +{ + // avoid console error spam +} + +function Trigger::objectRestore(%this) +{ + // avoid console error spam +} + +function TSStatic::objectRestore(%this) +{ + // avoid console error spam +} + +function ForceFieldBare::objectRestore(%this) +{ + // avoid console error spam +} + +// ------------------------------------------------------------------------ +// Waypoint managing + +function siegeGame::findObjectiveWaypoints(%game, %group) +{ + if(!%group) + %group = nameToId("MissionGroup/Teams"); + + for (%i = 0; %i < %group.getCount(); %i++) + { + %obj = %group.getObject(%i); + if(%obj.getClassName() $= SimGroup) + { + %game.findObjectiveWaypoints(%obj); + } + else if(%obj.needsObjectiveWaypoint) + { + %game.initializeWaypointAtObjective(%obj); + } + } +} + +function siegeGame::initializeWaypointAtObjective(%game, %object) +{ + // out with the old...jic + if ( %object.waypoint ) + { + if ( isObject( %object.waypoint ) ) + %object.waypoint.delete(); + else + %object.waypoint = ""; + } + + if(%object.team == %game.offenseTeam) + %team = %game.offenseTeam; + else + %team = (%game.offenseTeam == 1 ? 2 : 1); + + // to make the waypoint look a little prettier we are using the z from + // position and the x and y from worldBoxCenter + %posX = getWord(%object.getWorldBoxCenter(), 0); + %posY = getWord(%object.getWorldBoxCenter(), 1); + %posZ = getWord(%object.position, 2); + + %append = getTaggedString(%object.getDataBlock().targetTypeTag); + + %object.waypoint = new WayPoint() { + position = %posX SPC %posY SPC %posZ; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "WayPointMarker"; + team = %team; + name = getTaggedString(%object.nameTag) SPC %append; + }; + MissionCleanup.add(%object.waypoint); +} + +function siegeGame::switchWaypoint(%game, %waypoint) +{ + %team = %waypoint.team; + %newTeam = (%team == 1 ? 2 : 1); + + %waypoint.team = %newTeam; +} + + +function SiegeGame::gameOver(%game) +{ + //call the default + DefaultGame::gameOver(%game); + + cancel(%game.timeThread); + + messageAll('MsgClearObjHud', ""); +} + +function SiegeGame::sendDebriefing( %game, %client ) +{ + //if neither team captured + %winnerName = ""; + if ( $teamScore[1] == 0 && $teamScore[2] == 0 ) + %winner = -1; + + //else see if team1 won + else if ( $teamScore[1] > 0 && ( $teamScore[2] == 0 || $teamScore[1] < $teamScore[2] ) ) + { + %winner = 1; + %winnerName = $teamName[1]; + } + + //else see if team2 won + else if ($teamScore[2] > 0 && ($teamScore[1] == 0 || $teamScore[2] < $teamScore[1])) + { + %winner = 2; + %winnerName = $teamName[2]; + } + + //else see if it was a tie (right down to the millisecond - doubtful) + else if ($teamScore[1] == $teamScore[2]) + %winner = 0; + + //send the winner message + if (%winnerName $= 'Storm') + messageClient( %client, 'MsgGameOver', "Match has ended.~wvoice/announcer/ann.stowins.wav" ); + else if (%winnerName $= 'Inferno') + messageClient( %client, 'MsgGameOver', "Match has ended.~wvoice/announcer/ann.infwins.wav" ); + else + messageClient( %client, 'MsgGameOver', "Match has ended.~wvoice/announcer/ann.gameover.wav" ); + + // Mission result: + if (%winner > 0) + { + if (%winner == 1) + { + if ($teamScore[2] == 0) + messageClient(%client, 'MsgDebriefResult', "", 'Team %1 wins!', $TeamName[1]); + else + { + %timeDiffMS = $teamScore[2] - $teamScore[1]; + messageClient(%client, 'MsgDebriefResult', "", 'Team %1 won by capturing the base %2 faster!', $TeamName[1], %game.formatTime(%timeDiffMS, true)); + } + } + else + { + if ($teamScore[1] == 0) + messageClient(%client, 'MsgDebriefResult', "", 'Team %1 wins!', $TeamName[2]); + else + { + %timeDiffMS = $teamScore[1] - $teamScore[2]; + messageClient(%client, 'MsgDebriefResult', "", 'Team %1 won by capturing the base %2 faster!', $TeamName[2], %game.formatTime(%timeDiffMS, true)); + } + } + } + else + messageClient( %client, 'MsgDebriefResult', "", 'The mission ended in a tie.' ); + + // Game summary: + messageClient( %client, 'MsgDebriefAddLine', "", 'SUMMARY:' ); + %team1 = %game.offenseTeam == 1 ? 2 : 1; + %team2 = %game.offenseTeam; + if ( $teamScore[%team1] > 0 ) + { + %timeStr = %game.formatTime($teamScore[%team1], true); + messageClient( %client, 'MsgDebriefAddLine', "", '%1 captured the %2 base for Team %3 in %4.', %game.capPlayer[%team1], $TeamName[%team2], $TeamName[%team1], %timeStr); + } + else + messageClient( %client, 'MsgDebriefAddLine', "", 'Team %1 failed to capture the base.', $TeamName[%team1]); + + if ( $teamScore[%team2] > 0 ) + { + %timeStr = %game.formatTime($teamScore[%team2], true); + messageClient( %client, 'MsgDebriefAddLine', "", '%1 captured the %2 base for Team %3 in %4.', %game.capPlayer[%team2], $TeamName[%team1], $TeamName[%team2], %timeStr); + } + else + messageClient( %client, 'MsgDebriefAddLine', "", 'Team %1 failed to capture the base.', $TeamName[%team2]); + + // List out the team rosters: + messageClient( %client, 'MsgDebriefAddLine', "", '\n%1%2', $TeamName[1], $TeamName[2] ); + %max = $TeamRank[1, count] > $TeamRank[2, count] ? $TeamRank[1, count] : $TeamRank[2, count]; + for ( %line = 0; %line < %max; %line++ ) + { + %plyr1 = $TeamRank[1, %line] $= "" ? "" : $TeamRank[1, %line].name; + %plyr2 = $TeamRank[2, %line] $= "" ? "" : $TeamRank[2, %line].name; + messageClient( %client, 'MsgDebriefAddLine', "", ' %1 %2', %plyr1, %plyr2 ); + } + + // Show observers: + %count = ClientGroup.getCount(); + %header = false; + for ( %i = 0; %i < %count; %i++ ) + { + %cl = ClientGroup.getObject( %i ); + if ( %cl.team <= 0 ) + { + if ( !%header ) + { + messageClient( %client, 'MsgDebriefAddLine', "", '\nOBSERVERS' ); + %header = true; + } + + messageClient( %client, 'MsgDebriefAddLine', "", ' %1', %cl.name ); + } + } +} + +function SiegeGame::clientMissionDropReady(%game, %client) +{ + messageClient(%client, 'MsgClientReady', "", %game.class); + + for(%i = 1; %i <= %game.numTeams; %i++) + { + %isOffense = (%i == %game.offenseTeam); + messageClient(%client, 'MsgSiegeAddTeam', "", %i, $teamName[%i], %isOffense); + } + + messageClient(%client, 'MsgMissionDropInfo', '\c0You are in mission %1 (%2).', $MissionDisplayName, $MissionTypeDisplayName, $ServerName ); + DefaultGame::clientMissionDropReady(%game, %client); +} + +function SiegeGame::assignClientTeam(%game, %client, %respawn) +{ + DefaultGame::assignClientTeam(%game, %client, %respawn); + + // if player's team is not on top of objective hud, switch lines + messageClient(%client, 'MsgCheckTeamLines', "", %client.team); +} + +function SiegeGame::resetScore(%game, %client) +{ + %client.score = 0; + %client.kills = 0; + %client.deaths = 0; + %client.suicides = 0; + %client.objScore = 0; + %client.teamKills = 0; + %client.turretKills = 0; + %client.offenseScore = 0; + %client.defenseScore = 0; +} + +//--------------- Scoring functions ----------------- +function SiegeGame::recalcScore(%game, %cl) +{ + %killValue = %cl.kills * %game.SCORE_PER_KILL; + %deathValue = %cl.deaths * %game.SCORE_PER_DEATH; + + if (%killValue - %deathValue == 0) + %killPoints = 0; + else + %killPoints = (%killValue * %killValue) / (%killValue - %deathValue); + + %cl.offenseScore = %killPoints; + %cl.offenseScore += %cl.teamKills * %game.SCORE_PER_TEAMKILL; // -1 + %cl.offenseScore += %cl.objScore; + + %cl.defenseScore = %cl.turretKills * %game.SCORE_PER_TURRET_KILL; // 1 + + %cl.score = %cl.offenseScore + %cl.defenseScore; + %cl.score = mFloor(%cl.score); + %game.recalcTeamRanks(%cl); +} + +function SiegeGame::updateKillScores(%game, %clVictim, %clKiller, %damageType, %implement) +{ + if(%game.testTurretKill(%implement)) //check for turretkill before awarded a non client points for a kill + { + %game.awardScoreTurretKill(%clVictim, %implement); + } + else if (%game.testKill(%clVictim, %clKiller)) //verify victim was an enemy + { + %game.awardScoreKill(%clKiller); + %game.awardScoreDeath(%clVictim); + } + else + { + if (%game.testSuicide(%clVictim, %clKiller, %damageType)) //otherwise test for suicide + { + %game.awardScoreSuicide(%clVictim); + } + else + { + if (%game.testTeamKill(%clVictim, %clKiller)) //otherwise test for a teamkill + %game.awardScoreTeamKill(%clVictim, %clKiller); + } + } +} + +function SiegeGame::testValidRepair(%game, %obj) +{ + return ((%obj.lastDamagedByTeam != %obj.team) && (%obj.repairedBy.team == %obj.team)); +} + +function SiegeGame::genOnRepaired(%game, %obj, %objName) +{ + + if (%game.testValidRepair(%obj)) + { + %repairman = %obj.repairedBy; + messageTeam(%repairman.team, 'msgGenRepaired', '\c0%1 repaired the %2 generator!', %repairman.name, %obj.nameTag); + } +} + +function SiegeGame::stationOnRepaired(%game, %obj, %objName) +{ + if (%game.testValidRepair(%obj)) + { + %repairman = %obj.repairedBy; + messageTeam(%repairman.team, 'msgStationRepaired', '\c0%1 repaired the %2 inventory station!', %repairman.name, %obj.nameTag); + } +} + +function SiegeGame::sensorOnRepaired(%game, %obj, %objName) +{ + if (%game.testValidRepair(%obj)) + { + %repairman = %obj.repairedBy; + messageTeam(%repairman.team, 'msgSensorRepaired', '\c0%1 repaired the %2 pulse sensor!', %repairman.name, %obj.nameTag); + } +} + +function SiegeGame::turretOnRepaired(%game, %obj, %objName) +{ + if (%game.testValidRepair(%obj)) + { + %repairman = %obj.repairedBy; + messageTeam(%repairman.team, 'msgTurretRepaired', '\c0%1 repaired the %2 turret!', %repairman.name, %obj.nameTag); + } +} + +function SiegeGame::vStationOnRepaired(%game, %obj, %objName) +{ + if (%game.testValidRepair(%obj)) + { + %repairman = %obj.repairedBy; + messageTeam(%repairman.team, 'msgTurretRepaired', '\c0%1 repaired the %2 vehicle station!', %repairman.name, %obj.nameTag); + } +} + +function SiegeGame::halfTimeCountDown(%game, %time) +{ + %game.secondHalfCountDown = true; + $MatchStarted = false; + + %timeMS = %time * 1000; + %game.schedule(%timeMS, "startSecondHalf"); + notifyMatchStart(%timeMS); + + if(%timeMS > 30000) + schedule(%timeMS - 30000, 0, "notifyMatchStart", 30000); + if(%timeMS > 20000) + schedule(%timeMS - 20000, 0, "notifyMatchStart", 20000); + if(%timeMS > 10000) + schedule(%timeMS - 10000, 0, "notifyMatchStart", 10000); + if(%timeMS > 5000) + schedule(%timeMS - 5000, 0, "notifyMatchStart", 5000); + if(%timeMS > 4000) + schedule(%timeMS - 4000, 0, "notifyMatchStart", 4000); + if(%timeMS > 3000) + schedule(%timeMS - 3000, 0, "notifyMatchStart", 3000); + if(%timeMS > 2000) + schedule(%timeMS - 2000, 0, "notifyMatchStart", 2000); + if(%timeMS > 1000) + schedule(%timeMS - 1000, 0, "notifyMatchStart", 1000); +} + +function SiegeGame::applyConcussion(%game, %player) +{ +} + +function SiegeGame::updateScoreHud(%game, %client, %tag) +{ + %timeElapsedMS = getSimTime() - %game.startTimeMS; + %curTimeLeftMS = %game.timeLimitMS - %timeElapsedMS; + + if (!$MatchStarted) + %curTimeLeftStr = %game.formatTime(%game.timelimitMS, false); + else + %curTimeLeftStr = %game.formatTime(%curTimeLeftMS, false); + + // Send header: + if (%game.firstHalf) + messageClient( %client, 'SetScoreHudHeader', "", 'Team %1 has %2 to capture the base.', + $teamName[%game.offenseTeam], %curTimeLeftStr ); + else + messageClient( %client, 'SetScoreHudHeader', "", 'Team %1 must capture the base within %2 to win.', + $teamName[%game.offenseTeam], %curTimeLeftStr ); + + // Send subheader: + messageClient( %client, 'SetScoreHudSubheader', "", '\t%1 (%2)\t%3 (%4)', + $TeamName[1], $TeamRank[1, count], $TeamName[2], $TeamRank[2, count] ); + + %index = 0; + while (true) + { + if (%index >= $TeamRank[1, count] && %index >= $TeamRank[2, count]) + break; + + //get the team1 client info + %team1Client = ""; + %team1ClientScore = ""; + %col1Style = ""; + if (%index < $TeamRank[1, count]) + { + %team1Client = $TeamRank[1, %index]; + %team1ClientScore = %team1Client.score $= "" ? 0 : %team1Client.score; + if ( %team1Client == %client ) + %col1Style = ""; + } + + //get the team2 client info + %team2Client = ""; + %team2ClientScore = ""; + %col2Style = ""; + if (%index < $TeamRank[2, count]) + { + %team2Client = $TeamRank[2, %index]; + %team2ClientScore = %team2Client.score $= "" ? 0 : %team2Client.score; + if ( %team2Client == %client ) + %col2Style = ""; + } + + + //if the client is not an observer, send the message + if (%client.team != 0) + { + messageClient( %client, 'SetLineHud', "", %tag, %index, '\t%3%1\t%4%2', + %team1Client.name, %team2Client.name, %col1Style, %col2Style ); + } + //else for observers, create an anchor around the player name so they can be observed + else + { + messageClient( %client, 'SetLineHud', "", %tag, %index, '\t%3%1\t%4%2', + %team1Client.name, %team2Client.name, %col1Style, %col2Style, %team1Client, %team2Client ); + } + + %index++; + } + + // Tack on the list of observers: + %observerCount = 0; + for (%i = 0; %i < ClientGroup.getCount(); %i++) + { + %cl = ClientGroup.getObject(%i); + if (%cl.team == 0) + %observerCount++; + } + + if (%observerCount > 0) + { + messageClient( %client, 'SetLineHud', "", %tag, %index, ""); + %index++; + messageClient(%client, 'SetLineHud', "", %tag, %index, '\tOBSERVERS (%1)TIME', %observerCount); + %index++; + for (%i = 0; %i < ClientGroup.getCount(); %i++) + { + %cl = ClientGroup.getObject(%i); + //if this is an observer + if (%cl.team == 0) + { + %obsTime = getSimTime() - %cl.observerStartTime; + %obsTimeStr = %game.formatTime(%obsTime, false); + messageClient( %client, 'SetLineHud', "", %tag, %index, '\t%1%2', + %cl.name, %obsTimeStr ); + %index++; + } + } + } + + //clear the rest of Hud so we don't get old lines hanging around... + messageClient( %client, 'ClearHud', "", %tag, %index ); +} diff --git a/scripts/SinglePlayerGame.cs b/scripts/SinglePlayerGame.cs index 7c05804..623a860 100644 --- a/scripts/SinglePlayerGame.cs +++ b/scripts/SinglePlayerGame.cs @@ -1,1315 +1,1315 @@ -// Training Script -//echo("Running Training Script"); - -$InvBanList[SinglePlayer, "MiningTool"] = 1; - -datablock EffectProfile(TrainingHudUpdateEffect) -{ - effectname = "gui/objective_notification"; - minDistance = 10; -}; - -datablock AudioProfile(TrainingHudUpdateSound) -{ - filename = "gui/objective_notification.wav"; - description = AudioDefault3d; - effect = TrainingHudUpdateEffect; - preload = true; -}; - -datablock AudioProfile(MessageRecieveSound) -{ - filename = "gui/objective_notification.wav"; - description = AudioDefault3d; - preload = true; -}; - -// for training5 -datablock ForceFieldBareData(defaultNoTeamLavaLightField) -{ - fadeMS = 1000; - baseTranslucency = 1; - powerOffTranslucency = 0; - teamPermiable = false; - otherPermiable = false; - color = "1.0 0.4 0.0"; - targetTypeTag = 'ForceField'; - - texture[0] = "skins/forcef1"; - texture[1] = "skins/forcef2"; - texture[2] = "skins/forcef3"; - texture[3] = "skins/forcef4"; - texture[4] = "skins/forcef5"; - - framesPerSec = 10; - numFrames = 5; - scrollSpeed = 15; - umapping = 1.0; - vmapping = 0.15; -}; - -// load the voice text and wav file -exec("scripts/spDialog.cs"); - - -function setSinglePlayerGlobals() -{ - // server settings - //$MPRestoreBotCount = $Host::BotCount; this one is done automatically in server.cs - $MPRestoreBotMatchBotCount = $Host::BotMatchBotCount; - $MPRestoreBotsEnabled = $Host::BotsEnabled; - $MPRestoreMaxBotDifficulty = $Host::MaxBotDifficulty; - $MPRestoreMaxPlayers = $Host::MaxPlayers; - $MPRestoreMinBotDifficulty = $Host::MinBotDifficulty; - $MPRestoreTimeLimit = $Host::TimeLimit; - $MPRestoreTournamentMode = $Host::TournamentMode; - $MPRestorewarmupTime = $Host::warmupTime; - $MPRestoreTeamDamage = $teamDamage; - - //$Host::BotCount = "0"; - $Host::BotMatchBotCount = "0"; - $Host::BotsEnabled = "0"; - $Host::MaxBotDifficulty = "1"; - $Host::MaxPlayers = "64"; - $Host::MinBotDifficulty = "0"; - $Host::TimeLimit = "9999999"; - $Host::TournamentMode = "false"; - $Host::warmupTime = "0"; - - if($pref::trainingDifficulty < 1 || $pref::trainingDifficulty > 3) - $pref::trainingDifficulty = 1; - - if($pref::trainingDifficulty == 1) - $teamDamage = false; - else - $teamDamage = true; - - - // game settings - $MPRestoreteamSkin[1] = $teamSkin[1]; - $MPRestoreteamName[1] = $teamName[1]; - $MPRestoreholoName[1] = $holoName[1]; - $MPRestoreswitchSkin[1] = $switchSkin[1]; - - $MPRestoreteamSkin[2] = $teamSkin[2]; - $MPRestoreteamName[2] = $teamName[2]; - $MPRestoreholoName[2] = $holoName[2]; - $MPRestoreswitchSkin[2] = $switchSkin[2]; - - //Has been totally modified to support the functioning of multiple Campaigns - $playerTeam = $Training::PlayerTeam[$CurrentMission]; - $teamSkin[$playerTeam] = addTaggedString($Training::Skin[$CurrentMission]); - $teamName[$playerTeam] = addTaggedString($Training::TeamName[$CurrentMission]); - $holoName[$playerTeam] = stripChars($Training::TeamName[$CurrentMission]," "); - $switchSkin[$playerTeam] = addTaggedString($Training::Skin[$CurrentMission]); - $playerLivesAtEasy = $Training::StartLives[$CurrentMission]; - - $EnemyTeam = $Training::EnemyTeam[$CurrentMission]; - $teamSkin[$EnemyTeam] = addTaggedString($Training::EnemySkin[$CurrentMission]); - $teamName[$EnemyTeam] = addTaggedString($Training::EnemyName[$currentMission]); -// $holoName[$enemyTeam] = "Bioderm"; -// $switchSkin[$enemyTeam] = 'Bioderm'; - - if($enemyName $= "") - $EnemyName = "Enemy"; - - $trainingDefenseTauntList = "bas.enemy slf.att.attack slf.def.defend wrn.enemy tgt.acquired gbl.brag slf.def.base vqk.help"; - $trainingOffenseTauntList = "slf.att.attack gbl.brag vqk.help att.distract att.attack ene.disarray glb.awesome need.cover"; -} - -function resetSinglePlayerGlobals() -{ - - //error("================ single player global vars reset!"); - // server settings - //$Host::BotCount = $MPRestoreBotCount; - $Host::BotMatchBotCount = $MPRestoreBotMatchBotCount; - $Host::BotsEnabled = $MPRestoreBotsEnabled; - $Host::MaxBotDifficulty = $MPRestoreMaxBotDifficulty; - $Host::MaxPlayers = $MPRestoreMaxPlayers; - $Host::MinBotDifficulty = $MPRestoreMinBotDifficulty; - $Host::TimeLimit = $MPRestoreTimeLimit; - $Host::TournamentMode = $MPRestoreTournamentMode; - $Host::warmupTime = $MPRestorewarmupTime; - $teamDamage = $MPRestoreTeamDamage; - - // game settings - $teamSkin[1] = $MPRestoreteamSkin[1]; - $teamName[1] = $MPRestoreteamName[1]; - $holoName[1] = $MPRestoreholoName[1]; - $switchSkin[1] = $MPRestoreswitchSkin[1]; - - $teamSkin[2] = $MPRestoreteamSkin[2]; - $teamName[2] = $MPRestoreteamName[2]; - $holoName[2] = $MPRestoreholoName[2]; - $switchSkin[2] = $MPRestoreswitchSkin[2]; -} - -// Actors -//======================================================================================= - -function addEnemies() -{ - %num = $numberOfEnemies[$pref::TrainingDifficulty]; - error("Adding " @ %num @" enemies!"); - - %group = nameToId("MissionGroup/Teams/Team2/DropPoints"); - - for(%i = 0; %i < %num; %i++){ - %name = getUniqueEnemyName(); - %voice = "Derm"@getRandom(1,3); - %voicePitch = 1 - ((getRandom(20) - 10)/100); - - //%client = AIConnect($EnemyName@%i, $EnemyTeam, $missionBotSkill[$pref::TrainingDifficulty], true); - %client = AIConnect(%name, $EnemyTeam, $missionBotSkill[$pref::TrainingDifficulty], true, %voice, %voicePitch); - $Enemy[%i] = %client; - %client.race = $Training::EnemyRace[$CurrentMission]; - - setTargetSkin(%client.target, $teamSkin[$enemyTeam]); - //setTargetVoice(%client.target, addTaggedString(%client.voice)); - - //error("Setting race of "@$Enemy[%i]@" to "@$Enemy[%i].race); - if(%group.getObject(%i).Equipment || %group.getObject(%i).specialObjectives) { - %client.equipment = %group.getObject(%i).Equipment; - //error("Client: "@%client@ " has equipment "@%client.equipment); - %client.SpecialObjectives = %group.getObject(%i).SpecialObjectives; - //error("Client: "@%client@ " has specialEd "@%client.SpecialObjectives); - game.equip(%client.player); - } - - // this seems redundant after equip - %client.player.setArmor(%client.armor); - } -} - -// there are times (missions 2 and 4) where bots are not added with -// addEnemies(). there are x waves of bots with y number in each wave -// i do it a couple of times so im going to localize it here rather than -// do it twice or cut and paste it -function spawnWave(%wave) -{ - for(%i=1; %i<=$numberInWave[$pref::TrainingDifficulty]; %i++) { - %name = getUniqueEnemyName(); - %voice = "Derm"@getRandom(1,3); - %voicePitch = 1 - ((getRandom(20) - 10)/100); - %thisAi = aiConnect(%name, $enemyTeam, $missionBotSkill[$pref::TrainingDifficulty], false, %voice, %voicePitch); - //%thisAi = aiConnect("Wave"@%wave@"num"@%i, $enemyTeam, $missionBotSkill[$pref::TrainingDifficulty], false); - // here we differentiate the different drop points for wave spawned bots (these spawned bots are "!offense") - //error("added enemy "@%thisAi); - %thisAi.race = $Training::EnemyRace[$CurrentMission]; - %thisAi.voice = "Derm"@getRandom(3); - setTargetSkin(%thisAI.target, $teamSkin[$enemyTeam]); - setTargetVoice(%thisAI.target, addTaggedString(%thisAI.voice)); - %equipment = pickEquipment(); - game.equip(%thisAi.player, %equipment); - //%client.player.setArmor(%thisAi.armor); - - //create a little group - game.NumberInWave[%wave]++; - %thisAI.MemberOfWave = %wave; - - //anything mission specific that has to be done with this client - missionSpawnedAI(%thisAi); - } - game.spawnWaveTimer = spawnWaveTimer(%wave, false); -} - - -function addPlayersTeam(%num) -{ - //echo($player.team@"<---------players team on addPlayerTeam"); - - getTeammateGlobals(); - - for(%i=0; %i< %num; %i++){ - $Teammate[%i] = %client = AIConnect($TeammateWarnom[%i], $playerTeam, $teammateSkill[%i], true, $teammateVoice[%i]); - - %client.sex = $teammateGender[%i]; - %client.race = $Training::Race[$CurrentMission]; - %client.equipment = $teammateEquipment[%i]; - setTargetSkin(%client.target, $teamSkin[$playerTeam]); - game.equip(%client.player); - %client.player.setArmor(%client.armor); - - if (! %client.defaultTasksAdded) - { - %client.defaultTasksAdded = true; - %client.addTask(AIEngageTask); - %client.addTask(AIPickupItemTask); - %client.addTask(AIUseInventoryTask); - %client.addTask(AIEngageTurretTask); - %client.addtask(AIDetectMineTask); - } - - } - - //add Player=============================================================== - $player.lives = $playerLivesAtEasy - $pref::TrainingDifficulty; - - game.spawnPlayer($player, false); - setTargetSkin($player.target, $teamSkin[$playerTeam]); - -} - -function getUniqueEnemyName() -{ - if(!$enemyNameCount) - return; - - %used = false; - %name = pickUniqueEnemyName(); - %used = enemyNameIsUsed(%name); - while(%used) - { - if(%emergency++ > 1000) - { - //error("Too many times in the name while loop...using DEFAULT"); - return $enemyName; - } - %name = pickUniqueEnemyName(); - %used = enemyNameIsUsed(%name); - } - return %name; -} - -function pickUniqueEnemyName() -{ - %random = getRandom(1, $enemyNameCount); - %name = $EnemyNameList[%random]; - //error("returning" SPC %name SPC "from pick"); - return %name; -} - -function enemyNameIsUsed(%name) -{ - %number = game.usedNameCount; - for(%i = 0; %i <= %number; %i++) - { - if(game.usedName[%i] $= %name) - return true; - } - // the name is unused - game.usedName[game.usedNameCount++] = %name; - return false; -} - -function spawnWaveTimer(%wave, %reset) -{ - //error("SpawnTimer ACTIVATED"); - - if(%reset) - { - cancel(game.spawnWaveTimer); - %timeForAction = 60000 * 2; //2 min - } - else %timeForAction = 60000 * 4; //4 min - - game.spawnWaveTimer = schedule(%timeForAction, game, destroyWave, %wave); -} - -function DestroyWave(%wave) -{ - // this group has enemies in it that are dawdling and - // need to be killed to keep the game progressing - %num = clientGroup.getCount(); - for(%i = 0; %i < %num; %i++) - { - %client = clientGroup.getObject(%i); - if(%client.player && %client.MemberOfWave == %wave) - { - %client.player.applyDamage(%client.player.getDataBlock().maxDamage); - enemyWaveMemberKilled(%client); - } - } -} - - -function SinglePlayerGame::onClientKilled(%game, %clVictim, %clKiller, %damageType, %implement) -{ - if(game.missionOver) - return; - %clVictim.dead = true; - if(%clvictim.team == $enemyTeam && getRandom(1,1000) == 69) - doText(Any_jingo02); - missionClientKilled(%clVictim, %clKiller); - if(%clVictim.MemberOfWave) - enemyWaveMemberKilled(%clVictim ); - - Parent::onClientKilled(%game, %clVictim, %clKiller, %damageType, %implement); - cancel(%clVictim.respawnTimer); - - if(%clVictim == $player) { - // dead players are not out of bounds - cancel($player.OOB); - - $player.deaths++; - %num = $player.lives; - if( %num >= 1) { - if(%num == 1) - %textNum = "one life"; - else %textNum = %num SPC "lives"; - messageBoxOk("Restart", "You have" SPC %textNum SPC "remaining.", "spawnSinglePlayer();"); - } - else schedule(3000, $player.player, singlePlayerDead); - } -} - -function enemyWaveMemberKilled(%client) -{ - %wave = %client.MemberOfWave; - %remaining = game.numberInWave[%wave]--; - //error("Debug: Script reports that client " @ %client @ " was a member of wave " @ %wave @ " that now has " @ %remaining @ " members remaining."); - if(%remaining == 0) { - missionWaveDestroyed(%wave); - - if (%wave+1 <= $numberOfWaves[$pref::TrainingDifficulty]) - spawnWave(%wave+1); - //else error("Debug: " @ %wave @ " was the last wave."); - } -} - -function SinglePlayerGame::assignClientTeam(%game, %client) -{ - // The players team is set in singlePlayer::clientMissionDropReady - // and the bots are added to a team with aiConnect - // so this is unnecessary -} - -function singlePlayerGame::AIHasJoined() -{ - // Big deal...my missions are crawling with AI - // lets get rid of this mundane console spam -} - -function SinglePlayerGame::updateKillScores() -{ - // Do nothing other than get rid of the console warning... -} - -function singlePlayerGame::biodermAssume(%game, %client) -{ - //error(%client SPC "might talk."); - // dont do anything if we have just done this - if(%client.spgSpeaking) - return; - - %probability = 2; - %time = 30; // secs - - // we are going to POSSIBLY talk. flag it for %time secs - %client.spgSpeaking = true; - schedule(%time * 1000, %client, resetSpeakingFlag, %client); - - if(getRandom(%probability) == 1) - trainingBiodermSpeaks(%client); - -} - -function resetSpeakingFlag(%client) -{ - //error(%client SPC "can now speak again."); - %client.spgSpeaking = false; -} - -function trainingBiodermSpeaks(%client) -{ - if(%client.offense) // offense = defense? - %tauntlist = $trainingDefenseTauntList; //yes this seem wrong but its not - else - %tauntlist = $trainingOffenseTauntList; - %num = getWordCount(%tauntList); - %random = getRandom(%num - 1); - %use = getWord(%tauntList, %random); - //echo("Derm taunting:" SPC %use); - - playTargetAudio( %client.target, addTaggedString(%use), AudioClose3d, false ); -} - -function singlePlayerDead() -{ - missionFailed($player.miscMsg[trainingDeathLoss]); - AIMissionEnd(); - $objectiveQ[$enemyTeam].clear(); - cancel($player.distanceCheckSchedule); -} - -function SinglePlayerGame::missionLoadDone(%game) -{ - DefaultGame::missionLoadDone(%game); - - setSinglePlayerGlobals(); - $matchStarted = true; - //this has to happen sometime because game.startMatch never gets called - %game.clearDeployableMaxes(); -} - - -function SinglePlayerGame::notifyMatchStart(%game, %time) -{ - //do nothing -} - - -function SinglePlayerGame::clientMissionDropReady(%game, %client) -{ - DefaultGame::clientMissionDropReady(%game, %client); - - //echo(%client @ " is single player Ready!!!"); - messageClient(%client, 'MsgClientReady', "", %game.class); - - $Player = %client; - $player.race = $Training::Race[$CurrentMission]; - $player.sex = $Training::Sex[$CurrentMission]; - $player.team = $Training::PlayerTeam[$CurrentMission]; - $player.setTeam($Training::PlayerTeam); - setTargetSkin($teammate[%i].target, $teamSkin[$playerTeam]); - $player.clearBackpackIcon(); - - createText($player); - HUDMessageVector.clear(); - messageClient(%client, 'MsgMissionDropInfo', "", $MissionDisplayName, $MissionTypeDisplayName, $ServerName ); - - // We don't start in observer mode, so disable: - commandToClient(%client, 'setHudMode', 'Standard'); - - //custom training keymap - %game.createCustomKeyMap(); - - - addEnemies(); - //echo($player.team@"<---------players team on mission drop ready"); - addPlayersTeam($numberOfTeammates); - - //everybody's in, enable the AI system - AISystemEnabled(true); - - $player.setControlObject( $player.player ); - $player.camera = new Camera() - { - dataBlock = Observer; - }; - - startCurrentMission(%game); -} - -function SinglePlayerGame::AIInit(%game) -{ - //error("initializing Bot Q's for SinglePlayerGame..."); - for (%i = 0; %i <= %game.numTeams; %i++) - { - if (!isObject($ObjectiveQ[%i])) - { - $ObjectiveQ[%i] = new AIObjectiveQ(); - MissionCleanup.add($ObjectiveQ[%i]); - } - - //error("team " @ %i @ " objectives load..."); - $ObjectiveQ[%i].clear(); - AIInitObjectives(%i, %game); - } - - AIInit(); - - // Bots never throw grenades on Easy skills - if($pref::TrainingDifficulty == 1) - $AIDisableGrenades = true; -} - -// unlike the MP game, sometimes we start with switches (flipFlops) -// already on one team or the other and they are unskinned -function setFlipFlopSkins(%group) -{ - if(!%group) - %group = nameToID("Teams"); - - for(%i = 0; %i < %group.getCount(); %i++) { - %this = %group.getObject(%i); - if(%this.getClassName() $= "SimGroup") - setFlipFlopSkins(%this); - else if(%this.getDataBlock().getName() $= "FlipFlop") - setTargetSkin(%this.getTarget(), $teamSkin[%this.team]); - } -} - - - -function singlePlayerGame::gameOver(%game) -{ - moveMap.push(); - - ServerConnection.setBlackOut(false, 0); - - $timeScale = 1; - - game.missionOver = true; - - // clear the inventory and weapons hud - // BH: This doesn't actually DO anything... - //error("clearing Inv HUD for client " @ $player); - //$player.SetInventoryHudClearAll(); - - // im gonna try dropping all the clients - %count = clientGroup.getCount(); - echo("count=" SPC %count); - for(%i = 0; %i < %count; %i++) { - %client = clientGroup.getObject(%i); - game.client[%i] = %client; - freeClientTarget(%client); - } - for(%i = 0; %i < %count; %i++) { - %client = game.client[%i]; - echo("client=" SPC %client); - if(%client.isAIControlled()) - %client.drop(); - } - - //disable the AI system - AISystemEnabled(false); - $AIDisableChatResponse = ""; - - game.deactivatePackages(); - - if(isObject( $player.currentWaypoint )) - $player.currentWaypoint.delete(); - - if($player.OOB) - cancel($player.OOB); - - // clear the objective HUD - messageClient($player, 'MsgClearObjHud', ""); - - resetSinglePlayerGlobals(); - - $currentMissionType = ""; - DefaultGame::GameOver(%game); -} - -function singlePlayerGame::deactivatePackages(%game) -{ - error("singlePlayerGame packages deactivated"); - //Deactivate packages...gotta catch'm all - //deactivatepackage(SinglePlayer); - deactivatepackage(Training1); - deactivatepackage(Training2); - deactivatepackage(Training3); - deactivatepackage(Training4); - deactivatepackage(Training5); - deactivatepackage(Training6); - deactivatePackage(singlePlayerMissionAreaEnforce); -} -//------------------------------------------------------------------------------------ - - -// Voice line, text, function and audio parsing -//================================================================================= -// this is how we handle ALL the voice distribition and playing -// its NOT pretty -function doText(%name, %extraTime, %priority) -{ - if($player.text[%name, priority] || %priority) - addToQueueNext(%name); - else addToQueueEnd(%name); - - $player.text[%name, extraTime] = %extraTime; - processText(false); -} - -function processText(%cont) -{ - //we may need to fudge everysound to get it timed right - %universalSoundFudgingConstant = 400; - - if(isEventPending($currentlyPlaying) && !%cont) - return; - - %name = $player.Textque0; - if(%name $= "") - return; - - //echo("processing: "@%name); - if($player.Text[%name, eval] !$= "") - { - if (!isPureServer()) - eval($player.text[%name, eval]); - else - processTextEval($player.text[%name, eval]); - } - if($player.Text[%name, text] !$= "") { - // the old way: messageClient($player, 0, '\c2%1: %2',$trainerName, $player.Text[%name, line]); - messageClient($player, 0, "\c5"@$player.Text[%name, text]); - serverPlay2d(MessageRecieveSound); - } - if($player.Text[%name, wav] !$= "") { - //messageClient($player, 0, "~w"@$player.Text[%name, wav]); - %audio = alxCreateSource( AudioChat, $player.Text[%name, wav] ); - alxPlay( %audio ); - } - - removeFromQueue(); - - %wavLen = alxGetWaveLen($player.text[%name, wav]); - //if(%wavLen < 400) - // %wavLen = 400; // you cant go back in time, vge - - %time = %wavLen + $player.text[%name, extraTime] + %universalSoundFudgingConstant; - //echo("total delay time of"@%time); - - $currentlyPlaying = schedule(%time, $player.player, processText, true); - //if (!isPureServer()) - // schedule(%time, 0, eval, "$currentlyPlaying = false;"); - //else - // schedule(%time, 0, SPUnsetCurrentlyPlaying); -} - -function SPUnsetCurrentlyPlaying() -{ - $currentlyPlaying = ""; -error(getSimTime() SPC "DEBUG setting currentlyPlaying null"); -} - -function processTextEval(%evalStmt) -{ - switch$ (%evalStmt) - { - case "singlePlayerPlayGuiCheck();": - singlePlayerPlayGuiCheck(); - - case "schedule(3000, 0, disconnect);": - schedule(3000, 0, disconnect); - - case "lockArmorHack();autoToggleHelpHud(true);": - lockArmorHack();autoToggleHelpHud(true); - - case "flashMessage();": - flashMessage(); - - case "flashObjective();": - flashObjective(); - - case "flashCompass();": - flashCompass(); - - case "flashHealth();": - flashHealth(); - - case "flashEnergy();": - flashEnergy(); - - case "flashInventory();": - flashInventory(); - - case "flashSensor();": - flashSensor(); - - case "autoToggleHelpHud(false);": - autoToggleHelpHud(false); - - case "setWaypointAt(\"-287.5 393.1 76.2\", \"Health Patches\");movemap.push();$player.player.setMoveState(false);": - setWaypointAt("-287.5 393.1 76.2", "Health Patches");movemap.push();$player.player.setMoveState(false); - - case "$player.hurryUp = schedule(40000, 0, hurryPlayerUp); endOpeningSpiel(); updateTrainingObjectiveHud(obj8);": - $player.hurryUp = schedule(40000, 0, hurryPlayerUp); endOpeningSpiel(); updateTrainingObjectiveHud(obj8); - - case "updateTrainingObjectiveHud(obj7);": - updateTrainingObjectiveHud(obj7); - - case "flashWeapon(0);": - flashWeapon(0); - - case "flashWeapon(2);": - flashWeapon(2); - - case "flashWeapon(3); ": - flashWeapon(3); - - case "flashWeaponsHud();": - flashWeaponsHud(); - - case "use(Blaster);": - use(Blaster); - - case "queEnemySet(0); activatePackage(singlePlayerMissionAreaEnforce);": - queEnemySet(0); activatePackage(singlePlayerMissionAreaEnforce); - - case "setWaypointat(nameToId(Tower).position, \"BE Tower\"); updateTrainingObjectiveHud(obj4);": - setWaypointat(nameToId(Tower).position, "BE Tower"); updateTrainingObjectiveHud(obj4); - - case "flashPack();": - flashPack(); - - case "updateTrainingObjectiveHud(obj3);": - updateTrainingObjectiveHud(obj3); - - case "setWaypointAt(\"-8.82616 -131.779 119.756\", \"Control Switch\");": - setWaypointAt("-8.82616 -131.779 119.756", "Control Switch"); - - case "setWaypointAt(nameToId(InitialPulseSensor).position, \"Sensor\");": - setWaypointAt(nameToId(InitialPulseSensor).position, "Sensor"); - - case "setWaypointAt(\"-8.82616 -131.779 119.756\", \"Tower\");": - setWaypointAt("-8.82616 -131.779 119.756", "Tower"); - - case "setWaypointAt(\"380.262 -298.625 98.9719\", \"Tower\");": - setWaypointAt("380.262 -298.625 98.9719", "Tower"); - - case "firstPersonQuickPan();": - firstPersonQuickPan(); - - case "ThreeAEval();": - ThreeAEval(); - - case "game.ExpectiongSupportButton = true;": - game.ExpectiongSupportButton = true; - - case "game.expectingRepairOrder = true;": - game.expectingRepairOrder = true; - - case "$random = getRandom(20,40);schedule($random, 0, doText, T4_TipDefense06);": - $random = getRandom(20,40);schedule($random, 0, doText, T4_TipDefense06); - - case "training5addSafeDistance();": - training5addSafeDistance(); - } -} - - -function removeFromQueue() -{ - %i = 1; - while($player.textque[%i] !$= "") { - $player.textque[%i-1] = $player.textque[%i]; - %i++; - } - $player.textque[%i-1] = ""; -} - - -function addToQueueEnd(%name) -{ - %q = 0; - while($player.Textque[%q] !$= ""){ - %q++; - } - $player.Textque[%q] = %name; -} - -function addToQueueNext(%name) -{ - %q = 0; - while($player.Textque[%q] !$= ""){ - %q++; - } - for(%i=%q; %i>0; %i--) - $player.textque[%i] = $player.textque[%i-1]; - $player.textque0 = %name; -} - -function echoQueue() -{ - echo("Textque -------------------------------"); - %i = 0; - while($player.Textque[%i] !$= "") { - echo(%i@": "@$player.Textque[%i]); - %i++; - } -} - -function clearQueue() -{ - for(%i=0;%i<100; %i++) - $player.textQue[%i] = ""; -} - -//handy waypoint setting tool -//========================================================================= -function setWaypointAt(%location, %name, %team) -{ - %team = (!%team ? $playerTeam : %team); - // if(!%name) - // %name = ""; - if ( isObject( $player.currentWaypoint ) ) - $player.currentWaypoint.delete(); - - $player.currentWaypoint = new WayPoint(TurretTower) { - position = %location; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "WayPointMarker"; - team = %team; - name = %name; - }; - MissionCleanup.add($player.currentWaypoint); -} - -//this is just a little consolidation of functions -//its a little gregarious but allows text to live in spdialg.cs -//intent is to make hud updating easier and localization easier too ;) -function updateTrainingObjectiveHud( %objectiveNum ) -{ - - //sound - objectiveHud.setVisible(false); - if (!isPureServer()) - schedule(400, game, eval, "objectiveHud.setVisible(true);"); - else - schedule(400, game, setObjHudVisible); - - serverPlay2d(TrainingHudUpdateSound); - - //clear old text - messageClient($player, 'MsgSPCurrentObjective1', "", ' '); - messageClient($player, 'MsgSPCurrentObjective2', "", ' '); - - // find the lines from the spdialog file that are now attached to the sp client - %who = $player; - %mission = $currentMission; - for(%x = 1; %x <= 2; %x++) - %newObjectiveLine[%x] = $player.objHud[%mission, %objectiveNum, %x]; - - //add new text - messageClient($player, 'MsgSPCurrentObjective1', "", %newObjectiveLine1); - if(%newObjectiveLine2 !$= "") - messageClient($player, 'MsgSPCurrentObjective2', "", %newObjectiveLine2); -} - -function setObjHudVisible() -{ - objectiveHud.setVisible(true); -} - - -// Misc/Overwrites -//======================================================================================= - -function isSafe(%object, %radius) -{ - %team = %object.team; - %position = %object.player.getTransform(); - - //check for enemy players - %num = clientGroup.getCount(); - for(%client = 0; %client <= %num; %client++) - { - if(%team != %client.team && %client.player) { - %enemyPos = %client.player.getTransform(); - //okay, just in case we dont have a player for that client - //AND are close to "0 0 0" vge - if(!%enemyPos) - %dist = 100000; - else %dist = vectorDist(%position, %enemyPos); - //error("Debug: Client "@%client@" is "@%dist@" away"); - if ( %dist < %radius){ - //error("Unsafe because of client "@%client@" at a distance of "@%dist@"!!!!"); - return false; - } - } - } - //error("Safe for a radius of "@%radius@"!"); - return true; -} - -function singlePlayerGame::onAIRespawn(%game, %client) -{ - // add the default tasks - - if (! %client.defaultTasksAdded) - { - %client.defaultTasksAdded = true; - %client.addTask(AIEngageTask); - %client.addTask(AIPickupItemTask); - %client.addTask(AIUseInventoryTask); - %client.addTask(AIEngageTurretTask); - %client.addtask(AIDetectMineTask); - if(%client.team == $playerTeam || $pref::trainingDifficulty == 3) - %client.addTask(AITauntCorpseTask); - } -} - - -function singlePlayerGame::onAIKilled(%game, %clVictim, %clAttacker, %damageType, %implement) -{ - // dont respawn AI (this is overwritten in some of the mission packages) -} - - -function singleplayerGame::onClientDamaged(%game, %clVictim, %clAttacker, %damageType, %implement) -{ - //the DefaultGame will set some vars - DefaultGame::onClientDamaged(%game, %clVictim, %clAttacker, %damageType, %implement); - - //now see if both were on the same team - if(%clAttacker && %clAttacker != %clVictim && %clVictim.team == %clAttacker.team) - { - %game.friendlyFireMessage(%clVictim, %clAttacker); - } -} - -function singleplayerGame::onAIDamaged(%game, %clVictim, %clAttacker, %damageType, %implement) -{ - if(%clVictim.team != %clAttacker.team && %clVictim.MemberOfWave) - { - spawnWaveTimer(%clVictim.MemberOfWave, true); - } - - if (%clAttacker && %clAttacker != %clVictim && %clAttacker.team == %clVictim.team) - { - schedule(250, %clVictim, "AIPlayAnimSound", %clVictim, %clAttacker.player.getWorldBoxCenter(), "wrn.watchit", -1, -1, 0); - - //clear the "lastDamageClient" tag so we don't turn on teammates... unless it's uberbob! - %clVictim.lastDamageClient = -1; - } -} - -// find number of players on a team -// why isnt this in a std lib -function getPlayersOnTeam(%team) -{ - %num = clientGroup.getCount(); - for(%i=0; %i<%num; %i++){ - %client = clientGroup.getObject(%i); - if(%client.team == %team && %client.player) - %count++; - } - - return %count; -} - - -//mission completion/falure stuff============================================ -function missionComplete(%text) -{ - $player.endMission = schedule(15000, game, forceFinish); - - messageBoxOk("Victory", %text, "forceFinish();"); - - //AI stop - clearQueue(); - AIMissionEnd(); - $objectiveQ[$enemyTeam].clear(); -} - -function forceFinish() -{ - $timeScale = 1; - //kill the thread if we pressed a button to get here... - cancel($player.endMission); - - //make sure we end the game neatly - Game.gameOver(); - - //immediately disconnect - bringing us back to the main menu... - Disconnect(); -} - -function missionFailed(%text) -{ - - $player.endMission = schedule(30000, game, forceFinish); - - MessageBoxYesNo("Failure", %text, "reloadMission();", "forceFinish();"); - - //AI stop - cancel($Player.T1OpeningSpielSchedule); - cancel($Player.distanceCheckSchedule); - clearQueue(); - AIMissionEnd(); - $objectiveQ[$enemyTeam].clear(); -} - -function reloadMission() -{ - cancel($player.endMission); - Game.gameOver(); - Canvas.setContent( LoadingGui ); - loadMission($currentMission, singlePlayer); - debriefContinue(); -} - - -// silly...we fed it a movemap binding it retuns the capitalized key in (almost) english -function findTrainingControlButtons( %name ) -{ - %controlName = moveMap.getBinding(%name); - if (%controlName $= "") - return "[no key binding]"; - %prettyName = strupr(getMapDisplayName(getWord(%controlName, 0), getWord(%controlName, 1))); - %next = 2; - while( getWord( %controlName, %next ) !$= "" ) { - %extra = "-"@strupr(getWord( %controlName, 2 )); - %prettyName = %prettyName @ %extra; - %next++; - } - return %prettyName; -} - -// just a kinda cool little effect -function firstPersonQuickPan() -{ - if($firstperson) { - toggleFirstPerson($player); - schedule(4000, $player.player, toggleFirstPerson, $player); - } - -} - - -// Player spawning/respawning==================================================== -//since we are going through pickTeamSpawn rather than pickPlayerSpawn -// and for a couple other reasons, we are going to need to manually determine -// if this is a respawn or not. -function spawnSinglePlayer() -{ - $player.lives--; - - game.spawnPlayer($player, true); - $player.setControlObject($player.player); - //messageClient($player, 0, "Respawns Remaining: "@$player.lives); -} - - -function singleplayerGame::observerOnTrigger() -{ - //we dont want the player respawning (yet) - return false; -} - -function SinglePlayerGame::spawnPlayer( %game, %client, %respawn ) -{ - //error("Spawn Player: %client = " @%client@" %respawn = "@%respawn); - %spawnPoint = %game.pickPlayerSpawn( %client, %respawn ); - %game.createPlayer( %client, %spawnPoint, %respawn ); -} - -function singlePlayerGame::playerSpawned(%game, %player) -{ - defaultGame::playerSpawned(%game, %player); -} - -function singleplayerGame::pickPlayerSpawn(%game, %client, %respawn) -{ - // the bots, for some reason, always pass in %respawn as true - // well that's horse pucky, since the bots never respawn in SPG - // so I do this stupid thing - if(%client.isAIcontrolled()) - %respawn = false; - - if(!%client.offense) // this is a wave spawned attack bot - %respawn = true; - - - %game.pickTeamSpawn( %client, %respawn); -} - -function singleplayerGame::pickTeamSpawn(%game, %client, %respawn) -{ - %team = %client.team; - - if(%respawn) { - %group = nameToID("MissionGroup/Teams/team"@%team@"/DropPoints/Respawns"); - if(! isObject(%group)) { - //error("Client" SPC %client SPC "is attempting a respawn with no drop point"); - return "0 0 300"; - } - else %spawnLoc = %group.getObject(game.respawnPoint); - //error("REspawn loc is: " @ %spawnLoc); - } - - else { - %group = nameToID("MissionGroup/Teams/team" @ %team @ "/DropPoints"); - %spawnLoc = %group.getObject(game.spawnLoc[%team]); - //error("spawn loc is: "@game.spawnLoc[%team]); - game.spawnLoc[%team]++; - } - return %spawnLoc.getTransform(); -} - - -function SinglePlayerGame::createCustomKeymap(%game) -{ -// new ActionMap(TrainingMap); -// TrainingMap.bindCmd( keyboard, "escape", "escapeFromGame();", "" ); -} - -//======================================================================================= -// Escape dialog functions: -//======================================================================================= -function SinglePlayerEscapeDlg::onWake( %this ) -{ - $timeScale = 0; - - if( OptionsDlg.isAwake()) - { - Canvas.popDialog( OptionsDlg ); - } -} - -function SinglePlayerEscapeDlg::onSleep( %this ) -{ -// spMap.pop(); -// spMap.delete(); -} - - -function SinglePlayerEscapeDlg::leaveGame( %this ) -{ - Canvas.popDialog( SinglePlayerEscapeDlg ); - MessageBoxYesNo( "LEAVE GAME", $player.miscMsg[LeaveGame], "forceFinish();", "$timeScale = 1;" ); -} - -function SinglePlayerEscapeDlg::gotoSettings( %this ) -{ - Canvas.popDialog( SinglePlayerEscapeDlg ); - Canvas.pushDialog( OptionsDlg ); -} - -function SinglePlayerEscapeDlg::returnToGame( %this ) -{ - //error( "** CALLING SinglePlayerEscapeDlg::returnToGame **" ); - $timeScale = 1; - Canvas.popDialog( SinglePlayerEscapeDlg ); - - movemap.push(); - //trainingmap.push(); -} - - -function singlePlayerGame::OptionsDlgSleep(%game) -{ - $enableDirectInput = 1; - activateDirectInput(); - - Canvas.pushDialog( SinglePlayerEscapeDlg ); - // the player may have changed his keys - // we need to reload the big spdialog string table that - // holds all the text related to the players keymappings - createText($player); -} - -// mission Area package -package singlePlayerMissionAreaEnforce { -// -begin mission area package------------------------------------------------- - -// OOB -function SinglePlayerGame::leaveMissionArea(%game, %playerData, %player) -{ - parent::leaveMissionArea(%game, %playerData, %player); - if(%player == $player.player) { - $player.leftMissionArea++; - %timeAllowed = 30; - $player.OOB = schedule(%timeAllowed *1000, 0, wussOut, %player); - clearQueue(); - doText(Any_offcourse); - MessageClient($player, 0, $player.miscMsg[OOB]); - %player.playerLeftMissionArea = true; - } -} -function SinglePlayerGame::enterMissionArea(%game, %playerData, %player) -{ - parent::enterMissionArea(%game, %playerData, %player); - if(%player == $player.player && %player.playerLeftMissionArea) { - //echo("player back in bounds"); - cancel($player.OOB); - clearQueue(); - doText(Any_alright); - MessageClient($player, 0, $player.miscMsg[InBounds]); - } -} -function wussOut(%player) -{ - clearQueue(); - doText(Any_abort); - missionFailed($player.miscMsg[OOBLoss]); -} - -// -end mission area package------------------------------------------------- -}; - -// Custom Particle effects for training5 - -datablock ParticleData(BeforeT5particle) -{ - dragCoefficient = 0; - gravityCoefficient = -0.017094; - inheritedVelFactor = 0.0176125; - constantAcceleration = -0.8; - lifetimeMS = 1248; - lifetimeVarianceMS = 0; - useInvAlpha = 1; - spinRandomMin = -200; - spinRandomMax = 200; - textureName = "particleTest"; - colors[0] = "1.000000 0.677165 0.000000 1.000000"; - colors[1] = "0.708661 0.507812 0.000000 1.000000"; - colors[2] = "0.000000 0.000000 0.000000 0.000000"; - colors[3] = "1.000000 1.000000 1.000000 1.000000"; - sizes[0] = 0.991882; - sizes[1] = 2.99091; - sizes[2] = 4.98993; - sizes[3] = 1; - times[0] = 0; - times[1] = 0.2; - times[2] = 1; - times[3] = 2; -}; - -datablock ParticleData(AfterT5particle) -{ - dragCoefficient = 0; - gravityCoefficient = -0.017094; - inheritedVelFactor = 0.0176125; - constantAcceleration = -1.1129; - lifetimeMS = 2258; - lifetimeVarianceMS = 604; - useInvAlpha = 1; - spinRandomMin = -200; - spinRandomMax = 200; - textureName = "special/Smoke/smoke_001"; - colors[0] = "1.000000 0.677165 0.000000 1.000000"; - colors[1] = "0.181102 0.181102 0.181102 1.000000"; - colors[2] = "0.000000 0.000000 0.000000 0.000000"; - colors[3] = "1.000000 1.000000 1.000000 1.000000"; - sizes[0] = 0.991882; - sizes[1] = 2.99091; - sizes[2] = 4.98993; - sizes[3] = 1; - times[0] = 0; - times[1] = 0.2; - times[2] = 1; - times[3] = 2; -}; - -datablock ParticleEmitterData(BeforeT5) -{ - ejectionPeriodMS = 16; - periodVarianceMS = 10; - ejectionVelocity = 7.45968; - velocityVariance = 0.25; - ejectionOffset = 0; - thetaMin = 0; - thetaMax = 180; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = 0; - orientParticles= 0; - orientToNormal = 0; - orientOnVelocity = 1; - particles = "BeforeT5particle"; -}; - -datablock ParticleEmitterData(AfterT5) -{ - ejectionPeriodMS = 10; - periodVarianceMS = 0; - ejectionVelocity = 10.25; - velocityVariance = 0.25; - ejectionOffset = 0; - thetaMin = 0; - thetaMax = 180; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = 0; - orientParticles= 0; - orientToNormal = 0; - orientOnVelocity = 1; - particles = "AfterT5particle"; -}; +// Training Script +//echo("Running Training Script"); + +$InvBanList[SinglePlayer, "MiningTool"] = 1; + +datablock EffectProfile(TrainingHudUpdateEffect) +{ + effectname = "gui/objective_notification"; + minDistance = 10; +}; + +datablock AudioProfile(TrainingHudUpdateSound) +{ + filename = "gui/objective_notification.wav"; + description = AudioDefault3d; + effect = TrainingHudUpdateEffect; + preload = true; +}; + +datablock AudioProfile(MessageRecieveSound) +{ + filename = "gui/objective_notification.wav"; + description = AudioDefault3d; + preload = true; +}; + +// for training5 +datablock ForceFieldBareData(defaultNoTeamLavaLightField) +{ + fadeMS = 1000; + baseTranslucency = 1; + powerOffTranslucency = 0; + teamPermiable = false; + otherPermiable = false; + color = "1.0 0.4 0.0"; + targetTypeTag = 'ForceField'; + + texture[0] = "skins/forcef1"; + texture[1] = "skins/forcef2"; + texture[2] = "skins/forcef3"; + texture[3] = "skins/forcef4"; + texture[4] = "skins/forcef5"; + + framesPerSec = 10; + numFrames = 5; + scrollSpeed = 15; + umapping = 1.0; + vmapping = 0.15; +}; + +// load the voice text and wav file +exec("scripts/spDialog.cs"); + + +function setSinglePlayerGlobals() +{ + // server settings + //$MPRestoreBotCount = $Host::BotCount; this one is done automatically in server.cs + $MPRestoreBotMatchBotCount = $Host::BotMatchBotCount; + $MPRestoreBotsEnabled = $Host::BotsEnabled; + $MPRestoreMaxBotDifficulty = $Host::MaxBotDifficulty; + $MPRestoreMaxPlayers = $Host::MaxPlayers; + $MPRestoreMinBotDifficulty = $Host::MinBotDifficulty; + $MPRestoreTimeLimit = $Host::TimeLimit; + $MPRestoreTournamentMode = $Host::TournamentMode; + $MPRestorewarmupTime = $Host::warmupTime; + $MPRestoreTeamDamage = $teamDamage; + + //$Host::BotCount = "0"; + $Host::BotMatchBotCount = "0"; + $Host::BotsEnabled = "0"; + $Host::MaxBotDifficulty = "1"; + $Host::MaxPlayers = "64"; + $Host::MinBotDifficulty = "0"; + $Host::TimeLimit = "9999999"; + $Host::TournamentMode = "false"; + $Host::warmupTime = "0"; + + if($pref::trainingDifficulty < 1 || $pref::trainingDifficulty > 3) + $pref::trainingDifficulty = 1; + + if($pref::trainingDifficulty == 1) + $teamDamage = false; + else + $teamDamage = true; + + + // game settings + $MPRestoreteamSkin[1] = $teamSkin[1]; + $MPRestoreteamName[1] = $teamName[1]; + $MPRestoreholoName[1] = $holoName[1]; + $MPRestoreswitchSkin[1] = $switchSkin[1]; + + $MPRestoreteamSkin[2] = $teamSkin[2]; + $MPRestoreteamName[2] = $teamName[2]; + $MPRestoreholoName[2] = $holoName[2]; + $MPRestoreswitchSkin[2] = $switchSkin[2]; + + //Has been totally modified to support the functioning of multiple Campaigns + $playerTeam = $Training::PlayerTeam[$CurrentMission]; + $teamSkin[$playerTeam] = addTaggedString($Training::Skin[$CurrentMission]); + $teamName[$playerTeam] = addTaggedString($Training::TeamName[$CurrentMission]); + $holoName[$playerTeam] = stripChars($Training::TeamName[$CurrentMission]," "); + $switchSkin[$playerTeam] = addTaggedString($Training::Skin[$CurrentMission]); + $playerLivesAtEasy = $Training::StartLives[$CurrentMission]; + + $EnemyTeam = $Training::EnemyTeam[$CurrentMission]; + $teamSkin[$EnemyTeam] = addTaggedString($Training::EnemySkin[$CurrentMission]); + $teamName[$EnemyTeam] = addTaggedString($Training::EnemyName[$currentMission]); +// $holoName[$enemyTeam] = "Bioderm"; +// $switchSkin[$enemyTeam] = 'Bioderm'; + + if($enemyName $= "") + $EnemyName = "Enemy"; + + $trainingDefenseTauntList = "bas.enemy slf.att.attack slf.def.defend wrn.enemy tgt.acquired gbl.brag slf.def.base vqk.help"; + $trainingOffenseTauntList = "slf.att.attack gbl.brag vqk.help att.distract att.attack ene.disarray glb.awesome need.cover"; +} + +function resetSinglePlayerGlobals() +{ + + //error("================ single player global vars reset!"); + // server settings + //$Host::BotCount = $MPRestoreBotCount; + $Host::BotMatchBotCount = $MPRestoreBotMatchBotCount; + $Host::BotsEnabled = $MPRestoreBotsEnabled; + $Host::MaxBotDifficulty = $MPRestoreMaxBotDifficulty; + $Host::MaxPlayers = $MPRestoreMaxPlayers; + $Host::MinBotDifficulty = $MPRestoreMinBotDifficulty; + $Host::TimeLimit = $MPRestoreTimeLimit; + $Host::TournamentMode = $MPRestoreTournamentMode; + $Host::warmupTime = $MPRestorewarmupTime; + $teamDamage = $MPRestoreTeamDamage; + + // game settings + $teamSkin[1] = $MPRestoreteamSkin[1]; + $teamName[1] = $MPRestoreteamName[1]; + $holoName[1] = $MPRestoreholoName[1]; + $switchSkin[1] = $MPRestoreswitchSkin[1]; + + $teamSkin[2] = $MPRestoreteamSkin[2]; + $teamName[2] = $MPRestoreteamName[2]; + $holoName[2] = $MPRestoreholoName[2]; + $switchSkin[2] = $MPRestoreswitchSkin[2]; +} + +// Actors +//======================================================================================= + +function addEnemies() +{ + %num = $numberOfEnemies[$pref::TrainingDifficulty]; + error("Adding " @ %num @" enemies!"); + + %group = nameToId("MissionGroup/Teams/Team2/DropPoints"); + + for(%i = 0; %i < %num; %i++){ + %name = getUniqueEnemyName(); + %voice = "Derm"@getRandom(1,3); + %voicePitch = 1 - ((getRandom(20) - 10)/100); + + //%client = AIConnect($EnemyName@%i, $EnemyTeam, $missionBotSkill[$pref::TrainingDifficulty], true); + %client = AIConnect(%name, $EnemyTeam, $missionBotSkill[$pref::TrainingDifficulty], true, %voice, %voicePitch); + $Enemy[%i] = %client; + %client.race = $Training::EnemyRace[$CurrentMission]; + + setTargetSkin(%client.target, $teamSkin[$enemyTeam]); + //setTargetVoice(%client.target, addTaggedString(%client.voice)); + + //error("Setting race of "@$Enemy[%i]@" to "@$Enemy[%i].race); + if(%group.getObject(%i).Equipment || %group.getObject(%i).specialObjectives) { + %client.equipment = %group.getObject(%i).Equipment; + //error("Client: "@%client@ " has equipment "@%client.equipment); + %client.SpecialObjectives = %group.getObject(%i).SpecialObjectives; + //error("Client: "@%client@ " has specialEd "@%client.SpecialObjectives); + game.equip(%client.player); + } + + // this seems redundant after equip + %client.player.setArmor(%client.armor); + } +} + +// there are times (missions 2 and 4) where bots are not added with +// addEnemies(). there are x waves of bots with y number in each wave +// i do it a couple of times so im going to localize it here rather than +// do it twice or cut and paste it +function spawnWave(%wave) +{ + for(%i=1; %i<=$numberInWave[$pref::TrainingDifficulty]; %i++) { + %name = getUniqueEnemyName(); + %voice = "Derm"@getRandom(1,3); + %voicePitch = 1 - ((getRandom(20) - 10)/100); + %thisAi = aiConnect(%name, $enemyTeam, $missionBotSkill[$pref::TrainingDifficulty], false, %voice, %voicePitch); + //%thisAi = aiConnect("Wave"@%wave@"num"@%i, $enemyTeam, $missionBotSkill[$pref::TrainingDifficulty], false); + // here we differentiate the different drop points for wave spawned bots (these spawned bots are "!offense") + //error("added enemy "@%thisAi); + %thisAi.race = $Training::EnemyRace[$CurrentMission]; + %thisAi.voice = "Derm"@getRandom(3); + setTargetSkin(%thisAI.target, $teamSkin[$enemyTeam]); + setTargetVoice(%thisAI.target, addTaggedString(%thisAI.voice)); + %equipment = pickEquipment(); + game.equip(%thisAi.player, %equipment); + //%client.player.setArmor(%thisAi.armor); + + //create a little group + game.NumberInWave[%wave]++; + %thisAI.MemberOfWave = %wave; + + //anything mission specific that has to be done with this client + missionSpawnedAI(%thisAi); + } + game.spawnWaveTimer = spawnWaveTimer(%wave, false); +} + + +function addPlayersTeam(%num) +{ + //echo($player.team@"<---------players team on addPlayerTeam"); + + getTeammateGlobals(); + + for(%i=0; %i< %num; %i++){ + $Teammate[%i] = %client = AIConnect($TeammateWarnom[%i], $playerTeam, $teammateSkill[%i], true, $teammateVoice[%i]); + + %client.sex = $teammateGender[%i]; + %client.race = $Training::Race[$CurrentMission]; + %client.equipment = $teammateEquipment[%i]; + setTargetSkin(%client.target, $teamSkin[$playerTeam]); + game.equip(%client.player); + %client.player.setArmor(%client.armor); + + if (! %client.defaultTasksAdded) + { + %client.defaultTasksAdded = true; + %client.addTask(AIEngageTask); + %client.addTask(AIPickupItemTask); + %client.addTask(AIUseInventoryTask); + %client.addTask(AIEngageTurretTask); + %client.addtask(AIDetectMineTask); + } + + } + + //add Player=============================================================== + $player.lives = $playerLivesAtEasy - $pref::TrainingDifficulty; + + game.spawnPlayer($player, false); + setTargetSkin($player.target, $teamSkin[$playerTeam]); + +} + +function getUniqueEnemyName() +{ + if(!$enemyNameCount) + return; + + %used = false; + %name = pickUniqueEnemyName(); + %used = enemyNameIsUsed(%name); + while(%used) + { + if(%emergency++ > 1000) + { + //error("Too many times in the name while loop...using DEFAULT"); + return $enemyName; + } + %name = pickUniqueEnemyName(); + %used = enemyNameIsUsed(%name); + } + return %name; +} + +function pickUniqueEnemyName() +{ + %random = getRandom(1, $enemyNameCount); + %name = $EnemyNameList[%random]; + //error("returning" SPC %name SPC "from pick"); + return %name; +} + +function enemyNameIsUsed(%name) +{ + %number = game.usedNameCount; + for(%i = 0; %i <= %number; %i++) + { + if(game.usedName[%i] $= %name) + return true; + } + // the name is unused + game.usedName[game.usedNameCount++] = %name; + return false; +} + +function spawnWaveTimer(%wave, %reset) +{ + //error("SpawnTimer ACTIVATED"); + + if(%reset) + { + cancel(game.spawnWaveTimer); + %timeForAction = 60000 * 2; //2 min + } + else %timeForAction = 60000 * 4; //4 min + + game.spawnWaveTimer = schedule(%timeForAction, game, destroyWave, %wave); +} + +function DestroyWave(%wave) +{ + // this group has enemies in it that are dawdling and + // need to be killed to keep the game progressing + %num = clientGroup.getCount(); + for(%i = 0; %i < %num; %i++) + { + %client = clientGroup.getObject(%i); + if(%client.player && %client.MemberOfWave == %wave) + { + %client.player.applyDamage(%client.player.getDataBlock().maxDamage); + enemyWaveMemberKilled(%client); + } + } +} + + +function SinglePlayerGame::onClientKilled(%game, %clVictim, %clKiller, %damageType, %implement) +{ + if(game.missionOver) + return; + %clVictim.dead = true; + if(%clvictim.team == $enemyTeam && getRandom(1,1000) == 69) + doText(Any_jingo02); + missionClientKilled(%clVictim, %clKiller); + if(%clVictim.MemberOfWave) + enemyWaveMemberKilled(%clVictim ); + + Parent::onClientKilled(%game, %clVictim, %clKiller, %damageType, %implement); + cancel(%clVictim.respawnTimer); + + if(%clVictim == $player) { + // dead players are not out of bounds + cancel($player.OOB); + + $player.deaths++; + %num = $player.lives; + if( %num >= 1) { + if(%num == 1) + %textNum = "one life"; + else %textNum = %num SPC "lives"; + messageBoxOk("Restart", "You have" SPC %textNum SPC "remaining.", "spawnSinglePlayer();"); + } + else schedule(3000, $player.player, singlePlayerDead); + } +} + +function enemyWaveMemberKilled(%client) +{ + %wave = %client.MemberOfWave; + %remaining = game.numberInWave[%wave]--; + //error("Debug: Script reports that client " @ %client @ " was a member of wave " @ %wave @ " that now has " @ %remaining @ " members remaining."); + if(%remaining == 0) { + missionWaveDestroyed(%wave); + + if (%wave+1 <= $numberOfWaves[$pref::TrainingDifficulty]) + spawnWave(%wave+1); + //else error("Debug: " @ %wave @ " was the last wave."); + } +} + +function SinglePlayerGame::assignClientTeam(%game, %client) +{ + // The players team is set in singlePlayer::clientMissionDropReady + // and the bots are added to a team with aiConnect + // so this is unnecessary +} + +function singlePlayerGame::AIHasJoined() +{ + // Big deal...my missions are crawling with AI + // lets get rid of this mundane console spam +} + +function SinglePlayerGame::updateKillScores() +{ + // Do nothing other than get rid of the console warning... +} + +function singlePlayerGame::biodermAssume(%game, %client) +{ + //error(%client SPC "might talk."); + // dont do anything if we have just done this + if(%client.spgSpeaking) + return; + + %probability = 2; + %time = 30; // secs + + // we are going to POSSIBLY talk. flag it for %time secs + %client.spgSpeaking = true; + schedule(%time * 1000, %client, resetSpeakingFlag, %client); + + if(getRandom(%probability) == 1) + trainingBiodermSpeaks(%client); + +} + +function resetSpeakingFlag(%client) +{ + //error(%client SPC "can now speak again."); + %client.spgSpeaking = false; +} + +function trainingBiodermSpeaks(%client) +{ + if(%client.offense) // offense = defense? + %tauntlist = $trainingDefenseTauntList; //yes this seem wrong but its not + else + %tauntlist = $trainingOffenseTauntList; + %num = getWordCount(%tauntList); + %random = getRandom(%num - 1); + %use = getWord(%tauntList, %random); + //echo("Derm taunting:" SPC %use); + + playTargetAudio( %client.target, addTaggedString(%use), AudioClose3d, false ); +} + +function singlePlayerDead() +{ + missionFailed($player.miscMsg[trainingDeathLoss]); + AIMissionEnd(); + $objectiveQ[$enemyTeam].clear(); + cancel($player.distanceCheckSchedule); +} + +function SinglePlayerGame::missionLoadDone(%game) +{ + DefaultGame::missionLoadDone(%game); + + setSinglePlayerGlobals(); + $matchStarted = true; + //this has to happen sometime because game.startMatch never gets called + %game.clearDeployableMaxes(); +} + + +function SinglePlayerGame::notifyMatchStart(%game, %time) +{ + //do nothing +} + + +function SinglePlayerGame::clientMissionDropReady(%game, %client) +{ + DefaultGame::clientMissionDropReady(%game, %client); + + //echo(%client @ " is single player Ready!!!"); + messageClient(%client, 'MsgClientReady', "", %game.class); + + $Player = %client; + $player.race = $Training::Race[$CurrentMission]; + $player.sex = $Training::Sex[$CurrentMission]; + $player.team = $Training::PlayerTeam[$CurrentMission]; + $player.setTeam($Training::PlayerTeam); + setTargetSkin($teammate[%i].target, $teamSkin[$playerTeam]); + $player.clearBackpackIcon(); + + createText($player); + HUDMessageVector.clear(); + messageClient(%client, 'MsgMissionDropInfo', "", $MissionDisplayName, $MissionTypeDisplayName, $ServerName ); + + // We don't start in observer mode, so disable: + commandToClient(%client, 'setHudMode', 'Standard'); + + //custom training keymap + %game.createCustomKeyMap(); + + + addEnemies(); + //echo($player.team@"<---------players team on mission drop ready"); + addPlayersTeam($numberOfTeammates); + + //everybody's in, enable the AI system + AISystemEnabled(true); + + $player.setControlObject( $player.player ); + $player.camera = new Camera() + { + dataBlock = Observer; + }; + + startCurrentMission(%game); +} + +function SinglePlayerGame::AIInit(%game) +{ + //error("initializing Bot Q's for SinglePlayerGame..."); + for (%i = 0; %i <= %game.numTeams; %i++) + { + if (!isObject($ObjectiveQ[%i])) + { + $ObjectiveQ[%i] = new AIObjectiveQ(); + MissionCleanup.add($ObjectiveQ[%i]); + } + + //error("team " @ %i @ " objectives load..."); + $ObjectiveQ[%i].clear(); + AIInitObjectives(%i, %game); + } + + AIInit(); + + // Bots never throw grenades on Easy skills + if($pref::TrainingDifficulty == 1) + $AIDisableGrenades = true; +} + +// unlike the MP game, sometimes we start with switches (flipFlops) +// already on one team or the other and they are unskinned +function setFlipFlopSkins(%group) +{ + if(!%group) + %group = nameToID("Teams"); + + for(%i = 0; %i < %group.getCount(); %i++) { + %this = %group.getObject(%i); + if(%this.getClassName() $= "SimGroup") + setFlipFlopSkins(%this); + else if(%this.getDataBlock().getName() $= "FlipFlop") + setTargetSkin(%this.getTarget(), $teamSkin[%this.team]); + } +} + + + +function singlePlayerGame::gameOver(%game) +{ + moveMap.push(); + + ServerConnection.setBlackOut(false, 0); + + $timeScale = 1; + + game.missionOver = true; + + // clear the inventory and weapons hud + // BH: This doesn't actually DO anything... + //error("clearing Inv HUD for client " @ $player); + //$player.SetInventoryHudClearAll(); + + // im gonna try dropping all the clients + %count = clientGroup.getCount(); + echo("count=" SPC %count); + for(%i = 0; %i < %count; %i++) { + %client = clientGroup.getObject(%i); + game.client[%i] = %client; + freeClientTarget(%client); + } + for(%i = 0; %i < %count; %i++) { + %client = game.client[%i]; + echo("client=" SPC %client); + if(%client.isAIControlled()) + %client.drop(); + } + + //disable the AI system + AISystemEnabled(false); + $AIDisableChatResponse = ""; + + game.deactivatePackages(); + + if(isObject( $player.currentWaypoint )) + $player.currentWaypoint.delete(); + + if($player.OOB) + cancel($player.OOB); + + // clear the objective HUD + messageClient($player, 'MsgClearObjHud', ""); + + resetSinglePlayerGlobals(); + + $currentMissionType = ""; + DefaultGame::GameOver(%game); +} + +function singlePlayerGame::deactivatePackages(%game) +{ + error("singlePlayerGame packages deactivated"); + //Deactivate packages...gotta catch'm all + //deactivatepackage(SinglePlayer); + deactivatepackage(Training1); + deactivatepackage(Training2); + deactivatepackage(Training3); + deactivatepackage(Training4); + deactivatepackage(Training5); + deactivatepackage(Training6); + deactivatePackage(singlePlayerMissionAreaEnforce); +} +//------------------------------------------------------------------------------------ + + +// Voice line, text, function and audio parsing +//================================================================================= +// this is how we handle ALL the voice distribition and playing +// its NOT pretty +function doText(%name, %extraTime, %priority) +{ + if($player.text[%name, priority] || %priority) + addToQueueNext(%name); + else addToQueueEnd(%name); + + $player.text[%name, extraTime] = %extraTime; + processText(false); +} + +function processText(%cont) +{ + //we may need to fudge everysound to get it timed right + %universalSoundFudgingConstant = 400; + + if(isEventPending($currentlyPlaying) && !%cont) + return; + + %name = $player.Textque0; + if(%name $= "") + return; + + //echo("processing: "@%name); + if($player.Text[%name, eval] !$= "") + { + if (!isPureServer()) + eval($player.text[%name, eval]); + else + processTextEval($player.text[%name, eval]); + } + if($player.Text[%name, text] !$= "") { + // the old way: messageClient($player, 0, '\c2%1: %2',$trainerName, $player.Text[%name, line]); + messageClient($player, 0, "\c5"@$player.Text[%name, text]); + serverPlay2d(MessageRecieveSound); + } + if($player.Text[%name, wav] !$= "") { + //messageClient($player, 0, "~w"@$player.Text[%name, wav]); + %audio = alxCreateSource( AudioChat, $player.Text[%name, wav] ); + alxPlay( %audio ); + } + + removeFromQueue(); + + %wavLen = alxGetWaveLen($player.text[%name, wav]); + //if(%wavLen < 400) + // %wavLen = 400; // you cant go back in time, vge + + %time = %wavLen + $player.text[%name, extraTime] + %universalSoundFudgingConstant; + //echo("total delay time of"@%time); + + $currentlyPlaying = schedule(%time, $player.player, processText, true); + //if (!isPureServer()) + // schedule(%time, 0, eval, "$currentlyPlaying = false;"); + //else + // schedule(%time, 0, SPUnsetCurrentlyPlaying); +} + +function SPUnsetCurrentlyPlaying() +{ + $currentlyPlaying = ""; +error(getSimTime() SPC "DEBUG setting currentlyPlaying null"); +} + +function processTextEval(%evalStmt) +{ + switch$ (%evalStmt) + { + case "singlePlayerPlayGuiCheck();": + singlePlayerPlayGuiCheck(); + + case "schedule(3000, 0, disconnect);": + schedule(3000, 0, disconnect); + + case "lockArmorHack();autoToggleHelpHud(true);": + lockArmorHack();autoToggleHelpHud(true); + + case "flashMessage();": + flashMessage(); + + case "flashObjective();": + flashObjective(); + + case "flashCompass();": + flashCompass(); + + case "flashHealth();": + flashHealth(); + + case "flashEnergy();": + flashEnergy(); + + case "flashInventory();": + flashInventory(); + + case "flashSensor();": + flashSensor(); + + case "autoToggleHelpHud(false);": + autoToggleHelpHud(false); + + case "setWaypointAt(\"-287.5 393.1 76.2\", \"Health Patches\");movemap.push();$player.player.setMoveState(false);": + setWaypointAt("-287.5 393.1 76.2", "Health Patches");movemap.push();$player.player.setMoveState(false); + + case "$player.hurryUp = schedule(40000, 0, hurryPlayerUp); endOpeningSpiel(); updateTrainingObjectiveHud(obj8);": + $player.hurryUp = schedule(40000, 0, hurryPlayerUp); endOpeningSpiel(); updateTrainingObjectiveHud(obj8); + + case "updateTrainingObjectiveHud(obj7);": + updateTrainingObjectiveHud(obj7); + + case "flashWeapon(0);": + flashWeapon(0); + + case "flashWeapon(2);": + flashWeapon(2); + + case "flashWeapon(3); ": + flashWeapon(3); + + case "flashWeaponsHud();": + flashWeaponsHud(); + + case "use(Blaster);": + use(Blaster); + + case "queEnemySet(0); activatePackage(singlePlayerMissionAreaEnforce);": + queEnemySet(0); activatePackage(singlePlayerMissionAreaEnforce); + + case "setWaypointat(nameToId(Tower).position, \"BE Tower\"); updateTrainingObjectiveHud(obj4);": + setWaypointat(nameToId(Tower).position, "BE Tower"); updateTrainingObjectiveHud(obj4); + + case "flashPack();": + flashPack(); + + case "updateTrainingObjectiveHud(obj3);": + updateTrainingObjectiveHud(obj3); + + case "setWaypointAt(\"-8.82616 -131.779 119.756\", \"Control Switch\");": + setWaypointAt("-8.82616 -131.779 119.756", "Control Switch"); + + case "setWaypointAt(nameToId(InitialPulseSensor).position, \"Sensor\");": + setWaypointAt(nameToId(InitialPulseSensor).position, "Sensor"); + + case "setWaypointAt(\"-8.82616 -131.779 119.756\", \"Tower\");": + setWaypointAt("-8.82616 -131.779 119.756", "Tower"); + + case "setWaypointAt(\"380.262 -298.625 98.9719\", \"Tower\");": + setWaypointAt("380.262 -298.625 98.9719", "Tower"); + + case "firstPersonQuickPan();": + firstPersonQuickPan(); + + case "ThreeAEval();": + ThreeAEval(); + + case "game.ExpectiongSupportButton = true;": + game.ExpectiongSupportButton = true; + + case "game.expectingRepairOrder = true;": + game.expectingRepairOrder = true; + + case "$random = getRandom(20,40);schedule($random, 0, doText, T4_TipDefense06);": + $random = getRandom(20,40);schedule($random, 0, doText, T4_TipDefense06); + + case "training5addSafeDistance();": + training5addSafeDistance(); + } +} + + +function removeFromQueue() +{ + %i = 1; + while($player.textque[%i] !$= "") { + $player.textque[%i-1] = $player.textque[%i]; + %i++; + } + $player.textque[%i-1] = ""; +} + + +function addToQueueEnd(%name) +{ + %q = 0; + while($player.Textque[%q] !$= ""){ + %q++; + } + $player.Textque[%q] = %name; +} + +function addToQueueNext(%name) +{ + %q = 0; + while($player.Textque[%q] !$= ""){ + %q++; + } + for(%i=%q; %i>0; %i--) + $player.textque[%i] = $player.textque[%i-1]; + $player.textque0 = %name; +} + +function echoQueue() +{ + echo("Textque -------------------------------"); + %i = 0; + while($player.Textque[%i] !$= "") { + echo(%i@": "@$player.Textque[%i]); + %i++; + } +} + +function clearQueue() +{ + for(%i=0;%i<100; %i++) + $player.textQue[%i] = ""; +} + +//handy waypoint setting tool +//========================================================================= +function setWaypointAt(%location, %name, %team) +{ + %team = (!%team ? $playerTeam : %team); + // if(!%name) + // %name = ""; + if ( isObject( $player.currentWaypoint ) ) + $player.currentWaypoint.delete(); + + $player.currentWaypoint = new WayPoint(TurretTower) { + position = %location; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "WayPointMarker"; + team = %team; + name = %name; + }; + MissionCleanup.add($player.currentWaypoint); +} + +//this is just a little consolidation of functions +//its a little gregarious but allows text to live in spdialg.cs +//intent is to make hud updating easier and localization easier too ;) +function updateTrainingObjectiveHud( %objectiveNum ) +{ + + //sound + objectiveHud.setVisible(false); + if (!isPureServer()) + schedule(400, game, eval, "objectiveHud.setVisible(true);"); + else + schedule(400, game, setObjHudVisible); + + serverPlay2d(TrainingHudUpdateSound); + + //clear old text + messageClient($player, 'MsgSPCurrentObjective1', "", ' '); + messageClient($player, 'MsgSPCurrentObjective2', "", ' '); + + // find the lines from the spdialog file that are now attached to the sp client + %who = $player; + %mission = $currentMission; + for(%x = 1; %x <= 2; %x++) + %newObjectiveLine[%x] = $player.objHud[%mission, %objectiveNum, %x]; + + //add new text + messageClient($player, 'MsgSPCurrentObjective1', "", %newObjectiveLine1); + if(%newObjectiveLine2 !$= "") + messageClient($player, 'MsgSPCurrentObjective2', "", %newObjectiveLine2); +} + +function setObjHudVisible() +{ + objectiveHud.setVisible(true); +} + + +// Misc/Overwrites +//======================================================================================= + +function isSafe(%object, %radius) +{ + %team = %object.team; + %position = %object.player.getTransform(); + + //check for enemy players + %num = clientGroup.getCount(); + for(%client = 0; %client <= %num; %client++) + { + if(%team != %client.team && %client.player) { + %enemyPos = %client.player.getTransform(); + //okay, just in case we dont have a player for that client + //AND are close to "0 0 0" vge + if(!%enemyPos) + %dist = 100000; + else %dist = vectorDist(%position, %enemyPos); + //error("Debug: Client "@%client@" is "@%dist@" away"); + if ( %dist < %radius){ + //error("Unsafe because of client "@%client@" at a distance of "@%dist@"!!!!"); + return false; + } + } + } + //error("Safe for a radius of "@%radius@"!"); + return true; +} + +function singlePlayerGame::onAIRespawn(%game, %client) +{ + // add the default tasks + + if (! %client.defaultTasksAdded) + { + %client.defaultTasksAdded = true; + %client.addTask(AIEngageTask); + %client.addTask(AIPickupItemTask); + %client.addTask(AIUseInventoryTask); + %client.addTask(AIEngageTurretTask); + %client.addtask(AIDetectMineTask); + if(%client.team == $playerTeam || $pref::trainingDifficulty == 3) + %client.addTask(AITauntCorpseTask); + } +} + + +function singlePlayerGame::onAIKilled(%game, %clVictim, %clAttacker, %damageType, %implement) +{ + // dont respawn AI (this is overwritten in some of the mission packages) +} + + +function singleplayerGame::onClientDamaged(%game, %clVictim, %clAttacker, %damageType, %implement) +{ + //the DefaultGame will set some vars + DefaultGame::onClientDamaged(%game, %clVictim, %clAttacker, %damageType, %implement); + + //now see if both were on the same team + if(%clAttacker && %clAttacker != %clVictim && %clVictim.team == %clAttacker.team) + { + %game.friendlyFireMessage(%clVictim, %clAttacker); + } +} + +function singleplayerGame::onAIDamaged(%game, %clVictim, %clAttacker, %damageType, %implement) +{ + if(%clVictim.team != %clAttacker.team && %clVictim.MemberOfWave) + { + spawnWaveTimer(%clVictim.MemberOfWave, true); + } + + if (%clAttacker && %clAttacker != %clVictim && %clAttacker.team == %clVictim.team) + { + schedule(250, %clVictim, "AIPlayAnimSound", %clVictim, %clAttacker.player.getWorldBoxCenter(), "wrn.watchit", -1, -1, 0); + + //clear the "lastDamageClient" tag so we don't turn on teammates... unless it's uberbob! + %clVictim.lastDamageClient = -1; + } +} + +// find number of players on a team +// why isnt this in a std lib +function getPlayersOnTeam(%team) +{ + %num = clientGroup.getCount(); + for(%i=0; %i<%num; %i++){ + %client = clientGroup.getObject(%i); + if(%client.team == %team && %client.player) + %count++; + } + + return %count; +} + + +//mission completion/falure stuff============================================ +function missionComplete(%text) +{ + $player.endMission = schedule(15000, game, forceFinish); + + messageBoxOk("Victory", %text, "forceFinish();"); + + //AI stop + clearQueue(); + AIMissionEnd(); + $objectiveQ[$enemyTeam].clear(); +} + +function forceFinish() +{ + $timeScale = 1; + //kill the thread if we pressed a button to get here... + cancel($player.endMission); + + //make sure we end the game neatly + Game.gameOver(); + + //immediately disconnect - bringing us back to the main menu... + Disconnect(); +} + +function missionFailed(%text) +{ + + $player.endMission = schedule(30000, game, forceFinish); + + MessageBoxYesNo("Failure", %text, "reloadMission();", "forceFinish();"); + + //AI stop + cancel($Player.T1OpeningSpielSchedule); + cancel($Player.distanceCheckSchedule); + clearQueue(); + AIMissionEnd(); + $objectiveQ[$enemyTeam].clear(); +} + +function reloadMission() +{ + cancel($player.endMission); + Game.gameOver(); + Canvas.setContent( LoadingGui ); + loadMission($currentMission, singlePlayer); + debriefContinue(); +} + + +// silly...we fed it a movemap binding it retuns the capitalized key in (almost) english +function findTrainingControlButtons( %name ) +{ + %controlName = moveMap.getBinding(%name); + if (%controlName $= "") + return "[no key binding]"; + %prettyName = strupr(getMapDisplayName(getWord(%controlName, 0), getWord(%controlName, 1))); + %next = 2; + while( getWord( %controlName, %next ) !$= "" ) { + %extra = "-"@strupr(getWord( %controlName, 2 )); + %prettyName = %prettyName @ %extra; + %next++; + } + return %prettyName; +} + +// just a kinda cool little effect +function firstPersonQuickPan() +{ + if($firstperson) { + toggleFirstPerson($player); + schedule(4000, $player.player, toggleFirstPerson, $player); + } + +} + + +// Player spawning/respawning==================================================== +//since we are going through pickTeamSpawn rather than pickPlayerSpawn +// and for a couple other reasons, we are going to need to manually determine +// if this is a respawn or not. +function spawnSinglePlayer() +{ + $player.lives--; + + game.spawnPlayer($player, true); + $player.setControlObject($player.player); + //messageClient($player, 0, "Respawns Remaining: "@$player.lives); +} + + +function singleplayerGame::observerOnTrigger() +{ + //we dont want the player respawning (yet) + return false; +} + +function SinglePlayerGame::spawnPlayer( %game, %client, %respawn ) +{ + //error("Spawn Player: %client = " @%client@" %respawn = "@%respawn); + %spawnPoint = %game.pickPlayerSpawn( %client, %respawn ); + %game.createPlayer( %client, %spawnPoint, %respawn ); +} + +function singlePlayerGame::playerSpawned(%game, %player) +{ + defaultGame::playerSpawned(%game, %player); +} + +function singleplayerGame::pickPlayerSpawn(%game, %client, %respawn) +{ + // the bots, for some reason, always pass in %respawn as true + // well that's horse pucky, since the bots never respawn in SPG + // so I do this stupid thing + if(%client.isAIcontrolled()) + %respawn = false; + + if(!%client.offense) // this is a wave spawned attack bot + %respawn = true; + + + %game.pickTeamSpawn( %client, %respawn); +} + +function singleplayerGame::pickTeamSpawn(%game, %client, %respawn) +{ + %team = %client.team; + + if(%respawn) { + %group = nameToID("MissionGroup/Teams/team"@%team@"/DropPoints/Respawns"); + if(! isObject(%group)) { + //error("Client" SPC %client SPC "is attempting a respawn with no drop point"); + return "0 0 300"; + } + else %spawnLoc = %group.getObject(game.respawnPoint); + //error("REspawn loc is: " @ %spawnLoc); + } + + else { + %group = nameToID("MissionGroup/Teams/team" @ %team @ "/DropPoints"); + %spawnLoc = %group.getObject(game.spawnLoc[%team]); + //error("spawn loc is: "@game.spawnLoc[%team]); + game.spawnLoc[%team]++; + } + return %spawnLoc.getTransform(); +} + + +function SinglePlayerGame::createCustomKeymap(%game) +{ +// new ActionMap(TrainingMap); +// TrainingMap.bindCmd( keyboard, "escape", "escapeFromGame();", "" ); +} + +//======================================================================================= +// Escape dialog functions: +//======================================================================================= +function SinglePlayerEscapeDlg::onWake( %this ) +{ + $timeScale = 0; + + if( OptionsDlg.isAwake()) + { + Canvas.popDialog( OptionsDlg ); + } +} + +function SinglePlayerEscapeDlg::onSleep( %this ) +{ +// spMap.pop(); +// spMap.delete(); +} + + +function SinglePlayerEscapeDlg::leaveGame( %this ) +{ + Canvas.popDialog( SinglePlayerEscapeDlg ); + MessageBoxYesNo( "LEAVE GAME", $player.miscMsg[LeaveGame], "forceFinish();", "$timeScale = 1;" ); +} + +function SinglePlayerEscapeDlg::gotoSettings( %this ) +{ + Canvas.popDialog( SinglePlayerEscapeDlg ); + Canvas.pushDialog( OptionsDlg ); +} + +function SinglePlayerEscapeDlg::returnToGame( %this ) +{ + //error( "** CALLING SinglePlayerEscapeDlg::returnToGame **" ); + $timeScale = 1; + Canvas.popDialog( SinglePlayerEscapeDlg ); + + movemap.push(); + //trainingmap.push(); +} + + +function singlePlayerGame::OptionsDlgSleep(%game) +{ + $enableDirectInput = 1; + activateDirectInput(); + + Canvas.pushDialog( SinglePlayerEscapeDlg ); + // the player may have changed his keys + // we need to reload the big spdialog string table that + // holds all the text related to the players keymappings + createText($player); +} + +// mission Area package +package singlePlayerMissionAreaEnforce { +// -begin mission area package------------------------------------------------- + +// OOB +function SinglePlayerGame::leaveMissionArea(%game, %playerData, %player) +{ + parent::leaveMissionArea(%game, %playerData, %player); + if(%player == $player.player) { + $player.leftMissionArea++; + %timeAllowed = 30; + $player.OOB = schedule(%timeAllowed *1000, 0, wussOut, %player); + clearQueue(); + doText(Any_offcourse); + MessageClient($player, 0, $player.miscMsg[OOB]); + %player.playerLeftMissionArea = true; + } +} +function SinglePlayerGame::enterMissionArea(%game, %playerData, %player) +{ + parent::enterMissionArea(%game, %playerData, %player); + if(%player == $player.player && %player.playerLeftMissionArea) { + //echo("player back in bounds"); + cancel($player.OOB); + clearQueue(); + doText(Any_alright); + MessageClient($player, 0, $player.miscMsg[InBounds]); + } +} +function wussOut(%player) +{ + clearQueue(); + doText(Any_abort); + missionFailed($player.miscMsg[OOBLoss]); +} + +// -end mission area package------------------------------------------------- +}; + +// Custom Particle effects for training5 + +datablock ParticleData(BeforeT5particle) +{ + dragCoefficient = 0; + gravityCoefficient = -0.017094; + inheritedVelFactor = 0.0176125; + constantAcceleration = -0.8; + lifetimeMS = 1248; + lifetimeVarianceMS = 0; + useInvAlpha = 1; + spinRandomMin = -200; + spinRandomMax = 200; + textureName = "particleTest"; + colors[0] = "1.000000 0.677165 0.000000 1.000000"; + colors[1] = "0.708661 0.507812 0.000000 1.000000"; + colors[2] = "0.000000 0.000000 0.000000 0.000000"; + colors[3] = "1.000000 1.000000 1.000000 1.000000"; + sizes[0] = 0.991882; + sizes[1] = 2.99091; + sizes[2] = 4.98993; + sizes[3] = 1; + times[0] = 0; + times[1] = 0.2; + times[2] = 1; + times[3] = 2; +}; + +datablock ParticleData(AfterT5particle) +{ + dragCoefficient = 0; + gravityCoefficient = -0.017094; + inheritedVelFactor = 0.0176125; + constantAcceleration = -1.1129; + lifetimeMS = 2258; + lifetimeVarianceMS = 604; + useInvAlpha = 1; + spinRandomMin = -200; + spinRandomMax = 200; + textureName = "special/Smoke/smoke_001"; + colors[0] = "1.000000 0.677165 0.000000 1.000000"; + colors[1] = "0.181102 0.181102 0.181102 1.000000"; + colors[2] = "0.000000 0.000000 0.000000 0.000000"; + colors[3] = "1.000000 1.000000 1.000000 1.000000"; + sizes[0] = 0.991882; + sizes[1] = 2.99091; + sizes[2] = 4.98993; + sizes[3] = 1; + times[0] = 0; + times[1] = 0.2; + times[2] = 1; + times[3] = 2; +}; + +datablock ParticleEmitterData(BeforeT5) +{ + ejectionPeriodMS = 16; + periodVarianceMS = 10; + ejectionVelocity = 7.45968; + velocityVariance = 0.25; + ejectionOffset = 0; + thetaMin = 0; + thetaMax = 180; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = 0; + orientParticles= 0; + orientToNormal = 0; + orientOnVelocity = 1; + particles = "BeforeT5particle"; +}; + +datablock ParticleEmitterData(AfterT5) +{ + ejectionPeriodMS = 10; + periodVarianceMS = 0; + ejectionVelocity = 10.25; + velocityVariance = 0.25; + ejectionOffset = 0; + thetaMin = 0; + thetaMax = 180; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = 0; + orientParticles= 0; + orientToNormal = 0; + orientOnVelocity = 1; + particles = "AfterT5particle"; +}; diff --git a/scripts/Training.cs b/scripts/Training.cs index 8e5f081..237e16f 100644 --- a/scripts/Training.cs +++ b/scripts/Training.cs @@ -1,247 +1,247 @@ -// don't want this executing when building graphs -if($OFFLINE_NAV_BUILD) - return; - -// Script for Training -//=================================================================================== -//error("Training 1 script"); - -// package and callbacks -activatePackage(Training); - -// variables -$numberOfEnemies[1] = 1; -$numberOfEnemies[2] = 2; -$numberOfEnemies[3] = 3; -$numberOfTeammates = 0; //Raptor, Komodo Dragon and Sharp Tooth - Don't spawn them automatically though -$missionBotSkill[1] = 0.0; -$missionBotSkill[2] = 0.4; -$missionBotSkill[3] = 0.7; - -package Training { -//BEGIN TRAINING PACKAGE ======================================================================= - -function SinglePlayerGame::initGameVars(%game) -{ - echo("initializing training1 game vars"); -} - -function MP3Audio::play(%this) -{ - //too bad...no mp3 in training -} - -function toggleCommanderMap(%val) -{ - if ( %val ) - messageClient($player, 0, $player.miscMsg[noCC]); -} - -function toggleTaskListDlg( %val ) -{ - if ( %val ) - messageClient( $player, 0, $player.miscMsg[noTaskListDlg] ); -} - -function toggleInventoryHud( %val ) -{ - if ( %val ) - messageClient( $player, 0, $player.miscMsg[noInventoryHUD] ); -} - -function toggleNetDisplayHud( %val ) -{ - // Hello, McFly? This is training! There's no net in training! -} - -function voiceCapture( %val ) -{ - // Uh, who do you think you are talking to? -} - -function giveall() -{ - error("When the going gets tough...wussies like you start cheating!"); - messageClient($player, 0, "Cheating eh? What\'s next? Camping?"); -} - -function getTeammateGlobals() -{ -//No console errors -} - -function openingSpiel() -{ -} - -// get the ball rolling -//------------------------------------------------------------------------------ -function startCurrentMission() -{ - playGui.add(outerChatHud); - - $Player.player.setTransform(PlayerSpawn.getPosition() SPC "0 0 1 3.97136"); - //Raptor (Trainer) - $Bot1 = aiConnectByName("Raptor",1); - $Bot1.race = "Draakan"; - $Bot1.sex = "A"; - setVoice($Bot1, "Derm3"); - setSkin($Bot1, "Gecko"); - $Bot1.player.setArmor("LIGHT"); - $Bot1.player.setTransform(RaptorSpawn.getPosition()); - $Bot1.aimAt($player.player.getPosition()); - //Sharp Tooth - $Bot2 = aiConnectByName("Sharp Tooth",1); - $Bot2.race = "Draakan"; - $Bot2.sex = "A"; - setVoice($Bot2, "Derm3"); - setSkin($Bot2, "Gecko"); - $Bot2.player.setArmor("LIGHT"); - $Bot2.player.setTransform(Spawn01.getPosition()); - $Bot2.aimAt($Bot1.player.getPosition()); - //Komodo Dragon - $Bot3 = aiConnectByName("Komodo Dragon",1); - $Bot3.race = "Draakan"; - $Bot3.sex = "A"; - setVoice($Bot3, "Derm3"); - setSkin($Bot3, "Gecko"); - $Bot3.player.setArmor("LIGHT"); - $Bot3.player.setTransform(Spawn02.getPosition()); - $Bot3.aimAt($Bot1.player.getPosition()); - //Start our texts! - openingSpiel(); - $DoneIntro = false; -} - -//------------------------------------------------------------------------------ -function SinglePlayerGame::equip(%game, %player) -{ - //ya start with nothing...NOTHING! - %player.clearInventory(); - for(%i =0; %i<$InventoryHudCount; %i++) - %player.client.setInventoryHudItem($InventoryHudData[%i, itemDataName], 0, 1); - %player.client.clearBackpackIcon(); - - %set = %player.client.equipment; - - echo("using default equipment"); - - %player.setArmor("Light"); - %player.setInventory(RepairKit,1); - %player.setInventory(Chaingun, 1); - %player.setInventory(ChaingunAmmo, 100); - %player.setInventory(Disc,1); - %player.setInventory(DiscAmmo, 20); - %player.setInventory(Shocklance, 1); - %player.setInventory(AmmoPack, 1); - - //DefaultGame.cs does not assign flamer.. - %player.setInventory(flamer, 1); - %player.weaponCount = 4; - - %player.use(Chaingun); -} - -function PlayGui::onWake(%this) -{ - parent::onWake(%this); - - if (!$DoneIntro) - { - lockArmorHack(1); - ServerConnection.setBlackOut(false, 1000); - $DoneIntro = true; - } -} - -function singlePlayerGame::onAIRespawn(%game, %client) -{ - // DONT add the default tasks - //error("default tasks not added"); -} - -function singlePlayerGame::playerSpawned(%game, %player) -{ - parent::playerSpawned(%game, %player); -} - -function singlePlayerGame::gameOver(%game) -{ - //enable the voice chat menu again... - if (isObject(training1BlockMap)) - { - training1BlockMap.pop(); - training1BlockMap.delete(); - } - - if(HelpTextGui.isVisible()) - helpTextGui.setVisible(false); - - //re-enable the use of the settings button... - SinglePlayerEscSettingsBtn.setActive(1); - - Parent::gameOver(); -} - -function trainingPreloads() //Load any skins.. -{ - navGraph.preload("skins/Gecko.lbioderm", true); - navGraph.preload("skins/base.lbioderm", true); - navGraph.preload("skins/Horde.lbioderm", false); - navGraph.preload("skins/sensor_pulse_large", true); - navGraph.preload("skins/base.hmale", false); - navGraph.preload("skins/beagle.hmale", false); - navGraph.preload("skins/base.mmale", false); - navGraph.preload("skins/beagle.mmale", false); - navGraph.preload("skins/base.lmale", false); - navGraph.preload("skins/swolf.mmale", false); - navGraph.preload("skins/beagle.lmale", false); -} - -function SinglePlayerGame::missionLoadDone(%game) -{ - Parent::missionLoadDone(%game); - trainingPreloads(); -} - -function serverCmdBuildClientTask(%client, %task, %team) -{ - // player shouldnt be able to use the voice commands to do anything -} - -function openingSpiel() //Not sure how T2 originally handled the training.. but it's temporary -{ -updateTrainingObjectiveHud(obj1); -schedule(1000,0,"setActionThread",$bot1.player,"cel1",0); -schedule(3000,0,"setActionThread",$bot2.player,"cel1",0); -schedule(3000,0,"setActionThread",$bot3.player,"cel1",0); -schedule(3000,0,"setActionThread",$player.player,"cel1",0); -doText(TR_01, 3200); -doText(TR_02, 3500); -doText(TR_03, 3800); -doText(TR_04, 4100); -doText(TR_05, 4400); -schedule(4400,0,"lockArmorHack",false); //Got to release our hack for it to work.. -schedule(4400,0,"updateTrainingObjectiveHud",obj2); -} - -function lockArmorHack(%bool) -{ - if (%bool) - { - movemap.pop(); - } - else - moveMap.push(); - //$player.player.setMoveState(true); - //$player.player.schedule(1000,"setMoveState", false); -} -}; - -function setActionThread(%player,%anim,%bool) -{ -%player.setActionThread(%anim,%bool); -} - - - +// don't want this executing when building graphs +if($OFFLINE_NAV_BUILD) + return; + +// Script for Training +//=================================================================================== +//error("Training 1 script"); + +// package and callbacks +activatePackage(Training); + +// variables +$numberOfEnemies[1] = 1; +$numberOfEnemies[2] = 2; +$numberOfEnemies[3] = 3; +$numberOfTeammates = 0; //Raptor, Komodo Dragon and Sharp Tooth - Don't spawn them automatically though +$missionBotSkill[1] = 0.0; +$missionBotSkill[2] = 0.4; +$missionBotSkill[3] = 0.7; + +package Training { +//BEGIN TRAINING PACKAGE ======================================================================= + +function SinglePlayerGame::initGameVars(%game) +{ + echo("initializing training1 game vars"); +} + +function MP3Audio::play(%this) +{ + //too bad...no mp3 in training +} + +function toggleCommanderMap(%val) +{ + if ( %val ) + messageClient($player, 0, $player.miscMsg[noCC]); +} + +function toggleTaskListDlg( %val ) +{ + if ( %val ) + messageClient( $player, 0, $player.miscMsg[noTaskListDlg] ); +} + +function toggleInventoryHud( %val ) +{ + if ( %val ) + messageClient( $player, 0, $player.miscMsg[noInventoryHUD] ); +} + +function toggleNetDisplayHud( %val ) +{ + // Hello, McFly? This is training! There's no net in training! +} + +function voiceCapture( %val ) +{ + // Uh, who do you think you are talking to? +} + +function giveall() +{ + error("When the going gets tough...wussies like you start cheating!"); + messageClient($player, 0, "Cheating eh? What\'s next? Camping?"); +} + +function getTeammateGlobals() +{ +//No console errors +} + +function openingSpiel() +{ +} + +// get the ball rolling +//------------------------------------------------------------------------------ +function startCurrentMission() +{ + playGui.add(outerChatHud); + + $Player.player.setTransform(PlayerSpawn.getPosition() SPC "0 0 1 3.97136"); + //Raptor (Trainer) + $Bot1 = aiConnectByName("Raptor",1); + $Bot1.race = "Draakan"; + $Bot1.sex = "A"; + setVoice($Bot1, "Derm3"); + setSkin($Bot1, "Gecko"); + $Bot1.player.setArmor("LIGHT"); + $Bot1.player.setTransform(RaptorSpawn.getPosition()); + $Bot1.aimAt($player.player.getPosition()); + //Sharp Tooth + $Bot2 = aiConnectByName("Sharp Tooth",1); + $Bot2.race = "Draakan"; + $Bot2.sex = "A"; + setVoice($Bot2, "Derm3"); + setSkin($Bot2, "Gecko"); + $Bot2.player.setArmor("LIGHT"); + $Bot2.player.setTransform(Spawn01.getPosition()); + $Bot2.aimAt($Bot1.player.getPosition()); + //Komodo Dragon + $Bot3 = aiConnectByName("Komodo Dragon",1); + $Bot3.race = "Draakan"; + $Bot3.sex = "A"; + setVoice($Bot3, "Derm3"); + setSkin($Bot3, "Gecko"); + $Bot3.player.setArmor("LIGHT"); + $Bot3.player.setTransform(Spawn02.getPosition()); + $Bot3.aimAt($Bot1.player.getPosition()); + //Start our texts! + openingSpiel(); + $DoneIntro = false; +} + +//------------------------------------------------------------------------------ +function SinglePlayerGame::equip(%game, %player) +{ + //ya start with nothing...NOTHING! + %player.clearInventory(); + for(%i =0; %i<$InventoryHudCount; %i++) + %player.client.setInventoryHudItem($InventoryHudData[%i, itemDataName], 0, 1); + %player.client.clearBackpackIcon(); + + %set = %player.client.equipment; + + echo("using default equipment"); + + %player.setArmor("Light"); + %player.setInventory(RepairKit,1); + %player.setInventory(Chaingun, 1); + %player.setInventory(ChaingunAmmo, 100); + %player.setInventory(Disc,1); + %player.setInventory(DiscAmmo, 20); + %player.setInventory(Shocklance, 1); + %player.setInventory(AmmoPack, 1); + + //DefaultGame.cs does not assign flamer.. + %player.setInventory(flamer, 1); + %player.weaponCount = 4; + + %player.use(Chaingun); +} + +function PlayGui::onWake(%this) +{ + parent::onWake(%this); + + if (!$DoneIntro) + { + lockArmorHack(1); + ServerConnection.setBlackOut(false, 1000); + $DoneIntro = true; + } +} + +function singlePlayerGame::onAIRespawn(%game, %client) +{ + // DONT add the default tasks + //error("default tasks not added"); +} + +function singlePlayerGame::playerSpawned(%game, %player) +{ + parent::playerSpawned(%game, %player); +} + +function singlePlayerGame::gameOver(%game) +{ + //enable the voice chat menu again... + if (isObject(training1BlockMap)) + { + training1BlockMap.pop(); + training1BlockMap.delete(); + } + + if(HelpTextGui.isVisible()) + helpTextGui.setVisible(false); + + //re-enable the use of the settings button... + SinglePlayerEscSettingsBtn.setActive(1); + + Parent::gameOver(); +} + +function trainingPreloads() //Load any skins.. +{ + navGraph.preload("skins/Gecko.lbioderm", true); + navGraph.preload("skins/base.lbioderm", true); + navGraph.preload("skins/Horde.lbioderm", false); + navGraph.preload("skins/sensor_pulse_large", true); + navGraph.preload("skins/base.hmale", false); + navGraph.preload("skins/beagle.hmale", false); + navGraph.preload("skins/base.mmale", false); + navGraph.preload("skins/beagle.mmale", false); + navGraph.preload("skins/base.lmale", false); + navGraph.preload("skins/swolf.mmale", false); + navGraph.preload("skins/beagle.lmale", false); +} + +function SinglePlayerGame::missionLoadDone(%game) +{ + Parent::missionLoadDone(%game); + trainingPreloads(); +} + +function serverCmdBuildClientTask(%client, %task, %team) +{ + // player shouldnt be able to use the voice commands to do anything +} + +function openingSpiel() //Not sure how T2 originally handled the training.. but it's temporary +{ +updateTrainingObjectiveHud(obj1); +schedule(1000,0,"setActionThread",$bot1.player,"cel1",0); +schedule(3000,0,"setActionThread",$bot2.player,"cel1",0); +schedule(3000,0,"setActionThread",$bot3.player,"cel1",0); +schedule(3000,0,"setActionThread",$player.player,"cel1",0); +doText(TR_01, 3200); +doText(TR_02, 3500); +doText(TR_03, 3800); +doText(TR_04, 4100); +doText(TR_05, 4400); +schedule(4400,0,"lockArmorHack",false); //Got to release our hack for it to work.. +schedule(4400,0,"updateTrainingObjectiveHud",obj2); +} + +function lockArmorHack(%bool) +{ + if (%bool) + { + movemap.pop(); + } + else + moveMap.push(); + //$player.player.setMoveState(true); + //$player.player.schedule(1000,"setMoveState", false); +} +}; + +function setActionThread(%player,%anim,%bool) +{ +%player.setActionThread(%anim,%bool); +} + + + diff --git a/scripts/TrainingGui.cs b/scripts/TrainingGui.cs index addddec..36fcb4e 100644 --- a/scripts/TrainingGui.cs +++ b/scripts/TrainingGui.cs @@ -1,313 +1,313 @@ -//------------------------------------------------------------------------------ -// -// TrainingGui.cs -// -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -function LaunchTraining() -{ - LaunchTabView.viewTab( "CAMPAIGN", TrainingGui, 0 ); -} - -//------------------------------------------------------------------------------ -function TrainingGui::onWake( %this ) -{ - Canvas.pushDialog( LaunchToolbarDlg ); - - - //Reset the list - TrainingMissionList.clear(); - - if ($Pref::Campaign !$= "") - TrainingSelectMenu.onSelect(TrainingSelectMenu.findText($Pref::Campaign),$Pref::Campaign); - else - TrainingSelectMenu.onSelect(0,TrainingSelectMenu.getText()); - TrainingMissionList.sort( 1 ); - TrainingMissionList.setSelectedRow( 0 ); - if ( $pref::TrainingDifficulty > 0 && $pref::TrainingDifficulty < 4 ) - TrainingDifficultyMenu.setSelected( $pref::TrainingDifficulty ); - else - TrainingDifficultyMenu.setSelected( 1 ); -} - -//------------------------------------------------------------------------------ -function TrainingGui::onSleep( %this ) -{ - %this.stopBriefing(); - - Canvas.popDialog(LaunchToolbarDlg); -} - -//------------------------------------------------------------------------------ -function TrainingGui::updateList( %this ) -{ - %cam = $Pref::Campaign; - %dir = "Data/Campaigns/"; - %file = %dir @ %cam @ ".txt"; - - if (!IsFile(%file)) - return false; - - TrainingMissionList.clear(); - TrainingBriefingText.setValue( "" ); - TrainingPic.setBitmap( "" ); - TrainingPicFrame.setVisible( false ); - - if (!IsObject(CampaignLoader)) - new ScriptObject(CampaignLoader) { class = "BasicDataParser"; }; - CampaignLoader.empty(); - CampaignLoader.load(%file); - - %campaign = CampainLoader.get("Campaign",0); - %count = %campaign.element("MissionCount"); - - //Before we do the loopy stuff, we should check if there's a specific training mission first - %mission = %campaign.element("Practice"); - %text = %campaign.element("PracticeText"); - - if (%text != -1 && %mission != -1) - TrainingMissionList.addRow( 0, %text TAB %mission ); - - %settings = CampainLoader.get("Settings",0); - for (%i = 1; %i <= %count; %i++) - { - %mission = %campain.element("Mission" @ %i); - %text = %campaign.element("MissionText" @ %i); - TrainingMissionList.addRow( %i, %text TAB %mission ); - //Now the mission list is where we need it, find the player settings.. - $Training::Name[%Mission] = %settings.element("Name"); - $Training::Race[%Mission] = %settings.element("Race"); - $Training::Sex[%Mission] = %settings.element("Sex"); - $Training::Voice[%Mission] = %settings.element("Voice"); - $Training::VoicePitch[%Mission] = %settings.element("VoicePitch"); - $Training::Skin[%Mission] = %settings.element("Skin"); - $Training::EnemySkin[%Mission] = %settings.element("EnemySkin"); - $Training::EnemyName[%Mission] = %settings.element("EnemyName"); - $Training::EnemyTeam[%Mission] = %settings.element("EnemyTeam"); - $Training::PlayerTeam[%Mission] = %settings.element("PlayerTeam"); - $Training::StartLives[%Mission] = %settings.element("StartLives"); - $Training::EnemyRace[%Mission] = %settings.element("EnemyRace"); - } -} - -//------------------------------------------------------------------------------ -function TrainingGui::setKey( %this ) -{ -} - -//------------------------------------------------------------------------------ -function TrainingGui::onClose( %this ) -{ -} - -//------------------------------------------------------------------------------ -function TrainingDifficultyMenu::onAdd( %this ) -{ - %this.add( "Easy", 1 ); - %this.add( "Medium", 2 ); - %this.add( "Hard", 3 ); -} - -//------------------------------------------------------------------------------ -function TrainingDifficultyMenu::onSelect( %this, %id, %text ) -{ - $pref::TrainingDifficulty = %id; -} - -//------------------------------------------------------------------------------ -function TrainingSelectMenu::onAdd( %this ) -{ - - //Uber Dynamic Campaign Listing :) - %path = "Data/Campaigns/*.dat"; - %count = 0; - - if (!IsObject(CampaignLoader)) - new ScriptObject(CampaignLoader) { class = "BasicDataParser"; }; - CampaignLoader.empty(); - CampaignLoader.load(%file); - - for( %file = findFirstFile( %path ); %file !$= ""; %file = findNextFile( %path ) ) - { - CampaignLoader.load(%file); - %this.add( CampaignLoader.get("Campaign",%count).element("Name"), %count); - %count++; - } -} - -//------------------------------------------------------------------------------ -function TrainingSelectMenu::onSelect( %this, %id, %text ) -{ - $Pref::Campaign = %text; - - %row = TrainingMissionList.getSelectedID() - 1; - TrainingGui.updateList(); - TrainingGui.stopBriefing(); - TrainingSelectMenu.setText(%text); //Make sure our text is assigned.. - - if ($Pref::Campaign $= %text) - TrainingMissionList.setSelectedRow(%row); - else - TrainingMissionList.setSelectedRow(0); -} - -//------------------------------------------------------------------------------ -function TrainingMissionList::onSelect( %this, %id, %text ) -{ - TrainingGui.stopBriefing(); - %fileName = "missions/" @ getField( %text, 1 ) @ ".mis"; - %file = new FileObject(); - %state = 0; - if ( %file.openForRead( %fileName ) ) - { - // Get the mission briefing text: - while ( !%file.isEOF() ) - { - %line = %file.readLine(); - if ( %state == 0 && %line $= "//--- MISSION BRIEFING BEGIN ---" ) - %state = 1; - else if ( %state > 0 && %line $= "//--- MISSION BRIEFING END ---" ) - break; - else if ( %state == 1 ) - { - %briefText = %briefText @ getSubStr( %line, 2, 1000 ); - %state = 2; - } - else if ( %state == 2 ) - %briefText = %briefText NL getSubStr( %line, 2, 1000 ); - } - - // Get the mission briefing WAV file: - while ( !%file.isEOF() ) - { - %line = %file.readLine(); - if ( getSubStr( %line, 0, 17 ) $= "// BriefingWAV = " ) - { - %briefWAV = getSubStr( %line, 17, 1000 ); - break; - } - } - - // Get the bitmap name: - while ( !%file.isEOF() ) - { - %line = %file.readLine(); - if ( getSubStr( %line, 0, 12 ) $= "// Bitmap = " ) - { - %briefPic = getSubStr( %line, 12, 1000 ); - break; - } - } - %file.close(); - } - else - error( "Failed to open Single Player mission file " @ %fileName @ "!" ); - - if (!isDemo()) - %bmp = "gui/" @ %briefPic @ ".png"; - else - %bmp = "gui/" @ %briefPic @ ".bm8"; - - if ( isFile( "textures/" @ %bmp ) ) - { - TrainingPic.setBitmap( %bmp ); - TrainingPicFrame.setVisible( true ); - } - else - { - TrainingPic.setBitmap( "" ); - TrainingPicFrame.setVisible( false ); - } - - TrainingPlayBtn.setActive( %briefWAV !$= "" ); - TrainingBriefingText.setValue( %briefText ); - TrainingBriefingScroll.scrollToTop(); - TrainingGui.WAVBase = firstWord( %briefWAV ); - TrainingGui.WAVCount = restWords( %briefWAV ); - %file.delete(); - return true; -} - -//------------------------------------------------------------------------------ -function TrainingPlayTgl::onAction( %this ) -{ - if ( %this.getValue() ) - { - if ( TrainingMissionList.getSelectedId() != -1 ) - TrainingGui.startBriefing(); - } - else - TrainingGui.stopBriefing(); -} - -//-------------------------------------------------------- -function TrainingGui::toggleBriefing( %this ) -{ - if ( %this.soundHandle $= "" ) - { - %this.startBriefing(); - alxMusicFadeout($Pref::Audio::MusicVolume); - } - else - %this.stopBriefing(); -} - -//-------------------------------------------------------- -function TrainingGui::startBriefing( %this ) -{ - %this.stopBriefing(); - if ( %this.WAVBase !$= "" ) - { - %this.instance = %this.instance $= "" ? 0 : %this.instance; - %this.playNextBriefWAV( %this.WAVBase, 0, %this.WAVCount, %this.instance ); - } -} - -//-------------------------------------------------------- -function TrainingGui::playNextBriefWAV( %this, %wavBase, %id, %count, %instance ) -{ - if ( %instance == %this.instance ) - { - if ( %id < %count ) - { - %wav = "voice/Training/Briefings/" @ %wavBase @ ".brief0" @ ( %id + 1 ) @ ".wav"; - %this.soundHandle = alxCreateSource( AudioGui, %wav ); - alxPlay( %this.soundHandle ); - - // Schedule the next WAV: - %delay = alxGetWaveLen( %wav ) + 500; - %this.schedule( %delay, playNextBriefWAV, %wavBase, %id + 1, %count, %instance ); - } - else - { - // We're all done! - %this.soundHandle = ""; - } - } -} - -//-------------------------------------------------------- -function TrainingGui::stopBriefing( %this ) -{ - if ( %this.soundHandle !$= "" ) - { - alxStop( %this.soundHandle ); - %this.soundHandle = ""; - %this.instance++; - } -} - -//-------------------------------------------------------- -function TrainingGui::startTraining( %this ) -{ - MessagePopup( "STARTING MISSION", "Initializing, please wait..." ); - Canvas.repaint(); - cancelServerQuery(); - %file = getField( TrainingMissionList.getValue(), 1 ); - $ServerName = "Single Player Training"; - $HostGameType = "SinglePlayer"; - CreateServer( %file, "SinglePlayer" ); - alxMusicFadeout($Pref::Audio::MusicVolume); - localConnect( $Training::Name[%file], $Training::Race[%file] SPC $Training::Sex[%file], $Training::Skin[%file], $Training::Voice[%file] ); -} +//------------------------------------------------------------------------------ +// +// TrainingGui.cs +// +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +function LaunchTraining() +{ + LaunchTabView.viewTab( "CAMPAIGN", TrainingGui, 0 ); +} + +//------------------------------------------------------------------------------ +function TrainingGui::onWake( %this ) +{ + Canvas.pushDialog( LaunchToolbarDlg ); + + + //Reset the list + TrainingMissionList.clear(); + + if ($Pref::Campaign !$= "") + TrainingSelectMenu.onSelect(TrainingSelectMenu.findText($Pref::Campaign),$Pref::Campaign); + else + TrainingSelectMenu.onSelect(0,TrainingSelectMenu.getText()); + TrainingMissionList.sort( 1 ); + TrainingMissionList.setSelectedRow( 0 ); + if ( $pref::TrainingDifficulty > 0 && $pref::TrainingDifficulty < 4 ) + TrainingDifficultyMenu.setSelected( $pref::TrainingDifficulty ); + else + TrainingDifficultyMenu.setSelected( 1 ); +} + +//------------------------------------------------------------------------------ +function TrainingGui::onSleep( %this ) +{ + %this.stopBriefing(); + + Canvas.popDialog(LaunchToolbarDlg); +} + +//------------------------------------------------------------------------------ +function TrainingGui::updateList( %this ) +{ + %cam = $Pref::Campaign; + %dir = "Data/Campaigns/"; + %file = %dir @ %cam @ ".txt"; + + if (!IsFile(%file)) + return false; + + TrainingMissionList.clear(); + TrainingBriefingText.setValue( "" ); + TrainingPic.setBitmap( "" ); + TrainingPicFrame.setVisible( false ); + + if (!IsObject(CampaignLoader)) + new ScriptObject(CampaignLoader) { class = "BasicDataParser"; }; + CampaignLoader.empty(); + CampaignLoader.load(%file); + + %campaign = CampainLoader.get("Campaign",0); + %count = %campaign.element("MissionCount"); + + //Before we do the loopy stuff, we should check if there's a specific training mission first + %mission = %campaign.element("Practice"); + %text = %campaign.element("PracticeText"); + + if (%text != -1 && %mission != -1) + TrainingMissionList.addRow( 0, %text TAB %mission ); + + %settings = CampainLoader.get("Settings",0); + for (%i = 1; %i <= %count; %i++) + { + %mission = %campain.element("Mission" @ %i); + %text = %campaign.element("MissionText" @ %i); + TrainingMissionList.addRow( %i, %text TAB %mission ); + //Now the mission list is where we need it, find the player settings.. + $Training::Name[%Mission] = %settings.element("Name"); + $Training::Race[%Mission] = %settings.element("Race"); + $Training::Sex[%Mission] = %settings.element("Sex"); + $Training::Voice[%Mission] = %settings.element("Voice"); + $Training::VoicePitch[%Mission] = %settings.element("VoicePitch"); + $Training::Skin[%Mission] = %settings.element("Skin"); + $Training::EnemySkin[%Mission] = %settings.element("EnemySkin"); + $Training::EnemyName[%Mission] = %settings.element("EnemyName"); + $Training::EnemyTeam[%Mission] = %settings.element("EnemyTeam"); + $Training::PlayerTeam[%Mission] = %settings.element("PlayerTeam"); + $Training::StartLives[%Mission] = %settings.element("StartLives"); + $Training::EnemyRace[%Mission] = %settings.element("EnemyRace"); + } +} + +//------------------------------------------------------------------------------ +function TrainingGui::setKey( %this ) +{ +} + +//------------------------------------------------------------------------------ +function TrainingGui::onClose( %this ) +{ +} + +//------------------------------------------------------------------------------ +function TrainingDifficultyMenu::onAdd( %this ) +{ + %this.add( "Easy", 1 ); + %this.add( "Medium", 2 ); + %this.add( "Hard", 3 ); +} + +//------------------------------------------------------------------------------ +function TrainingDifficultyMenu::onSelect( %this, %id, %text ) +{ + $pref::TrainingDifficulty = %id; +} + +//------------------------------------------------------------------------------ +function TrainingSelectMenu::onAdd( %this ) +{ + + //Uber Dynamic Campaign Listing :) + %path = "Data/Campaigns/*.dat"; + %count = 0; + + if (!IsObject(CampaignLoader)) + new ScriptObject(CampaignLoader) { class = "BasicDataParser"; }; + CampaignLoader.empty(); + CampaignLoader.load(%file); + + for( %file = findFirstFile( %path ); %file !$= ""; %file = findNextFile( %path ) ) + { + CampaignLoader.load(%file); + %this.add( CampaignLoader.get("Campaign",%count).element("Name"), %count); + %count++; + } +} + +//------------------------------------------------------------------------------ +function TrainingSelectMenu::onSelect( %this, %id, %text ) +{ + $Pref::Campaign = %text; + + %row = TrainingMissionList.getSelectedID() - 1; + TrainingGui.updateList(); + TrainingGui.stopBriefing(); + TrainingSelectMenu.setText(%text); //Make sure our text is assigned.. + + if ($Pref::Campaign $= %text) + TrainingMissionList.setSelectedRow(%row); + else + TrainingMissionList.setSelectedRow(0); +} + +//------------------------------------------------------------------------------ +function TrainingMissionList::onSelect( %this, %id, %text ) +{ + TrainingGui.stopBriefing(); + %fileName = "missions/" @ getField( %text, 1 ) @ ".mis"; + %file = new FileObject(); + %state = 0; + if ( %file.openForRead( %fileName ) ) + { + // Get the mission briefing text: + while ( !%file.isEOF() ) + { + %line = %file.readLine(); + if ( %state == 0 && %line $= "//--- MISSION BRIEFING BEGIN ---" ) + %state = 1; + else if ( %state > 0 && %line $= "//--- MISSION BRIEFING END ---" ) + break; + else if ( %state == 1 ) + { + %briefText = %briefText @ getSubStr( %line, 2, 1000 ); + %state = 2; + } + else if ( %state == 2 ) + %briefText = %briefText NL getSubStr( %line, 2, 1000 ); + } + + // Get the mission briefing WAV file: + while ( !%file.isEOF() ) + { + %line = %file.readLine(); + if ( getSubStr( %line, 0, 17 ) $= "// BriefingWAV = " ) + { + %briefWAV = getSubStr( %line, 17, 1000 ); + break; + } + } + + // Get the bitmap name: + while ( !%file.isEOF() ) + { + %line = %file.readLine(); + if ( getSubStr( %line, 0, 12 ) $= "// Bitmap = " ) + { + %briefPic = getSubStr( %line, 12, 1000 ); + break; + } + } + %file.close(); + } + else + error( "Failed to open Single Player mission file " @ %fileName @ "!" ); + + if (!isDemo()) + %bmp = "gui/" @ %briefPic @ ".png"; + else + %bmp = "gui/" @ %briefPic @ ".bm8"; + + if ( isFile( "textures/" @ %bmp ) ) + { + TrainingPic.setBitmap( %bmp ); + TrainingPicFrame.setVisible( true ); + } + else + { + TrainingPic.setBitmap( "" ); + TrainingPicFrame.setVisible( false ); + } + + TrainingPlayBtn.setActive( %briefWAV !$= "" ); + TrainingBriefingText.setValue( %briefText ); + TrainingBriefingScroll.scrollToTop(); + TrainingGui.WAVBase = firstWord( %briefWAV ); + TrainingGui.WAVCount = restWords( %briefWAV ); + %file.delete(); + return true; +} + +//------------------------------------------------------------------------------ +function TrainingPlayTgl::onAction( %this ) +{ + if ( %this.getValue() ) + { + if ( TrainingMissionList.getSelectedId() != -1 ) + TrainingGui.startBriefing(); + } + else + TrainingGui.stopBriefing(); +} + +//-------------------------------------------------------- +function TrainingGui::toggleBriefing( %this ) +{ + if ( %this.soundHandle $= "" ) + { + %this.startBriefing(); + alxMusicFadeout($Pref::Audio::MusicVolume); + } + else + %this.stopBriefing(); +} + +//-------------------------------------------------------- +function TrainingGui::startBriefing( %this ) +{ + %this.stopBriefing(); + if ( %this.WAVBase !$= "" ) + { + %this.instance = %this.instance $= "" ? 0 : %this.instance; + %this.playNextBriefWAV( %this.WAVBase, 0, %this.WAVCount, %this.instance ); + } +} + +//-------------------------------------------------------- +function TrainingGui::playNextBriefWAV( %this, %wavBase, %id, %count, %instance ) +{ + if ( %instance == %this.instance ) + { + if ( %id < %count ) + { + %wav = "voice/Training/Briefings/" @ %wavBase @ ".brief0" @ ( %id + 1 ) @ ".wav"; + %this.soundHandle = alxCreateSource( AudioGui, %wav ); + alxPlay( %this.soundHandle ); + + // Schedule the next WAV: + %delay = alxGetWaveLen( %wav ) + 500; + %this.schedule( %delay, playNextBriefWAV, %wavBase, %id + 1, %count, %instance ); + } + else + { + // We're all done! + %this.soundHandle = ""; + } + } +} + +//-------------------------------------------------------- +function TrainingGui::stopBriefing( %this ) +{ + if ( %this.soundHandle !$= "" ) + { + alxStop( %this.soundHandle ); + %this.soundHandle = ""; + %this.instance++; + } +} + +//-------------------------------------------------------- +function TrainingGui::startTraining( %this ) +{ + MessagePopup( "STARTING MISSION", "Initializing, please wait..." ); + Canvas.repaint(); + cancelServerQuery(); + %file = getField( TrainingMissionList.getValue(), 1 ); + $ServerName = "Single Player Training"; + $HostGameType = "SinglePlayer"; + CreateServer( %file, "SinglePlayer" ); + alxMusicFadeout($Pref::Audio::MusicVolume); + localConnect( $Training::Name[%file], $Training::Race[%file] SPC $Training::Sex[%file], $Training::Skin[%file], $Training::Voice[%file] ); +} diff --git a/scripts/admin.cs b/scripts/admin.cs index 24d57b0..f7e74d8 100644 --- a/scripts/admin.cs +++ b/scripts/admin.cs @@ -1,429 +1,429 @@ -// These have been secured against all those wanna-be-hackers. -$VoteMessage["VoteAdminPlayer"] = "Admin Player"; -$VoteMessage["VoteKickPlayer"] = "Kick Player"; -$VoteMessage["VoteLockServer"] = "Lock Server"; -$VoteMessage["VoteGlobal"] = "Global Chat"; -$VoteMessage["VoteProgressiveMode"] = "Toggle Progressive Mode"; -$VoteMessage["BanPlayer"] = "Ban Player"; -$VoteMessage["VoteChangeMission"] = "change the mission to"; -$VoteMessage["VoteTeamDamage", 0] = "enable team damage"; -$VoteMessage["VoteTeamDamage", 1] = "disable team damage"; -$VoteMessage["VoteTournamentMode"] = "change the server to"; -$VoteMessage["VoteFFAMode"] = "change the server to"; -$VoteMessage["VoteChangeTimeLimit"] = "change the time limit to"; -$VoteMessage["VoteMatchStart"] = "start the match"; -$VoteMessage["VoteGreedMode", 0] = "enable Hoard Mode"; -$VoteMessage["VoteGreedMode", 1] = "disable Hoard Mode"; -$VoteMessage["VoteHoardMode", 0] = "enable Greed Mode"; -$VoteMessage["VoteHoardMode", 1] = "disable Greed Mode"; - -function serverCmdStartNewVote(%client, %typeName, %arg1, %arg2, %arg3, %arg4, %playerVote) -{ - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - - // haha - who gets the last laugh... No admin for you! - if( %typeName $= "VoteAdminPlayer" && !$Host::allowAdminPlayerVotes ) - if( !%client.isSuperAdmin ) // z0dd - ZOD, 5/12/02. Allow Supers to do whatever the hell they want - return; - - if ($CurrentMissionType $= "RPG") //Don't screw with the gamemode.. - switch$(%typeName) - { - case "VoteChangeTimeLimit": return; - case "VoteTournamentMode": return; - case "VoteTeamDamage": return; - case "MakeObserver": return; - case "VoteProgressiveMode": return; - } - - - %typePass = true; - - // if not a valid vote, turn back. - if( $VoteMessage[ %typeName ] $= "" && %typeName !$= "VoteTeamDamage" ) - if( $VoteMessage[ %typeName ] $= "" && %typeName !$= "VoteHoardMode" ) - if( $VoteMessage[ %typeName ] $= "" && %typeName !$= "VoteGreedMode" ) - %typePass = false; - - if(( $VoteMessage[ %typeName, $TeamDamage ] $= "" && %typeName $= "VoteTeamDamage" )) - %typePass = false; - - if( !%typePass ) - return; // -> bye ;) - - - // ------------------------------------ - // z0dd - ZOD, 10/03/02. Fixed ban code - //if( %typeName $= "BanPlayer" ) - // if( !%client.isSuperAdmin ) - // return; // -> bye ;) - if( %typeName $= "BanPlayer" ) - { - if( !%client.isSuperAdmin ) - { - return; // -> bye ;) - } - else - { - ban( %arg1, %client ); - return; - } - } - // ------------------------------------ - - %isAdmin = ( %client.isAdmin || %client.isSuperAdmin ); - - // z0dd - ZOD, 4/7/02. Get the Admins name. - if(%isAdmin) - $AdminName = %client.name; - - // keep these under the server's control. I win. - if( !%playerVote ) - %actionMsg = $VoteMessage[ %typeName ]; - else if( %typeName $= "VoteTeamDamage" || %typeName $= "VoteGreedMode" || %typeName $= "VoteHoardMode" ) - %actionMsg = $VoteMessage[ %typeName, $TeamDamage ]; - else - %actionMsg = $VoteMessage[ %typeName ]; - - if( !%client.canVote && !%isAdmin ) - return; - - if ( ( !%isAdmin || ( %arg1.isAdmin && ( %client != %arg1 ) ) ) && // z0dd - ZOD, 4/7/02. Allow SuperAdmins to kick Admins - !( ( %typeName $= "VoteKickPlayer" ) && %client.isSuperAdmin ) ) // z0dd - ZOD, 4/7/02. Allow SuperAdmins to kick Admins - { - %teamSpecific = false; - %gender = (%client.sex $= "Male" ? 'he' : 'she'); - if ( Game.scheduleVote $= "" ) - { - %clientsVoting = 0; - - //send a message to everyone about the vote... - if ( %playerVote ) - { - %teamSpecific = ( %typeName $= "VoteKickPlayer" ) && ( Game.numTeams > 1 ); - %kickerIsObs = %client.team == 0; - %kickeeIsObs = %arg1.team == 0; - %sameTeam = %client.team == %arg1.team; - - if( %kickeeIsObs ) - { - %teamSpecific = false; - %sameTeam = false; - } - if(( !%sameTeam && %teamSpecific) && %typeName !$= "VoteAdminPlayer") - { - messageClient(%client, '', '\c2Player votes must be team based.'); - return; - } - - // kicking is team specific - if( %typeName $= "VoteKickPlayer" ) - { - if(%arg1.isSuperAdmin) - { - messageClient(%client, '', '\c2You can not %1 %2, %3 is a Super Admin!', %actionMsg, %arg1.name, %gender); - return; - } - - Game.kickClient = %arg1; - Game.kickClientName = %arg1.name; - Game.kickGuid = %arg1.guid; - Game.kickTeam = %arg1.team; - - if(%teamSpecific) - { - for ( %idx = 0; %idx < ClientGroup.getCount(); %idx++ ) - { - %cl = ClientGroup.getObject( %idx ); - - if (%cl.team == %client.team && !%cl.isAIControlled()) - { - messageClient( %cl, 'VoteStarted', '\c2%1 initiated a vote to %2 %3.', %client.name, %actionMsg, %arg1.name); - %clientsVoting++; - } - } - } - else - { - for ( %idx = 0; %idx < ClientGroup.getCount(); %idx++ ) - { - %cl = ClientGroup.getObject( %idx ); - if ( !%cl.isAIControlled() ) - { - messageClient( %cl, 'VoteStarted', '\c2%1 initiated a vote to %2 %3.', %client.name, %actionMsg, %arg1.name); - %clientsVoting++; - } - } - } - } - else - { - for ( %idx = 0; %idx < ClientGroup.getCount(); %idx++ ) - { - %cl = ClientGroup.getObject( %idx ); - if ( !%cl.isAIControlled() ) - { - messageClient( %cl, 'VoteStarted', '\c2%1 initiated a vote to %2 %3.', %client.name, %actionMsg, %arg1.name); - %clientsVoting++; - } - } - } - } - else if ( %typeName $= "VoteChangeMission" ) - { - for ( %idx = 0; %idx < ClientGroup.getCount(); %idx++ ) - { - %cl = ClientGroup.getObject( %idx ); - if ( !%cl.isAIControlled() ) - { - messageClient( %cl, 'VoteStarted', '\c2%1 initiated a vote to %2 %3 (%4).', %client.name, %actionMsg, %arg1, %arg2 ); - %clientsVoting++; - } - } - } - else if (%arg1 !$= 0) - { - if (%arg2 !$= 0) - { - if(%typeName $= "VoteTournamentMode") - { - %admin = getAdmin(); - if(%admin > 0) - { - for ( %idx = 0; %idx < ClientGroup.getCount(); %idx++ ) - { - %cl = ClientGroup.getObject( %idx ); - if ( !%cl.isAIControlled() ) - { - messageClient( %cl, 'VoteStarted', '\c2%1 initiated a vote to %2 Tournament Mode (%3).', %client.name, %actionMsg, %arg1); - %clientsVoting++; - } - } - } - else - { - messageClient( %client, 'clientMsg', 'There must be a server admin to play in Tournament Mode.'); - return; - } - } - else - { - for ( %idx = 0; %idx < ClientGroup.getCount(); %idx++ ) - { - %cl = ClientGroup.getObject( %idx ); - if ( !%cl.isAIControlled() ) - { - messageClient( %cl, 'VoteStarted', '\c2%1 initiated a vote to %2 %3 %4.', %client.name, %actionMsg, %arg1, %arg2); - %clientsVoting++; - } - } - } - } - else - { - for ( %idx = 0; %idx < ClientGroup.getCount(); %idx++ ) - { - %cl = ClientGroup.getObject( %idx ); - if ( !%cl.isAIControlled() ) - { - messageClient( %cl, 'VoteStarted', '\c2%1 initiated a vote to %2 %3.', %client.name, %actionMsg, %arg1); - %clientsVoting++; - } - } - } - } - else - { - for ( %idx = 0; %idx < ClientGroup.getCount(); %idx++ ) - { - %cl = ClientGroup.getObject( %idx ); - if ( !%cl.isAIControlled() ) - { - messageClient( %cl, 'VoteStarted', '\c2%1 initiated a vote to %2.', %client.name, %actionMsg); - %clientsVoting++; - } - } - } - - // open the vote hud for all clients that will participate in this vote - if(%teamSpecific) - { - for ( %clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++ ) - { - %cl = ClientGroup.getObject( %clientIndex ); - - if(%cl.team == %client.team && !%cl.isAIControlled()) - messageClient(%cl, 'openVoteHud', "", %clientsVoting, ($Host::VotePassPercent / 100)); - } - } - else - { - for ( %clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++ ) - { - %cl = ClientGroup.getObject( %clientIndex ); - if ( !%cl.isAIControlled() ) - messageClient(%cl, 'openVoteHud', "", %clientsVoting, ($Host::VotePassPercent / 100)); - } - } - clearVotes(); - Game.voteType = %typeName; - Game.scheduleVote = schedule( ($Host::VoteTime * 1000), 0, "calcVotes", %typeName, %arg1, %arg2, %arg3, %arg4 ); - %client.vote = true; - messageAll('addYesVote', ""); - - if(!%client.team == 0) - clearBottomPrint(%client); - } - else - messageClient( %client, 'voteAlreadyRunning', '\c2A vote is already in progress.' ); - } - else - { - if ( Game.scheduleVote !$= "" && Game.voteType $= %typeName ) - { - messageAll('closeVoteHud', ""); - cancel(Game.scheduleVote); - Game.scheduleVote = ""; - } - - // if this is a superAdmin, don't kick or ban - if(%arg1 != %client) - { - if(!%arg1.isSuperAdmin) - { - // Set up kick/ban values: - if ( %typeName $= "VoteBanPlayer" || %typeName $= "VoteKickPlayer" ) - { - Game.kickClient = %arg1; - Game.kickClientName = %arg1.name; - Game.kickGuid = %arg1.guid; - Game.kickTeam = %arg1.team; - } - - //Tinman - PURE servers can't call "eval" - //Mark - True, but neither SHOULD a normal server - // - thanks Ian Hardingham - //if (!isPureServer()) - // eval( "Game." @ %typeName @ "(true,\"" @ %arg1 @ "\",\"" @ %arg2 @ "\",\"" @ %arg3 @ "\",\"" @ %arg4 @ "\");" ); - //else - Game.evalVote(%typeName, true, %arg1, %arg2, %arg3, %arg4); - } - else - messageClient(%client, '', '\c2You can not %1 %2, %3 is a Super Admin!', %actionMsg, %arg1.name, %gender); - } - } - %client.canVote = false; - %client.rescheduleVote = schedule( ($Host::voteSpread * 1000) + ($Host::voteTime * 1000) , 0, "resetVotePrivs", %client ); -} - -function resetVotePrivs( %client ) -{ - //messageClient( %client, '', 'You may now start a new vote.'); - %client.canVote = true; - %client.rescheduleVote = ""; -} - -function serverCmdSetPlayerVote(%client, %vote) -{ - // players can only vote once - if( %client.vote $= "" ) - { - %client.vote = %vote; - if(%client.vote == 1) - messageAll('addYesVote', ""); - else - messageAll('addNoVote', ""); - - commandToClient(%client, 'voteSubmitted', %vote); - } -} - -function calcVotes(%typeName, %arg1, %arg2, %arg3, %arg4) -{ - if(%typeName $= "voteMatchStart") - if($MatchStarted || $countdownStarted) - return; - - for ( %clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++ ) - { - %cl = ClientGroup.getObject( %clientIndex ); - messageClient(%cl, 'closeVoteHud', ""); - - if ( %cl.vote !$= "" ) - { - if ( %cl.vote ) - { - Game.votesFor[%cl.team]++; - Game.totalVotesFor++; - } - else - { - Game.votesAgainst[%cl.team]++; - Game.totalVotesAgainst++; - } - } - else - { - Game.votesNone[%cl.team]++; - Game.totalVotesNone++; - } - } - //Tinman - PURE servers can't call "eval" - //Mark - True, but neither SHOULD a normal server - // - thanks Ian Hardingham - //if (!isPureServer()) - // eval( "Game." @ %typeName @ "(false,\"" @ %arg1 @ "\",\"" @ %arg2 @ "\",\"" @ %arg3 @ "\",\"" @ %arg4 @ "\");" ); - //else - Game.evalVote(%typeName, false, %arg1, %arg2, %arg3, %arg4); - Game.scheduleVote = ""; - Game.kickClient = ""; - clearVotes(); -} - -function clearVotes() -{ - for(%clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++) - { - %client = ClientGroup.getObject(%clientIndex); - %client.vote = ""; - messageClient(%client, 'clearVoteHud', ""); - } - - for(%team = 1; %team < 5; %team++) - { - Game.votesFor[%team] = 0; - Game.votesAgainst[%team] = 0; - Game.votesNone[%team] = 0; - Game.totalVotesFor = 0; - Game.totalVotesAgainst = 0; - Game.totalVotesNone = 0; - } -} - -// Tournament mode Stuff----------------------------------- - -function setModeFFA( %mission, %missionType ) -{ - if( $Host::TournamentMode ) - { - $Host::TournamentMode = false; - - if( isObject( Game ) ) - Game.gameOver(); - - loadMission(%mission, %missionType, false); - } -} - -function setModeTournament( %mission, %missionType ) -{ - if( !$Host::TournamentMode ) - { - $Host::TournamentMode = true; - - if( isObject( Game ) ) - Game.gameOver(); - - loadMission(%mission, %missionType, false); - } -} +// These have been secured against all those wanna-be-hackers. +$VoteMessage["VoteAdminPlayer"] = "Admin Player"; +$VoteMessage["VoteKickPlayer"] = "Kick Player"; +$VoteMessage["VoteLockServer"] = "Lock Server"; +$VoteMessage["VoteGlobal"] = "global Chat"; +$VoteMessage["VoteProgressiveMode"] = "Toggle Progressive Mode"; +$VoteMessage["BanPlayer"] = "Ban Player"; +$VoteMessage["VoteChangeMission"] = "change the mission to"; +$VoteMessage["VoteTeamDamage", 0] = "enable team damage"; +$VoteMessage["VoteTeamDamage", 1] = "disable team damage"; +$VoteMessage["VoteTournamentMode"] = "change the server to"; +$VoteMessage["VoteFFAMode"] = "change the server to"; +$VoteMessage["VoteChangeTimeLimit"] = "change the time limit to"; +$VoteMessage["VoteMatchStart"] = "start the match"; +$VoteMessage["VoteGreedMode", 0] = "enable Hoard Mode"; +$VoteMessage["VoteGreedMode", 1] = "disable Hoard Mode"; +$VoteMessage["VoteHoardMode", 0] = "enable Greed Mode"; +$VoteMessage["VoteHoardMode", 1] = "disable Greed Mode"; + +function serverCmdStartNewVote(%client, %typeName, %arg1, %arg2, %arg3, %arg4, %playerVote) +{ + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + + // haha - who gets the last laugh... No admin for you! + if( %typeName $= "VoteAdminPlayer" && !$Host::allowAdminPlayerVotes ) + if( !%client.isSuperAdmin ) // z0dd - ZOD, 5/12/02. Allow Supers to do whatever the hell they want + return; + + if ($CurrentMissionType $= "RPG") //Don't screw with the gamemode.. + switch$(%typeName) + { + case "VoteChangeTimeLimit": return; + case "VoteTournamentMode": return; + case "VoteTeamDamage": return; + case "MakeObserver": return; + case "VoteProgressiveMode": return; + } + + + %typePass = true; + + // if not a valid vote, turn back. + if( $VoteMessage[ %typeName ] $= "" && %typeName !$= "VoteTeamDamage" ) + if( $VoteMessage[ %typeName ] $= "" && %typeName !$= "VoteHoardMode" ) + if( $VoteMessage[ %typeName ] $= "" && %typeName !$= "VoteGreedMode" ) + %typePass = false; + + if(( $VoteMessage[ %typeName, $TeamDamage ] $= "" && %typeName $= "VoteTeamDamage" )) + %typePass = false; + + if( !%typePass ) + return; // -> bye ;) + + + // ------------------------------------ + // z0dd - ZOD, 10/03/02. Fixed ban code + //if( %typeName $= "BanPlayer" ) + // if( !%client.isSuperAdmin ) + // return; // -> bye ;) + if( %typeName $= "BanPlayer" ) + { + if( !%client.isSuperAdmin ) + { + return; // -> bye ;) + } + else + { + ban( %arg1, %client ); + return; + } + } + // ------------------------------------ + + %isAdmin = ( %client.isAdmin || %client.isSuperAdmin ); + + // z0dd - ZOD, 4/7/02. Get the Admins name. + if(%isAdmin) + $AdminName = %client.name; + + // keep these under the server's control. I win. + if( !%playerVote ) + %actionMsg = $VoteMessage[ %typeName ]; + else if( %typeName $= "VoteTeamDamage" || %typeName $= "VoteGreedMode" || %typeName $= "VoteHoardMode" ) + %actionMsg = $VoteMessage[ %typeName, $TeamDamage ]; + else + %actionMsg = $VoteMessage[ %typeName ]; + + if( !%client.canVote && !%isAdmin ) + return; + + if ( ( !%isAdmin || ( %arg1.isAdmin && ( %client != %arg1 ) ) ) && // z0dd - ZOD, 4/7/02. Allow SuperAdmins to kick Admins + !( ( %typeName $= "VoteKickPlayer" ) && %client.isSuperAdmin ) ) // z0dd - ZOD, 4/7/02. Allow SuperAdmins to kick Admins + { + %teamSpecific = false; + %gender = (%client.sex $= "Male" ? 'he' : 'she'); + if ( Game.scheduleVote $= "" ) + { + %clientsVoting = 0; + + //send a message to everyone about the vote... + if ( %playerVote ) + { + %teamSpecific = ( %typeName $= "VoteKickPlayer" ) && ( Game.numTeams > 1 ); + %kickerIsObs = %client.team == 0; + %kickeeIsObs = %arg1.team == 0; + %sameTeam = %client.team == %arg1.team; + + if( %kickeeIsObs ) + { + %teamSpecific = false; + %sameTeam = false; + } + if(( !%sameTeam && %teamSpecific) && %typeName !$= "VoteAdminPlayer") + { + messageClient(%client, '', '\c2Player votes must be team based.'); + return; + } + + // kicking is team specific + if( %typeName $= "VoteKickPlayer" ) + { + if(%arg1.isSuperAdmin) + { + messageClient(%client, '', '\c2You can not %1 %2, %3 is a Super Admin!', %actionMsg, %arg1.name, %gender); + return; + } + + Game.kickClient = %arg1; + Game.kickClientName = %arg1.name; + Game.kickGuid = %arg1.guid; + Game.kickTeam = %arg1.team; + + if(%teamSpecific) + { + for ( %idx = 0; %idx < ClientGroup.getCount(); %idx++ ) + { + %cl = ClientGroup.getObject( %idx ); + + if (%cl.team == %client.team && !%cl.isAIControlled()) + { + messageClient( %cl, 'VoteStarted', '\c2%1 initiated a vote to %2 %3.', %client.name, %actionMsg, %arg1.name); + %clientsVoting++; + } + } + } + else + { + for ( %idx = 0; %idx < ClientGroup.getCount(); %idx++ ) + { + %cl = ClientGroup.getObject( %idx ); + if ( !%cl.isAIControlled() ) + { + messageClient( %cl, 'VoteStarted', '\c2%1 initiated a vote to %2 %3.', %client.name, %actionMsg, %arg1.name); + %clientsVoting++; + } + } + } + } + else + { + for ( %idx = 0; %idx < ClientGroup.getCount(); %idx++ ) + { + %cl = ClientGroup.getObject( %idx ); + if ( !%cl.isAIControlled() ) + { + messageClient( %cl, 'VoteStarted', '\c2%1 initiated a vote to %2 %3.', %client.name, %actionMsg, %arg1.name); + %clientsVoting++; + } + } + } + } + else if ( %typeName $= "VoteChangeMission" ) + { + for ( %idx = 0; %idx < ClientGroup.getCount(); %idx++ ) + { + %cl = ClientGroup.getObject( %idx ); + if ( !%cl.isAIControlled() ) + { + messageClient( %cl, 'VoteStarted', '\c2%1 initiated a vote to %2 %3 (%4).', %client.name, %actionMsg, %arg1, %arg2 ); + %clientsVoting++; + } + } + } + else if (%arg1 !$= 0) + { + if (%arg2 !$= 0) + { + if(%typeName $= "VoteTournamentMode") + { + %admin = getAdmin(); + if(%admin > 0) + { + for ( %idx = 0; %idx < ClientGroup.getCount(); %idx++ ) + { + %cl = ClientGroup.getObject( %idx ); + if ( !%cl.isAIControlled() ) + { + messageClient( %cl, 'VoteStarted', '\c2%1 initiated a vote to %2 Tournament Mode (%3).', %client.name, %actionMsg, %arg1); + %clientsVoting++; + } + } + } + else + { + messageClient( %client, 'clientMsg', 'There must be a server admin to play in Tournament Mode.'); + return; + } + } + else + { + for ( %idx = 0; %idx < ClientGroup.getCount(); %idx++ ) + { + %cl = ClientGroup.getObject( %idx ); + if ( !%cl.isAIControlled() ) + { + messageClient( %cl, 'VoteStarted', '\c2%1 initiated a vote to %2 %3 %4.', %client.name, %actionMsg, %arg1, %arg2); + %clientsVoting++; + } + } + } + } + else + { + for ( %idx = 0; %idx < ClientGroup.getCount(); %idx++ ) + { + %cl = ClientGroup.getObject( %idx ); + if ( !%cl.isAIControlled() ) + { + messageClient( %cl, 'VoteStarted', '\c2%1 initiated a vote to %2 %3.', %client.name, %actionMsg, %arg1); + %clientsVoting++; + } + } + } + } + else + { + for ( %idx = 0; %idx < ClientGroup.getCount(); %idx++ ) + { + %cl = ClientGroup.getObject( %idx ); + if ( !%cl.isAIControlled() ) + { + messageClient( %cl, 'VoteStarted', '\c2%1 initiated a vote to %2.', %client.name, %actionMsg); + %clientsVoting++; + } + } + } + + // open the vote hud for all clients that will participate in this vote + if(%teamSpecific) + { + for ( %clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++ ) + { + %cl = ClientGroup.getObject( %clientIndex ); + + if(%cl.team == %client.team && !%cl.isAIControlled()) + messageClient(%cl, 'openVoteHud', "", %clientsVoting, ($Host::VotePassPercent / 100)); + } + } + else + { + for ( %clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++ ) + { + %cl = ClientGroup.getObject( %clientIndex ); + if ( !%cl.isAIControlled() ) + messageClient(%cl, 'openVoteHud', "", %clientsVoting, ($Host::VotePassPercent / 100)); + } + } + clearVotes(); + Game.voteType = %typeName; + Game.scheduleVote = schedule( ($Host::VoteTime * 1000), 0, "calcVotes", %typeName, %arg1, %arg2, %arg3, %arg4 ); + %client.vote = true; + messageAll('addYesVote', ""); + + if(!%client.team == 0) + clearBottomPrint(%client); + } + else + messageClient( %client, 'voteAlreadyRunning', '\c2A vote is already in progress.' ); + } + else + { + if ( Game.scheduleVote !$= "" && Game.voteType $= %typeName ) + { + messageAll('closeVoteHud', ""); + cancel(Game.scheduleVote); + Game.scheduleVote = ""; + } + + // if this is a superAdmin, don't kick or ban + if(%arg1 != %client) + { + if(!%arg1.isSuperAdmin) + { + // Set up kick/ban values: + if ( %typeName $= "VoteBanPlayer" || %typeName $= "VoteKickPlayer" ) + { + Game.kickClient = %arg1; + Game.kickClientName = %arg1.name; + Game.kickGuid = %arg1.guid; + Game.kickTeam = %arg1.team; + } + + //Tinman - PURE servers can't call "eval" + //Mark - True, but neither SHOULD a normal server + // - thanks Ian Hardingham + //if (!isPureServer()) + // eval( "Game." @ %typeName @ "(true,\"" @ %arg1 @ "\",\"" @ %arg2 @ "\",\"" @ %arg3 @ "\",\"" @ %arg4 @ "\");" ); + //else + Game.evalVote(%typeName, true, %arg1, %arg2, %arg3, %arg4); + } + else + messageClient(%client, '', '\c2You can not %1 %2, %3 is a Super Admin!', %actionMsg, %arg1.name, %gender); + } + } + %client.canVote = false; + %client.rescheduleVote = schedule( ($Host::voteSpread * 1000) + ($Host::voteTime * 1000) , 0, "resetVotePrivs", %client ); +} + +function resetVotePrivs( %client ) +{ + //messageClient( %client, '', 'You may now start a new vote.'); + %client.canVote = true; + %client.rescheduleVote = ""; +} + +function serverCmdSetPlayerVote(%client, %vote) +{ + // players can only vote once + if( %client.vote $= "" ) + { + %client.vote = %vote; + if(%client.vote == 1) + messageAll('addYesVote', ""); + else + messageAll('addNoVote', ""); + + commandToClient(%client, 'voteSubmitted', %vote); + } +} + +function calcVotes(%typeName, %arg1, %arg2, %arg3, %arg4) +{ + if(%typeName $= "voteMatchStart") + if($MatchStarted || $countdownStarted) + return; + + for ( %clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++ ) + { + %cl = ClientGroup.getObject( %clientIndex ); + messageClient(%cl, 'closeVoteHud', ""); + + if ( %cl.vote !$= "" ) + { + if ( %cl.vote ) + { + Game.votesFor[%cl.team]++; + Game.totalVotesFor++; + } + else + { + Game.votesAgainst[%cl.team]++; + Game.totalVotesAgainst++; + } + } + else + { + Game.votesNone[%cl.team]++; + Game.totalVotesNone++; + } + } + //Tinman - PURE servers can't call "eval" + //Mark - True, but neither SHOULD a normal server + // - thanks Ian Hardingham + //if (!isPureServer()) + // eval( "Game." @ %typeName @ "(false,\"" @ %arg1 @ "\",\"" @ %arg2 @ "\",\"" @ %arg3 @ "\",\"" @ %arg4 @ "\");" ); + //else + Game.evalVote(%typeName, false, %arg1, %arg2, %arg3, %arg4); + Game.scheduleVote = ""; + Game.kickClient = ""; + clearVotes(); +} + +function clearVotes() +{ + for(%clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++) + { + %client = ClientGroup.getObject(%clientIndex); + %client.vote = ""; + messageClient(%client, 'clearVoteHud', ""); + } + + for(%team = 1; %team < 5; %team++) + { + Game.votesFor[%team] = 0; + Game.votesAgainst[%team] = 0; + Game.votesNone[%team] = 0; + Game.totalVotesFor = 0; + Game.totalVotesAgainst = 0; + Game.totalVotesNone = 0; + } +} + +// Tournament mode Stuff----------------------------------- + +function setModeFFA( %mission, %missionType ) +{ + if( $Host::TournamentMode ) + { + $Host::TournamentMode = false; + + if( isObject( Game ) ) + Game.gameOver(); + + loadMission(%mission, %missionType, false); + } +} + +function setModeTournament( %mission, %missionType ) +{ + if( !$Host::TournamentMode ) + { + $Host::TournamentMode = true; + + if( isObject( Game ) ) + Game.gameOver(); + + loadMission(%mission, %missionType, false); + } +} diff --git a/scripts/ai.cs b/scripts/ai.cs index d62c41b..c59ccd1 100644 --- a/scripts/ai.cs +++ b/scripts/ai.cs @@ -1,912 +1,912 @@ -//-----------------------------------// -// AI SCRIPT FUNCTIONS // -//-----------------------------------// - -//first, exec the supporting scripts -exec("scripts/aiDebug.cs"); -exec("scripts/aiDefaultTasks.cs"); -exec("scripts/aiObjectives.cs"); -exec("scripts/aiInventory.cs"); -exec("scripts/aiChat.cs"); -exec("scripts/aiHumanTasks.cs"); -exec("scripts/aiObjectiveBuilder.cs"); -exec("scripts/aiBotProfiles.cs"); - -$AIModeStop = 0; -$AIModeWalk = 1; -$AIModeGainHeight = 2; -$AIModeExpress = 3; -$AIModeMountVehicle = 4; - -$AIClientLOSTimeout = 15000; //how long a client has to remain out of sight of the bot - //before the bot "can't see" the client anymore... -$AIClientMinLOSTime = 10000; //how long a bot will search for a client - - -//-----------------------------------// -//Objective weights - level 1 - -$AIWeightCapFlag[1] = 5000; //range 5100 to 5320 -$AIWeightKillFlagCarrier[1] = 4800; //range 4800 to 5120 -$AIWeightReturnFlag[1] = 5001; //range 5101 to 5321 -$AIWeightDefendFlag[1] = 3900; //range 4000 to 4220 -$AIWeightGrabFlag[1] = 3850; //range 3950 to 4170 - -$AIWeightDefendFlipFlop[1] = 3900; //range 4000 to 4220 -$AIWeightCaptureFlipFlop[1] = 3850; //range 3850 to 4170 - -$AIWeightAttackGenerator[1] = 3100; //range 3200 to 3520 -$AIWeightRepairGenerator[1] = 3200; //range 3300 to 3620 -$AIWeightDefendGenerator[1] = 3100; //range 3200 to 3420 - -$AIWeightMortarTurret[1] = 3400; //range 3500 to 3600 -$AIWeightLazeObject[1] = 3200; //range 3300 to 3400 -$AIWeightRepairTurret[1] = 3100; //range 3200 to 3420 - -$AIWeightAttackInventory[1] = 2900; //range 2800 to 2920 -$AIWeightRepairInventory[1] = 2900; //range 2800 to 2920 - -$AIWeightEscortOffense[1] = 2900; //range 2800 to 2920 -$AIWeightEscortCapper[1] = 3250; //range 3350 to 3470 - -//used to allow a bot to finish tasks once started. -$AIWeightContinueDeploying = 4250; -$AIWeightContinueRepairing = 4250; - -//Objective weights from human -$AIWeightHumanIssuedCommand = 4450; -$AIWeightHumanIssuedEscort = 4425; - -//Objective weights - level 2 -$AIWeightCapFlag[2] = 0; //only one person can ever cap a flag -$AIWeightKillFlagCarrier[2] = 4800; //range 4800 to 5020 -$AIWeightReturnFlag[2] = 4100; //range 4200 to 4320 -$AIWeightDefendFlag[2] = 2000; //range 2100 to 2220 -$AIWeightGrabFlag[2] = 2000; //range 2100 to 2220 - -$AIWeightDefendFlipFlop[2] = 2000; //range 2100 to 2220 -$AIWeightDefendFlipFlop[3] = 1500; //range 1600 to 1720 -$AIWeightDefendFlipFlop[4] = 1000; //range 1100 to 1220 - -$AIWeightAttackGenerator[2] = 1600; //range 1700 to 1920 -$AIWeightRepairGenerator[2] = 1600; //range 1700 to 1920 -$AIWeightDefendGenerator[2] = 1500; //range 1600 to 1720 - -$AIWeightAttackInventory[2] = 1400; //range 1500 to 1720 -$AIWeightRepairInventory[2] = 1400; //range 1500 to 1720 - -$AIWeightMortarTurret[2] = 1000; //range 1100 to 1320 -$AIWeightLazeObject[2] = 0; //no need to have more than one targetter -$AIWeightRepairTurret[2] = 1000; //range 1100 to 1320 - -$AIWeightEscortOffense[2] = 2900; //range 3300 to 3420 -$AIWeightEscortCapper[2] = 3000; //range 3100 to 3220 - - -function AIInit() -{ - AISlicerInit(); - installNavThreats(); - NavDetectForceFields(); -// ShowFPS(); - - //enable the use of grenades - $AIDisableGrenades = false; - $AIDisableChat = false; - - //create the "objective delete set" - if(nameToId("AIBombLocationSet") <= 0) - { - $AIBombLocationSet = new SimSet("AIBombLocationSet"); - MissionCleanup.add($AIBombLocationSet); - } - - //create the Inventory group - if(nameToId("AIStationInventorySet") <= 0) - { - $AIInvStationSet = new SimSet("AIStationInventorySet"); - MissionCleanup.add($AIInvStationSet); - } - - //create the Item group - if (nameToId("AIItemSet") <= 0) - { - $AIItemSet = new SimSet("AIItemSet"); - MissionCleanup.add($AIItemSet); - } - - //create the Item group - if (nameToId("AIGrenadeSet") <= 0) - { - $AIGrenadeSet = new SimSet("AIGrenadeSet"); - MissionCleanup.add($AIGrenadeSet); - } - - //create the weapon group - if (nameToId("AIWeaponSet") <= 0) - { - $AIWeaponSet = new SimSet("AIWeaponSet"); - MissionCleanup.add($AIWeaponSet); - } - - //create the deployed turret group - if (nameToID("AIRemoteTurretSet") <= 0) - { - $AIRemoteTurretSet = new SimSet("AIRemoteTurretSet"); - MissionCleanup.add($AIRemoteTurretSet); - } - - //create the deployed turret group - if (nameToID("AIDeployedMineSet") <= 0) - { - $AIDeployedMineSet = new SimSet("AIDeployedMineSet"); - MissionCleanup.add($AIDeployedMineSet); - } - - //create the deployed turret group - if (nameToID("AIVehicleSet") <= 0) - { - $AIVehicleSet = new SimSet("AIVehicleSet"); - MissionCleanup.add($AIVehicleSet); - } - - %missionGroupFolder = nameToID("MissionGroup"); - %missionGroupFolder.AIMissionInit(); -} - -// this is called at mission load by the specific game type -function AIInitObjectives(%team, %game) -{ - %group = nameToID("MissionGroup/Teams/team" @ %team @ "/AIObjectives"); - if(%group < 0) - return; // opps, there is no Objectives set for this team. - - // add the grouped objectives to the teams Q - %count = %group.getCount(); - for (%i = 0; %i < %count; %i++) - { - %objective = %group.getObject(%i); - if (%objective.getClassName() !$= "AIObjective") - { - %grpCount = %objective.getCount(); - for (%j = 0; %j < %grpCount; %j++) - { - %grpObj = %objective.getObject(%j); - if (%objective.gameType $= "" || %objective.gameType $= "all") - %objType = ""; - else - %objType = %objective.gameType @ "Game"; - - if (%objType $= "" || %objType $= %game.class) - { - %grpObj.group = %objective; - $ObjectiveQ[%team].add(%grpObj); - } - } - } - } - - - // add the non-grouped objectives to the teams Q - %count = %group.getCount(); - for(%i = 0; %i < %count; %i++) - { - %objective = %group.getObject(%i); - - //if the objective is not an "AIObjective", assume it's a group and continue - if (%objective.getClassName() !$= "AIObjective") - continue; - - if (%objective.gameType $= "" || %objective.gameType $= "all") - %objType = ""; - else - %objType = %objective.gameType @ "Game"; - - if (%objType $= "" || %objType $= %game.class) - { - %objective.group = ""; - $ObjectiveQ[%team].add(%objective); - } - } - - // initialize the objectives - %count = $ObjectiveQ[%team].getCount(); - for(%i = 0; %i < %count; %i++) - { - %objective = $ObjectiveQ[%team].getObject(%i); - - //clear out any dynamic fields - %objective.clientLevel1 = ""; - %objective.clientLevel2 = ""; - %objective.clientLevel3 = ""; - %objective.isInvalid = false; - %objective.repairObjective = ""; - - //set the location, if required - if (%objective.position !$= "0 0 0") - %objective.location = %objective.position; - - // find targeted object ID's - if(%objective.targetObject !$= "") - %objective.targetObjectId = NameToId(%objective.targetObject); - else - %objective.targetObjectId = -1; - - if(%objective.targetClientObject !$= "") - %objective.targetClientId = NameToId(%objective.targetClient); - else - %objective.targetClientId = -1; - - if (%objective.position $= "0 0 0") - { - if (%objective.location $= "0 0 0") - { - if (%objective.targetObjectId > 0) - %objective.position = %objective.targetObjectId.position; - } - else - %objective.position = %objective.location; - } - } - - //finally, sort the objectiveQ - $ObjectiveQ[%team].sortByWeight(); -} - -//This function is designed to clear out the objective Q's, and clear the task lists from all the AIs -function AIMissionEnd() -{ - //disable the AI system - AISystemEnabled(false); - - //loop through the client list, and clear the tasks of each bot - %count = ClientGroup.getCount(); - for (%i = 0; %i < %count; %i++) - { - %client = ClientGroup.getObject(%i); - if (%client.isAIControlled()) - { - //cancel the respawn thread and the objective thread... - cancel(%client.respawnThread); - cancel(%client.objectiveThread); - - //reset the clients tasks, variables, etc... - AIUnassignClient(%client); - %client.stop(); - %client.clearTasks(); - %client.clearStep(); - %client.lastDamageClient = -1; - %client.lastDamageTurret = -1; - %client.shouldEngage = -1; - %client.setEngageTarget(-1); - %client.setTargetObject(-1); - %client.pilotVehicle = false; - %client.defaultTasksAdded = false; - - //do the nav graph cleanup - %client.missionCycleCleanup(); - } - } - - //clear the objective Q's - for (%i = 0; %i <= Game.numTeams; %i++) - { - if (isObject($ObjectiveQ[%i])) - { - $ObjectiveQ[%i].clear(); - $ObjectiveQ[%i].delete(); - } - $ObjectiveQ[%i] = ""; - } - - //now delete all the sets used by the AI system... - if (isObject($AIBombLocationSet)) - $AIBombLocationSet.delete(); - $AIBombLocationSet = ""; - - if (isObject($AIInvStationSet)) - $AIInvStationSet.delete(); - $AIInvStationSet = ""; - - if (isObject($AIItemSet)) - $AIItemSet.delete(); - $AIItemSet = ""; - - if (isObject($AIGrenadeSet)) - $AIGrenadeSet.delete(); - $AIGrenadeSet = ""; - - if (isObject($AIWeaponSet)) - $AIWeaponSet.delete(); - $AIWeaponSet = ""; - - if (isObject($AIRemoteTurretSet)) - $AIRemoteTurretSet.delete(); - $AIRemoteTurretSet = ""; - - if (isObject($AIDeployedMineSet)) - $AIDeployedMineSet.delete(); - $AIDeployedMineSet = ""; - - if (isObject($AIVehicleSet)) - $AIVehicleSet.delete(); - $AIVehicleSet = ""; -} - -//FUNCTIONS ON EACH OBJECT EXECUTED AT MISSION LOAD TIME -function SimGroup::AIMissionInit(%this) -{ - for(%i = 0; %i < %this.getCount(); %i++) - %this.getObject(%i).AIMissionInit(%this); -} - -function GameBase::AIMissionInit(%this) -{ - %this.getDataBlock().AIMissionInit(%this); -} - -function StationInventory::AIMissionInit(%data, %object) -{ - $AIInvStationSet.add(%object); -} - -function Flag::AIMissionInit(%data, %object) -{ - if (%object.team >= 0) - $AITeamFlag[%object.team] = %object; -} - -function SimObject::AIMissionInit(%this) -{ - //this function is declared to prevent console error msg spam... -} - -function ItemData::AIMissionInit(%data, %object) -{ - $AIItemSet.add(%object); -} - -function AIThrowObject(%object) -{ - $AIItemSet.add(%object); -} - -function AIGrenadeThrown(%object) -{ - $AIGrenadeSet.add(%object); -} - -function AIDeployObject(%client, %object) -{ - //first, set the object id on the client - %client.lastDeployedObject = %object; - - //now see if it was a turret... - %type = %object.getDataBlock().getName(); - if (%type $= "TurretDeployedFloorIndoor" || %type $= "TurretDeployedWallIndoor" || - %type $= "TurretDeployedCeilingIndoor" || %type $= "TurretDeployedOutdoor") - { - $AIRemoteTurretSet.add(%object); - } -} - -function AIDeployMine(%object) -{ - $AIDeployedMineSet.add(%object); -} - -function AIVehicleMounted(%vehicle) -{ - $AIVehicleSet.add(%vehicle); -} - -function AICorpseAdded(%corpse) -{ - if (isObject(%corpse)) - { - %corpse.isCorpse = true; - $AIItemSet.add(%corpse); - } -} - -//OTHER UTILITY FUNCTIONS - -function AIConnection::onAIDrop(%client) -{ - //make sure we're trying to drop an AI - if (!isObject(%client) || !%client.isAIControlled()) - return; - - //clear the ai from any objectives, etc... - AIUnassignClient(%client); - %client.clearTasks(); - %client.clearStep(); - %client.defaultTasksAdded = false; - - //kill the player, which should cause the Game object to perform whatever cleanup is required. - if (isObject(%client.player)) - %client.player.scriptKill(0); - - //do the nav graph cleanup - %client.missionCycleCleanup(); -} - -function AIConnection::endMission(%client) -{ - //cancel the respawn thread, and spawn them manually - cancel(%client.respawnThread); - cancel(%client.objectiveThread); -} - -function AIConnection::startMission(%client) -{ - //assign the team - if (%client.team <= 0) - Game.assignClientTeam(%client); - - //set the client's sensor group... - setTargetSensorGroup( %client.target, %client.team ); - %client.setSensorGroup( %client.team ); - - //sends a message so everyone know the bot is in the game... - Game.AIHasJoined(%client); - %client.matchStartReady = true; - - //spawn the bot... - onAIRespawn(%client); -} - -function AIConnection::onAIConnect(%client, %name, %team, %skill, %offense, %voice, %voicePitch) -{ - // Sex/Race defaults - %client.armor = "Light"; - %client.isBot = 1; - - //setup the voice and voicePitch - if (%voicePitch $= "" || %voicePitch < 0.5 || %voicePitch > 2.0) - %voicePitch = 1.0; - %client.voicePitch = %voicePitch; - - %client.name = addTaggedString( "\cp\c9" @ %name @ "\co" ); - %client.nameBase = %name; - - echo(%client.name); - echo("CADD: " @ %client @ " " @ %client.getAddress()); - - // DDDX: Don't increment player count in RPG/Survival Games - if ($CurrentMissionType !$= "RPG" && $CurrentMissionType !$= "SV") - $HostGamePlayerCount++; - - //set the initial team - Game.assignClientTeam() should be called later on... - %client.team = %team; - - //setup the target for use with the sensor net, etc... - %client.target = allocClientTarget(%client, %client.name, %client.skin, %client.voiceTag, '_ClientConnection', 0, 0, %client.voicePitch); - - //i need to send a "silent" version of this for single player but still use the callback -jr` - if ($currentMissionType !$= "RPG") //Ok.. the bots should not be added to the lobby - { - if($currentMissionType $= "SinglePlayer" || $currentMissionType $= "SV") - messageAllExcept(%client, -1, 'MsgClientJoin', "", %name, %client, %client.target, true); - else - messageAllExcept(%client, -1, 'MsgClientJoin', '\c1%1 joined the game.', %name, %client, %client.target, true); - } - - //assign the skill - %client.setSkillLevel(%skill); - - //assign the affinity - %client.offense = %offense; - - //clear any flags - %client.stop(); // this will clear the players move state - %client.clearStep(); - %client.lastDamageClient = -1; - %client.lastDamageTurret = -1; - %client.setEngageTarget(-1); - %client.setTargetObject(-1); - %client.objective = ""; - - //clear the defaulttasks flag - %client.defaultTasksAdded = false; - - //if the mission is already running, spawn the bot - if ($missionRunning) - %client.startMission(); - - //If the gamemode is RPG, add to our AIGroup -- so the bot is not shown in server info - if ($CurrentMissionType $= "RPG") - { - if (!IsObject(AIGroup)) - MissionCleanup.add(new SimGroup(AIGroup)); - - AIGroup.add(%client); - } -} - -// This routes through C++ code so profiler can register it. Also, the console function -// ProfilePatch1() tracks time spent (at MS resolution), # calls, average time per call. -// See console variables $patch1Total (MS so far in routine), $patch1Avg (average MS -// per call), and $patch1Calls (# of calls). -function patchForTimeTest(%client) -{ - if( isObject( Game ) ) - Game.AIChooseGameObjective(%client); -} - -function AIReassessObjective(%client) -{ - ProfilePatch1(patchForTimeTest, %client); - // Game.AIChooseGameObjective(%client); - %client.objectiveThread = schedule(5000, %client, "AIReassessObjective", %client); -} - -function onAIRespawn(%client) -{ - %markerObj = Game.pickPlayerSpawn(%client, true); - Game.createPlayer(%client, %markerObj); - - //make sure the player object is the AI's control object - even during the mission warmup time - //the function AISystemEnabled(true/false) will control whether they actually move... - %client.setControlObject(%client.player); - - if (%client.objective) - error("ERROR!!! " @ %client @ " is still assigned to objective: " @ %client.objective); - - //clear the objective and choose a new one - AIUnassignClient(%client); - %client.stop(); - %client.clearStep(); - %client.lastDamageClient = -1; - %client.lastDamageTurret = -1; - %client.shouldEngage = -1; - %client.setEngageTarget(-1); - %client.setTargetObject(-1); - %client.pilotVehicle = false; - - //set the spawn time - %client.spawnTime = getSimTime(); - %client.respawnThread = ""; - - //timeslice the objective reassessment for the bots - if (!isEventPending(%client.objectiveThread)) - { - %curTime = getSimTime(); - %remainder = %curTime % 5000; - %schedTime = $AITimeSliceReassess - %remainder; - if (%schedTime <= 0) - %schedTime += 5000; - %client.objectiveThread = schedule(%schedTime, %client, "AIReassessObjective", %client); - - //set the next time slice "slot" - $AITimeSliceReassess += 300; - if ($AITimeSliceReassess > 5000) - $AITimeSliceReassess -= 5000; - } - - //call the game specific spawn function - Game.onAIRespawn(%client); -} - -function AIClientIsAlive(%client, %duration) -{ - if(%client < 0 || %client.player <= 0) - return false; - if (isObject(%client.player)) - { - %state = %client.player.getState(); - if (%state !$= "Dead" && %state !$= "" && (%duration $= "" || getSimTime() - %client.spawnTime >= %duration)) - return true; - else - return false; - } - else - return false; -} - -//------------------------------ -function AIFindClosestEnemy(%srcClient, %radius, %losTimeout) -{ - //see if there's an enemy near our defense location... - if (isObject(%srcClient.player)) - %srcLocation = %srcClient.player.getWorldBoxCenter(); - else - %srcLocation = "0 0 0"; - return AIFindClosestEnemyToLoc(%srcClient, %srcLocation, %radius, %losTimeout, false, true); -} - -function AIFindClosestEnemyToLoc(%srcClient, %srcLocation, %radius, %losTimeout, %ignoreLOS, %distFromClient) -{ - if (%ignoreLOS $= "") - %ignoreLOS = false; - if (%distFromClient $= "") - %distFromClient = false; - - %count = ClientGroup.getCount(); - %closestClient = -1; - %closestDistance = 32767; - for(%i = 0; %i < %count; %i++) - { - %cl = ClientGroup.getObject(%i); - - //make sure we find someone who's alive - if (AIClientIsAlive(%cl) && %cl.team != %srcClient.team) - { - %clIsCloaked = !isTargetVisible(%cl.target, %srcClient.getSensorGroup()); - - //make sure the client can see the enemy - %hasLOS = %srcClient.hasLOSToClient(%cl); - %losTime = %srcClient.getClientLOSTime(%cl); - if (%ignoreLOS || %hasLOS || (%losTime < %losTimeout && AIClientIsAlive(%cl, %losTime + 1000))) - { - %testPos = %cl.player.getWorldBoxCenter(); - if (%distFromClient) - %distance = %srcClient.getPathDistance(%testPos); - else - %distance = AIGetPathDistance(%srcLocation, %testPos); - if (%distance > 0 && (%radius < 0 || %distance < %radius) && %distance < %closestDistance && (!%clIsCloaked || %distance < 8)) - { - %closestClient = %cl; - %closestDistance = %distance; - } - } - } - } - - return %closestClient SPC %closestDistance; -} - -function AIFindClosestEnemyPilot(%client, %radius, %losTimeout) -{ - //loop through the vehicle set, looking for pilotted vehicles... - %closestPilot = -1; - %closestDist = %radius; - %count = $AIVehicleSet.getCount(); - for (%i = 0; %i < %count; %i++) - { - //first, make sure the vehicle is mounted by pilotted - %vehicle = $AIVehicleSet.getObject(%i); - %pilot = %vehicle.getMountNodeObject(0); - if (%pilot <= 0 || !AIClientIsAlive(%pilot.client)) - continue; - - //make sure the pilot is an enemy - if (%pilot.client.team == %client.team) - continue; - - //see if the pilot has been seen by the client - %hasLOS = %client.hasLOSToClient(%pilot.client); - %losTime = %client.getClientLOSTime(%pilot.client); - if (%hasLOS || (%losTime < %losTimeout && AIClientIsAlive(%pilot.client, %losTime + 1000))) - { - //see if it's the closest - %clientPos = %client.player.getWorldBoxCenter(); - %pilotPos = %pilot.getWorldBoxCenter(); - %dist = VectorDist(%clientPos, %pilotPos); - if (%dist < %closestDist) - { - %closestPilot = %pilot.client; - %closestDist = %dist; - } - } - } - - return %closestPilot SPC %closestDist; -} - -function AIFindAIClientInView(%srcClient, %team, %radius) -{ - //make sure the player is alive - if (! AIClientIsAlive(%srcClient)) - return -1; - - //get various info about the player's eye - %srcEyeTransform = %srcClient.player.getEyeTransform(); - %srcEyePoint = firstWord(%srcEyeTransform) @ " " @ getWord(%srcEyeTransform, 1) @ " " @ getWord(%srcEyeTransform, 2); - %srcEyeVector = VectorNormalize(%srcClient.player.getEyeVector()); - - //see if there's an enemy near our defense location... - %count = ClientGroup.getCount(); - %viewedClient = -1; - %clientDot = -1; - for(%i = 0; %i < %count; %i++) - { - %cl = ClientGroup.getObject(%i); - - //make sure we find an AI who's alive and not the srcClient - if (%cl != %srcClient && AIClientIsAlive(%cl) && %cl.isAIControlled() && (%team < 0 || %cl.team == %team)) - { - //make sure the player is within range - %clPos = %cl.player.getWorldBoxCenter(); - %distance = VectorDist(%clPos, %srcEyePoint); - if (%radius <= 0 || %distance <= %radius) - { - //create the vector from the srcClient to the client - %clVector = VectorNormalize(VectorSub(%clPos, %srcEyePoint)); - - //see if the dot product is greater than our current, and greater than 0.6 - %dot = VectorDot(%clVector, %srcEyeVector); - - if (%dot > 0.6 && %dot > %clientDot) - { - %viewedClient = %cl; - %clientDot = %dot; - } - } - } - } - - return %viewedClient; -} - -//----------------------------------------------------------------------------- -//AI VEHICLE FUNCTIONS - -function Armor::AIonMount(%this, %obj, %vehicle, %node) -{ - //set the client var... - %client = %obj.client; - %client.turretMounted = -1; - - //make sure the AI was *supposed* to mount the vehicle - if (!%client.isMountingVehicle()) - { - AIDisembarkVehicle(%client); - return; - } - - //get the vehicle's pilot - %pilot = %vehicle.getMountNodeObject(0); - - //make sure the bot is in node 0 if'f the bot is piloting the vehicle - if ((%node == 0 && !%client.pilotVehicle) || (%node > 0 && %client.pilotVehicle)) - { - AIDisembarkVehicle(%client); - return; - } - - //make sure the bot didn't is on the same team as the pilot - if (%pilot > 0 && isObject(%pilot) && %pilot.client.team != %client.team) - { - AIDisembarkVehicle(%client); - return; - } - - //if we're supposed to pilot the vehicle, set the control object - if (%client.pilotVehicle) - %client.setControlObject(%vehicle); - - //each vehicle may be built differently... - if (%vehicle.getDataBlock().getName() $= "AssaultVehicle") - { - //node 1 is this vehicle's turret seat - if (%node == 1) - { - %turret = %vehicle.getMountNodeObject(10); - %skill = %client.getSkillLevel(); - %turret.setSkill(%skill); - %client.turretMounted = %turret; - %turret.setAutoFire(true); - } - } - - else if (%vehicle.getDataBlock().getName() $= "BomberFlyer") - { - //node 1 is this vehicle's turret seat - if (%node == 1) - { - %turret = %vehicle.getMountNodeObject(10); - %skill = %client.getSkillLevel(); - %turret.setSkill(%skill); - %client.turretMounted = %turret; - %client.setTurretMounted(%turret); - %turret.setAutoFire(true); - } - } -} - -function Armor::AIonUnMount(%this, %obj, %vehicle, %node) -{ - //get the client var - %client = %obj.client; - - //reset the control object - if (%client.pilotVehicle) - %client.setControlObject(%client.player); - %client.pilotVehicle = false; - - //if the client had mounted a turret, turn the turret back off - if (%client.turretMounted > 0) - %client.turretMounted.setAutoFire(false); - %client.turretMounted = -1; - %client.setTurretMounted(-1); - - // reset the turret skill level - if(%vehicle.getDataBlock().getName() $= "AssaultVehicle") - if (%node == 1) - %vehicle.getMountNodeObject(10).setSkill(1.0); - - if(%vehicle.getDataBlock().getName() $= "BomberFlyer") - if(%node == 1) - %vehicle.getMountNodeObject(10).setSkill(1.0); -} - -function AIDisembarkVehicle(%client) -{ - if (%client.player.isMounted()) - { - if (%client.pilotVehicle) - %client.setControlObject(%client.player); - %client.pressJump(); - } -} - -function AIProcessVehicle(%client) -{ - //see if we're mounted on a turret, and if that turret has a target - if (%client.turretMounted > 0) - { - %turretDB = %client.turretMounted.getDataBlock(); - - //see if we're in a bomber close to a bomb site... - if (%turretDB.getName() $= "BomberTurret") - { - %clientPos = getWords(%client.player.position, 0, 1) @ " 0"; - %found = false; - %count = $AIBombLocationSet.getCount(); - for (%i = 0; %i < %count; %i++) - { - %bombObj = $AIBombLocationSet.getObject(%i); - %bombLocation = %bombObj.location; - - //make sure the objective was issued by someone in the vehicle - if (%bombObj.issuedByClientId.vehicleMounted == %client.vehicleMounted) - { - //find out where the bomb is going to drop... first, how high up are we... - %bombLocation2D = getWord(%bombLocation, 0) SPC getWord(%bombLocation, 1) SPC "0"; - %height = getWord(%client.vehicleMounted.position, 2) - getWord(%bombLocation, 2); - - //find out how long it'll take the bomb to fall that far... - //assume no initial velocity in the Z axis... - %timeToFall = mSqrt((2.0 * %height) / 9.81); - - //how fast is the vehicle moving in the XY plane... - %myLocation = %client.vehicleMounted.position; - %myLocation2D = getWord(%myLocation, 0) SPC getWord(%myLocation, 1) SPC "0"; - %vel = %client.vehicleMounted.getVelocity(); - %vel2D = getWord(%vel, 0) SPC getWord(%vel, 1) SPC "0"; - - %bombImpact2D = VectorAdd(%myLocation2D, VectorScale(%vel2D, %timeToFall)); - - //see if the bomb inpact position is within 20m of the desired bomb site... - %distToBombsite2D = VectorDist(%bombImpact2D, %bombLocation2D); - if (%height > 20 && %distToBombsite2D < 25) - { - %found = true; - break; - } - } - } - - //see if we found a bomb site - if (%found) - { - %client.turretMounted.selectedWeapon = 2; - %turretDB.onTrigger(%client.turretMounted, 0, true); - return; - } - } - - //we're not bombing, make sure we have the regular weapon selected - %client.turretMounted.selectedWeapon = 1; - if (isObject(%client.turretMounted.getTargetObject())) - %turretDB.onTrigger(%client.turretMounted, 0, true); - else - %turretDB.onTrigger(%client.turretMounted, 0, false); - } -} - -function AIPilotVehicle(%client) -{ - //this is not very well supported, but someone will find a use for this function... -} +//-----------------------------------// +// AI SCRIPT FUNCTIONS // +//-----------------------------------// + +//first, exec the supporting scripts +exec("scripts/aiDebug.cs"); +exec("scripts/aiDefaultTasks.cs"); +exec("scripts/aiObjectives.cs"); +exec("scripts/aiInventory.cs"); +exec("scripts/aiChat.cs"); +exec("scripts/aiHumanTasks.cs"); +exec("scripts/aiObjectiveBuilder.cs"); +exec("scripts/aiBotProfiles.cs"); + +$AIModeStop = 0; +$AIModeWalk = 1; +$AIModeGainHeight = 2; +$AIModeExpress = 3; +$AIModeMountVehicle = 4; + +$AIClientLOSTimeout = 15000; //how long a client has to remain out of sight of the bot + //before the bot "can't see" the client anymore... +$AIClientMinLOSTime = 10000; //how long a bot will search for a client + + +//-----------------------------------// +//Objective weights - level 1 + +$AIWeightCapFlag[1] = 5000; //range 5100 to 5320 +$AIWeightKillFlagCarrier[1] = 4800; //range 4800 to 5120 +$AIWeightReturnFlag[1] = 5001; //range 5101 to 5321 +$AIWeightDefendFlag[1] = 3900; //range 4000 to 4220 +$AIWeightGrabFlag[1] = 3850; //range 3950 to 4170 + +$AIWeightDefendFlipFlop[1] = 3900; //range 4000 to 4220 +$AIWeightCaptureFlipFlop[1] = 3850; //range 3850 to 4170 + +$AIWeightAttackGenerator[1] = 3100; //range 3200 to 3520 +$AIWeightRepairGenerator[1] = 3200; //range 3300 to 3620 +$AIWeightDefendGenerator[1] = 3100; //range 3200 to 3420 + +$AIWeightMortarTurret[1] = 3400; //range 3500 to 3600 +$AIWeightLazeObject[1] = 3200; //range 3300 to 3400 +$AIWeightRepairTurret[1] = 3100; //range 3200 to 3420 + +$AIWeightAttackInventory[1] = 2900; //range 2800 to 2920 +$AIWeightRepairInventory[1] = 2900; //range 2800 to 2920 + +$AIWeightEscortOffense[1] = 2900; //range 2800 to 2920 +$AIWeightEscortCapper[1] = 3250; //range 3350 to 3470 + +//used to allow a bot to finish tasks once started. +$AIWeightContinueDeploying = 4250; +$AIWeightContinueRepairing = 4250; + +//Objective weights from human +$AIWeightHumanIssuedCommand = 4450; +$AIWeightHumanIssuedEscort = 4425; + +//Objective weights - level 2 +$AIWeightCapFlag[2] = 0; //only one person can ever cap a flag +$AIWeightKillFlagCarrier[2] = 4800; //range 4800 to 5020 +$AIWeightReturnFlag[2] = 4100; //range 4200 to 4320 +$AIWeightDefendFlag[2] = 2000; //range 2100 to 2220 +$AIWeightGrabFlag[2] = 2000; //range 2100 to 2220 + +$AIWeightDefendFlipFlop[2] = 2000; //range 2100 to 2220 +$AIWeightDefendFlipFlop[3] = 1500; //range 1600 to 1720 +$AIWeightDefendFlipFlop[4] = 1000; //range 1100 to 1220 + +$AIWeightAttackGenerator[2] = 1600; //range 1700 to 1920 +$AIWeightRepairGenerator[2] = 1600; //range 1700 to 1920 +$AIWeightDefendGenerator[2] = 1500; //range 1600 to 1720 + +$AIWeightAttackInventory[2] = 1400; //range 1500 to 1720 +$AIWeightRepairInventory[2] = 1400; //range 1500 to 1720 + +$AIWeightMortarTurret[2] = 1000; //range 1100 to 1320 +$AIWeightLazeObject[2] = 0; //no need to have more than one targetter +$AIWeightRepairTurret[2] = 1000; //range 1100 to 1320 + +$AIWeightEscortOffense[2] = 2900; //range 3300 to 3420 +$AIWeightEscortCapper[2] = 3000; //range 3100 to 3220 + + +function AIInit() +{ + AISlicerInit(); + installNavThreats(); + NavDetectForceFields(); +// ShowFPS(); + + //enable the use of grenades + $AIDisableGrenades = false; + $AIDisableChat = false; + + //create the "objective delete set" + if(nameToId("AIBombLocationSet") <= 0) + { + $AIBombLocationSet = new SimSet("AIBombLocationSet"); + MissionCleanup.add($AIBombLocationSet); + } + + //create the Inventory group + if(nameToId("AIStationInventorySet") <= 0) + { + $AIInvStationSet = new SimSet("AIStationInventorySet"); + MissionCleanup.add($AIInvStationSet); + } + + //create the Item group + if (nameToId("AIItemSet") <= 0) + { + $AIItemSet = new SimSet("AIItemSet"); + MissionCleanup.add($AIItemSet); + } + + //create the Item group + if (nameToId("AIGrenadeSet") <= 0) + { + $AIGrenadeSet = new SimSet("AIGrenadeSet"); + MissionCleanup.add($AIGrenadeSet); + } + + //create the weapon group + if (nameToId("AIWeaponSet") <= 0) + { + $AIWeaponSet = new SimSet("AIWeaponSet"); + MissionCleanup.add($AIWeaponSet); + } + + //create the deployed turret group + if (nameToID("AIRemoteTurretSet") <= 0) + { + $AIRemoteTurretSet = new SimSet("AIRemoteTurretSet"); + MissionCleanup.add($AIRemoteTurretSet); + } + + //create the deployed turret group + if (nameToID("AIDeployedMineSet") <= 0) + { + $AIDeployedMineSet = new SimSet("AIDeployedMineSet"); + MissionCleanup.add($AIDeployedMineSet); + } + + //create the deployed turret group + if (nameToID("AIVehicleSet") <= 0) + { + $AIVehicleSet = new SimSet("AIVehicleSet"); + MissionCleanup.add($AIVehicleSet); + } + + %missionGroupFolder = nameToID("MissionGroup"); + %missionGroupFolder.AIMissionInit(); +} + +// this is called at mission load by the specific game type +function AIInitObjectives(%team, %game) +{ + %group = nameToID("MissionGroup/Teams/team" @ %team @ "/AIObjectives"); + if(%group < 0) + return; // opps, there is no Objectives set for this team. + + // add the grouped objectives to the teams Q + %count = %group.getCount(); + for (%i = 0; %i < %count; %i++) + { + %objective = %group.getObject(%i); + if (%objective.getClassName() !$= "AIObjective") + { + %grpCount = %objective.getCount(); + for (%j = 0; %j < %grpCount; %j++) + { + %grpObj = %objective.getObject(%j); + if (%objective.gameType $= "" || %objective.gameType $= "all") + %objType = ""; + else + %objType = %objective.gameType @ "Game"; + + if (%objType $= "" || %objType $= %game.class) + { + %grpObj.group = %objective; + $ObjectiveQ[%team].add(%grpObj); + } + } + } + } + + + // add the non-grouped objectives to the teams Q + %count = %group.getCount(); + for(%i = 0; %i < %count; %i++) + { + %objective = %group.getObject(%i); + + //if the objective is not an "AIObjective", assume it's a group and continue + if (%objective.getClassName() !$= "AIObjective") + continue; + + if (%objective.gameType $= "" || %objective.gameType $= "all") + %objType = ""; + else + %objType = %objective.gameType @ "Game"; + + if (%objType $= "" || %objType $= %game.class) + { + %objective.group = ""; + $ObjectiveQ[%team].add(%objective); + } + } + + // initialize the objectives + %count = $ObjectiveQ[%team].getCount(); + for(%i = 0; %i < %count; %i++) + { + %objective = $ObjectiveQ[%team].getObject(%i); + + //clear out any dynamic fields + %objective.clientLevel1 = ""; + %objective.clientLevel2 = ""; + %objective.clientLevel3 = ""; + %objective.isInvalid = false; + %objective.repairObjective = ""; + + //set the location, if required + if (%objective.position !$= "0 0 0") + %objective.location = %objective.position; + + // find targeted object ID's + if(%objective.targetObject !$= "") + %objective.targetObjectId = NameToId(%objective.targetObject); + else + %objective.targetObjectId = -1; + + if(%objective.targetClientObject !$= "") + %objective.targetClientId = NameToId(%objective.targetClient); + else + %objective.targetClientId = -1; + + if (%objective.position $= "0 0 0") + { + if (%objective.location $= "0 0 0") + { + if (%objective.targetObjectId > 0) + %objective.position = %objective.targetObjectId.position; + } + else + %objective.position = %objective.location; + } + } + + //finally, sort the objectiveQ + $ObjectiveQ[%team].sortByWeight(); +} + +//This function is designed to clear out the objective Q's, and clear the task lists from all the AIs +function AIMissionEnd() +{ + //disable the AI system + AISystemEnabled(false); + + //loop through the client list, and clear the tasks of each bot + %count = ClientGroup.getCount(); + for (%i = 0; %i < %count; %i++) + { + %client = ClientGroup.getObject(%i); + if (%client.isAIControlled()) + { + //cancel the respawn thread and the objective thread... + cancel(%client.respawnThread); + cancel(%client.objectiveThread); + + //reset the clients tasks, variables, etc... + AIUnassignClient(%client); + %client.stop(); + %client.clearTasks(); + %client.clearStep(); + %client.lastDamageClient = -1; + %client.lastDamageTurret = -1; + %client.shouldEngage = -1; + %client.setEngageTarget(-1); + %client.setTargetObject(-1); + %client.pilotVehicle = false; + %client.defaultTasksAdded = false; + + //do the nav graph cleanup + %client.missionCycleCleanup(); + } + } + + //clear the objective Q's + for (%i = 0; %i <= Game.numTeams; %i++) + { + if (isObject($ObjectiveQ[%i])) + { + $ObjectiveQ[%i].clear(); + $ObjectiveQ[%i].delete(); + } + $ObjectiveQ[%i] = ""; + } + + //now delete all the sets used by the AI system... + if (isObject($AIBombLocationSet)) + $AIBombLocationSet.delete(); + $AIBombLocationSet = ""; + + if (isObject($AIInvStationSet)) + $AIInvStationSet.delete(); + $AIInvStationSet = ""; + + if (isObject($AIItemSet)) + $AIItemSet.delete(); + $AIItemSet = ""; + + if (isObject($AIGrenadeSet)) + $AIGrenadeSet.delete(); + $AIGrenadeSet = ""; + + if (isObject($AIWeaponSet)) + $AIWeaponSet.delete(); + $AIWeaponSet = ""; + + if (isObject($AIRemoteTurretSet)) + $AIRemoteTurretSet.delete(); + $AIRemoteTurretSet = ""; + + if (isObject($AIDeployedMineSet)) + $AIDeployedMineSet.delete(); + $AIDeployedMineSet = ""; + + if (isObject($AIVehicleSet)) + $AIVehicleSet.delete(); + $AIVehicleSet = ""; +} + +//FUNCTIONS ON EACH OBJECT EXECUTED AT MISSION LOAD TIME +function SimGroup::AIMissionInit(%this) +{ + for(%i = 0; %i < %this.getCount(); %i++) + %this.getObject(%i).AIMissionInit(%this); +} + +function GameBase::AIMissionInit(%this) +{ + %this.getDataBlock().AIMissionInit(%this); +} + +function StationInventory::AIMissionInit(%data, %object) +{ + $AIInvStationSet.add(%object); +} + +function Flag::AIMissionInit(%data, %object) +{ + if (%object.team >= 0) + $AITeamFlag[%object.team] = %object; +} + +function SimObject::AIMissionInit(%this) +{ + //this function is declared to prevent console error msg spam... +} + +function ItemData::AIMissionInit(%data, %object) +{ + $AIItemSet.add(%object); +} + +function AIThrowObject(%object) +{ + $AIItemSet.add(%object); +} + +function AIGrenadeThrown(%object) +{ + $AIGrenadeSet.add(%object); +} + +function AIDeployObject(%client, %object) +{ + //first, set the object id on the client + %client.lastDeployedObject = %object; + + //now see if it was a turret... + %type = %object.getDataBlock().getName(); + if (%type $= "TurretDeployedFloorIndoor" || %type $= "TurretDeployedWallIndoor" || + %type $= "TurretDeployedCeilingIndoor" || %type $= "TurretDeployedOutdoor") + { + $AIRemoteTurretSet.add(%object); + } +} + +function AIDeployMine(%object) +{ + $AIDeployedMineSet.add(%object); +} + +function AIVehicleMounted(%vehicle) +{ + $AIVehicleSet.add(%vehicle); +} + +function AICorpseAdded(%corpse) +{ + if (isObject(%corpse)) + { + %corpse.isCorpse = true; + $AIItemSet.add(%corpse); + } +} + +//OTHER UTILITY FUNCTIONS + +function AIConnection::onAIDrop(%client) +{ + //make sure we're trying to drop an AI + if (!isObject(%client) || !%client.isAIControlled()) + return; + + //clear the ai from any objectives, etc... + AIUnassignClient(%client); + %client.clearTasks(); + %client.clearStep(); + %client.defaultTasksAdded = false; + + //kill the player, which should cause the Game object to perform whatever cleanup is required. + if (isObject(%client.player)) + %client.player.scriptKill(0); + + //do the nav graph cleanup + %client.missionCycleCleanup(); +} + +function AIConnection::endMission(%client) +{ + //cancel the respawn thread, and spawn them manually + cancel(%client.respawnThread); + cancel(%client.objectiveThread); +} + +function AIConnection::startMission(%client) +{ + //assign the team + if (%client.team <= 0) + Game.assignClientTeam(%client); + + //set the client's sensor group... + setTargetSensorGroup( %client.target, %client.team ); + %client.setSensorGroup( %client.team ); + + //sends a message so everyone know the bot is in the game... + Game.AIHasJoined(%client); + %client.matchStartReady = true; + + //spawn the bot... + onAIRespawn(%client); +} + +function AIConnection::onAIConnect(%client, %name, %team, %skill, %offense, %voice, %voicePitch) +{ + // Sex/Race defaults + %client.armor = "Light"; + %client.isBot = 1; + + //setup the voice and voicePitch + if (%voicePitch $= "" || %voicePitch < 0.5 || %voicePitch > 2.0) + %voicePitch = 1.0; + %client.voicePitch = %voicePitch; + + %client.name = addTaggedString( "\cp\c9" @ %name @ "\co" ); + %client.nameBase = %name; + + echo(%client.name); + echo("CADD: " @ %client @ " " @ %client.getAddress()); + + // DDDX: Don't increment player count in RPG/Survival Games + if ($CurrentMissionType !$= "RPG" && $CurrentMissionType !$= "SV") + $HostGamePlayerCount++; + + //set the initial team - Game.assignClientTeam() should be called later on... + %client.team = %team; + + //setup the target for use with the sensor net, etc... + %client.target = allocClientTarget(%client, %client.name, %client.skin, %client.voiceTag, '_ClientConnection', 0, 0, %client.voicePitch); + + //i need to send a "silent" version of this for single player but still use the callback -jr` + if ($currentMissionType !$= "RPG") //Ok.. the bots should not be added to the lobby + { + if($currentMissionType $= "SinglePlayer" || $currentMissionType $= "SV") + messageAllExcept(%client, -1, 'MsgClientJoin', "", %name, %client, %client.target, true); + else + messageAllExcept(%client, -1, 'MsgClientJoin', '\c1%1 joined the game.', %name, %client, %client.target, true); + } + + //assign the skill + %client.setSkillLevel(%skill); + + //assign the affinity + %client.offense = %offense; + + //clear any flags + %client.stop(); // this will clear the players move state + %client.clearStep(); + %client.lastDamageClient = -1; + %client.lastDamageTurret = -1; + %client.setEngageTarget(-1); + %client.setTargetObject(-1); + %client.objective = ""; + + //clear the defaulttasks flag + %client.defaultTasksAdded = false; + + //if the mission is already running, spawn the bot + if ($missionRunning) + %client.startMission(); + + //If the gamemode is RPG, add to our AIGroup -- so the bot is not shown in server info + if ($CurrentMissionType $= "RPG") + { + if (!IsObject(AIGroup)) + MissionCleanup.add(new SimGroup(AIGroup)); + + AIGroup.add(%client); + } +} + +// This routes through C++ code so profiler can register it. Also, the console function +// ProfilePatch1() tracks time spent (at MS resolution), # calls, average time per call. +// See console variables $patch1Total (MS so far in routine), $patch1Avg (average MS +// per call), and $patch1Calls (# of calls). +function patchForTimeTest(%client) +{ + if( isObject( Game ) ) + Game.AIChooseGameObjective(%client); +} + +function AIReassessObjective(%client) +{ + ProfilePatch1(patchForTimeTest, %client); + // Game.AIChooseGameObjective(%client); + %client.objectiveThread = schedule(5000, %client, "AIReassessObjective", %client); +} + +function onAIRespawn(%client) +{ + %markerObj = Game.pickPlayerSpawn(%client, true); + Game.createPlayer(%client, %markerObj); + + //make sure the player object is the AI's control object - even during the mission warmup time + //the function AISystemEnabled(true/false) will control whether they actually move... + %client.setControlObject(%client.player); + + if (%client.objective) + error("ERROR!!! " @ %client @ " is still assigned to objective: " @ %client.objective); + + //clear the objective and choose a new one + AIUnassignClient(%client); + %client.stop(); + %client.clearStep(); + %client.lastDamageClient = -1; + %client.lastDamageTurret = -1; + %client.shouldEngage = -1; + %client.setEngageTarget(-1); + %client.setTargetObject(-1); + %client.pilotVehicle = false; + + //set the spawn time + %client.spawnTime = getSimTime(); + %client.respawnThread = ""; + + //timeslice the objective reassessment for the bots + if (!isEventPending(%client.objectiveThread)) + { + %curTime = getSimTime(); + %remainder = %curTime % 5000; + %schedTime = $AITimeSliceReassess - %remainder; + if (%schedTime <= 0) + %schedTime += 5000; + %client.objectiveThread = schedule(%schedTime, %client, "AIReassessObjective", %client); + + //set the next time slice "slot" + $AITimeSliceReassess += 300; + if ($AITimeSliceReassess > 5000) + $AITimeSliceReassess -= 5000; + } + + //call the game specific spawn function + Game.onAIRespawn(%client); +} + +function AIClientIsAlive(%client, %duration) +{ + if(%client < 0 || %client.player <= 0) + return false; + if (isObject(%client.player)) + { + %state = %client.player.getState(); + if (%state !$= "Dead" && %state !$= "" && (%duration $= "" || getSimTime() - %client.spawnTime >= %duration)) + return true; + else + return false; + } + else + return false; +} + +//------------------------------ +function AIFindClosestEnemy(%srcClient, %radius, %losTimeout) +{ + //see if there's an enemy near our defense location... + if (isObject(%srcClient.player)) + %srcLocation = %srcClient.player.getWorldBoxCenter(); + else + %srcLocation = "0 0 0"; + return AIFindClosestEnemyToLoc(%srcClient, %srcLocation, %radius, %losTimeout, false, true); +} + +function AIFindClosestEnemyToLoc(%srcClient, %srcLocation, %radius, %losTimeout, %ignoreLOS, %distFromClient) +{ + if (%ignoreLOS $= "") + %ignoreLOS = false; + if (%distFromClient $= "") + %distFromClient = false; + + %count = ClientGroup.getCount(); + %closestClient = -1; + %closestDistance = 32767; + for(%i = 0; %i < %count; %i++) + { + %cl = ClientGroup.getObject(%i); + + //make sure we find someone who's alive + if (AIClientIsAlive(%cl) && %cl.team != %srcClient.team) + { + %clIsCloaked = !isTargetVisible(%cl.target, %srcClient.getSensorGroup()); + + //make sure the client can see the enemy + %hasLOS = %srcClient.hasLOSToClient(%cl); + %losTime = %srcClient.getClientLOSTime(%cl); + if (%ignoreLOS || %hasLOS || (%losTime < %losTimeout && AIClientIsAlive(%cl, %losTime + 1000))) + { + %testPos = %cl.player.getWorldBoxCenter(); + if (%distFromClient) + %distance = %srcClient.getPathDistance(%testPos); + else + %distance = AIGetPathDistance(%srcLocation, %testPos); + if (%distance > 0 && (%radius < 0 || %distance < %radius) && %distance < %closestDistance && (!%clIsCloaked || %distance < 8)) + { + %closestClient = %cl; + %closestDistance = %distance; + } + } + } + } + + return %closestClient SPC %closestDistance; +} + +function AIFindClosestEnemyPilot(%client, %radius, %losTimeout) +{ + //loop through the vehicle set, looking for pilotted vehicles... + %closestPilot = -1; + %closestDist = %radius; + %count = $AIVehicleSet.getCount(); + for (%i = 0; %i < %count; %i++) + { + //first, make sure the vehicle is mounted by pilotted + %vehicle = $AIVehicleSet.getObject(%i); + %pilot = %vehicle.getMountNodeObject(0); + if (%pilot <= 0 || !AIClientIsAlive(%pilot.client)) + continue; + + //make sure the pilot is an enemy + if (%pilot.client.team == %client.team) + continue; + + //see if the pilot has been seen by the client + %hasLOS = %client.hasLOSToClient(%pilot.client); + %losTime = %client.getClientLOSTime(%pilot.client); + if (%hasLOS || (%losTime < %losTimeout && AIClientIsAlive(%pilot.client, %losTime + 1000))) + { + //see if it's the closest + %clientPos = %client.player.getWorldBoxCenter(); + %pilotPos = %pilot.getWorldBoxCenter(); + %dist = VectorDist(%clientPos, %pilotPos); + if (%dist < %closestDist) + { + %closestPilot = %pilot.client; + %closestDist = %dist; + } + } + } + + return %closestPilot SPC %closestDist; +} + +function AIFindAIClientInView(%srcClient, %team, %radius) +{ + //make sure the player is alive + if (! AIClientIsAlive(%srcClient)) + return -1; + + //get various info about the player's eye + %srcEyeTransform = %srcClient.player.getEyeTransform(); + %srcEyePoint = firstWord(%srcEyeTransform) @ " " @ getWord(%srcEyeTransform, 1) @ " " @ getWord(%srcEyeTransform, 2); + %srcEyeVector = VectorNormalize(%srcClient.player.getEyeVector()); + + //see if there's an enemy near our defense location... + %count = ClientGroup.getCount(); + %viewedClient = -1; + %clientDot = -1; + for(%i = 0; %i < %count; %i++) + { + %cl = ClientGroup.getObject(%i); + + //make sure we find an AI who's alive and not the srcClient + if (%cl != %srcClient && AIClientIsAlive(%cl) && %cl.isAIControlled() && (%team < 0 || %cl.team == %team)) + { + //make sure the player is within range + %clPos = %cl.player.getWorldBoxCenter(); + %distance = VectorDist(%clPos, %srcEyePoint); + if (%radius <= 0 || %distance <= %radius) + { + //create the vector from the srcClient to the client + %clVector = VectorNormalize(VectorSub(%clPos, %srcEyePoint)); + + //see if the dot product is greater than our current, and greater than 0.6 + %dot = VectorDot(%clVector, %srcEyeVector); + + if (%dot > 0.6 && %dot > %clientDot) + { + %viewedClient = %cl; + %clientDot = %dot; + } + } + } + } + + return %viewedClient; +} + +//----------------------------------------------------------------------------- +//AI VEHICLE FUNCTIONS + +function Armor::AIonMount(%this, %obj, %vehicle, %node) +{ + //set the client var... + %client = %obj.client; + %client.turretMounted = -1; + + //make sure the AI was *supposed* to mount the vehicle + if (!%client.isMountingVehicle()) + { + AIDisembarkVehicle(%client); + return; + } + + //get the vehicle's pilot + %pilot = %vehicle.getMountNodeObject(0); + + //make sure the bot is in node 0 if'f the bot is piloting the vehicle + if ((%node == 0 && !%client.pilotVehicle) || (%node > 0 && %client.pilotVehicle)) + { + AIDisembarkVehicle(%client); + return; + } + + //make sure the bot didn't is on the same team as the pilot + if (%pilot > 0 && isObject(%pilot) && %pilot.client.team != %client.team) + { + AIDisembarkVehicle(%client); + return; + } + + //if we're supposed to pilot the vehicle, set the control object + if (%client.pilotVehicle) + %client.setControlObject(%vehicle); + + //each vehicle may be built differently... + if (%vehicle.getDataBlock().getName() $= "AssaultVehicle") + { + //node 1 is this vehicle's turret seat + if (%node == 1) + { + %turret = %vehicle.getMountNodeObject(10); + %skill = %client.getSkillLevel(); + %turret.setSkill(%skill); + %client.turretMounted = %turret; + %turret.setAutoFire(true); + } + } + + else if (%vehicle.getDataBlock().getName() $= "BomberFlyer") + { + //node 1 is this vehicle's turret seat + if (%node == 1) + { + %turret = %vehicle.getMountNodeObject(10); + %skill = %client.getSkillLevel(); + %turret.setSkill(%skill); + %client.turretMounted = %turret; + %client.setTurretMounted(%turret); + %turret.setAutoFire(true); + } + } +} + +function Armor::AIonUnMount(%this, %obj, %vehicle, %node) +{ + //get the client var + %client = %obj.client; + + //reset the control object + if (%client.pilotVehicle) + %client.setControlObject(%client.player); + %client.pilotVehicle = false; + + //if the client had mounted a turret, turn the turret back off + if (%client.turretMounted > 0) + %client.turretMounted.setAutoFire(false); + %client.turretMounted = -1; + %client.setTurretMounted(-1); + + // reset the turret skill level + if(%vehicle.getDataBlock().getName() $= "AssaultVehicle") + if (%node == 1) + %vehicle.getMountNodeObject(10).setSkill(1.0); + + if(%vehicle.getDataBlock().getName() $= "BomberFlyer") + if(%node == 1) + %vehicle.getMountNodeObject(10).setSkill(1.0); +} + +function AIDisembarkVehicle(%client) +{ + if (%client.player.isMounted()) + { + if (%client.pilotVehicle) + %client.setControlObject(%client.player); + %client.pressJump(); + } +} + +function AIProcessVehicle(%client) +{ + //see if we're mounted on a turret, and if that turret has a target + if (%client.turretMounted > 0) + { + %turretDB = %client.turretMounted.getDataBlock(); + + //see if we're in a bomber close to a bomb site... + if (%turretDB.getName() $= "BomberTurret") + { + %clientPos = getWords(%client.player.position, 0, 1) @ " 0"; + %found = false; + %count = $AIBombLocationSet.getCount(); + for (%i = 0; %i < %count; %i++) + { + %bombObj = $AIBombLocationSet.getObject(%i); + %bombLocation = %bombObj.location; + + //make sure the objective was issued by someone in the vehicle + if (%bombObj.issuedByClientId.vehicleMounted == %client.vehicleMounted) + { + //find out where the bomb is going to drop... first, how high up are we... + %bombLocation2D = getWord(%bombLocation, 0) SPC getWord(%bombLocation, 1) SPC "0"; + %height = getWord(%client.vehicleMounted.position, 2) - getWord(%bombLocation, 2); + + //find out how long it'll take the bomb to fall that far... + //assume no initial velocity in the Z axis... + %timeToFall = mSqrt((2.0 * %height) / 9.81); + + //how fast is the vehicle moving in the XY plane... + %myLocation = %client.vehicleMounted.position; + %myLocation2D = getWord(%myLocation, 0) SPC getWord(%myLocation, 1) SPC "0"; + %vel = %client.vehicleMounted.getVelocity(); + %vel2D = getWord(%vel, 0) SPC getWord(%vel, 1) SPC "0"; + + %bombImpact2D = VectorAdd(%myLocation2D, VectorScale(%vel2D, %timeToFall)); + + //see if the bomb inpact position is within 20m of the desired bomb site... + %distToBombsite2D = VectorDist(%bombImpact2D, %bombLocation2D); + if (%height > 20 && %distToBombsite2D < 25) + { + %found = true; + break; + } + } + } + + //see if we found a bomb site + if (%found) + { + %client.turretMounted.selectedWeapon = 2; + %turretDB.onTrigger(%client.turretMounted, 0, true); + return; + } + } + + //we're not bombing, make sure we have the regular weapon selected + %client.turretMounted.selectedWeapon = 1; + if (isObject(%client.turretMounted.getTargetObject())) + %turretDB.onTrigger(%client.turretMounted, 0, true); + else + %turretDB.onTrigger(%client.turretMounted, 0, false); + } +} + +function AIPilotVehicle(%client) +{ + //this is not very well supported, but someone will find a use for this function... +} diff --git a/scripts/aiBotProfiles.cs b/scripts/aiBotProfiles.cs index c13cf38..7312db3 100644 --- a/scripts/aiBotProfiles.cs +++ b/scripts/aiBotProfiles.cs @@ -1,279 +1,279 @@ -function aiConnectByIndex(%index, %team) -{ - if (%index < 0 || $BotProfile[%index, name] $= "") - return; - - if (%team $= "") - %team = -1; - - //initialize the profile, if required - if ($BotProfile[%index, skill] $= "") - $BotProfile[%index, skill] = 0.5; - if ($BotProfile[%index, race] $= "") - $BotProfile[%index, race] = "Human"; - if ($BotProfile[%index, Sex] $= "") - $BotProfile[%index, Sex] = "Male"; - if ($BotProfile[%index, Voice] $= "") - $BotProfile[%index, Voice] = "Bot1"; - - %skin[0] = "BaseBot"; - %skin[1] = "BaseBBot"; - - if ($BotProfile[%index, Skin] $= '') - $BotProfile[%index, Skin] = %skin[getRandom(0,1)]; - $BotProfile[%index, Skin] = addTaggedString($BotProfile[%index, Skin]); - //$BotProfile[%index, Voice] = addTaggedString($BotProfile[%index, Voice]); - - %client = aiConnect($BotProfile[%index, name], %team, $BotProfile[%index, skill], $BotProfile[%index, offense], $BotProfile[%index, voice], $BotProfile[%index, voicePitch]); - %client.skin = $BotProfile[%index, skin]; - %client.race = $BotProfile[%index, race]; - %client.sex = $BotProfile[%index, sex]; - %client.voice = $BotProfile[%index, voice]; - - //Make sure our voices and skins are set - setSkin(%client,getTaggedString(%client.skin)); //Yay.. bots are not ugly anymore! - setVoice(%client,%client.voice); - %client.player.setArmor(%client.armor); - - return %client; -} - -function aiConnectByName(%name, %team) -{ - if (%name $= "") - return; - - if (%team $= "") - %team = -1; - - %foundIndex = -1; - %index = 0; - while ($BotProfile[%index, name] !$= "") - { - if ($BotProfile[%index, name] $= %name) - { - %foundIndex = %index; - break; - } - else - %index++; - } - - //see if we found our bot - if (%foundIndex >= 0) - return aiConnectByIndex(%foundIndex, %team); - - //else add a new bot profile - else - { - $BotProfile[%index, name] = %name; - return aiConnectByIndex(%index, %team); - } -} - -function aiBotAlreadyConnected(%name) -{ - %count = ClientGroup.getCount(); - for (%i = 0; %i < %count; %i++) - { - %client = ClientGroup.getObject(%i); - if (%name $= getTaggedString(%client.name)) - return true; - } - - return false; -} - -function aiConnectMultiple(%numToConnect, %minSkill, %maxSkill, %team) -{ - //validate the args - if (%numToConnect <= 0) - return; - - if (%maxSkill < 0) - %maxSkill = 0; - - if (%minSkill >= %maxSkill) - %minSkill = %maxSkill - 0.01; - - if (%team $= "") - %team = -1; - - //loop through the profiles, and set the flags and initialize - %numBotsAlreadyConnected = 0; - %index = 0; - while ($BotProfile[%index, name] !$= "") - { - //initialize the profile if required - if ($BotProfile[%index, skill] $= "") - $BotProfile[%index, skill] = 0.5; - - //if the bot is already playing, it shouldn't be reselected - if (aiBotAlreadyConnected($BotProfile[%index, name])) - { - $BotProfile[%index, canSelect] = false; - %numBotsAlreadyConnected++; - } - else - $BotProfile[%index, canSelect] = true; - - %index++; - } - - //make sure we're not trying to add more bots than we have... - if (%numToConnect > (%index - %numBotsAlreadyConnected)) - %numToConnect = (%index - %numBotsAlreadyConnected); - - //build the array of possible candidates... - %index = 0; - %tableCount = 0; - while ($BotProfile[%index, name] !$= "") - { - %botSkill = $BotProfile[%index, skill]; - - //see if the skill is within range - if ($BotProfile[%index, canSelect] && %botSkill >= %minSkill && %botSkill <= %maxSkill) - { - $BotSelectTable[%tableCount] = %index; - %tableCount++; - $BotProfile[%index, canSelect] = false; - } - - //check the next bot - %index++; - } - - //if we didn't find enough bots, we'll have to search the rest of the profiles... - %searchMinSkill = %minSkill; - while ((%tableCount < %numToConnect) && (%searchMinSkill > 0)) - { - %index = 0; - while ($BotProfile[%index, name] !$= "") - { - %botSkill = $BotProfile[%index, skill]; - - //see if the skill is within range - if ($BotProfile[%index, canSelect] && %botSkill >= (%searchMinSkill - 0.1) && %botSkill <= %searchMinSkill) - { - $BotSelectTable[%tableCount] = %index; - %tableCount++; - $BotProfile[%index, canSelect] = false; - } - - //check the next bot - %index++; - } - - //now lower the search min Skill, and take another pass at a lower skill level - %searchMinSkill = %searchMinSkill - 0.1; - } - - //if we're still short of bots, search the higher skill levels - %searchMaxSkill = %maxSkill; - while ((%tableCount < %numToConnect) && (%searchMaxSkill < 1.0)) - { - %index = 0; - while ($BotProfile[%index, name] !$= "") - { - %botSkill = $BotProfile[%index, skill]; - //see if the skill is within range - if ($BotProfile[%index, canSelect] && %botSkill >= %searchMaxSkill && %botSkill <= (%searchMaxSkill + 0.1)) - { - $BotSelectTable[%tableCount] = %index; - %tableCount++; - $BotProfile[%index, canSelect] = false; - } - - //check the next bot - %index++; - } - - //now raise the search max Skill, and take another pass at a higher skill level - %searchMaxSkill = %searchMaxSkill + 0.1; - } - - //since the numToConnect was capped at the table size, we should have enough bots in the - //table to fulfill the quota - - //loop through five times, picking random indices, and adding them until we've added enough - %numBotsConnected = 0; - for (%i = 0; %i < 5; %i++) - { - for (%j = 0; %j < %numToConnect; %j++) - { - %selectedIndex = mFloor(getRandom() * (%tableCount - 0.1)); - if ($BotSelectTable[%selectedIndex] >= 0) - { - //connect the bot - %botClient = aiConnectByIndex($BotSelectTable[%selectedIndex], %team); - %numBotsConnected++; - - //adjust the skill level, if required - %botSkill = %botClient.getSkillLevel(); - if (%botSkill < %minSkill || %botSkill > %maxSkill) - { - %newSkill = %minSKill + (getRandom() * (%maxSkill - %minSkill)); - %botClient.setSkillLevel(%newSkill); - } - - //clear the table entry to avoid connecting duplicates - $BotSelectTable[%selectedIndex] = -1; - - //see if we've connected enough - if (%numBotsConnected == %numToConnect) - return; - } - } - } - - //at this point, we've looped though the table, and kept hitting duplicates, search the table sequentially - for (%i = 0; %i < %tableCount; %i++) - { - if ($BotSelectTable[%i] >= 0) - { - //connect the bot - %botClient = aiConnectByIndex($BotSelectTable[%i], %team); - %numBotsConnected++; - - //adjust the skill level, if required - %botSkill = %botClient.getSkillLevel(); - if (%botSkill < %minSkill || %botSkill > %maxSkill) - { - %newSkill = %minSKill + (getRandom() * (%maxSkill - %minSkill)); - %botClient.setSkillLevel(%newSkill); - } - - //clear the table entry to avoid connecting duplicates - $BotSelectTable[%i] = -1; - - //see if we've connected enough - if (%numBotsConnected == %numToConnect) - return; - } - } -} - -function aiReloadProfiles() -{ - if (!IsObject(BotProfiles)) - new ScriptObject(BotProfiles) { class = "BasicDataParser"; }; - BotProfiles.empty(); - BotProfiles.load("prefs/Bot Profiles.conf"); - %count = BotProfiles.count("Bot"); - for (%i = 0; %i < %count; %i++) - { - %Entry = BotProfiles.get("Bot",%i); - $BotProfile[%i, name] = %Entry.element("Name"); - $BotProfile[%i, skill] = %Entry.element("skill"); - $BotProfile[%i, offense] = %Entry.element("offense"); - $BotProfile[%i, voicePitch] = %Entry.element("voicePitch"); - $BotProfile[%i, race] = %Entry.element("race"); - $BotProfile[%i, skin] = %Entry.element("skin"); - $BotProfile[%i, voice] = %Entry.element("voice"); - $BotProfile[%i, sex] = %Entry.element("sex"); - } - $BotProfile::Count = %count; - warn("scripts/aiBotProfiles.cs: Loaded" SPC %count SPC "bot profiles."); - return true; -} +function aiConnectByIndex(%index, %team) +{ + if (%index < 0 || $BotProfile[%index, name] $= "") + return; + + if (%team $= "") + %team = -1; + + //initialize the profile, if required + if ($BotProfile[%index, skill] $= "") + $BotProfile[%index, skill] = 0.5; + if ($BotProfile[%index, race] $= "") + $BotProfile[%index, race] = "Human"; + if ($BotProfile[%index, Sex] $= "") + $BotProfile[%index, Sex] = "Male"; + if ($BotProfile[%index, Voice] $= "") + $BotProfile[%index, Voice] = "Bot1"; + + %skin[0] = "BaseBot"; + %skin[1] = "BaseBBot"; + + if ($BotProfile[%index, Skin] $= '') + $BotProfile[%index, Skin] = %skin[getRandom(0,1)]; + $BotProfile[%index, Skin] = addTaggedString($BotProfile[%index, Skin]); + //$BotProfile[%index, Voice] = addTaggedString($BotProfile[%index, Voice]); + + %client = aiConnect($BotProfile[%index, name], %team, $BotProfile[%index, skill], $BotProfile[%index, offense], $BotProfile[%index, voice], $BotProfile[%index, voicePitch]); + %client.skin = $BotProfile[%index, skin]; + %client.race = $BotProfile[%index, race]; + %client.sex = $BotProfile[%index, sex]; + %client.voice = $BotProfile[%index, voice]; + + //Make sure our voices and skins are set + setSkin(%client,getTaggedString(%client.skin)); //Yay.. bots are not ugly anymore! + setVoice(%client,%client.voice); + %client.player.setArmor(%client.armor); + + return %client; +} + +function aiConnectByName(%name, %team) +{ + if (%name $= "") + return; + + if (%team $= "") + %team = -1; + + %foundIndex = -1; + %index = 0; + while ($BotProfile[%index, name] !$= "") + { + if ($BotProfile[%index, name] $= %name) + { + %foundIndex = %index; + break; + } + else + %index++; + } + + //see if we found our bot + if (%foundIndex >= 0) + return aiConnectByIndex(%foundIndex, %team); + + //else add a new bot profile + else + { + $BotProfile[%index, name] = %name; + return aiConnectByIndex(%index, %team); + } +} + +function aiBotAlreadyConnected(%name) +{ + %count = ClientGroup.getCount(); + for (%i = 0; %i < %count; %i++) + { + %client = ClientGroup.getObject(%i); + if (%name $= getTaggedString(%client.name)) + return true; + } + + return false; +} + +function aiConnectMultiple(%numToConnect, %minSkill, %maxSkill, %team) +{ + //validate the args + if (%numToConnect <= 0) + return; + + if (%maxSkill < 0) + %maxSkill = 0; + + if (%minSkill >= %maxSkill) + %minSkill = %maxSkill - 0.01; + + if (%team $= "") + %team = -1; + + //loop through the profiles, and set the flags and initialize + %numBotsAlreadyConnected = 0; + %index = 0; + while ($BotProfile[%index, name] !$= "") + { + //initialize the profile if required + if ($BotProfile[%index, skill] $= "") + $BotProfile[%index, skill] = 0.5; + + //if the bot is already playing, it shouldn't be reselected + if (aiBotAlreadyConnected($BotProfile[%index, name])) + { + $BotProfile[%index, canSelect] = false; + %numBotsAlreadyConnected++; + } + else + $BotProfile[%index, canSelect] = true; + + %index++; + } + + //make sure we're not trying to add more bots than we have... + if (%numToConnect > (%index - %numBotsAlreadyConnected)) + %numToConnect = (%index - %numBotsAlreadyConnected); + + //build the array of possible candidates... + %index = 0; + %tableCount = 0; + while ($BotProfile[%index, name] !$= "") + { + %botSkill = $BotProfile[%index, skill]; + + //see if the skill is within range + if ($BotProfile[%index, canSelect] && %botSkill >= %minSkill && %botSkill <= %maxSkill) + { + $BotSelectTable[%tableCount] = %index; + %tableCount++; + $BotProfile[%index, canSelect] = false; + } + + //check the next bot + %index++; + } + + //if we didn't find enough bots, we'll have to search the rest of the profiles... + %searchMinSkill = %minSkill; + while ((%tableCount < %numToConnect) && (%searchMinSkill > 0)) + { + %index = 0; + while ($BotProfile[%index, name] !$= "") + { + %botSkill = $BotProfile[%index, skill]; + + //see if the skill is within range + if ($BotProfile[%index, canSelect] && %botSkill >= (%searchMinSkill - 0.1) && %botSkill <= %searchMinSkill) + { + $BotSelectTable[%tableCount] = %index; + %tableCount++; + $BotProfile[%index, canSelect] = false; + } + + //check the next bot + %index++; + } + + //now lower the search min Skill, and take another pass at a lower skill level + %searchMinSkill = %searchMinSkill - 0.1; + } + + //if we're still short of bots, search the higher skill levels + %searchMaxSkill = %maxSkill; + while ((%tableCount < %numToConnect) && (%searchMaxSkill < 1.0)) + { + %index = 0; + while ($BotProfile[%index, name] !$= "") + { + %botSkill = $BotProfile[%index, skill]; + //see if the skill is within range + if ($BotProfile[%index, canSelect] && %botSkill >= %searchMaxSkill && %botSkill <= (%searchMaxSkill + 0.1)) + { + $BotSelectTable[%tableCount] = %index; + %tableCount++; + $BotProfile[%index, canSelect] = false; + } + + //check the next bot + %index++; + } + + //now raise the search max Skill, and take another pass at a higher skill level + %searchMaxSkill = %searchMaxSkill + 0.1; + } + + //since the numToConnect was capped at the table size, we should have enough bots in the + //table to fulfill the quota + + //loop through five times, picking random indices, and adding them until we've added enough + %numBotsConnected = 0; + for (%i = 0; %i < 5; %i++) + { + for (%j = 0; %j < %numToConnect; %j++) + { + %selectedIndex = mFloor(getRandom() * (%tableCount - 0.1)); + if ($BotSelectTable[%selectedIndex] >= 0) + { + //connect the bot + %botClient = aiConnectByIndex($BotSelectTable[%selectedIndex], %team); + %numBotsConnected++; + + //adjust the skill level, if required + %botSkill = %botClient.getSkillLevel(); + if (%botSkill < %minSkill || %botSkill > %maxSkill) + { + %newSkill = %minSKill + (getRandom() * (%maxSkill - %minSkill)); + %botClient.setSkillLevel(%newSkill); + } + + //clear the table entry to avoid connecting duplicates + $BotSelectTable[%selectedIndex] = -1; + + //see if we've connected enough + if (%numBotsConnected == %numToConnect) + return; + } + } + } + + //at this point, we've looped though the table, and kept hitting duplicates, search the table sequentially + for (%i = 0; %i < %tableCount; %i++) + { + if ($BotSelectTable[%i] >= 0) + { + //connect the bot + %botClient = aiConnectByIndex($BotSelectTable[%i], %team); + %numBotsConnected++; + + //adjust the skill level, if required + %botSkill = %botClient.getSkillLevel(); + if (%botSkill < %minSkill || %botSkill > %maxSkill) + { + %newSkill = %minSKill + (getRandom() * (%maxSkill - %minSkill)); + %botClient.setSkillLevel(%newSkill); + } + + //clear the table entry to avoid connecting duplicates + $BotSelectTable[%i] = -1; + + //see if we've connected enough + if (%numBotsConnected == %numToConnect) + return; + } + } +} + +function aiReloadProfiles() +{ + if (!IsObject(BotProfiles)) + new ScriptObject(BotProfiles) { class = "BasicDataParser"; }; + BotProfiles.empty(); + BotProfiles.load("prefs/Bot Profiles.conf"); + %count = BotProfiles.count("Bot"); + for (%i = 0; %i < %count; %i++) + { + %Entry = BotProfiles.get("Bot",%i); + $BotProfile[%i, name] = %Entry.element("Name"); + $BotProfile[%i, skill] = %Entry.element("skill"); + $BotProfile[%i, offense] = %Entry.element("offense"); + $BotProfile[%i, voicePitch] = %Entry.element("voicePitch"); + $BotProfile[%i, race] = %Entry.element("race"); + $BotProfile[%i, skin] = %Entry.element("skin"); + $BotProfile[%i, voice] = %Entry.element("voice"); + $BotProfile[%i, sex] = %Entry.element("sex"); + } + $BotProfile::Count = %count; + warn("scripts/aiBotProfiles.cs: Loaded" SPC %count SPC "bot profiles."); + return true; +} aiReloadProfiles(); \ No newline at end of file diff --git a/scripts/aiDeathMatch.cs b/scripts/aiDeathMatch.cs index 31380e9..1bd9a96 100644 --- a/scripts/aiDeathMatch.cs +++ b/scripts/aiDeathMatch.cs @@ -1,25 +1,25 @@ -function DMGame::AIInit(%game) -{ - //call the default AIInit() function - AIInit(); -} - -function DMGame::onAIRespawn(%game, %client) -{ - //add the default task - if (! %client.defaultTasksAdded) - { - %client.defaultTasksAdded = true; - %client.addTask(AIEngageTask); - %client.addTask(AIPickupItemTask); - %client.addTask(AIUseInventoryTask); - %client.addTask(AITauntCorpseTask); - %client.addTask(AIEngageTurretTask); - %client.addtask(AIDetectMineTask); - %client.addTask(AIPatrolTask); - } - - //set the inv flag - %client.spawnUseInv = true; -} - +function DMGame::AIInit(%game) +{ + //call the default AIInit() function + AIInit(); +} + +function DMGame::onAIRespawn(%game, %client) +{ + //add the default task + if (! %client.defaultTasksAdded) + { + %client.defaultTasksAdded = true; + %client.addTask(AIEngageTask); + %client.addTask(AIPickupItemTask); + %client.addTask(AIUseInventoryTask); + %client.addTask(AITauntCorpseTask); + %client.addTask(AIEngageTurretTask); + %client.addtask(AIDetectMineTask); + %client.addTask(AIPatrolTask); + } + + //set the inv flag + %client.spawnUseInv = true; +} + diff --git a/scripts/aiDebug.cs b/scripts/aiDebug.cs index c389b65..291d6a1 100644 --- a/scripts/aiDebug.cs +++ b/scripts/aiDebug.cs @@ -1,1053 +1,1053 @@ -//------------------------------ -//AI Debugging functions - -function aics() -{ - aidebug(-1); - exec("scripts/ai.cs"); -} - -function ga(%pack) -{ - $testcheats = 1; - giveall(); - switch$ (%pack) - { - case "repair": - LocalClientConnection.player.setInventory(RepairPack, 1); - case "charge": - LocalClientConnection.player.setInventory(SatchelCharge, 1); - case "energy": - LocalClientConnection.player.setInventory(EnergyPack, 1); - case "cloak": - LocalClientConnection.player.setInventory(CloakingPack, 1); - case "shield": - LocalClientConnection.player.setInventory(ShieldPack, 1); - case "jammer": - LocalClientConnection.player.setInventory(SensorJammerPack, 1); - } -} - -function aiga(%client) -{ - $TestCheats = 1; - %player = %client.player; - %player.setInventory(RepairKit,999); - %player.setInventory(Mine,999); - %player.setInventory(MineAir,999); - %player.setInventory(MineLand,999); - %player.setInventory(MineSticky,999); - %player.setInventory(Grenade,999); - %player.setInventory(FlashGrenade,999); - %player.setInventory(FlareGrenade,999); - %player.setInventory(ConcussionGrenade,999); - %player.setInventory(CameraGrenade, 999); - %player.setInventory(Blaster,1); - %player.setInventory(Plasma,1); - %player.setInventory(Disc,1); - %player.setInventory(Chaingun, 1); - %player.setInventory(GrenadeLauncher, 1); - %player.setInventory(MissileLauncher, 1); - %player.setInventory(Mortar, 1); - %player.setInventory(MissileLauncherAmmo, 999); - %player.setInventory(GrenadeLauncherAmmo, 999); - %player.setInventory(MortarAmmo, 999); - %player.setInventory(PlasmaAmmo,999); - %player.setInventory(ChaingunAmmo, 999); - %player.setInventory(DiscAmmo, 999); - %player.setInventory(TargetingLaser, 1); - %player.setInventory(ELFGun, 1); - %player.setInventory(SniperRifle, 1); - %player.setInventory(ShockLance, 1); -} - -function aiCome(%from, %to) -{ - if (%to $= "") - %to = 2; - %from.player.setTransform(%to.player.getTransform()); -} - -function findBotWithInv(%item) -{ - for (%i = 0; %i < ClientGroup.getCount(); %i++) - { - %cl = ClientGroup.getObject(%i); - if (isObject(%cl.player) && %cl.player.getInventory(%item)) - echo(%cl @ ":" SPC getTaggedString(%cl.name) SPC "has item" SPC %item); - } -} - -function listInv(%client) -{ - %player = %client.player; - %count = %player.getInventory(RepairKit); - if (%count > 0) - echo("RepairKit: " @ %count); - %count = %player.getInventory(Mine); - if (%count > 0) - echo("Mine: " @ %count); - %count = %player.getInventory(MineAir); - if (%count > 0) - echo("MineAir: " @ %count); - %count = %player.getInventory(MineLand); - if (%count > 0) - echo("MineLand: " @ %count); - %count = %player.getInventory(MineSticky); - if (%count > 0) - echo("MineSticky: " @ %count); - %count = %player.getInventory(Grenade); - if (%count > 0) - echo("Grenade: " @ %count); - %count = %player.getInventory(FlashGrenade); - if (%count > 0) - echo("FlashGrenade: " @ %count); - %count = %player.getInventory(FlareGrenade); - if (%count > 0) - echo("FlareGrenade: " @ %count); - %count = %player.getInventory(ConcussionGrenade); - if (%count > 0) - echo("ConcussionGrenade: " @ %count); - %count = %player.getInventory(CameraGrenade); - if (%count > 0) - echo("CameraGrenade: " @ %count); - %count = %player.getInventory(Blaster); - if (%count > 0) - echo("Blaster: " @ %count); - %count = %player.getInventory(Plasma); - if (%count > 0) - echo("Plasma: " @ %count); - %count = %player.getInventory(Disc); - if (%count > 0) - echo("Disc: " @ %count); - %count = %player.getInventory(Chaingun); - if (%count > 0) - echo("Chaingun: " @ %count); - %count = %player.getInventory(GrenadeLauncher); - if (%count > 0) - echo("GrenadeLauncher: " @ %count); - %count = %player.getInventory(MissileLauncher); - if (%count > 0) - echo("MissileLauncher: " @ %count); - %count = %player.getInventory(Mortar); - if (%count > 0) - echo("Mortar: " @ %count); - %count = %player.getInventory(MissileLauncherAmmo); - if (%count > 0) - echo("MissileLauncherAmmo: " @ %count); - %count = %player.getInventory(GrenadeLauncherAmmo); - if (%count > 0) - echo("GrenadeLauncherAmmo: " @ %count); - %count = %player.getInventory(MortarAmmo); - if (%count > 0) - echo("MortarAmmo: " @ %count); - %count = %player.getInventory(PlasmaAmmo); - if (%count > 0) - echo("PlasmaAmmo: " @ %count); - %count = %player.getInventory(ChaingunAmmo); - if (%count > 0) - echo("ChaingunAmmo: " @ %count); - %count = %player.getInventory(DiscAmmo); - if (%count > 0) - echo("DiscAmmo: " @ %count); - %count = %player.getInventory(TargetingLaser); - if (%count > 0) - echo("TargetingLaser: " @ %count); - %count = %player.getInventory(ELFGun); - if (%count > 0) - echo("ELFGun: " @ %count); - %count = %player.getInventory(SniperRifle); - if (%count > 0) - echo("SniperRifle: " @ %count); - %count = %player.getInventory(ShockLance); - if (%count > 0) - echo("ShockLance: " @ %count); - %count = %player.getInventory(RepairPack); - if (%count > 0) - echo("RepairPack: " @ %count); - %count = %player.getInventory(EnergyPack); - if (%count > 0) - echo("EnergyPack: " @ %count); - %count = %player.getInventory(ShieldPack); - if (%count > 0) - echo("ShieldPack: " @ %count); - %count = %player.getInventory(CloakingPack); - if (%count > 0) - echo("CloakingPack: " @ %count); - %count = %player.getInventory(SensorJammerPack); - if (%count > 0) - echo("SensorJammerPack: " @ %count); -} - -function createAIDebugDlg() -{ - if (!isObject("AIDebugViewProfile")) - { - new GuiControlProfile("AIDebugViewProfile") - { - fontType = "Arial Bold"; - fontSize = 12; - fontColor = "255 0 255"; - autoSizeWidth = false; - autoSizeHeight = false; - modal = "false"; - }; - - new GuiControl(aiDebugDlg) - { - profile = "GuiDefaultProfile"; - horizSizing = "width"; - vertSizing = "height"; - position = "0 0"; - extent = "640 480"; - minExtent = "8 8"; - visible = "True"; - setFirstResponder = "True"; - helpTag = "0"; - bypassHideCursor = "1"; - - new DebugView(aiDebug) - { - profile = "AIDebugViewProfile"; - horizSizing = "width"; - vertSizing = "height"; - position = "8 8"; - extent = "624 464"; - minExtent = "8 8"; - visible = "True"; - setFirstResponder = "False"; - helpTag = "0"; - }; - }; - } -} - -function ToggleAIDebug(%make) -{ - if (%make) - { - if ($AIDebugActive) - { - Canvas.popDialog(aiDebugDlg); - $AIDebugActive = false; - } - else - { - createAIDebugDlg(); - Canvas.pushDialog(aiDebugDlg, 70); - $AIDebugActive = true; - - //make sure we're debuging the correct client - if (LocalClientConnection.getControlObject() == LocalClientConnection.camera) - { - if (isObject(LocalClientConnection.observeClient)) - aidebug(LocalClientConnection.observeClient); - } - } - } -} - -GlobalActionMap.bind(keyboard, "ctrl tilde", "ToggleAIDebug"); - -//function showFPS() -//{ -// if (isObject(aiDebug)) -// aiDebug.setText(0, "FPS:" SPC $fps::real SPC " $patch1Avg" SPC $Patch1Avg); -// schedule(1000, 0, "ShowFPS"); -//} - -function aiDebug(%client) -{ - if ($AIDebugTeam < 0 && $AIDebugClient < 0) - { - createAIDebugDlg(); - Canvas.pushDialog(aiDebugDlg, 70); - } - - $AIDebugClient = %client; - $AIDebugTeam = -1; - - if (%client > 0) - { - createAIDebugDlg(); - Canvas.pushDialog(aiDebugDlg, 70); - aiDebug.clearText(); - $AIDebugActive = true; - } - else - { - $AIDebugActive = false; - Canvas.popDialog(aiDebugDlg); - } -} - -function aiDebugText(%client, %line, %text) -{ - if (%client != $AIDebugClient) - return; - - aiDebug.setText(%line, %text); -} - -function aiDebugLine(%client, %startPt, %endPt, %color) -{ - if (%client != $AIDebugClient) - return; - - aiDebug.addLine(%startPt, %endPt, %color); -} - -function aiDebugClearLines(%client) -{ - if (%client != $AIDebugClient) - return; - - aiDebug.clearLines(); -} - -function aiGetTaskDesc(%client) -{ - if (!%client.isAIControlled()) - %returnStr = getTaggedString(%client.name) @ ": " @ "HUMAN"; - - else if (%client.objective > 0) - { - if (%client.objective.description !$= "") - %returnStr = %client @ " " @ getTaggedString(%client.name) @ ": " @ %client.objective.description; - else - %returnStr = %client @ " " @ getTaggedString(%client.name) @ ": " @ %client.objective @ " NO DESC"; - } - else - { - %curTask = %client.getTaskName(); - %curStep = %client.getStepName(); - if (%curTask !$= "") - %returnStr = %client @ " " @ getTaggedString(%client.name) @ ": " @ %curTask; - else if (%curStep !$= "") - %returnStr = %client @ " " @ getTaggedString(%client.name) @ ": " @ %curStep; - else - %returnStr = getTaggedString(%client.name) @ ": " @ "UNKNOWN"; - } - - //add in some color info - if (Game.numTeams != 2) - %color = "E"; - else if (%client.team == LocalClientConnection.team) - %color = "F"; - else - %color = "E"; - - return %color @ ":" @ %returnStr; -} - -$AIDebugTeam = -1; -$AIDebugClient = -1; -$AIDebugTasks = true; -Canvas.popDialog(aiDebugDlg); -$AIDebugActive = false; - -function aiEchoObjective(%objective, %lineNum, %group) -{ - %clientAssigned = false; - %indent = " "; - if (%group > 0) - { - %indent = " "; - if (%group.clientLevel[1] > 0 && %group.clientLevel[1].objective == %objective) - { - %assigned1 = getTaggedString(%group.clientLevel[1].name) @ ":" @ %group.clientLevel[1].objectiveWeight; - %clientAssigned = true; - } - else - %assigned1 = " "; - if (%group.clientLevel[2] > 0 && %group.clientLevel[2].objective == %objective) - { - %assigned2 = getTaggedString(%group.clientLevel[2].name); - %clientAssigned = true; - } - else - %assigned2 = " "; - } - else - { - if (%objective.clientLevel[1] > 0) - { - %assigned1 = getTaggedString(%objective.clientLevel[1].name) @ ":" @ %objective.clientLevel[1].objectiveWeight; - %clientAssigned = true; - } - else - %assigned1 = " "; - if (%objective.clientLevel[2] > 0) - { - %assigned2 = getTaggedString(%objective.clientLevel[2].name); - %clientAssigned = true; - } - else - %assigned2 = " "; - } - - %text = %indent @ %objective @ " " @ %objective.weightLevel1 @ " " @ %assigned1 @ " " @ %assigned2 @ " " @ %objective.description; - if (%clientAssigned) - %color = "0 0 1"; - else - %color = "1 0 1"; - aiDebug.setText(%lineNum, %text, %color); -} - -function aiDebugQ(%team, %showTasks) -{ - if ($AIDebugTeam < 0 && $AIDebugClient < 0) - { - createAIDebugDlg(); - Canvas.pushDialog(aiDebugDlg, 70); - $AIDebugActive = true; - } - - $AIDebugTeam = %team; - $AIDebugClient = -1; - - if ($AIDebugTeam < 0) - { - Canvas.popDialog(aiDebugDlg); - $AIDebugActive = false; - return; - } - - if (%showTasks $= "") - %showTasks = $AIDebugTasks; - else - $AIDebugTasks = %showTasks; - - aiDebug.clearText(); - - if (! %showTasks) - return; - - //make sure we have a valid objectiveQ - if (!isObject($ObjectiveQ[%team])) - return; - - %timeStamp = getSimTime(); - %lineNum = 1; - %count = $ObjectiveQ[%team].getCount(); - - //clear the time stamps from all groups - for (%i = 0; %i < %count; %i++) - { - %objective = $ObjectiveQ[%team].getObject(%i); - if (%objective.group > 0) - %objective.group.debugStamp = 0; - } - - //now loop through and echo out all the objectives... - for (%i = 0; %i < %count; %i++) - { - %objective = $ObjectiveQ[%team].getObject(%i); - - //if the objective is part of a group, echo out the entire group first - if (%objective.group > 0) - { - %group = %objective.group; - if (%group.debugStamp != %timeStamp) - { - %group.debugStamp = %timeStamp; - %grpCount = %group.getCount(); - - //first print out the group label - %text = %group @ " GROUP: " @ %group.getName(); - aiDebug.setText(%lineNum, %text); - %lineNum++; - - //now loop through and print out the grouped objectives in the order they appear in the main list - for (%j = 0; %j < %count; %j++) - { - //print them in the order they appear in the main list - %obj = $ObjectiveQ[%team].getObject(%j); - if (%obj.group == %group) - { - aiEchoObjective(%obj, %lineNum, %group); - %lineNum++; - } - } - } - } - - else - { - aiEchoObjective(%objective, %lineNum, 0); - %lineNum++; - } - } -} - -//------------------------------ - -function aioTest() -{ - //clear out the objective Q's - $ObjectiveQ[0].clear(); - $ObjectiveQ[1].clear(); - $ObjectiveQ[2].clear(); - - /////////////////////////////// - // team 1 objectives // - /////////////////////////////// -// %newObjective = new AIObjective(AIORepairObject) { -// position = "0 0 0"; -// rotation = "1 0 0 0"; -// scale = "1 1 1"; -// description = "Repair the generator"; -// targetObject = "Team0GeneratorLarge1"; -// targetClientId = "-1"; -// targetObjectId = nameToId("Team0GeneratorLarge1"); -// location = "0 0 0"; -// weightLevel1 = "3200"; -// weightLevel2 = "1600"; -// weightLevel3 = "0"; -// weightLevel4 = "0"; -// offense = "0"; -// defense = "1"; -// equipment = "RepairPack"; -// buyEquipmentSet = "HeavyRepairSet"; -// issuedByHuman = "0"; -// issuingClientId = "-1"; -// forceClientId = "-1"; -// locked = "0"; -// }; -// $ObjectiveQ[0].add(%newObjective); -// -// %newObjective = new AIObjective(AIODefendLocation) { -// position = "-178 -156 120"; -// rotation = "1 0 0 0"; -// scale = "1 1 1"; -// description = "Defend our generator"; -// targetObject = "Team0GeneratorLarge1"; -// targetClientId = "-1"; -// targetObjectId = "-1"; -// location = "-178 -156 120"; -// weightLevel1 = "3900"; -// weightLevel2 = "2000"; -// weightLevel3 = "0"; -// weightLevel4 = "0"; -// offense = "0"; -// defense = "1"; -// desiredEquipment = "ShieldPack Plasma PlasmaAmmo"; -// buyEquipmentSet = "MediumShieldSet LightShieldSet HeavyShieldSet"; -// chat = ""; -// issuedByHuman = "0"; -// issuingClientId = "-1"; -// forceClientId = "-1"; -// locked = "1"; -// radius = "0"; -// team = "0"; -// }; -// $ObjectiveQ[0].add(%newObjective); - -// %newObjective = new AIObjective(AIODefendLocation) { -// position = "0 0 0"; -// rotation = "1 0 0 0"; -// scale = "1 1 1"; -// description = "Defend the generator"; -// targetObject = "Team0GeneratorLarge1"; -// targetClientId = "-1"; -// targetObjectId = nameToId("Team0GeneratorLarge1"); -// location = "0 0 0"; -// weightLevel1 = "3100"; -// weightLevel2 = "1500"; -// weightLevel3 = "0"; -// weightLevel4 = "0"; -// offense = "0"; -// defense = "1"; -// desiredEquipment = "ShieldPack Plasma PlasmaAmmo"; -// buyEquipmentSet = "HeavyShieldSet"; -// issuedByHuman = "0"; -// issuingClientId = "-1"; -// forceClientId = "-1"; -// locked = "0"; -// }; -// $ObjectiveQ[0].add(%newObjective); -// -// %newObjective = new AIObjective(AIOAttackLocation) -// { -// weightLevel1 = 2000; -// description = "Sniper"; -// location = "50 218 95"; -// offense = true; -// defense = false; -// equipment = "SniperRifle EnergyPack"; -// buyEquipmentSet = "LightEnergySniper"; -// }; -// $ObjectiveQ[0].add(%newObjective); -// -// %newObjective = new AIObjective(AIOLazeObject) -// { -// weightLevel1 = 10000; -// description = "Laze the enemy turret"; -// targetObject = NameToId("Team1Turret"); -// targetClient = %client; //note, used to store the task requester -// offense = true; -// equipment = "TargetingLaser"; -// buyEquipmentSet = "LightEnergySniper"; -// }; -// $ObjectiveQ[0].add(%newObjective); -// -// %newObjective = new AIObjective(AIOMortarObject) -// { -// weightLevel1 = $AIWeightMortarTurret[1]; -// weightLevel2 = $AIWeightMortarTurret[2]; -// description = "Mortar the enemy turret"; -// targetObject = "Team1TurretBaseLarge1"; -// targetObjectId = nameToId("Team1TurretBaseLarge1"); -// location = ""; -// offense = true; -// defense = false; -// equipment = "Mortar MortarAmmo"; -// buyEquipmentSet = "HeavyShieldSet"; -// }; -// $ObjectiveQ[0].add(%newObjective); -// -// %newObjective = new AIObjective(AIORepairObject) -// { -// weightLevel1 = $AIWeightRepairTurret[1]; -// weightLevel2 = $AIWeightRepairTurret[2]; -// description = "Repair the turret"; -// targetObject = NameToId("Team0Turret"); -// location = ""; -// offense = false; -// defense = true; -// equipment = "RepairPack"; -// }; -// $ObjectiveQ[0].add(%newObjective); -// -// %newObjective = new AIObjective(AIOAttackObject) -// { -// weightLevel1 = $AIWeightAttackGenerator[1]; -// weightLevel2 = $AIWeightAttackGenerator[2]; -// description = "Attack the enemy generator"; -// targetObject = NameToId("Team1Generator"); -// location = ""; -// offense = true; -// defense = false; -// equipment = "plasma plasmaAmmo"; -// buyEquipmentSet = "HeavyShieldSet"; -// }; -// $ObjectiveQ[0].add(%newObjective); -// -// %newObjective = new AIObjective(AIORepairObject) -// { -// //weightLevel1 = $AIWeightRepairGenerator[1]; -// weightLevel1 = 10000; -// weightLevel2 = $AIWeightRepairGenerator[2]; -// description = "Repair the generator"; -// targetObject = NameToId("Team0Generator"); -// location = ""; -// offense = false; -// defense = true; -// equipment = "RepairPack"; -// }; -// $ObjectiveQ[0].add(%newObjective); -// -// %newObjective = new AIObjective(AIODefendLocation) -// { -// weightLevel1 = $AIWeightDefendGenerator[1]; -// weightLevel2 = $AIWeightDefendGenerator[2]; -// description = "Defend our generator"; -// //targetObject = NameToId("Team0Generator"); -// location = "-20 -292 46"; -// offense = false; -// defense = true; -// }; -// $ObjectiveQ[0].add(%newObjective); -// %newObjective = new AIObjective(AIOEscortPlayer) -// { -// weightLevel1 = $AIWeightEscortOffense[1]; -// weightLevel2 = $AIWeightEscortOffense[2]; -// targetClientId = 2; -// description = "Escort " @ getTaggedString(LocalClientConnection.name); -// offense = true; -// desiredEquipment = "EnergyPack"; -// buyEquipmentSet = "LightEnergyELF"; -// }; -// $ObjectiveQ[1].add(%newObjective); - - /////////////////////////////// - // team 2 objectives // - /////////////////////////////// -// %newObjective = new AIObjective(AIODefendLocation) { -// position = "196 461 181"; -// rotation = "1 0 0 0"; -// scale = "1 1 1"; -// description = "Missile defense"; -// targetObject = ""; -// targetClientId = "-1"; -// targetObjectId = "-1"; -// location = "196 461 181"; -// weightLevel1 = "3900"; -// weightLevel2 = "2000"; -// weightLevel3 = "0"; -// weightLevel4 = "0"; -// offense = "0"; -// defense = "1"; -// equipment = "MissileLauncher"; -// buyEquipmentSet = "MediumMissileSet HeavyMissileSet"; -// chat = ""; -// issuedByHuman = "0"; -// issuingClientId = "-1"; -// forceClientId = "-1"; -// locked = "1"; -// radius = "0"; -// team = "0"; -// }; -// $ObjectiveQ[2].add(%newObjective); -// -// %newObjective = new AIObjective(AIOAttackLocation) -// { -// weightLevel1 = 12000; -// description = "Sniper"; -// location = "-164 381 134"; -// offense = true; -// defense = false; -// equipment = "SniperRifle EnergyPack"; -// buyEquipmentSet = "LightEnergySniper"; -// }; -// $ObjectiveQ[2].add(%newObjective); -} - -function aiGo(%count) -{ - %offense = true; - for (%i = 0; %i < %count; %i++) - { - aiConnect(friendly @ %i, 1, 0.5, %offense); - aiConnect(enemy @ %i, 2, 0.5, %offense); - %offense = !%offense; - } -} - -function addBots(%count) -{ - if(%count > 0) - { - %count++; - while(%count--) - aiConnect("dude " @ %count); - } -} - -function aiGoTest(%count, %team) -{ - if (%team <= 0) - %team = 1; - - %offense = false; - for (%i = 0; %i < %count; %i++) - { - if (%offense) - aiConnect(Offense @ %i, %team, 0.5, true); - else - aiConnect(Defense @ %i, %team, 0.5, false); - - %offense = !%offense; - } -} - -//------------------------------ - -function aiTest() -{ - //find/create an enemy - %count = ClientGroup.getCount(); - if (%count <= 1) - { - %enemyCl = aiConnect(test, 1, 0.5, false); - } - else - %enemyCl = ClientGroup.getObject(1); - - //create the objective - if (! $testObjective) - { - $testObjective = new AIObjective(AIOAttackPlayer) - { - weightLevel1 = 10000; - description = "Attack the human!"; - targetClient = nameToId(LocalClientConnection); - location = ""; - offense = true; - defense = true; - }; - MissionCleanup.add($testObjective); - } - - //set the enemy inventory - %enemyPl = %enemyCl.player; - %enemyPl.setInventory(RepairKit,1); - %enemyPl.setInventory(Grenade,5); - //%enemyPl.setInventory(Blaster,1); - //%enemyPl.setInventory(Plasma,1); - %enemyPl.setInventory(Disc,1); - %enemyPl.setInventory(Chaingun, 1); - %enemyPl.setInventory(GrenadeLauncher, 1); - //%enemyPl.setInventory(Mortar, 1); - %enemyPl.setInventory(ChaingunAmmo, 100); - %enemyPl.setInventory(DiscAmmo, 15); - %enemyPl.setInventory(PlasmaAmmo,20); - %enemyPl.setInventory(GrenadeLauncherAmmo, 10); - %enemyPl.setInventory(MortarAmmo, 10); - - %enemyPl.setDamageLevel(0.0); - - //set the target inventory - %targetCl = 2; - %targetPl = %targetCl.player; - %targetPl.setInventory(RepairKit,1); - %targetPl.setInventory(Grenade,5); - //%targetPl.setInventory(Blaster,1); - //%targetPl.setInventory(Plasma,1); - %targetPl.setInventory(Disc,1); - %targetPl.setInventory(Chaingun, 1); - %targetPl.setInventory(GrenadeLauncher, 1); - //%targetPl.setInventory(Mortar, 1); - %targetPl.setInventory(ChaingunAmmo, 100); - %targetPl.setInventory(DiscAmmo, 15); - %targetPl.setInventory(PlasmaAmmo,20); - %targetPl.setInventory(GrenadeLauncherAmmo, 10); - %targetPl.setInventory(MortarAmmo, 10); - %targetPl.setDamageLevel(0.0); - - //now force the attack objective - AIForceObjective(%enemyCl, $testObjective); - %enemyCl.stepEngage(2); -} - -function aibump() -{ - %t1 = "-348 -470 142 0 0 1 0"; - %t2 = "-347 -453 142 0 0 1 3.14"; - - %t3 = "-348 -462 142 0 0 1 0"; - 2.player.setTransform(%t3); - - 3.player.setTransform(%t1); - 4.player.setTransform(%t2); - - 3.stepMove(%t2, 0.1); - 4.stepMove(%t1, 0.1); -} - -function aibump2() -{ - %t1 = "-345.082 -464.229 142 0 0 1 0"; - %t2 = "-347 -453 142 0 0 1 3.14"; - %t3 = "-347.22 -463.439 142 0 0 1 1.89"; - 2.player.setTransform(%t3); - - 3.player.setTransform(%t1); - 3.stepMove(%t2, 0.1); -} - -function aiTestDeploys(%client, %objective) -{ - //if we're just starting the test, unassign the client - if (!isObject(%objective)) - { - error("DEBUG begin testing deploy objectives!"); - $AITestDeployObjective = -1; - aiUnassignClient(%client); - } - - //if the client isn't still on the test objective, choose the next one - if (%client.objective != $AITestDeployObjective) - { - //if there's a corresponding "repairObjective" for the deploy, then the deploy succeeded - if (isobject($AITestDeployObjective)) - { - if (!isObject($AITestDeployObjective.repairObjective)) - $AITestDeployObjective.isInvalid = true; - } - - //loop through all the objectives, looking for next deploy ones... - %foundCurrent = !isObject($AITestDeployObjective); - %nextObjective = -1; - %found = false; - %count = $ObjectiveQ[%client.team].getCount(); - for (%i = 0; %i < %count && !%found; %i++) - { - %obj = $ObjectiveQ[%client.team].getObject(%i); - - //see if the objective is a group... - if (%obj.getClassName() !$= "AIObjective") - { - %grpCount = %obj.getCount(); - for (%j = 0; %j < %grpCount && !%found; %j++) - { - %grpObj = %obj.getObject(%j); - if (%grpObj.getName() $= "AIODeployEquipment") - { - if (%foundCurrent) - { - %nextObjective = %grpObj; - %found = true; - } - else if (%grpObj == $AITestDeployObjective) - %foundCurrent = true; - } - } - } - else if (%obj.getName() $= "AIODeployEquipment") - { - //see if this is the next one - if (%foundCurrent) - { - %nextObjective = %obj; - %found = true; - } - else if (%obj == $AITestDeployObjective) - %foundCurrent = true; - } - } - - if (isObject(%nextObjective)) - { - //kill all the turrets for your team... - while (isObject($AIRemoteTurretSet.getObject(0))) - $AIRemoteTurretSet.getObject(0).delete(); - - //remove any associated repairobjective from this deploy - if (isObject(%nextObjective.repairObjective)) - { - AIClearObjective(%nextObjective.repairObjective); - %nextObjective.repairObjective.delete(); - %nextObjective.repairObjective = ""; - } - - //assign the bot to the objective... - error("DEBUG testing objective:" SPC %nextObjective); - $AITestDeployObjective = %nextObjective; - AIUnassignClient(%client); - AIForceObjective(%client, $AITestDeployObjective, 10000); - } - else - { - error("DEBUG testing of deploy objectives is complete:"); - %count = $ObjectiveQ[%client.team].getCount(); - for (%i = 0; %i < %count && !%found; %i++) - { - %obj = $ObjectiveQ[%client.team].getObject(%i); - - //see if the objective is a group... - if (%obj.getClassName() !$= "AIObjective") - { - %grpCount = %obj.getCount(); - for (%j = 0; %j < %grpCount && !%found; %j++) - { - %grpObj = %obj.getObject(%j); - if (%grpObj.getName() $= "AIODeployEquipment") - { - if (%grpObj.isInvalid) - error(%grpObj SPC "is invalid."); - else - error(%grpObj SPC "passed."); - } - } - } - else if (%obj.getName() $= "AIODeployEquipment") - { - if (%obj.isInvalid) - error(%obj SPC "is invalid."); - else - error(%obj SPC "passed."); - } - } - return; - } - } - - //schedule the next call to see if we're still deploying... - schedule(2000, %client.player, "aiTestDeploys", %client, $AITestDeployObjective); -} - -//----------------------------------------------------------------------------- -//AI test pilot task -$TestPilotHeadings[0] = "203 -59 120"; -$TestPilotHeadings[1] = "52 10 120"; -$TestPilotHeadings[2] = "-112 125 120"; -$TestPilotHeadings[3] = "-195 219 120"; -$TestPilotHeadings[4] = "-198 323 120"; -$TestPilotHeadings[5] = "-38 423 120"; -$TestPilotHeadings[6] = "84 445 120"; -$TestPilotHeadings[7] = "290 382 120"; -$TestPilotHeadings[8] = "385 259 120"; -$TestPilotHeadings[9] = "255 6 120"; -$TestPilotHeadings[10] = "219 -49 120"; -$TestPilotHeadings[11] = "222 -168 120"; - -function AITestPilot::assume(%task, %client) -{ - %task.setWeightFreq(30); - %task.setMonitorFreq(10); - - //first, make sure the pilot is in light, and doesn't have an backpacks... - %client.player.throwPack(); - %client.player.setArmor(Light); - - //next, start the pilot on his way to mounting the vehicle - %client.pilotVehicle = true; - %client.stepMove(%task.vehicle.position, 0.25, $AIModeMountVehicle); - - %task.locationIndex = -1; -} - -function AITestPilot::weight(%task, %client) -{ - %task.setWeight(10000); -} - -function AITestPilot::monitor(%task, %client) -{ - //see if we've mounted yet - if (%task.locationIndex == -1) - { - //mount the vehicle - %client.pilotVehicle = true; - %client.stepMove(%task.vehicle.position, 0.25, $AIModeMountVehicle); - - if (isObject(%client.vehicleMounted)) - { - %task.locationIndex++; - %client.setPilotDestination($TestPilotHeadings[%task.locationIndex]); - } - } - - //else see if we're close enough to the current destination to choose the next - else - { - %pos = %client.vehicleMounted.position; - %pos2D = getWord(%pos, 0) SPC getWord(%pos, 1) SPC "0"; - %dest = $TestPilotHeadings[%task.locationIndex]; - %dest2D = getWord(%dest, 0) SPC getWord(%dest, 1) SPC "0"; - - if (VectorDist(%dest2D, %pos2D) < 20) - { - if ($TestPilotHeadings[%task.locationIndex + 1] !$= "") - { - %task.locationIndex++; - %client.setPilotDestination($TestPilotHeadings[%task.locationIndex]); - } - else - %client.setPilotAim($TestPilotHeadings[0]); - } - } -} - -function testPilot(%client, %vehicle) -{ - %client.clearTasks(); - - if (%vehicle $= "") - %vehicle = LocalClientConnection.vehicleMounted; - - %client.pilotTask = %client.addTask(AITestPilot); - %client.pilotTask.vehicle = %vehicle; -} - +//------------------------------ +//AI Debugging functions + +function aics() +{ + aidebug(-1); + exec("scripts/ai.cs"); +} + +function ga(%pack) +{ + $testcheats = 1; + giveall(); + switch$ (%pack) + { + case "repair": + LocalClientConnection.player.setInventory(RepairPack, 1); + case "charge": + LocalClientConnection.player.setInventory(SatchelCharge, 1); + case "energy": + LocalClientConnection.player.setInventory(EnergyPack, 1); + case "cloak": + LocalClientConnection.player.setInventory(CloakingPack, 1); + case "shield": + LocalClientConnection.player.setInventory(ShieldPack, 1); + case "jammer": + LocalClientConnection.player.setInventory(SensorJammerPack, 1); + } +} + +function aiga(%client) +{ + $TestCheats = 1; + %player = %client.player; + %player.setInventory(RepairKit,999); + %player.setInventory(Mine,999); + %player.setInventory(MineAir,999); + %player.setInventory(MineLand,999); + %player.setInventory(MineSticky,999); + %player.setInventory(Grenade,999); + %player.setInventory(FlashGrenade,999); + %player.setInventory(FlareGrenade,999); + %player.setInventory(ConcussionGrenade,999); + %player.setInventory(CameraGrenade, 999); + %player.setInventory(Blaster,1); + %player.setInventory(Plasma,1); + %player.setInventory(Disc,1); + %player.setInventory(Chaingun, 1); + %player.setInventory(GrenadeLauncher, 1); + %player.setInventory(MissileLauncher, 1); + %player.setInventory(Mortar, 1); + %player.setInventory(MissileLauncherAmmo, 999); + %player.setInventory(GrenadeLauncherAmmo, 999); + %player.setInventory(MortarAmmo, 999); + %player.setInventory(PlasmaAmmo,999); + %player.setInventory(ChaingunAmmo, 999); + %player.setInventory(DiscAmmo, 999); + %player.setInventory(TargetingLaser, 1); + %player.setInventory(ELFGun, 1); + %player.setInventory(SniperRifle, 1); + %player.setInventory(ShockLance, 1); +} + +function aiCome(%from, %to) +{ + if (%to $= "") + %to = 2; + %from.player.setTransform(%to.player.getTransform()); +} + +function findBotWithInv(%item) +{ + for (%i = 0; %i < ClientGroup.getCount(); %i++) + { + %cl = ClientGroup.getObject(%i); + if (isObject(%cl.player) && %cl.player.getInventory(%item)) + echo(%cl @ ":" SPC getTaggedString(%cl.name) SPC "has item" SPC %item); + } +} + +function listInv(%client) +{ + %player = %client.player; + %count = %player.getInventory(RepairKit); + if (%count > 0) + echo("RepairKit: " @ %count); + %count = %player.getInventory(Mine); + if (%count > 0) + echo("Mine: " @ %count); + %count = %player.getInventory(MineAir); + if (%count > 0) + echo("MineAir: " @ %count); + %count = %player.getInventory(MineLand); + if (%count > 0) + echo("MineLand: " @ %count); + %count = %player.getInventory(MineSticky); + if (%count > 0) + echo("MineSticky: " @ %count); + %count = %player.getInventory(Grenade); + if (%count > 0) + echo("Grenade: " @ %count); + %count = %player.getInventory(FlashGrenade); + if (%count > 0) + echo("FlashGrenade: " @ %count); + %count = %player.getInventory(FlareGrenade); + if (%count > 0) + echo("FlareGrenade: " @ %count); + %count = %player.getInventory(ConcussionGrenade); + if (%count > 0) + echo("ConcussionGrenade: " @ %count); + %count = %player.getInventory(CameraGrenade); + if (%count > 0) + echo("CameraGrenade: " @ %count); + %count = %player.getInventory(Blaster); + if (%count > 0) + echo("Blaster: " @ %count); + %count = %player.getInventory(Plasma); + if (%count > 0) + echo("Plasma: " @ %count); + %count = %player.getInventory(Disc); + if (%count > 0) + echo("Disc: " @ %count); + %count = %player.getInventory(Chaingun); + if (%count > 0) + echo("Chaingun: " @ %count); + %count = %player.getInventory(GrenadeLauncher); + if (%count > 0) + echo("GrenadeLauncher: " @ %count); + %count = %player.getInventory(MissileLauncher); + if (%count > 0) + echo("MissileLauncher: " @ %count); + %count = %player.getInventory(Mortar); + if (%count > 0) + echo("Mortar: " @ %count); + %count = %player.getInventory(MissileLauncherAmmo); + if (%count > 0) + echo("MissileLauncherAmmo: " @ %count); + %count = %player.getInventory(GrenadeLauncherAmmo); + if (%count > 0) + echo("GrenadeLauncherAmmo: " @ %count); + %count = %player.getInventory(MortarAmmo); + if (%count > 0) + echo("MortarAmmo: " @ %count); + %count = %player.getInventory(PlasmaAmmo); + if (%count > 0) + echo("PlasmaAmmo: " @ %count); + %count = %player.getInventory(ChaingunAmmo); + if (%count > 0) + echo("ChaingunAmmo: " @ %count); + %count = %player.getInventory(DiscAmmo); + if (%count > 0) + echo("DiscAmmo: " @ %count); + %count = %player.getInventory(TargetingLaser); + if (%count > 0) + echo("TargetingLaser: " @ %count); + %count = %player.getInventory(ELFGun); + if (%count > 0) + echo("ELFGun: " @ %count); + %count = %player.getInventory(SniperRifle); + if (%count > 0) + echo("SniperRifle: " @ %count); + %count = %player.getInventory(ShockLance); + if (%count > 0) + echo("ShockLance: " @ %count); + %count = %player.getInventory(RepairPack); + if (%count > 0) + echo("RepairPack: " @ %count); + %count = %player.getInventory(EnergyPack); + if (%count > 0) + echo("EnergyPack: " @ %count); + %count = %player.getInventory(ShieldPack); + if (%count > 0) + echo("ShieldPack: " @ %count); + %count = %player.getInventory(CloakingPack); + if (%count > 0) + echo("CloakingPack: " @ %count); + %count = %player.getInventory(SensorJammerPack); + if (%count > 0) + echo("SensorJammerPack: " @ %count); +} + +function createAIDebugDlg() +{ + if (!isObject("AIDebugViewProfile")) + { + new GuiControlProfile("AIDebugViewProfile") + { + fontType = "Arial Bold"; + fontSize = 12; + fontColor = "255 0 255"; + autoSizeWidth = false; + autoSizeHeight = false; + modal = "false"; + }; + + new GuiControl(aiDebugDlg) + { + profile = "GuiDefaultProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "True"; + helpTag = "0"; + bypassHideCursor = "1"; + + new DebugView(aiDebug) + { + profile = "AIDebugViewProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "8 8"; + extent = "624 464"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + helpTag = "0"; + }; + }; + } +} + +function ToggleAIDebug(%make) +{ + if (%make) + { + if ($AIDebugActive) + { + Canvas.popDialog(aiDebugDlg); + $AIDebugActive = false; + } + else + { + createAIDebugDlg(); + Canvas.pushDialog(aiDebugDlg, 70); + $AIDebugActive = true; + + //make sure we're debuging the correct client + if (LocalClientConnection.getControlObject() == LocalClientConnection.camera) + { + if (isObject(LocalClientConnection.observeClient)) + aidebug(LocalClientConnection.observeClient); + } + } + } +} + +GlobalActionMap.bind(keyboard, "ctrl tilde", "ToggleAIDebug"); + +//function showFPS() +//{ +// if (isObject(aiDebug)) +// aiDebug.setText(0, "FPS:" SPC $fps::real SPC " $patch1Avg" SPC $Patch1Avg); +// schedule(1000, 0, "ShowFPS"); +//} + +function aiDebug(%client) +{ + if ($AIDebugTeam < 0 && $AIDebugClient < 0) + { + createAIDebugDlg(); + Canvas.pushDialog(aiDebugDlg, 70); + } + + $AIDebugClient = %client; + $AIDebugTeam = -1; + + if (%client > 0) + { + createAIDebugDlg(); + Canvas.pushDialog(aiDebugDlg, 70); + aiDebug.clearText(); + $AIDebugActive = true; + } + else + { + $AIDebugActive = false; + Canvas.popDialog(aiDebugDlg); + } +} + +function aiDebugText(%client, %line, %text) +{ + if (%client != $AIDebugClient) + return; + + aiDebug.setText(%line, %text); +} + +function aiDebugLine(%client, %startPt, %endPt, %color) +{ + if (%client != $AIDebugClient) + return; + + aiDebug.addLine(%startPt, %endPt, %color); +} + +function aiDebugClearLines(%client) +{ + if (%client != $AIDebugClient) + return; + + aiDebug.clearLines(); +} + +function aiGetTaskDesc(%client) +{ + if (!%client.isAIControlled()) + %returnStr = getTaggedString(%client.name) @ ": " @ "HUMAN"; + + else if (%client.objective > 0) + { + if (%client.objective.description !$= "") + %returnStr = %client @ " " @ getTaggedString(%client.name) @ ": " @ %client.objective.description; + else + %returnStr = %client @ " " @ getTaggedString(%client.name) @ ": " @ %client.objective @ " NO DESC"; + } + else + { + %curTask = %client.getTaskName(); + %curStep = %client.getStepName(); + if (%curTask !$= "") + %returnStr = %client @ " " @ getTaggedString(%client.name) @ ": " @ %curTask; + else if (%curStep !$= "") + %returnStr = %client @ " " @ getTaggedString(%client.name) @ ": " @ %curStep; + else + %returnStr = getTaggedString(%client.name) @ ": " @ "UNKNOWN"; + } + + //add in some color info + if (Game.numTeams != 2) + %color = "E"; + else if (%client.team == LocalClientConnection.team) + %color = "F"; + else + %color = "E"; + + return %color @ ":" @ %returnStr; +} + +$AIDebugTeam = -1; +$AIDebugClient = -1; +$AIDebugTasks = true; +Canvas.popDialog(aiDebugDlg); +$AIDebugActive = false; + +function aiEchoObjective(%objective, %lineNum, %group) +{ + %clientAssigned = false; + %indent = " "; + if (%group > 0) + { + %indent = " "; + if (%group.clientLevel[1] > 0 && %group.clientLevel[1].objective == %objective) + { + %assigned1 = getTaggedString(%group.clientLevel[1].name) @ ":" @ %group.clientLevel[1].objectiveWeight; + %clientAssigned = true; + } + else + %assigned1 = " "; + if (%group.clientLevel[2] > 0 && %group.clientLevel[2].objective == %objective) + { + %assigned2 = getTaggedString(%group.clientLevel[2].name); + %clientAssigned = true; + } + else + %assigned2 = " "; + } + else + { + if (%objective.clientLevel[1] > 0) + { + %assigned1 = getTaggedString(%objective.clientLevel[1].name) @ ":" @ %objective.clientLevel[1].objectiveWeight; + %clientAssigned = true; + } + else + %assigned1 = " "; + if (%objective.clientLevel[2] > 0) + { + %assigned2 = getTaggedString(%objective.clientLevel[2].name); + %clientAssigned = true; + } + else + %assigned2 = " "; + } + + %text = %indent @ %objective @ " " @ %objective.weightLevel1 @ " " @ %assigned1 @ " " @ %assigned2 @ " " @ %objective.description; + if (%clientAssigned) + %color = "0 0 1"; + else + %color = "1 0 1"; + aiDebug.setText(%lineNum, %text, %color); +} + +function aiDebugQ(%team, %showTasks) +{ + if ($AIDebugTeam < 0 && $AIDebugClient < 0) + { + createAIDebugDlg(); + Canvas.pushDialog(aiDebugDlg, 70); + $AIDebugActive = true; + } + + $AIDebugTeam = %team; + $AIDebugClient = -1; + + if ($AIDebugTeam < 0) + { + Canvas.popDialog(aiDebugDlg); + $AIDebugActive = false; + return; + } + + if (%showTasks $= "") + %showTasks = $AIDebugTasks; + else + $AIDebugTasks = %showTasks; + + aiDebug.clearText(); + + if (! %showTasks) + return; + + //make sure we have a valid objectiveQ + if (!isObject($ObjectiveQ[%team])) + return; + + %timeStamp = getSimTime(); + %lineNum = 1; + %count = $ObjectiveQ[%team].getCount(); + + //clear the time stamps from all groups + for (%i = 0; %i < %count; %i++) + { + %objective = $ObjectiveQ[%team].getObject(%i); + if (%objective.group > 0) + %objective.group.debugStamp = 0; + } + + //now loop through and echo out all the objectives... + for (%i = 0; %i < %count; %i++) + { + %objective = $ObjectiveQ[%team].getObject(%i); + + //if the objective is part of a group, echo out the entire group first + if (%objective.group > 0) + { + %group = %objective.group; + if (%group.debugStamp != %timeStamp) + { + %group.debugStamp = %timeStamp; + %grpCount = %group.getCount(); + + //first print out the group label + %text = %group @ " GROUP: " @ %group.getName(); + aiDebug.setText(%lineNum, %text); + %lineNum++; + + //now loop through and print out the grouped objectives in the order they appear in the main list + for (%j = 0; %j < %count; %j++) + { + //print them in the order they appear in the main list + %obj = $ObjectiveQ[%team].getObject(%j); + if (%obj.group == %group) + { + aiEchoObjective(%obj, %lineNum, %group); + %lineNum++; + } + } + } + } + + else + { + aiEchoObjective(%objective, %lineNum, 0); + %lineNum++; + } + } +} + +//------------------------------ + +function aioTest() +{ + //clear out the objective Q's + $ObjectiveQ[0].clear(); + $ObjectiveQ[1].clear(); + $ObjectiveQ[2].clear(); + + /////////////////////////////// + // team 1 objectives // + /////////////////////////////// +// %newObjective = new AIObjective(AIORepairObject) { +// position = "0 0 0"; +// rotation = "1 0 0 0"; +// scale = "1 1 1"; +// description = "Repair the generator"; +// targetObject = "Team0GeneratorLarge1"; +// targetClientId = "-1"; +// targetObjectId = nameToId("Team0GeneratorLarge1"); +// location = "0 0 0"; +// weightLevel1 = "3200"; +// weightLevel2 = "1600"; +// weightLevel3 = "0"; +// weightLevel4 = "0"; +// offense = "0"; +// defense = "1"; +// equipment = "RepairPack"; +// buyEquipmentSet = "HeavyRepairSet"; +// issuedByHuman = "0"; +// issuingClientId = "-1"; +// forceClientId = "-1"; +// locked = "0"; +// }; +// $ObjectiveQ[0].add(%newObjective); +// +// %newObjective = new AIObjective(AIODefendLocation) { +// position = "-178 -156 120"; +// rotation = "1 0 0 0"; +// scale = "1 1 1"; +// description = "Defend our generator"; +// targetObject = "Team0GeneratorLarge1"; +// targetClientId = "-1"; +// targetObjectId = "-1"; +// location = "-178 -156 120"; +// weightLevel1 = "3900"; +// weightLevel2 = "2000"; +// weightLevel3 = "0"; +// weightLevel4 = "0"; +// offense = "0"; +// defense = "1"; +// desiredEquipment = "ShieldPack Plasma PlasmaAmmo"; +// buyEquipmentSet = "MediumShieldSet LightShieldSet HeavyShieldSet"; +// chat = ""; +// issuedByHuman = "0"; +// issuingClientId = "-1"; +// forceClientId = "-1"; +// locked = "1"; +// radius = "0"; +// team = "0"; +// }; +// $ObjectiveQ[0].add(%newObjective); + +// %newObjective = new AIObjective(AIODefendLocation) { +// position = "0 0 0"; +// rotation = "1 0 0 0"; +// scale = "1 1 1"; +// description = "Defend the generator"; +// targetObject = "Team0GeneratorLarge1"; +// targetClientId = "-1"; +// targetObjectId = nameToId("Team0GeneratorLarge1"); +// location = "0 0 0"; +// weightLevel1 = "3100"; +// weightLevel2 = "1500"; +// weightLevel3 = "0"; +// weightLevel4 = "0"; +// offense = "0"; +// defense = "1"; +// desiredEquipment = "ShieldPack Plasma PlasmaAmmo"; +// buyEquipmentSet = "HeavyShieldSet"; +// issuedByHuman = "0"; +// issuingClientId = "-1"; +// forceClientId = "-1"; +// locked = "0"; +// }; +// $ObjectiveQ[0].add(%newObjective); +// +// %newObjective = new AIObjective(AIOAttackLocation) +// { +// weightLevel1 = 2000; +// description = "Sniper"; +// location = "50 218 95"; +// offense = true; +// defense = false; +// equipment = "SniperRifle EnergyPack"; +// buyEquipmentSet = "LightEnergySniper"; +// }; +// $ObjectiveQ[0].add(%newObjective); +// +// %newObjective = new AIObjective(AIOLazeObject) +// { +// weightLevel1 = 10000; +// description = "Laze the enemy turret"; +// targetObject = NameToId("Team1Turret"); +// targetClient = %client; //note, used to store the task requester +// offense = true; +// equipment = "TargetingLaser"; +// buyEquipmentSet = "LightEnergySniper"; +// }; +// $ObjectiveQ[0].add(%newObjective); +// +// %newObjective = new AIObjective(AIOMortarObject) +// { +// weightLevel1 = $AIWeightMortarTurret[1]; +// weightLevel2 = $AIWeightMortarTurret[2]; +// description = "Mortar the enemy turret"; +// targetObject = "Team1TurretBaseLarge1"; +// targetObjectId = nameToId("Team1TurretBaseLarge1"); +// location = ""; +// offense = true; +// defense = false; +// equipment = "Mortar MortarAmmo"; +// buyEquipmentSet = "HeavyShieldSet"; +// }; +// $ObjectiveQ[0].add(%newObjective); +// +// %newObjective = new AIObjective(AIORepairObject) +// { +// weightLevel1 = $AIWeightRepairTurret[1]; +// weightLevel2 = $AIWeightRepairTurret[2]; +// description = "Repair the turret"; +// targetObject = NameToId("Team0Turret"); +// location = ""; +// offense = false; +// defense = true; +// equipment = "RepairPack"; +// }; +// $ObjectiveQ[0].add(%newObjective); +// +// %newObjective = new AIObjective(AIOAttackObject) +// { +// weightLevel1 = $AIWeightAttackGenerator[1]; +// weightLevel2 = $AIWeightAttackGenerator[2]; +// description = "Attack the enemy generator"; +// targetObject = NameToId("Team1Generator"); +// location = ""; +// offense = true; +// defense = false; +// equipment = "plasma plasmaAmmo"; +// buyEquipmentSet = "HeavyShieldSet"; +// }; +// $ObjectiveQ[0].add(%newObjective); +// +// %newObjective = new AIObjective(AIORepairObject) +// { +// //weightLevel1 = $AIWeightRepairGenerator[1]; +// weightLevel1 = 10000; +// weightLevel2 = $AIWeightRepairGenerator[2]; +// description = "Repair the generator"; +// targetObject = NameToId("Team0Generator"); +// location = ""; +// offense = false; +// defense = true; +// equipment = "RepairPack"; +// }; +// $ObjectiveQ[0].add(%newObjective); +// +// %newObjective = new AIObjective(AIODefendLocation) +// { +// weightLevel1 = $AIWeightDefendGenerator[1]; +// weightLevel2 = $AIWeightDefendGenerator[2]; +// description = "Defend our generator"; +// //targetObject = NameToId("Team0Generator"); +// location = "-20 -292 46"; +// offense = false; +// defense = true; +// }; +// $ObjectiveQ[0].add(%newObjective); +// %newObjective = new AIObjective(AIOEscortPlayer) +// { +// weightLevel1 = $AIWeightEscortOffense[1]; +// weightLevel2 = $AIWeightEscortOffense[2]; +// targetClientId = 2; +// description = "Escort " @ getTaggedString(LocalClientConnection.name); +// offense = true; +// desiredEquipment = "EnergyPack"; +// buyEquipmentSet = "LightEnergyELF"; +// }; +// $ObjectiveQ[1].add(%newObjective); + + /////////////////////////////// + // team 2 objectives // + /////////////////////////////// +// %newObjective = new AIObjective(AIODefendLocation) { +// position = "196 461 181"; +// rotation = "1 0 0 0"; +// scale = "1 1 1"; +// description = "Missile defense"; +// targetObject = ""; +// targetClientId = "-1"; +// targetObjectId = "-1"; +// location = "196 461 181"; +// weightLevel1 = "3900"; +// weightLevel2 = "2000"; +// weightLevel3 = "0"; +// weightLevel4 = "0"; +// offense = "0"; +// defense = "1"; +// equipment = "MissileLauncher"; +// buyEquipmentSet = "MediumMissileSet HeavyMissileSet"; +// chat = ""; +// issuedByHuman = "0"; +// issuingClientId = "-1"; +// forceClientId = "-1"; +// locked = "1"; +// radius = "0"; +// team = "0"; +// }; +// $ObjectiveQ[2].add(%newObjective); +// +// %newObjective = new AIObjective(AIOAttackLocation) +// { +// weightLevel1 = 12000; +// description = "Sniper"; +// location = "-164 381 134"; +// offense = true; +// defense = false; +// equipment = "SniperRifle EnergyPack"; +// buyEquipmentSet = "LightEnergySniper"; +// }; +// $ObjectiveQ[2].add(%newObjective); +} + +function aiGo(%count) +{ + %offense = true; + for (%i = 0; %i < %count; %i++) + { + aiConnect(friendly @ %i, 1, 0.5, %offense); + aiConnect(enemy @ %i, 2, 0.5, %offense); + %offense = !%offense; + } +} + +function addBots(%count) +{ + if(%count > 0) + { + %count++; + while(%count--) + aiConnect("dude " @ %count); + } +} + +function aiGoTest(%count, %team) +{ + if (%team <= 0) + %team = 1; + + %offense = false; + for (%i = 0; %i < %count; %i++) + { + if (%offense) + aiConnect(Offense @ %i, %team, 0.5, true); + else + aiConnect(Defense @ %i, %team, 0.5, false); + + %offense = !%offense; + } +} + +//------------------------------ + +function aiTest() +{ + //find/create an enemy + %count = ClientGroup.getCount(); + if (%count <= 1) + { + %enemyCl = aiConnect(test, 1, 0.5, false); + } + else + %enemyCl = ClientGroup.getObject(1); + + //create the objective + if (! $testObjective) + { + $testObjective = new AIObjective(AIOAttackPlayer) + { + weightLevel1 = 10000; + description = "Attack the human!"; + targetClient = nameToId(LocalClientConnection); + location = ""; + offense = true; + defense = true; + }; + MissionCleanup.add($testObjective); + } + + //set the enemy inventory + %enemyPl = %enemyCl.player; + %enemyPl.setInventory(RepairKit,1); + %enemyPl.setInventory(Grenade,5); + //%enemyPl.setInventory(Blaster,1); + //%enemyPl.setInventory(Plasma,1); + %enemyPl.setInventory(Disc,1); + %enemyPl.setInventory(Chaingun, 1); + %enemyPl.setInventory(GrenadeLauncher, 1); + //%enemyPl.setInventory(Mortar, 1); + %enemyPl.setInventory(ChaingunAmmo, 100); + %enemyPl.setInventory(DiscAmmo, 15); + %enemyPl.setInventory(PlasmaAmmo,20); + %enemyPl.setInventory(GrenadeLauncherAmmo, 10); + %enemyPl.setInventory(MortarAmmo, 10); + + %enemyPl.setDamageLevel(0.0); + + //set the target inventory + %targetCl = 2; + %targetPl = %targetCl.player; + %targetPl.setInventory(RepairKit,1); + %targetPl.setInventory(Grenade,5); + //%targetPl.setInventory(Blaster,1); + //%targetPl.setInventory(Plasma,1); + %targetPl.setInventory(Disc,1); + %targetPl.setInventory(Chaingun, 1); + %targetPl.setInventory(GrenadeLauncher, 1); + //%targetPl.setInventory(Mortar, 1); + %targetPl.setInventory(ChaingunAmmo, 100); + %targetPl.setInventory(DiscAmmo, 15); + %targetPl.setInventory(PlasmaAmmo,20); + %targetPl.setInventory(GrenadeLauncherAmmo, 10); + %targetPl.setInventory(MortarAmmo, 10); + %targetPl.setDamageLevel(0.0); + + //now force the attack objective + AIForceObjective(%enemyCl, $testObjective); + %enemyCl.stepEngage(2); +} + +function aibump() +{ + %t1 = "-348 -470 142 0 0 1 0"; + %t2 = "-347 -453 142 0 0 1 3.14"; + + %t3 = "-348 -462 142 0 0 1 0"; + 2.player.setTransform(%t3); + + 3.player.setTransform(%t1); + 4.player.setTransform(%t2); + + 3.stepMove(%t2, 0.1); + 4.stepMove(%t1, 0.1); +} + +function aibump2() +{ + %t1 = "-345.082 -464.229 142 0 0 1 0"; + %t2 = "-347 -453 142 0 0 1 3.14"; + %t3 = "-347.22 -463.439 142 0 0 1 1.89"; + 2.player.setTransform(%t3); + + 3.player.setTransform(%t1); + 3.stepMove(%t2, 0.1); +} + +function aiTestDeploys(%client, %objective) +{ + //if we're just starting the test, unassign the client + if (!isObject(%objective)) + { + error("DEBUG begin testing deploy objectives!"); + $AITestDeployObjective = -1; + aiUnassignClient(%client); + } + + //if the client isn't still on the test objective, choose the next one + if (%client.objective != $AITestDeployObjective) + { + //if there's a corresponding "repairObjective" for the deploy, then the deploy succeeded + if (isobject($AITestDeployObjective)) + { + if (!isObject($AITestDeployObjective.repairObjective)) + $AITestDeployObjective.isInvalid = true; + } + + //loop through all the objectives, looking for next deploy ones... + %foundCurrent = !isObject($AITestDeployObjective); + %nextObjective = -1; + %found = false; + %count = $ObjectiveQ[%client.team].getCount(); + for (%i = 0; %i < %count && !%found; %i++) + { + %obj = $ObjectiveQ[%client.team].getObject(%i); + + //see if the objective is a group... + if (%obj.getClassName() !$= "AIObjective") + { + %grpCount = %obj.getCount(); + for (%j = 0; %j < %grpCount && !%found; %j++) + { + %grpObj = %obj.getObject(%j); + if (%grpObj.getName() $= "AIODeployEquipment") + { + if (%foundCurrent) + { + %nextObjective = %grpObj; + %found = true; + } + else if (%grpObj == $AITestDeployObjective) + %foundCurrent = true; + } + } + } + else if (%obj.getName() $= "AIODeployEquipment") + { + //see if this is the next one + if (%foundCurrent) + { + %nextObjective = %obj; + %found = true; + } + else if (%obj == $AITestDeployObjective) + %foundCurrent = true; + } + } + + if (isObject(%nextObjective)) + { + //kill all the turrets for your team... + while (isObject($AIRemoteTurretSet.getObject(0))) + $AIRemoteTurretSet.getObject(0).delete(); + + //remove any associated repairobjective from this deploy + if (isObject(%nextObjective.repairObjective)) + { + AIClearObjective(%nextObjective.repairObjective); + %nextObjective.repairObjective.delete(); + %nextObjective.repairObjective = ""; + } + + //assign the bot to the objective... + error("DEBUG testing objective:" SPC %nextObjective); + $AITestDeployObjective = %nextObjective; + AIUnassignClient(%client); + AIForceObjective(%client, $AITestDeployObjective, 10000); + } + else + { + error("DEBUG testing of deploy objectives is complete:"); + %count = $ObjectiveQ[%client.team].getCount(); + for (%i = 0; %i < %count && !%found; %i++) + { + %obj = $ObjectiveQ[%client.team].getObject(%i); + + //see if the objective is a group... + if (%obj.getClassName() !$= "AIObjective") + { + %grpCount = %obj.getCount(); + for (%j = 0; %j < %grpCount && !%found; %j++) + { + %grpObj = %obj.getObject(%j); + if (%grpObj.getName() $= "AIODeployEquipment") + { + if (%grpObj.isInvalid) + error(%grpObj SPC "is invalid."); + else + error(%grpObj SPC "passed."); + } + } + } + else if (%obj.getName() $= "AIODeployEquipment") + { + if (%obj.isInvalid) + error(%obj SPC "is invalid."); + else + error(%obj SPC "passed."); + } + } + return; + } + } + + //schedule the next call to see if we're still deploying... + schedule(2000, %client.player, "aiTestDeploys", %client, $AITestDeployObjective); +} + +//----------------------------------------------------------------------------- +//AI test pilot task +$TestPilotHeadings[0] = "203 -59 120"; +$TestPilotHeadings[1] = "52 10 120"; +$TestPilotHeadings[2] = "-112 125 120"; +$TestPilotHeadings[3] = "-195 219 120"; +$TestPilotHeadings[4] = "-198 323 120"; +$TestPilotHeadings[5] = "-38 423 120"; +$TestPilotHeadings[6] = "84 445 120"; +$TestPilotHeadings[7] = "290 382 120"; +$TestPilotHeadings[8] = "385 259 120"; +$TestPilotHeadings[9] = "255 6 120"; +$TestPilotHeadings[10] = "219 -49 120"; +$TestPilotHeadings[11] = "222 -168 120"; + +function AITestPilot::assume(%task, %client) +{ + %task.setWeightFreq(30); + %task.setMonitorFreq(10); + + //first, make sure the pilot is in light, and doesn't have an backpacks... + %client.player.throwPack(); + %client.player.setArmor(Light); + + //next, start the pilot on his way to mounting the vehicle + %client.pilotVehicle = true; + %client.stepMove(%task.vehicle.position, 0.25, $AIModeMountVehicle); + + %task.locationIndex = -1; +} + +function AITestPilot::weight(%task, %client) +{ + %task.setWeight(10000); +} + +function AITestPilot::monitor(%task, %client) +{ + //see if we've mounted yet + if (%task.locationIndex == -1) + { + //mount the vehicle + %client.pilotVehicle = true; + %client.stepMove(%task.vehicle.position, 0.25, $AIModeMountVehicle); + + if (isObject(%client.vehicleMounted)) + { + %task.locationIndex++; + %client.setPilotDestination($TestPilotHeadings[%task.locationIndex]); + } + } + + //else see if we're close enough to the current destination to choose the next + else + { + %pos = %client.vehicleMounted.position; + %pos2D = getWord(%pos, 0) SPC getWord(%pos, 1) SPC "0"; + %dest = $TestPilotHeadings[%task.locationIndex]; + %dest2D = getWord(%dest, 0) SPC getWord(%dest, 1) SPC "0"; + + if (VectorDist(%dest2D, %pos2D) < 20) + { + if ($TestPilotHeadings[%task.locationIndex + 1] !$= "") + { + %task.locationIndex++; + %client.setPilotDestination($TestPilotHeadings[%task.locationIndex]); + } + else + %client.setPilotAim($TestPilotHeadings[0]); + } + } +} + +function testPilot(%client, %vehicle) +{ + %client.clearTasks(); + + if (%vehicle $= "") + %vehicle = LocalClientConnection.vehicleMounted; + + %client.pilotTask = %client.addTask(AITestPilot); + %client.pilotTask.vehicle = %vehicle; +} + diff --git a/scripts/aiInventory.cs b/scripts/aiInventory.cs index 7cce6c4..010e76c 100644 --- a/scripts/aiInventory.cs +++ b/scripts/aiInventory.cs @@ -1,1475 +1,1475 @@ -//------------------------------ -//AI Inventory functions - -function AINeedEquipment(%equipmentList, %client) -{ - %index = 0; - %item = getWord(%equipmentList, %index); - - //first, see if we're testing the armor class as well... - if (%item $= "Heavy" || %item $= "Medium" || %item $= "Light") - { - if (%client.player.getArmorSize() !$= %item) - return true; - %index++; - %item = getWord(%equipmentList, %index); - } - - while (%item !$= "") - { - if (%client.player.getInventory(%item) == 0) - return true; - - //get the next item - %index++; - %item = getWord(%equipmentList, %index); - } - - //made it through the list without needing anything - return false; -} - -function AIBuyInventory(%client, %requiredEquipment, %equipmentSets, %buyInvTime) -{ - //make sure we have a live player - %player = %client.player; - if (!isObject(%player)) - return "Failed"; - - if (! AIClientIsAlive(%client)) - return "Failed"; - - //see if we've already initialized our state machine - if (%client.buyInvTime == %buyInvTime) - return AIProcessBuyInventory(%client); - - //if the closest inv station is not a remote, buy the first available set... - %result = AIFindClosestInventory(%client, false); - %closestInv = getWord(%result, 0); - %closestDist = getWord(%result, 1); - if (%closestInv <= 0) - return "Failed"; - - //see if the closest inv station was a remote - %buyingSet = false; - %usingRemote = false; - if (%closestInv.getDataBlock().getName() $= "DeployedStationInventory") - { - //see if we can buy at least the required equipment from the set - if (%requiredEquipment !$= "") - { - if (! AIMustUseRegularInvStation(%requiredEquipment, %client)) - %canUseRemote = true; - else - %canUseRemote = false; - } - else - { - %inventorySet = AIFindSameArmorEquipSet(%equipmentSets, %client); - if (%inventorySet !$= "") - %canUseRemote = true; - else - %canUseRemote = false; - } - - //if we can't use a remote, we need to look for a regular inv station - if (! %canUseRemote) - { - %result = AIFindClosestInventory(%client, true); - %closestInv = getWord(%result, 0); - %closestDist = getWord(%result, 1); - if (%closestInv <= 0) - return "Failed"; - } - else - %usingRemote = true; - } - - //at this point we've found the closest inv, see which set/list we need to buy - if (!%usingRemote) - { - //choose the equipment first equipment set - if (%equipmentSets !$= "") - { - %inventorySet = getWord(%equipmentSets, 0); - %buyingSet = true; - } - else - { - %inventorySet = %requiredEquipment; - %buyingSet = false; - } - } - else - { - %inventorySet = AIFindSameArmorEquipSet(%equipmentSets, %client); - if (%inventorySet $= "") - { - %inventorySet = %requiredEquipment; - %buyingSet = false; - } - else - %buyingSet = true; - } - - //init some vars for the state machine... - %client.buyInvTime = %buyInvTime; //used to mark the begining of the inv buy session - %client.invToUse = %closestInv; //used if we need to go to an alternate inv station - %client.invWaitTime = ""; //used to track how long we've been waiting - %client.invBuyList = %inventorySet; //the list/set of items we're going to buy... - %client.buyingSet = %buyingSet; //whether it's a list or a set... - %client.isSeekingInv = false; - %client.seekingInv = ""; - - //now process the state machine - return AIProcessBuyInventory(%client); -} - -function AIProcessBuyInventory(%client) -{ - //get some vars - %player = %client.player; - if (!isObject(%player)) - return "Failed"; - - %closestInv = %client.invToUse; - %inventorySet = %client.invBuyList; - %buyingSet = %client.buyingSet; - - //make sure it's still valid, enabled, and on our team - if (! (%closestInv > 0 && isObject(%closestInv) && - (%closestInv.team <= 0 || %closestInv.team == %client.team) && %closestInv.isEnabled())) - { - //reset the state machine - %client.buyInvTime = 0; - return "InProgress"; - } - - //make sure the inventory station is not blocked - %invLocation = %closestInv.getWorldBoxCenter(); - InitContainerRadiusSearch(%invLocation, 2, $TypeMasks::PlayerObjectType); - %objSrch = containerSearchNext(); - if (%objSrch == %client.player) - %objSrch = containerSearchNext(); - - //the closestInv is busy... - if (%objSrch > 0) - { - //have the AI range the inv - if (%client.seekingInv $= "" || %client.seekingInv != %closestInv) - { - %client.invWaitTime = ""; - %client.seekingInv = %closestInv; - %client.stepRangeObject(%closestInv, "DefaultRepairBeam", 5, 10); - } - - //inv is still busy - see if we're within range - else if (%client.getStepStatus() $= "Finished") - { - //initialize the wait time - if (%client.invWaitTime $= "") - %client.invWaitTime = getSimTime() + 5000 + (getRandom() * 10000); - - //else see if we've waited long enough - else if (getSimTime() > %client.invWaitTime) - { - schedule(250, %client, "AIPlayAnimSound", %client, %objSrch.getWorldBoxCenter(), "vqk.move", -1, -1, 0); - %client.invWaitTime = getSimTime() + 5000 + (getRandom() * 10000); - } - } - else - { - //in case we got bumped, and are ranging the target again... - %client.invWaitTime = ""; - } - } - - //else if we've triggered the inv, automatically give us the equipment... - else if (isObject(%closestInv) && isObject(%closestInv.trigger) && VectorDist(%closestInv.trigger.getWorldBoxCenter(), %player.getWorldBoxCenter()) < 1.5) - { - //first stop... - %client.stop(); - - %index = 0; - if (%buyingSet) - { - //first, clear the players inventory - %player.clearInventory(); - %item = $AIEquipmentSet[%inventorySet, %index]; - } - else - %item = getWord(%inventorySet, %index); - - - //armor must always be bought first - if (%item $= "Light" || %item $= "Medium" || %item $= "Heavy") - { - %player.setArmor(%item); - %index++; - } - - //set the data block after the armor had been upgraded - %playerDataBlock = %player.getDataBlock(); - - //next, loop through the inventory set, and buy each item - if (%buyingSet) - %item = $AIEquipmentSet[%inventorySet, %index]; - else - %item = getWord(%inventorySet, %index); - while (%item !$= "") - { - //set the inventory amount to the maximum quantity available - if (%player.getInventory(AmmoPack) > 0) - %ammoPackQuantity = AmmoPack.max[%item]; - else - %ammoPackQuantity = 0; - - %quantity = %player.getDataBlock().max[%item] + %ammoPackQuantity; - if ($InvBanList[$CurrentMissionType, %item]) - %quantity = 0; - %player.setInventory(%item, %quantity); - - //get the next item - %index++; - if (%buyingSet) - %item = $AIEquipmentSet[%inventorySet, %index]; - else - %item = getWord(%inventorySet, %index); - } - - //put a weapon in the bot's hand... - %player.cycleWeapon(); - - //return a success - return "Finished"; - } - - //else, keep moving towards the inv station - else - { - if (isObject(%closestInv) && isObject(%closestInv.trigger)) - { - //quite possibly we may need to deal with what happens if a bot doesn't have a path to the inv... - //the current premise is that no inventory stations are "unpathable"... - //if (%client.isSeekingInv) - //{ - // %dist = %client.getPathDistance(%closestInv.trigger.getWorldBoxCenter()); - // if (%dist < 0) - // error("DEBUG Tinman - still need to handle bot stuck trying to get to an inv!"); - //} - - %client.stepMove(%closestInv.trigger.getWorldBoxCenter(), 1.5); - %client.isSeekingInv = true; - } - return "InProgress"; - } -} - -function AIFindSameArmorEquipSet(%equipmentSets, %client) -{ - %clientArmor = %client.player.getArmorSize(); - %index = 0; - %set = getWord(%equipmentSets, %index); - while (%set !$= "") - { - if ($AIEquipmentSet[%set, 0] $= %clientArmor) - return %set; - - //get the next equipment set in the list of sets - %index++; - %set = getWord(%equipmentSets, %index); - } - return ""; -} - -function AIMustUseRegularInvStation(%equipmentList, %client) -{ - %clientArmor = %client.player.getArmorSize(); - - //first, see if the set contains an item not available - %needRemoteInv = false; - %index = 0; - %item = getWord(%equipmentList, 0); - while (%item !$= "") - { - if (%item $= "InventoryDeployable" || (%clientArmor !$= "Light" && %item $= "SniperRifle") || - (%clientArmor $= "Light" && (%item $= "Mortar" || %item $= "MissileLauncher"))) - { - return true; - } - else - { - %index++; - %item = getWord(%equipmentList, %index); - } - } - if (%needRemoteInv) - return true; - - - //otherwise, see if the set begins with an armor class - %needArmor = %equipmentList[0]; - if (%needArmor !$= "Light" && %needArmor !$= "Medium" && %needArmor !$= "Heavy") - return false; - - //also including looking for an inventory set - if (%needArmor != %client.player.getArmorSize()) - return true; - - //we must be fine... - return false; -} - -function AICouldUseItem(%client, %item) -{ - if(!AIClientIsAlive(%client)) - return false; - - %player = %client.player; - if (!isObject(%player)) - return false; - - %playerDataBlock = %client.player.getDataBlock(); - %armor = %player.getArmorSize(); - %type = %item.getDataBlock().getName(); - - //check packs first - if (%type $= "RepairPack" || %type $= "EnergyPack" || %type $= "ShieldPack" || - %type $= "CloakingPack" || %type $= "AmmoPack") - { - if (%client.player.getMountedImage($BackpackSlot) <= 0) - return true; - else - return false; - } - - //if the item is acutally, a corpse, check the corpse inventory... - if (%item.isCorpse) - { - %corpse = %item; - if (%corpse.getInventory("ChainGunAmmo") > 0 && %player.getInventory(%type) < %playerDataBlock.max[ChainGunAmmo]) - return true; - if (%corpse.getInventory("PlasmaAmmo") > 0 && %player.getInventory(%type) < %playerDataBlock.max[PlasmaAmmo]) - return true; - if (%corpse.getInventory("DiscAmmo") > 0 && %player.getInventory(%type) < %playerDataBlock.max[DiscAmmo]) - return true; - if (%corpse.getInventory("GrenadeLauncher") > 0 && %player.getInventory(%type) < %playerDataBlock.max[GrenadeLauncher]) - return true; - if (%corpse.getInventory("MortarAmmo") > 0 && %player.getInventory(%type) < %playerDataBlock.max[MortarAmmo] && %player.getInventory("Mortar") > 0) - return true; - } - else - { - //check ammo - %quantity = mFloor(%playerDataBlock.max[%type]); - if (%player.getInventory(%type) < %quantity) - { - if (%type $= "ChainGunAmmo") - return true; - if (%type $= "PlasmaAmmo") - return true; - if (%type $= "DiscAmmo") - return true; - if (%type $= "GrenadeLauncher") - return true; - if (%type $= "MortarAmmo" && %player.getInventory("Mortar") > 0) - return true; - - //check mines and grenades as well - if (%type $= "Grenade" || %type $= "FlashGrenade" || %type $= "ConcussionGrenade") - return true; - } - - //see if we can carry another weapon... - if (AICanPickupWeapon(%client, %type)) - return true; - } - - //guess we didn't find anything useful... (should still check for mines and grenades) - return false; -} - -function AIEngageOutofAmmo(%client) -{ - //this function only cares about weapons used in engagement... - //no mortars, or missiles - %player = %client.player; - if (!isObject(%player)) - return false; - - %ammoWeapons = 0; - %energyWeapons = 0; - - //get our inventory - %hasBlaster = (%player.getInventory("Blaster") > 0); - %hasPlasma = (%player.getInventory("Plasma") > 0); - %hasChain = (%player.getInventory("Chaingun") > 0); - %hasDisc = (%player.getInventory("Disc") > 0); - %hasGrenade = (%player.getInventory("GrenadeLauncher") > 0); - %hasSniper = (%player.getInventory("SniperRifle") > 0) && (%player.getInventory("EnergyPack") > 0); - %hasELF = (%player.getInventory("ELFGun") > 0); - %hasMortar = (%player.getInventory("Mortar") > 0); - %hasMissile = (%player.getInventory("MissileLauncher") > 0); - %hasLance = (%player.getInventory("ShockLance") > 0); - - if (%hasBlaster || %hasSniper || %hasElf || %hasLance) - return false; - else - { - // we only have ammo type weapons - if(%hasDisc && (%player.getInventory("DiscAmmo") > 0)) - return false; - else if(%hasChain && (%player.getInventory("ChainGunAmmo") > 0)) - return false; - else if(%hasGrenade && (%player.getInventory("GrenadeLauncherAmmo") > 0)) - return false; - else if(%hasPlasma && (%player.getInventory("PlasmaAmmo") > 0)) - return false; - } - return true; // were out! -} - -function AICanPickupWeapon(%client, %weapon) -{ - //first, make sure it's not a weapon we already have... - %player = %client.player; - if (!isObject(%player)) - return false; - - %armor = %player.getArmorSize(); - if (%player.getInventory(%weapon) > 0) - return false; - - //make sure the %weapon given is a weapon they can use for engagement - if (%weapon !$= "Blaster" && %weapon !$= "Plasma" && %weapon !$= "Chaingun" && %weapon !$= "Disc" && - %weapon !$= "GrenadeLauncher" && %weapon !$= "SniperRifle" && %weapon !$= "ELFGun" && %weapon !$= "ShockLance") - { - return false; - } - - %weaponCount = 0; - if (%player.getInventory("Blaster") > 0) - %weaponCount++; - if (%player.getInventory("Plasma") > 0) - %weaponCount++; - if (%player.getInventory("Chaingun") > 0) - %weaponCount++; - if (%player.getInventory("Disc") > 0) - %weaponCount++; - if (%player.getInventory("GrenadeLauncher") > 0) - %weaponCount++; - if (%player.getInventory("SniperRifle") > 0) - %weaponCount++; - if (%player.getInventory("ELFGun") > 0) - %weaponCount++; - if (%player.getInventory("Mortar") > 0) - %weaponCount++; - if (%player.getInventory("MissileLauncher") > 0) - %weaponCount++; - if (%player.getInventory("ShockLance") > 0) - %weaponCount++; - - if ((%armor $= "Light" && %weaponCount < 3) || (%armor $= "Medium" && %weaponCount < 4) || - (%armor $= "Heavy" && %weaponCount < 5)) - { - if ((%type $= "Mortar" && %armor !$= "Heavy") || (%type $= "MissileLauncher" && %armor $= "Light") || - (%type $= "SniperRifle" && %armor !$= "Light")) - return false; - else - return true; - } - - //else we're full of weapons already... - return false; -} - -function AIEngageWeaponRating(%client) -{ - %player = %client.player; - if (!isObject(%player)) - return; - - %playerDataBlock = %client.player.getDataBlock(); - - //get our inventory - %hasBlaster = (%player.getInventory("Blaster") > 0); - %hasPlasma = (%player.getInventory("Plasma") > 0 && %player.getInventory("PlasmaAmmo") >= 1); - %hasChain = (%player.getInventory("Chaingun") > 0 && %player.getInventory("ChaingunAmmo") >= 1); - %hasDisc = (%player.getInventory("Disc") > 0 && %player.getInventory("DiscAmmo") >= 1); - %hasGrenade = (%player.getInventory("GrenadeLauncher") > 0 && %player.getInventory("GrenadeLauncherAmmo") >= 1); - %hasSniper = (%player.getInventory("SniperRifle") > 0) && (%player.getInventory("EnergyPack") > 0); - %hasELF = (%player.getInventory("ELFGun") > 0); - - //check ammo - %quantity = mFloor(%playerDataBlock.max[%type] * 0.7); - - %rating = 0; - if (%hasBlaster) - %rating += 9; - if (%hasSniper) - %rating += 9; - if (%hasElf) - %rating += 9; - - if (%hasDisc) - { - %quantity = %player.getInventory("DiscAmmo") / %playerDataBlock.max["DiscAmmo"]; - %rating += 15 + (15 * %quantity); - } - if (%hasPlasma) - { - %quantity = %player.getInventory("PlasmaAmmo") / %playerDataBlock.max["PlasmaAmmo"]; - %rating += 15 + (15 * %quantity); - } - if (%hasChain) - { - %quantity = %player.getInventory("ChainGunAmmo") / %playerDataBlock.max["ChainGunAmmo"]; - %rating += 15 + (15 * %quantity); - } - -//not really an effective weapon for hand to hand... -// if (%hasGrenade) -// { -// %quantity = %player.getInventory("GrenadeLauncherAmmo") / %playerDataBlock.max["GrenadeLauncherAmmo"]; -// %rating += 10 + (15 * %quantity); -// } - - //note a rating of 20+ means at least two energy weapons, or an ammo weapon with at least 1/3 ammo... - return %rating; -} - -function AIFindSafeItem(%client, %needType) -{ - %player = %client.player; - if (!isObject(%player)) - return -1; - - %closestItem = -1; - %closestDist = 32767; - - %itemCount = $AIItemSet.getCount(); - for (%i = 0; %i < %itemCount; %i++) - { - %item = $AIItemSet.getObject(%i); - if (%item.isHidden()) - continue; - - %type = %item.getDataBlock().getName(); - if ((%needType $= "Health" && (%type $= "RepairKit" || %type $= "RepairPatch") && %player.getDamagePercent() > 0) || - (%needType $= "Ammo" && (%type $= "ChainGunAmmo" || %type $= "PlasmaAmmo" || %type $= "DiscAmmo" || - %type $= "GrenadeLauncherAmmo" || %type $= "MortarAmmo") && AICouldUseItem(%client, %item)) || - (%needType $= "Ammo" && AICanPickupWeapon(%type)) || - ((%needType $= "" || %needType $= "Any") && AICouldUseItem(%client, %item))) - { - //first, see if it's close to us... - %distance = %client.getPathDistance(%item.getTransform()); - if (%distance > 0 && %distance < %closestDist) - { - //now see if it's got bad enemies near it... - %clientCount = ClientGroup.getCount(); - for (%j = 0; %j < %clientCount; %j++) - { - %cl = ClientGroup.getObject(%j); - if (%cl == %client || %cl.team == %client.team || !AIClientIsAlive(%cl)) - continue; - - //if the enemy is stronger, see if they're close to the item - if (AIEngageWhoWillWin(%client, %cl) == %cl) - { - %tempDist = %client.getPathDistance(%item.getWorldBoxCenter()); - if (%tempDist > 0 && %tempDist < %distance + 50) - continue; - } - - //either no enemy, or a weaker one... - %closestItem = %item; - %closestDist = %distance; - } - } - } - } - - return %closestItem; -} - -function AIChooseObjectWeapon(%client, %targetObject, %distToTarg, %mode, %canUseEnergyStr, %environmentStr) -{ - //get our inventory - %player = %client.player; - if (!isObject(%player)) - return; - - if (!isObject(%targetObject)) - return; - - %canUseEnergy = (%canUseEnergyStr $= "true"); - %inWater = (%environmentStr $= "water"); - %hasBlaster = (%player.getInventory("Blaster") > 0) && %canUseEnergy; - %hasPlasma = (%player.getInventory("Plasma") > 0) && (%player.getInventory("PlasmaAmmo") > 0) && !%inWater; - %hasChain = (%player.getInventory("Chaingun") > 0) && (%player.getInventory("ChaingunAmmo") > 0); - %hasDisc = (%player.getInventory("Disc") > 0) && (%player.getInventory("DiscAmmo") > 0); - %hasGrenade = (%player.getInventory("GrenadeLauncher") > 0) && (%player.getInventory("GrenadeLauncherAmmo") > 0); - %hasMortar = (%player.getInventory("Mortar") > 0) && (%player.getInventory("MortarAmmo") > 0); - %hasRepairPack = (%player.getInventory("RepairPack") > 0) && %canUseEnergy; - %hasTargetingLaser = (%player.getInventory("TargetingLaser") > 0) && %canUseEnergy; - %hasMissile = (%player.getInventory("MissileLauncher") > 0) && (%player.getInventory("MissileLauncherAmmo") > 0); - - //see if we're destroying the object - if (%mode $= "Destroy") - { - if ((%targetObject.getDataBlock().getClassName() $= "TurretData" || - %targetObject.getDataBlock().getName() $= "MineDeployed") && %distToTarg < 50) - { - if (%hasPlasma) - %useWeapon = "Plasma"; - else if (%hasDisc) - %useWeapon = "Disc"; - else if (%hasBlaster) - %useWeapon = "Blaster"; - else if (%hasChain) - %useWeapon = "Chaingun"; - else - %useWeapon = "NoAmmo"; - } - else if (%distToTarg < 40) - { - if (%hasPlasma) - %useWeapon = "Plasma"; - else if (%hasChain) - %useWeapon = "Chaingun"; - else if (%hasBlaster) - %useWeapon = "Blaster"; - else if (%hasDisc) - %useWeapon = "Disc"; - else - %useWeapon = "NoAmmo"; - } - else - %useWeapon = "NoAmmo"; - } - - //else See if we're repairing the object - else if (%mode $= "Repair") - { - if (%hasRepairPack) - %useWeapon = "RepairPack"; - else - %useWeapon = "NoAmmo"; - } - - //else see if we're lazing the object - else if (%mode $= "Laze") - { - if (%hasTargetingLaser) - %useWeapon = "TargetingLaser"; - else - %useWeapon = "NoAmmo"; - } - - //else see if we're mortaring the object - else if (%mode $= "Mortar") - { - if (%hasMortar) - %useWeapon = "Mortar"; - else - %useWeapon = "NoAmmo"; - } - - //else see if we're rocketing the object - else if (%mode $= "Missile" || %mode $= "MissileNoLock") - { - if (%hasMissile) - %useWeapon = "MissileLauncher"; - else - %useWeapon = "NoAmmo"; - } - - //now select the weapon - switch$ (%useWeapon) - { - case "Blaster": - %client.player.use("Blaster"); - %client.setWeaponInfo("EnergyBolt", 25, 50, 1, 0.1); - - case "Plasma": - %client.player.use("Plasma"); - %client.setWeaponInfo("PlasmaBolt", 25, 50); - - case "Chaingun": - %client.player.use("Chaingun"); - %client.setWeaponInfo("ChaingunBullet", 30, 75, 150); - - case "Disc": - %client.player.use("Disc"); - %client.setWeaponInfo("DiscProjectile", 30, 75); - - case "GrenadeLauncher": - %client.player.use("GrenadeLauncher"); - %client.setWeaponInfo("BasicGrenade", 40, 75); - - case "Mortar": - %client.player.use("Mortar"); - %client.setWeaponInfo("MortarShot", 100, 350); - - case "RepairPack": - if (%player.getImageState($BackpackSlot) $= "Idle") - %client.player.use("RepairPack"); - %client.setWeaponInfo("DefaultRepairBeam", 40, 75, 300, 0.1); - - case "TargetingLaser": - %client.player.use("TargetingLaser"); - %client.setWeaponInfo("BasicTargeter", 20, 300, 300, 0.1); - - case "MissileLauncher": - %client.player.use("MissileLauncher"); - %client.setWeaponInfo("ShoulderMissile", 80, 300); - - case "NoAmmo": - %client.setWeaponInfo("NoAmmo", 30, 75); - } -} - -function AIChooseEngageWeapon(%client, %targetClient, %distToTarg, %canUseEnergyStr, %environmentStr) -{ - //get some status - %player = %client.player; - if (!isObject(%player)) - return; - - %enemy = %targetClient.player; - if (!isObject(%enemy)) - return; - - %canUseEnergy = (%canUseEnergyStr $= "true"); - %inWater = (%environmentStr $= "water"); - %outdoors = (%environmentStr $= "outdoors"); - %targVelocity = %targetClient.player.getVelocity(); - %targEnergy = %targetClient.player.getEnergyPercent(); - %targDamage = %targetClient.player.getDamagePercent(); - %myEnergy = %player.getEnergyPercent(); - %myDamage = %player.getDamagePercent(); - - //get our inventory - %hasBlaster = (%player.getInventory("Blaster") > 0) && %canUseEnergy; - %hasPlasma = (%player.getInventory("Plasma") > 0) && (%player.getInventory("PlasmaAmmo") > 0) && !%inWater; - %hasChain = (%player.getInventory("Chaingun") > 0) && (%player.getInventory("ChaingunAmmo") > 0); - %hasDisc = (%player.getInventory("Disc") > 0) && (%player.getInventory("DiscAmmo") > 0); - %hasGrenade = (%player.getInventory("GrenadeLauncher") > 0) && (%player.getInventory("GrenadeLauncherAmmo") > 0); - %hasSniper = (%player.getInventory("SniperRifle") > 0) && (%player.getInventory("EnergyPack") > 0) && %canUseEnergy && !%inWater; - %hasELF = (%player.getInventory("ELFGun") > 0) && %canUseEnergy && !%inWater; - %hasMortar = (%player.getInventory("Mortar") > 0) && (%player.getInventory("MortarAmmo") > 0); - %hasMissile = (%player.getInventory("MissileLauncher") > 0) && (%player.getInventory("MissileLauncherAmmo") > 0); - %hasShockLance = (%player.getInventory("ShockLance") > 0) && %canUseEnergy && !%inWater; - - //choose the weapon - %useWeapon = "NoAmmo"; - - //first, see if it's a pilot we're shooting - if (%dist > 50 && %enemy.isMounted() && %hasMissile) - { - %useWeapon = "MissileLauncher"; - } - else if (%distToTarg < 5 && %hasShockLance) - { - %useWeapon = "ShockLance"; - } - else if (%distToTarg < 15) - { - if (%hasELF && %myEnergy > 0.5 && %targEnergy > 0.3 && %myDamage < %targDamage && %targetZ > %myZ + 20) - %useWeapon = "ELFGun"; - else if (%hasPlasma) - %useWeapon = "Plasma"; - else if (%hasChain) - %useWeapon = "Chaingun"; - else if (%hasBlaster) - %useWeapon = "Blaster"; - else if (%hasELF && %targEnergy > 0.2) - %useWeapon = "ELFGun"; - else if (%hasDisc) - %useWeapon = "Disc"; - else if (%hasShockLance) - %useWeapon = "ShockLance"; - } - else if (%distToTarg < 35) - { - if (%hasELF && %targEnergy > 0.4 && (%myDamage < 0.3 || %myDamage - %targDamage < 0.2) && %targetZ > %myZ + 20) - %useWeapon = "ELFGun"; - else if (!%outdoors && %hasPlasma) - %useWeapon = "Plasma"; - else if (%hasChain && %hasDisc) - { - %speed = VectorDist("0 0 0", %targVelocity); - %myZ = getWord(%player.getTransform(), 2); - %targetZ = getWord(%enemy.getTransform(), 2); - %targetZVel = getWord(%targVelocity, 2); - - if (%speed > 15.0 || %targetZ > %myZ || %targetZVel > 1.0) - %useWeapon = "Chaingun"; - else - %useWeapon = "Disc"; - } - else if (%hasPlasma) - %useWeapon = "Plasma"; - else if (%hasChain) - %useWeapon = "Chaingun"; - else if (%hasDisc) - %useWeapon = "Disc"; - else if (%hasBlaster) - %useWeapon = "Blaster"; - } - else if (%distToTarg < 60) - { - if (%hasGrenade) - %useWeapon = "GrenadeLauncher"; - else if (%hasSniper && %myEnergy > 0.6) - %useWeapon = "SniperRifle"; - - } - else if (%distToTarg < 80) - { - if (%hasSniper && %myEnergy > 0.4) - %useWeapon = "SniperRifle"; - else if (%hasDisc) - %useWeapon = "Disc"; - else if (%hasChain) - %useWeapon = "Chaingun"; - else if (%hasBlaster) - %useWeapon = "Blaster"; - } - else - { - if (%hasSniper) - %useWeapon = "SniperRifle"; - } - - //now make sure we actually selected something - if (%useWeapon $= "NoAmmo") - { - if (%hasDisc) - %useWeapon = "Disc"; - else if (%hasChain) - %useWeapon = "Chaingun"; - else if (%hasPlasma) - %useWeapon = "Plasma"; - else if (%hasBlaster) - %useWeapon = "Blaster"; - else if (%hasELF) - %useWeapon = "ELFGun"; - else if (%hasSniper) - %useWeapon = "SniperRifle"; - else if (%hasShockLance) - %useWeapon = "ShockLance"; - else if (%hasGrenade) - %useWeapon = "GrenadeLauncher"; - else if (%hasMissile) - %useWeapon = "MissileLauncher"; - } - - //now select the weapon - switch$ (%useWeapon) - { - case "Blaster": - %client.player.use("Blaster"); - %client.setWeaponInfo("EnergyBolt", 25, 50, 1, 0.1); - - case "Plasma": - %client.player.use("Plasma"); - %client.setWeaponInfo("PlasmaBolt", 25, 50); - - case "Chaingun": - %client.player.use("Chaingun"); - %client.setWeaponInfo("ChaingunBullet", 30, 75, 150); - - case "Disc": - %client.player.use("Disc"); - %client.setWeaponInfo("DiscProjectile", 30, 75); - - case "GrenadeLauncher": - %client.player.use("GrenadeLauncher"); - %client.setWeaponInfo("BasicGrenade", 40, 75); - - case "SniperRifle": - %client.player.use("SniperRifle"); - %client.setWeaponInfo("BasicSniperShot", 80, 350, 1, 0.75, 0.5); - - case "ELFGun": - %client.player.use("ELFGun"); - %client.setWeaponInfo("BasicELF", 25, 45, 90, 0.1); - - case "ShockLance": - %client.player.use("ShockLance"); - %client.setWeaponInfo("BasicShocker", 0.5, 8, 1, 0.1); - - case "MissileLauncher": - %client.player.use("MissileLauncher"); - %client.setWeaponInfo("ShoulderMissile", 80, 350); - - case "NoAmmo": - %client.setWeaponInfo("NoAmmo", 30, 75); - } -} - -//function is called once per frame, to handle packs, healthkits, grenades, etc... -function AIProcessEngagement(%client, %target, %type, %projectile) -{ - //make sure we're still alive - if (! AIClientIsAlive(%client)) - return; - - //clear the pressFire - %client.pressFire(-1); - - //see if we have to use a repairkit - %player = %client.player; - if (!isObject(%player)) - return; - - if (%client.getSkillLevel() > 0.1 && %player.getDamagePercent() > 0.3 && %player.getInventory("RepairKit") > 0) - { - //add in a "skill" value to delay the using of the repair kit for up to 10 seconds... - %elapsedTime = getSimTime() - %client.lastDamageTime; - %skillValue = (1.0 - %client.getSkillLevel()) * (1.0 - %client.getSkillLevel()); - if (%elapsedTime > (%skillValue * 20000)) - %player.use("RepairKit"); - } - - //see if we've been blinded - if (%player.getWhiteOut() > 0.6) - %client.setBlinded(2000); - - //else see if there's a grenade in the vicinity... - else - { - %count = $AIGrenadeSet.getCount(); - for (%i = 0; %i < %count; %i++) - { - %grenade = $AIGrenadeSet.getObject(%i); - - //make sure the grenade isn't ours - if (%grenade.sourceObject.client != %client) - { - //see if it's within 15 m - if (VectorDist(%grenade.position, %client.player.position) < 15) - { - %client.setDangerLocation(%grenade.position, 20); - break; - } - } - } - } - - //if we're being hunted by a seeker projectile, throw a flare grenade - if (%player.getInventory("FlareGrenade") > 0) - { - %missileCount = MissileSet.getCount(); - for (%i = 0; %i < %missileCount; %i++) - { - %missile = MissileSet.getObject(%i); - if (%missile.getTargetObject() == %player) - { - //see if the missile is within range - if (VectorDist(%missile.getTransform(), %player.getTransform()) < 50) - { - %player.throwStrength = 1.5; - %player.use("FlareGrenade"); - break; - } - } - } - } - - //see what we're fighting - switch$ (%type) - { - case "player": - //make sure the target is alive - if (AIClientIsAlive(%target)) - { - //if the target is in range, and within 10-40 m, and heading in this direction, toss a grenade - if (!$AIDisableGrenades && %client.getSkillLevel() >= 0.3) - { - if (%player.getInventory("Grenade") > 0) - %grenadeType = "Grenade"; - else if (%player.getInventory("FlashGrenade") > 0) - %grenadeType = "FlashGrenade"; - else if (%player.getInventory("ConcussionGrenade") > 0) - %grenadeType = "ConcussionGrenade"; - else %grenadeType = ""; - if (%grenadeType !$= "" && %client.targetInSight()) - { - //see if the predicted location of the target is within 10m - %targPos = %target.player.getWorldBoxCenter(); - %clientPos = %player.getWorldBoxCenter(); - - //make sure we're not *way* above the target - if (getWord(%clientPos, 2) - getWord(%targPos, 2) < 3) - { - %dist = VectorDist(%targPos, %clientPos); - %direction = VectorDot(VectorSub(%clientPos, %targPos), %target.player.getVelocity()); - %facing = VectorDot(VectorSub(%client.getAimLocation(), %clientPos), VectorSub(%targPos, %clientPos)); - if (%dist > 20 && %dist < 45 && (%direction > 0.9 || %direction < -0.9) && (%facing > 0.9)) - { - %player.throwStrength = 1.0; - %player.use(%grenadeType); - } - } - } - } - - //see if we have a shield pack that we need to use - if (%player.getInventory("ShieldPack") > 0) - { - if (%projectile > 0 && %player.getImageState($BackpackSlot) $= "Idle") - { - %player.use("Backpack"); - } - else if (%projectile <= 0 && %player.getImageState($BackpackSlot) $= "activate") - { - %player.use("Backpack"); - } - } - } - - case "object": - %hasGrenade = %player.getInventory("Grenade"); - if (%hasGrenade && %client.targetInRange()) - { - %targPos = %target.getWorldBoxCenter(); - %myPos = %player.getWorldBoxCenter(); - %dist = VectorDist(%targPos, %myPos); - if (%dist > 5 && %dist < 20) - { - %player.throwStrength = 1.0; - %player.use("Grenade"); - } - } - - case "none": - //use the repair pack if we have one - if (%player.getDamagePercent() > 0 && %player.getInventory(RepairPack) > 0) - { - if (%player.getImageState($BackpackSlot) $= "Idle") - %client.player.use("RepairPack"); - else - //sustain the fire for 30 frames - this callback is timesliced... - %client.pressFire(30); - } - } -} - -function AIFindClosestInventory(%client, %armorChange) -{ - %closestInv = -1; - %closestDist = 32767; - - %depCount = 0; - %depGroup = nameToID("MissionCleanup/Deployables"); - if (%depGroup > 0) - %depCount = %depGroup.getCount(); - - // there exists a deployed station, lets find it - if(!%armorChange && %depCount > 0) - { - for(%i = 0; %i < %depCount; %i++) - { - %obj = %depGroup.getObject(%i); - - if(%obj.getDataBlock().getName() $= "DeployedStationInventory" && %obj.team == %client.team && %obj.isEnabled()) - { - %distance = %client.getPathDistance(%obj.getTransform()); - if (%distance > 0 && %distance < %closestDist) - { - %closestInv = %obj; - %closestDist = %distance; - } - } - } - } - - // still check if there is one that is closer - %invCount = $AIInvStationSet.getCount(); - for (%i = 0; %i < %invCount; %i++) - { - %invStation = $AIInvStationSet.getObject(%i); - if (%invStation.team <= 0 || %invStation.team == %client.team) - { - //error("DEBUG: found an inventory station: " @ %invStation @ " status: " @ %invStation.isPowered()); - //make sure the station is powered - if (!%invStation.isDisabled() && %invStation.isPowered()) - { - %dist = %client.getPathDistance(%invStation.getTransform()); - if (%dist > 0 && %dist < %closestDist) - { - %closestInv = %invStation; - %closestDist = %dist; - } - } - } - } - - return %closestInv @ " " @ %closestDist; -} - -//------------------------------ -//find the closest inventories for the objective weight functions -function AIFindClosestInventories(%client) -{ - %closestInv = -1; - %closestDist = 32767; - %closestRemoteInv = -1; - %closestRemoteDist = 32767; - - %depCount = 0; - %depGroup = nameToID("MissionCleanup/Deployables"); - - //first, search for the nearest deployable inventory station - if (isObject(%depGroup)) - { - %depCount = %depGroup.getCount(); - for (%i = 0; %i < %depCount; %i++) - { - %obj = %depGroup.getObject(%i); - - if (%obj.getDataBlock().getName() $= "DeployedStationInventory" && %obj.team == %client.team && %obj.isEnabled()) - { - %distance = %client.getPathDistance(%obj.getTransform()); - if (%distance > 0 && %distance < %closestRemoteDist) - { - %closestRemoteInv = %obj; - %closestRemoteDist = %distance; - } - } - } - } - - // now find the closest regular inventory station - %invCount = $AIInvStationSet.getCount(); - for (%i = 0; %i < %invCount; %i++) - { - %invStation = $AIInvStationSet.getObject(%i); - if (%invStation.team <= 0 || %invStation.team == %client.team) - { - //make sure the station is powered - if (!%invStation.isDisabled() && %invStation.isPowered()) - { - %dist = %client.getPathDistance(%invStation.getTransform()); - if (%dist > 0 && %dist < %closestDist) - { - %closestInv = %invStation; - %closestDist = %dist; - } - } - } - } - - //if the regular inv station is closer than the deployed, don't bother with the remote - if (%closestDist < %closestRemoteDist) - %returnStr = %closestInv SPC %closestDist; - else - %returnStr = %closestInv SPC %closestDist SPC %closestRemoteInv SPC %closestRemoteDist; - - return %returnStr; -} - -//------------------------------ -//AI Equipment Configs -$EquipConfigIndex = -1; -$AIEquipmentSet[HeavyAmmoSet, $EquipConfigIndex++] = "Heavy"; -$AIEquipmentSet[HeavyAmmoSet, $EquipConfigIndex++] = "AmmoPack"; -$AIEquipmentSet[HeavyAmmoSet, $EquipConfigIndex++] = "Plasma"; -$AIEquipmentSet[HeavyAmmoSet, $EquipConfigIndex++] = "PlasmaAmmo"; -$AIEquipmentSet[HeavyAmmoSet, $EquipConfigIndex++] = "Chaingun"; -$AIEquipmentSet[HeavyAmmoSet, $EquipConfigIndex++] = "ChaingunAmmo"; -$AIEquipmentSet[HeavyAmmoSet, $EquipConfigIndex++] = "Disc"; -$AIEquipmentSet[HeavyAmmoSet, $EquipConfigIndex++] = "DiscAmmo"; -$AIEquipmentSet[HeavyAmmoSet, $EquipConfigIndex++] = "GrenadeLauncher"; -$AIEquipmentSet[HeavyAmmoSet, $EquipConfigIndex++] = "GrenadeLauncherAmmo"; -$AIEquipmentSet[HeavyAmmoSet, $EquipConfigIndex++] = "Mortar"; -$AIEquipmentSet[HeavyAmmoSet, $EquipConfigIndex++] = "MortarAmmo"; -$AIEquipmentSet[HeavyAmmoSet, $EquipConfigIndex++] = "RepairKit"; -$AIEquipmentSet[HeavyAmmoSet, $EquipConfigIndex++] = "Grenade"; -$AIEquipmentSet[HeavyAmmoSet, $EquipConfigIndex++] = "Mine"; - -$EquipConfigIndex = -1; -$AIEquipmentSet[HeavyShieldSet, $EquipConfigIndex++] = "Heavy"; -$AIEquipmentSet[HeavyShieldSet, $EquipConfigIndex++] = "ShieldPack"; -$AIEquipmentSet[HeavyShieldSet, $EquipConfigIndex++] = "Plasma"; -$AIEquipmentSet[HeavyShieldSet, $EquipConfigIndex++] = "PlasmaAmmo"; -$AIEquipmentSet[HeavyShieldSet, $EquipConfigIndex++] = "Chaingun"; -$AIEquipmentSet[HeavyShieldSet, $EquipConfigIndex++] = "ChaingunAmmo"; -$AIEquipmentSet[HeavyShieldSet, $EquipConfigIndex++] = "Disc"; -$AIEquipmentSet[HeavyShieldSet, $EquipConfigIndex++] = "DiscAmmo"; -$AIEquipmentSet[HeavyShieldSet, $EquipConfigIndex++] = "GrenadeLauncher"; -$AIEquipmentSet[HeavyShieldSet, $EquipConfigIndex++] = "GrenadeLauncherAmmo"; -$AIEquipmentSet[HeavyShieldSet, $EquipConfigIndex++] = "Mortar"; -$AIEquipmentSet[HeavyShieldSet, $EquipConfigIndex++] = "MortarAmmo"; -$AIEquipmentSet[HeavyShieldSet, $EquipConfigIndex++] = "RepairKit"; -$AIEquipmentSet[HeavyShieldSet, $EquipConfigIndex++] = "Grenade"; -$AIEquipmentSet[HeavyShieldSet, $EquipConfigIndex++] = "Mine"; - -$EquipConfigIndex = -1; -$AIEquipmentSet[HeavyEnergySet, $EquipConfigIndex++] = "Heavy"; -$AIEquipmentSet[HeavyEnergySet, $EquipConfigIndex++] = "EnergyPack"; -$AIEquipmentSet[HeavyEnergySet, $EquipConfigIndex++] = "Plasma"; -$AIEquipmentSet[HeavyEnergySet, $EquipConfigIndex++] = "PlasmaAmmo"; -$AIEquipmentSet[HeavyEnergySet, $EquipConfigIndex++] = "Disc"; -$AIEquipmentSet[HeavyEnergySet, $EquipConfigIndex++] = "DiscAmmo"; -$AIEquipmentSet[HeavyEnergySet, $EquipConfigIndex++] = "GrenadeLauncher"; -$AIEquipmentSet[HeavyEnergySet, $EquipConfigIndex++] = "GrenadeLauncherAmmo"; -$AIEquipmentSet[HeavyEnergySet, $EquipConfigIndex++] = "ELFGun"; -$AIEquipmentSet[HeavyEnergySet, $EquipConfigIndex++] = "Mortar"; -$AIEquipmentSet[HeavyEnergySet, $EquipConfigIndex++] = "MortarAmmo"; -$AIEquipmentSet[HeavyEnergySet, $EquipConfigIndex++] = "RepairKit"; -$AIEquipmentSet[HeavyEnergySet, $EquipConfigIndex++] = "Grenade"; -$AIEquipmentSet[HeavyEnergySet, $EquipConfigIndex++] = "Mine"; - -$EquipConfigIndex = -1; -$AIEquipmentSet[HeavyRepairSet, $EquipConfigIndex++] = "Heavy"; -$AIEquipmentSet[HeavyRepairSet, $EquipConfigIndex++] = "RepairPack"; -$AIEquipmentSet[HeavyRepairSet, $EquipConfigIndex++] = "Chaingun"; -$AIEquipmentSet[HeavyRepairSet, $EquipConfigIndex++] = "ChaingunAmmo"; -$AIEquipmentSet[HeavyRepairSet, $EquipConfigIndex++] = "Disc"; -$AIEquipmentSet[HeavyRepairSet, $EquipConfigIndex++] = "DiscAmmo"; -$AIEquipmentSet[HeavyRepairSet, $EquipConfigIndex++] = "GrenadeLauncher"; -$AIEquipmentSet[HeavyRepairSet, $EquipConfigIndex++] = "GrenadeLauncherAmmo"; -$AIEquipmentSet[HeavyRepairSet, $EquipConfigIndex++] = "ELFGun"; -$AIEquipmentSet[HeavyRepairSet, $EquipConfigIndex++] = "Mortar"; -$AIEquipmentSet[HeavyRepairSet, $EquipConfigIndex++] = "MortarAmmo"; -$AIEquipmentSet[HeavyRepairSet, $EquipConfigIndex++] = "RepairKit"; -$AIEquipmentSet[HeavyRepairSet, $EquipConfigIndex++] = "Grenade"; -$AIEquipmentSet[HeavyRepairSet, $EquipConfigIndex++] = "Mine"; - -$EquipConfigIndex = -1; -$AIEquipmentSet[HeavyIndoorTurretSet, $EquipConfigIndex++] = "Heavy"; -$AIEquipmentSet[HeavyIndoorTurretSet, $EquipConfigIndex++] = "TurretIndoorDeployable"; -$AIEquipmentSet[HeavyIndoorTurretSet, $EquipConfigIndex++] = "Chaingun"; -$AIEquipmentSet[HeavyIndoorTurretSet, $EquipConfigIndex++] = "ChaingunAmmo"; -$AIEquipmentSet[HeavyIndoorTurretSet, $EquipConfigIndex++] = "Disc"; -$AIEquipmentSet[HeavyIndoorTurretSet, $EquipConfigIndex++] = "DiscAmmo"; -$AIEquipmentSet[HeavyIndoorTurretSet, $EquipConfigIndex++] = "GrenadeLauncher"; -$AIEquipmentSet[HeavyIndoorTurretSet, $EquipConfigIndex++] = "GrenadeLauncherAmmo"; -$AIEquipmentSet[HeavyIndoorTurretSet, $EquipConfigIndex++] = "ELFGun"; -$AIEquipmentSet[HeavyIndoorTurretSet, $EquipConfigIndex++] = "TargetingLaser"; -$AIEquipmentSet[HeavyIndoorTurretSet, $EquipConfigIndex++] = "RepairKit"; -$AIEquipmentSet[HeavyIndoorTurretSet, $EquipConfigIndex++] = "Grenade"; -$AIEquipmentSet[HeavyIndoorTurretSet, $EquipConfigIndex++] = "Mine"; - -$EquipConfigIndex = -1; -$AIEquipmentSet[HeavyInventorySet, $EquipConfigIndex++] = "Heavy"; -$AIEquipmentSet[HeavyInventorySet, $EquipConfigIndex++] = "InventoryDeployable"; -$AIEquipmentSet[HeavyInventorySet, $EquipConfigIndex++] = "Chaingun"; -$AIEquipmentSet[HeavyInventorySet, $EquipConfigIndex++] = "ChaingunAmmo"; -$AIEquipmentSet[HeavyInventorySet, $EquipConfigIndex++] = "Disc"; -$AIEquipmentSet[HeavyInventorySet, $EquipConfigIndex++] = "DiscAmmo"; -$AIEquipmentSet[HeavyInventorySet, $EquipConfigIndex++] = "GrenadeLauncher"; -$AIEquipmentSet[HeavyInventorySet, $EquipConfigIndex++] = "GrenadeLauncherAmmo"; -$AIEquipmentSet[HeavyInventorySet, $EquipConfigIndex++] = "ELFGun"; -$AIEquipmentSet[HeavyInventorySet, $EquipConfigIndex++] = "TargetingLaser"; -$AIEquipmentSet[HeavyInventorySet, $EquipConfigIndex++] = "RepairKit"; -$AIEquipmentSet[HeavyInventorySet, $EquipConfigIndex++] = "Grenade"; -$AIEquipmentSet[HeavyInventorySet, $EquipConfigIndex++] = "Mine"; - -//------------------------------ - -$EquipConfigIndex = -1; -$AIEquipmentSet[MediumRepairSet, $EquipConfigIndex++] = "Medium"; -$AIEquipmentSet[MediumRepairSet, $EquipConfigIndex++] = "RepairPack"; -$AIEquipmentSet[MediumRepairSet, $EquipConfigIndex++] = "Plasma"; -$AIEquipmentSet[MediumRepairSet, $EquipConfigIndex++] = "PlasmaAmmo"; -$AIEquipmentSet[MediumRepairSet, $EquipConfigIndex++] = "Chaingun"; -$AIEquipmentSet[MediumRepairSet, $EquipConfigIndex++] = "ChaingunAmmo"; -$AIEquipmentSet[MediumRepairSet, $EquipConfigIndex++] = "Disc"; -$AIEquipmentSet[MediumRepairSet, $EquipConfigIndex++] = "DiscAmmo"; -$AIEquipmentSet[MediumRepairSet, $EquipConfigIndex++] = "GrenadeLauncher"; -$AIEquipmentSet[MediumRepairSet, $EquipConfigIndex++] = "GrenadeLauncherAmmo"; -$AIEquipmentSet[MediumRepairSet, $EquipConfigIndex++] = "TargetingLaser"; -$AIEquipmentSet[MediumRepairSet, $EquipConfigIndex++] = "RepairKit"; -$AIEquipmentSet[MediumRepairSet, $EquipConfigIndex++] = "Grenade"; -$AIEquipmentSet[MediumRepairSet, $EquipConfigIndex++] = "Mine"; - -$EquipConfigIndex = -1; -$AIEquipmentSet[MediumShieldSet, $EquipConfigIndex++] = "Medium"; -$AIEquipmentSet[MediumShieldSet, $EquipConfigIndex++] = "ShieldPack"; -$AIEquipmentSet[MediumShieldSet, $EquipConfigIndex++] = "Plasma"; -$AIEquipmentSet[MediumShieldSet, $EquipConfigIndex++] = "PlasmaAmmo"; -$AIEquipmentSet[MediumShieldSet, $EquipConfigIndex++] = "Chaingun"; -$AIEquipmentSet[MediumShieldSet, $EquipConfigIndex++] = "ChaingunAmmo"; -$AIEquipmentSet[MediumShieldSet, $EquipConfigIndex++] = "Disc"; -$AIEquipmentSet[MediumShieldSet, $EquipConfigIndex++] = "DiscAmmo"; -$AIEquipmentSet[MediumShieldSet, $EquipConfigIndex++] = "GrenadeLauncher"; -$AIEquipmentSet[MediumShieldSet, $EquipConfigIndex++] = "GrenadeLauncherAmmo"; -$AIEquipmentSet[MediumShieldSet, $EquipConfigIndex++] = "TargetingLaser"; -$AIEquipmentSet[MediumShieldSet, $EquipConfigIndex++] = "RepairKit"; -$AIEquipmentSet[MediumShieldSet, $EquipConfigIndex++] = "Grenade"; -$AIEquipmentSet[MediumShieldSet, $EquipConfigIndex++] = "Mine"; - -$EquipConfigIndex = -1; -$AIEquipmentSet[MediumEnergySet, $EquipConfigIndex++] = "Medium"; -$AIEquipmentSet[MediumEnergySet, $EquipConfigIndex++] = "EnergyPack"; -$AIEquipmentSet[MediumEnergySet, $EquipConfigIndex++] = "Chaingun"; -$AIEquipmentSet[MediumEnergySet, $EquipConfigIndex++] = "ChaingunAmmo"; -$AIEquipmentSet[MediumEnergySet, $EquipConfigIndex++] = "Disc"; -$AIEquipmentSet[MediumEnergySet, $EquipConfigIndex++] = "DiscAmmo"; -$AIEquipmentSet[MediumEnergySet, $EquipConfigIndex++] = "GrenadeLauncher"; -$AIEquipmentSet[MediumEnergySet, $EquipConfigIndex++] = "GrenadeLauncherAmmo"; -$AIEquipmentSet[MediumEnergySet, $EquipConfigIndex++] = "ELFGun"; -$AIEquipmentSet[MediumEnergySet, $EquipConfigIndex++] = "TargetingLaser"; -$AIEquipmentSet[MediumEnergySet, $EquipConfigIndex++] = "RepairKit"; -$AIEquipmentSet[MediumEnergySet, $EquipConfigIndex++] = "Grenade"; -$AIEquipmentSet[MediumEnergySet, $EquipConfigIndex++] = "Mine"; - -$EquipConfigIndex = -1; -$AIEquipmentSet[MediumMissileSet, $EquipConfigIndex++] = "Medium"; -$AIEquipmentSet[MediumMissileSet, $EquipConfigIndex++] = "EnergyPack"; -$AIEquipmentSet[MediumMissileSet, $EquipConfigIndex++] = "Chaingun"; -$AIEquipmentSet[MediumMissileSet, $EquipConfigIndex++] = "ChaingunAmmo"; -$AIEquipmentSet[MediumMissileSet, $EquipConfigIndex++] = "Disc"; -$AIEquipmentSet[MediumMissileSet, $EquipConfigIndex++] = "DiscAmmo"; -$AIEquipmentSet[MediumMissileSet, $EquipConfigIndex++] = "MissileLauncher"; -$AIEquipmentSet[MediumMissileSet, $EquipConfigIndex++] = "MissileLauncherAmmo"; -$AIEquipmentSet[MediumMissileSet, $EquipConfigIndex++] = "ELFGun"; -$AIEquipmentSet[MediumMissileSet, $EquipConfigIndex++] = "TargetingLaser"; -$AIEquipmentSet[MediumMissileSet, $EquipConfigIndex++] = "RepairKit"; -$AIEquipmentSet[MediumMissileSet, $EquipConfigIndex++] = "Grenade"; -$AIEquipmentSet[MediumMissileSet, $EquipConfigIndex++] = "Mine"; - -$EquipConfigIndex = -1; -$AIEquipmentSet[MediumOutdoorTurretSet, $EquipConfigIndex++] = "Medium"; -$AIEquipmentSet[MediumOutdoorTurretSet, $EquipConfigIndex++] = "TurretOutdoorDeployable"; -$AIEquipmentSet[MediumOutdoorTurretSet, $EquipConfigIndex++] = "Chaingun"; -$AIEquipmentSet[MediumOutdoorTurretSet, $EquipConfigIndex++] = "ChaingunAmmo"; -$AIEquipmentSet[MediumOutdoorTurretSet, $EquipConfigIndex++] = "Disc"; -$AIEquipmentSet[MediumOutdoorTurretSet, $EquipConfigIndex++] = "DiscAmmo"; -$AIEquipmentSet[MediumOutdoorTurretSet, $EquipConfigIndex++] = "GrenadeLauncher"; -$AIEquipmentSet[MediumOutdoorTurretSet, $EquipConfigIndex++] = "GrenadeLauncherAmmo"; -$AIEquipmentSet[MediumOutdoorTurretSet, $EquipConfigIndex++] = "ELFGun"; -$AIEquipmentSet[MediumOutdoorTurretSet, $EquipConfigIndex++] = "RepairKit"; -$AIEquipmentSet[MediumOutdoorTurretSet, $EquipConfigIndex++] = "Grenade"; -$AIEquipmentSet[MediumOutdoorTurretSet, $EquipConfigIndex++] = "Mine"; - -$EquipConfigIndex = -1; -$AIEquipmentSet[MediumIndoorTurretSet, $EquipConfigIndex++] = "Medium"; -$AIEquipmentSet[MediumIndoorTurretSet, $EquipConfigIndex++] = "TurretIndoorDeployable"; -$AIEquipmentSet[MediumIndoorTurretSet, $EquipConfigIndex++] = "Chaingun"; -$AIEquipmentSet[MediumIndoorTurretSet, $EquipConfigIndex++] = "ChaingunAmmo"; -$AIEquipmentSet[MediumIndoorTurretSet, $EquipConfigIndex++] = "Disc"; -$AIEquipmentSet[MediumIndoorTurretSet, $EquipConfigIndex++] = "DiscAmmo"; -$AIEquipmentSet[MediumIndoorTurretSet, $EquipConfigIndex++] = "GrenadeLauncher"; -$AIEquipmentSet[MediumIndoorTurretSet, $EquipConfigIndex++] = "GrenadeLauncherAmmo"; -$AIEquipmentSet[MediumIndoorTurretSet, $EquipConfigIndex++] = "ELFGun"; -$AIEquipmentSet[MediumIndoorTurretSet, $EquipConfigIndex++] = "TargetingLaser"; -$AIEquipmentSet[MediumIndoorTurretSet, $EquipConfigIndex++] = "RepairKit"; -$AIEquipmentSet[MediumIndoorTurretSet, $EquipConfigIndex++] = "Grenade"; -$AIEquipmentSet[MediumIndoorTurretSet, $EquipConfigIndex++] = "Mine"; - -$EquipConfigIndex = -1; -$AIEquipmentSet[MediumInventorySet, $EquipConfigIndex++] = "Medium"; -$AIEquipmentSet[MediumInventorySet, $EquipConfigIndex++] = "InventoryDeployable"; -$AIEquipmentSet[MediumInventorySet, $EquipConfigIndex++] = "Chaingun"; -$AIEquipmentSet[MediumInventorySet, $EquipConfigIndex++] = "ChaingunAmmo"; -$AIEquipmentSet[MediumInventorySet, $EquipConfigIndex++] = "Disc"; -$AIEquipmentSet[MediumInventorySet, $EquipConfigIndex++] = "DiscAmmo"; -$AIEquipmentSet[MediumInventorySet, $EquipConfigIndex++] = "GrenadeLauncher"; -$AIEquipmentSet[MediumInventorySet, $EquipConfigIndex++] = "GrenadeLauncherAmmo"; -$AIEquipmentSet[MediumInventorySet, $EquipConfigIndex++] = "ELFGun"; -$AIEquipmentSet[MediumInventorySet, $EquipConfigIndex++] = "TargetingLaser"; -$AIEquipmentSet[MediumInventorySet, $EquipConfigIndex++] = "RepairKit"; -$AIEquipmentSet[MediumInventorySet, $EquipConfigIndex++] = "Grenade"; -$AIEquipmentSet[MediumInventorySet, $EquipConfigIndex++] = "Mine"; - -//------------------------------ - -$EquipConfigIndex = -1; -$AIEquipmentSet[LightEnergyDefault, $EquipConfigIndex++] = "Light"; -$AIEquipmentSet[LightEnergyDefault, $EquipConfigIndex++] = "EnergyPack"; -$AIEquipmentSet[LightEnergyDefault, $EquipConfigIndex++] = "Chaingun"; -$AIEquipmentSet[LightEnergyDefault, $EquipConfigIndex++] = "ChaingunAmmo"; -$AIEquipmentSet[LightEnergyDefault, $EquipConfigIndex++] = "Disc"; -$AIEquipmentSet[LightEnergyDefault, $EquipConfigIndex++] = "DiscAmmo"; -$AIEquipmentSet[LightEnergyDefault, $EquipConfigIndex++] = "GrenadeLauncher"; -$AIEquipmentSet[LightEnergyDefault, $EquipConfigIndex++] = "GrenadeLauncherAmmo"; -$AIEquipmentSet[LightEnergyDefault, $EquipConfigIndex++] = "TargetingLaser"; -$AIEquipmentSet[LightEnergyDefault, $EquipConfigIndex++] = "RepairKit"; -$AIEquipmentSet[LightEnergyDefault, $EquipConfigIndex++] = "Grenade"; -$AIEquipmentSet[LightEnergyDefault, $EquipConfigIndex++] = "Mine"; - -$EquipConfigIndex = -1; -$AIEquipmentSet[LightEnergySniper, $EquipConfigIndex++] = "Light"; -$AIEquipmentSet[LightEnergySniper, $EquipConfigIndex++] = "EnergyPack"; -$AIEquipmentSet[LightEnergySniper, $EquipConfigIndex++] = "Disc"; -$AIEquipmentSet[LightEnergySniper, $EquipConfigIndex++] = "DiscAmmo"; -$AIEquipmentSet[LightEnergySniper, $EquipConfigIndex++] = "GrenadeLauncher"; -$AIEquipmentSet[LightEnergySniper, $EquipConfigIndex++] = "GrenadeLauncherAmmo"; -$AIEquipmentSet[LightEnergySniper, $EquipConfigIndex++] = "SniperRifle"; -$AIEquipmentSet[LightEnergySniper, $EquipConfigIndex++] = "TargetingLaser"; -$AIEquipmentSet[LightEnergySniper, $EquipConfigIndex++] = "RepairKit"; -$AIEquipmentSet[LightEnergySniper, $EquipConfigIndex++] = "Grenade"; -$AIEquipmentSet[LightEnergySniper, $EquipConfigIndex++] = "Mine"; - -$EquipConfigIndex = -1; -$AIEquipmentSet[LightEnergyELF, $EquipConfigIndex++] = "Light"; -$AIEquipmentSet[LightEnergyELF, $EquipConfigIndex++] = "EnergyPack"; -$AIEquipmentSet[LightEnergyELF, $EquipConfigIndex++] = "Chaingun"; -$AIEquipmentSet[LightEnergyELF, $EquipConfigIndex++] = "ChaingunAmmo"; -$AIEquipmentSet[LightEnergyELF, $EquipConfigIndex++] = "Disc"; -$AIEquipmentSet[LightEnergyELF, $EquipConfigIndex++] = "DiscAmmo"; -$AIEquipmentSet[LightEnergyELF, $EquipConfigIndex++] = "ELFGun"; -$AIEquipmentSet[LightEnergyELF, $EquipConfigIndex++] = "TargetingLaser"; -$AIEquipmentSet[LightEnergyELF, $EquipConfigIndex++] = "RepairKit"; -$AIEquipmentSet[LightEnergyELF, $EquipConfigIndex++] = "Grenade"; -$AIEquipmentSet[LightEnergyELF, $EquipConfigIndex++] = "Mine"; - -$EquipConfigIndex = -1; -$AIEquipmentSet[LightShieldSet, $EquipConfigIndex++] = "Light"; -$AIEquipmentSet[LightShieldSet, $EquipConfigIndex++] = "ShieldPack"; -$AIEquipmentSet[LightShieldSet, $EquipConfigIndex++] = "Plasma"; -$AIEquipmentSet[LightShieldSet, $EquipConfigIndex++] = "PlasmaAmmo"; -$AIEquipmentSet[LightShieldSet, $EquipConfigIndex++] = "Disc"; -$AIEquipmentSet[LightShieldSet, $EquipConfigIndex++] = "DiscAmmo"; -$AIEquipmentSet[LightShieldSet, $EquipConfigIndex++] = "GrenadeLauncher"; -$AIEquipmentSet[LightShieldSet, $EquipConfigIndex++] = "GrenadeLauncherAmmo"; -$AIEquipmentSet[LightShieldSet, $EquipConfigIndex++] = "TargetingLaser"; -$AIEquipmentSet[LightShieldSet, $EquipConfigIndex++] = "RepairKit"; -$AIEquipmentSet[LightShieldSet, $EquipConfigIndex++] = "Grenade"; -$AIEquipmentSet[LightShieldSet, $EquipConfigIndex++] = "Mine"; - -$EquipConfigIndex = -1; -$AIEquipmentSet[LightCloakSet, $EquipConfigIndex++] = "Light"; -$AIEquipmentSet[LightCloakSet, $EquipConfigIndex++] = "CloakingPack"; -$AIEquipmentSet[LightCloakSet, $EquipConfigIndex++] = "Plasma"; -$AIEquipmentSet[LightCloakSet, $EquipConfigIndex++] = "PlasmaAmmo"; -$AIEquipmentSet[LightCloakSet, $EquipConfigIndex++] = "Disc"; -$AIEquipmentSet[LightCloakSet, $EquipConfigIndex++] = "DiscAmmo"; -$AIEquipmentSet[LightCloakSet, $EquipConfigIndex++] = "GrenadeLauncher"; -$AIEquipmentSet[LightCloakSet, $EquipConfigIndex++] = "GrenadeLauncherAmmo"; -$AIEquipmentSet[LightCloakSet, $EquipConfigIndex++] = "TargetingLaser"; -$AIEquipmentSet[LightCloakSet, $EquipConfigIndex++] = "RepairKit"; -$AIEquipmentSet[LightCloakSet, $EquipConfigIndex++] = "FlashGrenade"; -$AIEquipmentSet[LightCloakSet, $EquipConfigIndex++] = "Mine"; - -$EquipConfigIndex = -1; -$AIEquipmentSet[LightRepairSet, $EquipConfigIndex++] = "Light"; -$AIEquipmentSet[LightRepairSet, $EquipConfigIndex++] = "RepairPack"; -$AIEquipmentSet[LightRepairSet, $EquipConfigIndex++] = "Chaingun"; -$AIEquipmentSet[LightRepairSet, $EquipConfigIndex++] = "ChaingunAmmo"; -$AIEquipmentSet[LightRepairSet, $EquipConfigIndex++] = "Disc"; -$AIEquipmentSet[LightRepairSet, $EquipConfigIndex++] = "DiscAmmo"; -$AIEquipmentSet[LightRepairSet, $EquipConfigIndex++] = "GrenadeLauncher"; -$AIEquipmentSet[LightRepairSet, $EquipConfigIndex++] = "GrenadeLauncherAmmo"; -$AIEquipmentSet[LightRepairSet, $EquipConfigIndex++] = "TargetingLaser"; -$AIEquipmentSet[LightRepairSet, $EquipConfigIndex++] = "RepairKit"; -$AIEquipmentSet[LightRepairSet, $EquipConfigIndex++] = "Grenade"; -$AIEquipmentSet[LightRepairSet, $EquipConfigIndex++] = "Mine"; - -$EquipConfigIndex = -1; -$AIEquipmentSet[LightSniperChain, $EquipConfigIndex++] = "Light"; -$AIEquipmentSet[LightSniperChain, $EquipConfigIndex++] = "EnergyPack"; -$AIEquipmentSet[LightSniperChain, $EquipConfigIndex++] = "Disc"; -$AIEquipmentSet[LightSniperChain, $EquipConfigIndex++] = "DiscAmmo"; -$AIEquipmentSet[LightSniperChain, $EquipConfigIndex++] = "Chaingun"; -$AIEquipmentSet[LightSniperChain, $EquipConfigIndex++] = "ChaingunAmmo"; -$AIEquipmentSet[LightSniperChain, $EquipConfigIndex++] = "SniperRifle"; -$AIEquipmentSet[LightSniperChain, $EquipConfigIndex++] = "TargetingLaser"; -$AIEquipmentSet[LightSniperChain, $EquipConfigIndex++] = "RepairKit"; -$AIEquipmentSet[LightSniperChain, $EquipConfigIndex++] = "Grenade"; -$AIEquipmentSet[LightSniperChain, $EquipConfigIndex++] = "Mine"; +//------------------------------ +//AI Inventory functions + +function AINeedEquipment(%equipmentList, %client) +{ + %index = 0; + %item = getWord(%equipmentList, %index); + + //first, see if we're testing the armor class as well... + if (%item $= "Heavy" || %item $= "Medium" || %item $= "Light") + { + if (%client.player.getArmorSize() !$= %item) + return true; + %index++; + %item = getWord(%equipmentList, %index); + } + + while (%item !$= "") + { + if (%client.player.getInventory(%item) == 0) + return true; + + //get the next item + %index++; + %item = getWord(%equipmentList, %index); + } + + //made it through the list without needing anything + return false; +} + +function AIBuyInventory(%client, %requiredEquipment, %equipmentSets, %buyInvTime) +{ + //make sure we have a live player + %player = %client.player; + if (!isObject(%player)) + return "Failed"; + + if (! AIClientIsAlive(%client)) + return "Failed"; + + //see if we've already initialized our state machine + if (%client.buyInvTime == %buyInvTime) + return AIProcessBuyInventory(%client); + + //if the closest inv station is not a remote, buy the first available set... + %result = AIFindClosestInventory(%client, false); + %closestInv = getWord(%result, 0); + %closestDist = getWord(%result, 1); + if (%closestInv <= 0) + return "Failed"; + + //see if the closest inv station was a remote + %buyingSet = false; + %usingRemote = false; + if (%closestInv.getDataBlock().getName() $= "DeployedStationInventory") + { + //see if we can buy at least the required equipment from the set + if (%requiredEquipment !$= "") + { + if (! AIMustUseRegularInvStation(%requiredEquipment, %client)) + %canUseRemote = true; + else + %canUseRemote = false; + } + else + { + %inventorySet = AIFindSameArmorEquipSet(%equipmentSets, %client); + if (%inventorySet !$= "") + %canUseRemote = true; + else + %canUseRemote = false; + } + + //if we can't use a remote, we need to look for a regular inv station + if (! %canUseRemote) + { + %result = AIFindClosestInventory(%client, true); + %closestInv = getWord(%result, 0); + %closestDist = getWord(%result, 1); + if (%closestInv <= 0) + return "Failed"; + } + else + %usingRemote = true; + } + + //at this point we've found the closest inv, see which set/list we need to buy + if (!%usingRemote) + { + //choose the equipment first equipment set + if (%equipmentSets !$= "") + { + %inventorySet = getWord(%equipmentSets, 0); + %buyingSet = true; + } + else + { + %inventorySet = %requiredEquipment; + %buyingSet = false; + } + } + else + { + %inventorySet = AIFindSameArmorEquipSet(%equipmentSets, %client); + if (%inventorySet $= "") + { + %inventorySet = %requiredEquipment; + %buyingSet = false; + } + else + %buyingSet = true; + } + + //init some vars for the state machine... + %client.buyInvTime = %buyInvTime; //used to mark the begining of the inv buy session + %client.invToUse = %closestInv; //used if we need to go to an alternate inv station + %client.invWaitTime = ""; //used to track how long we've been waiting + %client.invBuyList = %inventorySet; //the list/set of items we're going to buy... + %client.buyingSet = %buyingSet; //whether it's a list or a set... + %client.isSeekingInv = false; + %client.seekingInv = ""; + + //now process the state machine + return AIProcessBuyInventory(%client); +} + +function AIProcessBuyInventory(%client) +{ + //get some vars + %player = %client.player; + if (!isObject(%player)) + return "Failed"; + + %closestInv = %client.invToUse; + %inventorySet = %client.invBuyList; + %buyingSet = %client.buyingSet; + + //make sure it's still valid, enabled, and on our team + if (! (%closestInv > 0 && isObject(%closestInv) && + (%closestInv.team <= 0 || %closestInv.team == %client.team) && %closestInv.isEnabled())) + { + //reset the state machine + %client.buyInvTime = 0; + return "InProgress"; + } + + //make sure the inventory station is not blocked + %invLocation = %closestInv.getWorldBoxCenter(); + InitContainerRadiusSearch(%invLocation, 2, $TypeMasks::PlayerObjectType); + %objSrch = containerSearchNext(); + if (%objSrch == %client.player) + %objSrch = containerSearchNext(); + + //the closestInv is busy... + if (%objSrch > 0) + { + //have the AI range the inv + if (%client.seekingInv $= "" || %client.seekingInv != %closestInv) + { + %client.invWaitTime = ""; + %client.seekingInv = %closestInv; + %client.stepRangeObject(%closestInv, "DefaultRepairBeam", 5, 10); + } + + //inv is still busy - see if we're within range + else if (%client.getStepStatus() $= "Finished") + { + //initialize the wait time + if (%client.invWaitTime $= "") + %client.invWaitTime = getSimTime() + 5000 + (getRandom() * 10000); + + //else see if we've waited long enough + else if (getSimTime() > %client.invWaitTime) + { + schedule(250, %client, "AIPlayAnimSound", %client, %objSrch.getWorldBoxCenter(), "vqk.move", -1, -1, 0); + %client.invWaitTime = getSimTime() + 5000 + (getRandom() * 10000); + } + } + else + { + //in case we got bumped, and are ranging the target again... + %client.invWaitTime = ""; + } + } + + //else if we've triggered the inv, automatically give us the equipment... + else if (isObject(%closestInv) && isObject(%closestInv.trigger) && VectorDist(%closestInv.trigger.getWorldBoxCenter(), %player.getWorldBoxCenter()) < 1.5) + { + //first stop... + %client.stop(); + + %index = 0; + if (%buyingSet) + { + //first, clear the players inventory + %player.clearInventory(); + %item = $AIEquipmentSet[%inventorySet, %index]; + } + else + %item = getWord(%inventorySet, %index); + + + //armor must always be bought first + if (%item $= "Light" || %item $= "Medium" || %item $= "Heavy") + { + %player.setArmor(%item); + %index++; + } + + //set the data block after the armor had been upgraded + %playerDataBlock = %player.getDataBlock(); + + //next, loop through the inventory set, and buy each item + if (%buyingSet) + %item = $AIEquipmentSet[%inventorySet, %index]; + else + %item = getWord(%inventorySet, %index); + while (%item !$= "") + { + //set the inventory amount to the maximum quantity available + if (%player.getInventory(AmmoPack) > 0) + %ammoPackQuantity = AmmoPack.max[%item]; + else + %ammoPackQuantity = 0; + + %quantity = %player.getDataBlock().max[%item] + %ammoPackQuantity; + if ($InvBanList[$CurrentMissionType, %item]) + %quantity = 0; + %player.setInventory(%item, %quantity); + + //get the next item + %index++; + if (%buyingSet) + %item = $AIEquipmentSet[%inventorySet, %index]; + else + %item = getWord(%inventorySet, %index); + } + + //put a weapon in the bot's hand... + %player.cycleWeapon(); + + //return a success + return "Finished"; + } + + //else, keep moving towards the inv station + else + { + if (isObject(%closestInv) && isObject(%closestInv.trigger)) + { + //quite possibly we may need to deal with what happens if a bot doesn't have a path to the inv... + //the current premise is that no inventory stations are "unpathable"... + //if (%client.isSeekingInv) + //{ + // %dist = %client.getPathDistance(%closestInv.trigger.getWorldBoxCenter()); + // if (%dist < 0) + // error("DEBUG Tinman - still need to handle bot stuck trying to get to an inv!"); + //} + + %client.stepMove(%closestInv.trigger.getWorldBoxCenter(), 1.5); + %client.isSeekingInv = true; + } + return "InProgress"; + } +} + +function AIFindSameArmorEquipSet(%equipmentSets, %client) +{ + %clientArmor = %client.player.getArmorSize(); + %index = 0; + %set = getWord(%equipmentSets, %index); + while (%set !$= "") + { + if ($AIEquipmentSet[%set, 0] $= %clientArmor) + return %set; + + //get the next equipment set in the list of sets + %index++; + %set = getWord(%equipmentSets, %index); + } + return ""; +} + +function AIMustUseRegularInvStation(%equipmentList, %client) +{ + %clientArmor = %client.player.getArmorSize(); + + //first, see if the set contains an item not available + %needRemoteInv = false; + %index = 0; + %item = getWord(%equipmentList, 0); + while (%item !$= "") + { + if (%item $= "InventoryDeployable" || (%clientArmor !$= "Light" && %item $= "SniperRifle") || + (%clientArmor $= "Light" && (%item $= "Mortar" || %item $= "MissileLauncher"))) + { + return true; + } + else + { + %index++; + %item = getWord(%equipmentList, %index); + } + } + if (%needRemoteInv) + return true; + + + //otherwise, see if the set begins with an armor class + %needArmor = %equipmentList[0]; + if (%needArmor !$= "Light" && %needArmor !$= "Medium" && %needArmor !$= "Heavy") + return false; + + //also including looking for an inventory set + if (%needArmor != %client.player.getArmorSize()) + return true; + + //we must be fine... + return false; +} + +function AICouldUseItem(%client, %item) +{ + if(!AIClientIsAlive(%client)) + return false; + + %player = %client.player; + if (!isObject(%player)) + return false; + + %playerDataBlock = %client.player.getDataBlock(); + %armor = %player.getArmorSize(); + %type = %item.getDataBlock().getName(); + + //check packs first + if (%type $= "RepairPack" || %type $= "EnergyPack" || %type $= "ShieldPack" || + %type $= "CloakingPack" || %type $= "AmmoPack") + { + if (%client.player.getMountedImage($BackpackSlot) <= 0) + return true; + else + return false; + } + + //if the item is acutally, a corpse, check the corpse inventory... + if (%item.isCorpse) + { + %corpse = %item; + if (%corpse.getInventory("ChainGunAmmo") > 0 && %player.getInventory(%type) < %playerDataBlock.max[ChainGunAmmo]) + return true; + if (%corpse.getInventory("PlasmaAmmo") > 0 && %player.getInventory(%type) < %playerDataBlock.max[PlasmaAmmo]) + return true; + if (%corpse.getInventory("DiscAmmo") > 0 && %player.getInventory(%type) < %playerDataBlock.max[DiscAmmo]) + return true; + if (%corpse.getInventory("GrenadeLauncher") > 0 && %player.getInventory(%type) < %playerDataBlock.max[GrenadeLauncher]) + return true; + if (%corpse.getInventory("MortarAmmo") > 0 && %player.getInventory(%type) < %playerDataBlock.max[MortarAmmo] && %player.getInventory("Mortar") > 0) + return true; + } + else + { + //check ammo + %quantity = mFloor(%playerDataBlock.max[%type]); + if (%player.getInventory(%type) < %quantity) + { + if (%type $= "ChainGunAmmo") + return true; + if (%type $= "PlasmaAmmo") + return true; + if (%type $= "DiscAmmo") + return true; + if (%type $= "GrenadeLauncher") + return true; + if (%type $= "MortarAmmo" && %player.getInventory("Mortar") > 0) + return true; + + //check mines and grenades as well + if (%type $= "Grenade" || %type $= "FlashGrenade" || %type $= "ConcussionGrenade") + return true; + } + + //see if we can carry another weapon... + if (AICanPickupWeapon(%client, %type)) + return true; + } + + //guess we didn't find anything useful... (should still check for mines and grenades) + return false; +} + +function AIEngageOutofAmmo(%client) +{ + //this function only cares about weapons used in engagement... + //no mortars, or missiles + %player = %client.player; + if (!isObject(%player)) + return false; + + %ammoWeapons = 0; + %energyWeapons = 0; + + //get our inventory + %hasBlaster = (%player.getInventory("Blaster") > 0); + %hasPlasma = (%player.getInventory("Plasma") > 0); + %hasChain = (%player.getInventory("Chaingun") > 0); + %hasDisc = (%player.getInventory("Disc") > 0); + %hasGrenade = (%player.getInventory("GrenadeLauncher") > 0); + %hasSniper = (%player.getInventory("SniperRifle") > 0) && (%player.getInventory("EnergyPack") > 0); + %hasELF = (%player.getInventory("ELFGun") > 0); + %hasMortar = (%player.getInventory("Mortar") > 0); + %hasMissile = (%player.getInventory("MissileLauncher") > 0); + %hasLance = (%player.getInventory("ShockLance") > 0); + + if (%hasBlaster || %hasSniper || %hasElf || %hasLance) + return false; + else + { + // we only have ammo type weapons + if(%hasDisc && (%player.getInventory("DiscAmmo") > 0)) + return false; + else if(%hasChain && (%player.getInventory("ChainGunAmmo") > 0)) + return false; + else if(%hasGrenade && (%player.getInventory("GrenadeLauncherAmmo") > 0)) + return false; + else if(%hasPlasma && (%player.getInventory("PlasmaAmmo") > 0)) + return false; + } + return true; // were out! +} + +function AICanPickupWeapon(%client, %weapon) +{ + //first, make sure it's not a weapon we already have... + %player = %client.player; + if (!isObject(%player)) + return false; + + %armor = %player.getArmorSize(); + if (%player.getInventory(%weapon) > 0) + return false; + + //make sure the %weapon given is a weapon they can use for engagement + if (%weapon !$= "Blaster" && %weapon !$= "Plasma" && %weapon !$= "Chaingun" && %weapon !$= "Disc" && + %weapon !$= "GrenadeLauncher" && %weapon !$= "SniperRifle" && %weapon !$= "ELFGun" && %weapon !$= "ShockLance") + { + return false; + } + + %weaponCount = 0; + if (%player.getInventory("Blaster") > 0) + %weaponCount++; + if (%player.getInventory("Plasma") > 0) + %weaponCount++; + if (%player.getInventory("Chaingun") > 0) + %weaponCount++; + if (%player.getInventory("Disc") > 0) + %weaponCount++; + if (%player.getInventory("GrenadeLauncher") > 0) + %weaponCount++; + if (%player.getInventory("SniperRifle") > 0) + %weaponCount++; + if (%player.getInventory("ELFGun") > 0) + %weaponCount++; + if (%player.getInventory("Mortar") > 0) + %weaponCount++; + if (%player.getInventory("MissileLauncher") > 0) + %weaponCount++; + if (%player.getInventory("ShockLance") > 0) + %weaponCount++; + + if ((%armor $= "Light" && %weaponCount < 3) || (%armor $= "Medium" && %weaponCount < 4) || + (%armor $= "Heavy" && %weaponCount < 5)) + { + if ((%type $= "Mortar" && %armor !$= "Heavy") || (%type $= "MissileLauncher" && %armor $= "Light") || + (%type $= "SniperRifle" && %armor !$= "Light")) + return false; + else + return true; + } + + //else we're full of weapons already... + return false; +} + +function AIEngageWeaponRating(%client) +{ + %player = %client.player; + if (!isObject(%player)) + return; + + %playerDataBlock = %client.player.getDataBlock(); + + //get our inventory + %hasBlaster = (%player.getInventory("Blaster") > 0); + %hasPlasma = (%player.getInventory("Plasma") > 0 && %player.getInventory("PlasmaAmmo") >= 1); + %hasChain = (%player.getInventory("Chaingun") > 0 && %player.getInventory("ChaingunAmmo") >= 1); + %hasDisc = (%player.getInventory("Disc") > 0 && %player.getInventory("DiscAmmo") >= 1); + %hasGrenade = (%player.getInventory("GrenadeLauncher") > 0 && %player.getInventory("GrenadeLauncherAmmo") >= 1); + %hasSniper = (%player.getInventory("SniperRifle") > 0) && (%player.getInventory("EnergyPack") > 0); + %hasELF = (%player.getInventory("ELFGun") > 0); + + //check ammo + %quantity = mFloor(%playerDataBlock.max[%type] * 0.7); + + %rating = 0; + if (%hasBlaster) + %rating += 9; + if (%hasSniper) + %rating += 9; + if (%hasElf) + %rating += 9; + + if (%hasDisc) + { + %quantity = %player.getInventory("DiscAmmo") / %playerDataBlock.max["DiscAmmo"]; + %rating += 15 + (15 * %quantity); + } + if (%hasPlasma) + { + %quantity = %player.getInventory("PlasmaAmmo") / %playerDataBlock.max["PlasmaAmmo"]; + %rating += 15 + (15 * %quantity); + } + if (%hasChain) + { + %quantity = %player.getInventory("ChainGunAmmo") / %playerDataBlock.max["ChainGunAmmo"]; + %rating += 15 + (15 * %quantity); + } + +//not really an effective weapon for hand to hand... +// if (%hasGrenade) +// { +// %quantity = %player.getInventory("GrenadeLauncherAmmo") / %playerDataBlock.max["GrenadeLauncherAmmo"]; +// %rating += 10 + (15 * %quantity); +// } + + //note a rating of 20+ means at least two energy weapons, or an ammo weapon with at least 1/3 ammo... + return %rating; +} + +function AIFindSafeItem(%client, %needType) +{ + %player = %client.player; + if (!isObject(%player)) + return -1; + + %closestItem = -1; + %closestDist = 32767; + + %itemCount = $AIItemSet.getCount(); + for (%i = 0; %i < %itemCount; %i++) + { + %item = $AIItemSet.getObject(%i); + if (%item.isHidden()) + continue; + + %type = %item.getDataBlock().getName(); + if ((%needType $= "Health" && (%type $= "RepairKit" || %type $= "RepairPatch") && %player.getDamagePercent() > 0) || + (%needType $= "Ammo" && (%type $= "ChainGunAmmo" || %type $= "PlasmaAmmo" || %type $= "DiscAmmo" || + %type $= "GrenadeLauncherAmmo" || %type $= "MortarAmmo") && AICouldUseItem(%client, %item)) || + (%needType $= "Ammo" && AICanPickupWeapon(%type)) || + ((%needType $= "" || %needType $= "Any") && AICouldUseItem(%client, %item))) + { + //first, see if it's close to us... + %distance = %client.getPathDistance(%item.getTransform()); + if (%distance > 0 && %distance < %closestDist) + { + //now see if it's got bad enemies near it... + %clientCount = ClientGroup.getCount(); + for (%j = 0; %j < %clientCount; %j++) + { + %cl = ClientGroup.getObject(%j); + if (%cl == %client || %cl.team == %client.team || !AIClientIsAlive(%cl)) + continue; + + //if the enemy is stronger, see if they're close to the item + if (AIEngageWhoWillWin(%client, %cl) == %cl) + { + %tempDist = %client.getPathDistance(%item.getWorldBoxCenter()); + if (%tempDist > 0 && %tempDist < %distance + 50) + continue; + } + + //either no enemy, or a weaker one... + %closestItem = %item; + %closestDist = %distance; + } + } + } + } + + return %closestItem; +} + +function AIChooseObjectWeapon(%client, %targetObject, %distToTarg, %mode, %canUseEnergyStr, %environmentStr) +{ + //get our inventory + %player = %client.player; + if (!isObject(%player)) + return; + + if (!isObject(%targetObject)) + return; + + %canUseEnergy = (%canUseEnergyStr $= "true"); + %inWater = (%environmentStr $= "water"); + %hasBlaster = (%player.getInventory("Blaster") > 0) && %canUseEnergy; + %hasPlasma = (%player.getInventory("Plasma") > 0) && (%player.getInventory("PlasmaAmmo") > 0) && !%inWater; + %hasChain = (%player.getInventory("Chaingun") > 0) && (%player.getInventory("ChaingunAmmo") > 0); + %hasDisc = (%player.getInventory("Disc") > 0) && (%player.getInventory("DiscAmmo") > 0); + %hasGrenade = (%player.getInventory("GrenadeLauncher") > 0) && (%player.getInventory("GrenadeLauncherAmmo") > 0); + %hasMortar = (%player.getInventory("Mortar") > 0) && (%player.getInventory("MortarAmmo") > 0); + %hasRepairPack = (%player.getInventory("RepairPack") > 0) && %canUseEnergy; + %hasTargetingLaser = (%player.getInventory("TargetingLaser") > 0) && %canUseEnergy; + %hasMissile = (%player.getInventory("MissileLauncher") > 0) && (%player.getInventory("MissileLauncherAmmo") > 0); + + //see if we're destroying the object + if (%mode $= "Destroy") + { + if ((%targetObject.getDataBlock().getClassName() $= "TurretData" || + %targetObject.getDataBlock().getName() $= "MineDeployed") && %distToTarg < 50) + { + if (%hasPlasma) + %useWeapon = "Plasma"; + else if (%hasDisc) + %useWeapon = "Disc"; + else if (%hasBlaster) + %useWeapon = "Blaster"; + else if (%hasChain) + %useWeapon = "Chaingun"; + else + %useWeapon = "NoAmmo"; + } + else if (%distToTarg < 40) + { + if (%hasPlasma) + %useWeapon = "Plasma"; + else if (%hasChain) + %useWeapon = "Chaingun"; + else if (%hasBlaster) + %useWeapon = "Blaster"; + else if (%hasDisc) + %useWeapon = "Disc"; + else + %useWeapon = "NoAmmo"; + } + else + %useWeapon = "NoAmmo"; + } + + //else See if we're repairing the object + else if (%mode $= "Repair") + { + if (%hasRepairPack) + %useWeapon = "RepairPack"; + else + %useWeapon = "NoAmmo"; + } + + //else see if we're lazing the object + else if (%mode $= "Laze") + { + if (%hasTargetingLaser) + %useWeapon = "TargetingLaser"; + else + %useWeapon = "NoAmmo"; + } + + //else see if we're mortaring the object + else if (%mode $= "Mortar") + { + if (%hasMortar) + %useWeapon = "Mortar"; + else + %useWeapon = "NoAmmo"; + } + + //else see if we're rocketing the object + else if (%mode $= "Missile" || %mode $= "MissileNoLock") + { + if (%hasMissile) + %useWeapon = "MissileLauncher"; + else + %useWeapon = "NoAmmo"; + } + + //now select the weapon + switch$ (%useWeapon) + { + case "Blaster": + %client.player.use("Blaster"); + %client.setWeaponInfo("EnergyBolt", 25, 50, 1, 0.1); + + case "Plasma": + %client.player.use("Plasma"); + %client.setWeaponInfo("PlasmaBolt", 25, 50); + + case "Chaingun": + %client.player.use("Chaingun"); + %client.setWeaponInfo("ChaingunBullet", 30, 75, 150); + + case "Disc": + %client.player.use("Disc"); + %client.setWeaponInfo("DiscProjectile", 30, 75); + + case "GrenadeLauncher": + %client.player.use("GrenadeLauncher"); + %client.setWeaponInfo("BasicGrenade", 40, 75); + + case "Mortar": + %client.player.use("Mortar"); + %client.setWeaponInfo("MortarShot", 100, 350); + + case "RepairPack": + if (%player.getImageState($BackpackSlot) $= "Idle") + %client.player.use("RepairPack"); + %client.setWeaponInfo("DefaultRepairBeam", 40, 75, 300, 0.1); + + case "TargetingLaser": + %client.player.use("TargetingLaser"); + %client.setWeaponInfo("BasicTargeter", 20, 300, 300, 0.1); + + case "MissileLauncher": + %client.player.use("MissileLauncher"); + %client.setWeaponInfo("ShoulderMissile", 80, 300); + + case "NoAmmo": + %client.setWeaponInfo("NoAmmo", 30, 75); + } +} + +function AIChooseEngageWeapon(%client, %targetClient, %distToTarg, %canUseEnergyStr, %environmentStr) +{ + //get some status + %player = %client.player; + if (!isObject(%player)) + return; + + %enemy = %targetClient.player; + if (!isObject(%enemy)) + return; + + %canUseEnergy = (%canUseEnergyStr $= "true"); + %inWater = (%environmentStr $= "water"); + %outdoors = (%environmentStr $= "outdoors"); + %targVelocity = %targetClient.player.getVelocity(); + %targEnergy = %targetClient.player.getEnergyPercent(); + %targDamage = %targetClient.player.getDamagePercent(); + %myEnergy = %player.getEnergyPercent(); + %myDamage = %player.getDamagePercent(); + + //get our inventory + %hasBlaster = (%player.getInventory("Blaster") > 0) && %canUseEnergy; + %hasPlasma = (%player.getInventory("Plasma") > 0) && (%player.getInventory("PlasmaAmmo") > 0) && !%inWater; + %hasChain = (%player.getInventory("Chaingun") > 0) && (%player.getInventory("ChaingunAmmo") > 0); + %hasDisc = (%player.getInventory("Disc") > 0) && (%player.getInventory("DiscAmmo") > 0); + %hasGrenade = (%player.getInventory("GrenadeLauncher") > 0) && (%player.getInventory("GrenadeLauncherAmmo") > 0); + %hasSniper = (%player.getInventory("SniperRifle") > 0) && (%player.getInventory("EnergyPack") > 0) && %canUseEnergy && !%inWater; + %hasELF = (%player.getInventory("ELFGun") > 0) && %canUseEnergy && !%inWater; + %hasMortar = (%player.getInventory("Mortar") > 0) && (%player.getInventory("MortarAmmo") > 0); + %hasMissile = (%player.getInventory("MissileLauncher") > 0) && (%player.getInventory("MissileLauncherAmmo") > 0); + %hasShockLance = (%player.getInventory("ShockLance") > 0) && %canUseEnergy && !%inWater; + + //choose the weapon + %useWeapon = "NoAmmo"; + + //first, see if it's a pilot we're shooting + if (%dist > 50 && %enemy.isMounted() && %hasMissile) + { + %useWeapon = "MissileLauncher"; + } + else if (%distToTarg < 5 && %hasShockLance) + { + %useWeapon = "ShockLance"; + } + else if (%distToTarg < 15) + { + if (%hasELF && %myEnergy > 0.5 && %targEnergy > 0.3 && %myDamage < %targDamage && %targetZ > %myZ + 20) + %useWeapon = "ELFGun"; + else if (%hasPlasma) + %useWeapon = "Plasma"; + else if (%hasChain) + %useWeapon = "Chaingun"; + else if (%hasBlaster) + %useWeapon = "Blaster"; + else if (%hasELF && %targEnergy > 0.2) + %useWeapon = "ELFGun"; + else if (%hasDisc) + %useWeapon = "Disc"; + else if (%hasShockLance) + %useWeapon = "ShockLance"; + } + else if (%distToTarg < 35) + { + if (%hasELF && %targEnergy > 0.4 && (%myDamage < 0.3 || %myDamage - %targDamage < 0.2) && %targetZ > %myZ + 20) + %useWeapon = "ELFGun"; + else if (!%outdoors && %hasPlasma) + %useWeapon = "Plasma"; + else if (%hasChain && %hasDisc) + { + %speed = VectorDist("0 0 0", %targVelocity); + %myZ = getWord(%player.getTransform(), 2); + %targetZ = getWord(%enemy.getTransform(), 2); + %targetZVel = getWord(%targVelocity, 2); + + if (%speed > 15.0 || %targetZ > %myZ || %targetZVel > 1.0) + %useWeapon = "Chaingun"; + else + %useWeapon = "Disc"; + } + else if (%hasPlasma) + %useWeapon = "Plasma"; + else if (%hasChain) + %useWeapon = "Chaingun"; + else if (%hasDisc) + %useWeapon = "Disc"; + else if (%hasBlaster) + %useWeapon = "Blaster"; + } + else if (%distToTarg < 60) + { + if (%hasGrenade) + %useWeapon = "GrenadeLauncher"; + else if (%hasSniper && %myEnergy > 0.6) + %useWeapon = "SniperRifle"; + + } + else if (%distToTarg < 80) + { + if (%hasSniper && %myEnergy > 0.4) + %useWeapon = "SniperRifle"; + else if (%hasDisc) + %useWeapon = "Disc"; + else if (%hasChain) + %useWeapon = "Chaingun"; + else if (%hasBlaster) + %useWeapon = "Blaster"; + } + else + { + if (%hasSniper) + %useWeapon = "SniperRifle"; + } + + //now make sure we actually selected something + if (%useWeapon $= "NoAmmo") + { + if (%hasDisc) + %useWeapon = "Disc"; + else if (%hasChain) + %useWeapon = "Chaingun"; + else if (%hasPlasma) + %useWeapon = "Plasma"; + else if (%hasBlaster) + %useWeapon = "Blaster"; + else if (%hasELF) + %useWeapon = "ELFGun"; + else if (%hasSniper) + %useWeapon = "SniperRifle"; + else if (%hasShockLance) + %useWeapon = "ShockLance"; + else if (%hasGrenade) + %useWeapon = "GrenadeLauncher"; + else if (%hasMissile) + %useWeapon = "MissileLauncher"; + } + + //now select the weapon + switch$ (%useWeapon) + { + case "Blaster": + %client.player.use("Blaster"); + %client.setWeaponInfo("EnergyBolt", 25, 50, 1, 0.1); + + case "Plasma": + %client.player.use("Plasma"); + %client.setWeaponInfo("PlasmaBolt", 25, 50); + + case "Chaingun": + %client.player.use("Chaingun"); + %client.setWeaponInfo("ChaingunBullet", 30, 75, 150); + + case "Disc": + %client.player.use("Disc"); + %client.setWeaponInfo("DiscProjectile", 30, 75); + + case "GrenadeLauncher": + %client.player.use("GrenadeLauncher"); + %client.setWeaponInfo("BasicGrenade", 40, 75); + + case "SniperRifle": + %client.player.use("SniperRifle"); + %client.setWeaponInfo("BasicSniperShot", 80, 350, 1, 0.75, 0.5); + + case "ELFGun": + %client.player.use("ELFGun"); + %client.setWeaponInfo("BasicELF", 25, 45, 90, 0.1); + + case "ShockLance": + %client.player.use("ShockLance"); + %client.setWeaponInfo("BasicShocker", 0.5, 8, 1, 0.1); + + case "MissileLauncher": + %client.player.use("MissileLauncher"); + %client.setWeaponInfo("ShoulderMissile", 80, 350); + + case "NoAmmo": + %client.setWeaponInfo("NoAmmo", 30, 75); + } +} + +//function is called once per frame, to handle packs, healthkits, grenades, etc... +function AIProcessEngagement(%client, %target, %type, %projectile) +{ + //make sure we're still alive + if (! AIClientIsAlive(%client)) + return; + + //clear the pressFire + %client.pressFire(-1); + + //see if we have to use a repairkit + %player = %client.player; + if (!isObject(%player)) + return; + + if (%client.getSkillLevel() > 0.1 && %player.getDamagePercent() > 0.3 && %player.getInventory("RepairKit") > 0) + { + //add in a "skill" value to delay the using of the repair kit for up to 10 seconds... + %elapsedTime = getSimTime() - %client.lastDamageTime; + %skillValue = (1.0 - %client.getSkillLevel()) * (1.0 - %client.getSkillLevel()); + if (%elapsedTime > (%skillValue * 20000)) + %player.use("RepairKit"); + } + + //see if we've been blinded + if (%player.getWhiteOut() > 0.6) + %client.setBlinded(2000); + + //else see if there's a grenade in the vicinity... + else + { + %count = $AIGrenadeSet.getCount(); + for (%i = 0; %i < %count; %i++) + { + %grenade = $AIGrenadeSet.getObject(%i); + + //make sure the grenade isn't ours + if (%grenade.sourceObject.client != %client) + { + //see if it's within 15 m + if (VectorDist(%grenade.position, %client.player.position) < 15) + { + %client.setDangerLocation(%grenade.position, 20); + break; + } + } + } + } + + //if we're being hunted by a seeker projectile, throw a flare grenade + if (%player.getInventory("FlareGrenade") > 0) + { + %missileCount = MissileSet.getCount(); + for (%i = 0; %i < %missileCount; %i++) + { + %missile = MissileSet.getObject(%i); + if (%missile.getTargetObject() == %player) + { + //see if the missile is within range + if (VectorDist(%missile.getTransform(), %player.getTransform()) < 50) + { + %player.throwStrength = 1.5; + %player.use("FlareGrenade"); + break; + } + } + } + } + + //see what we're fighting + switch$ (%type) + { + case "player": + //make sure the target is alive + if (AIClientIsAlive(%target)) + { + //if the target is in range, and within 10-40 m, and heading in this direction, toss a grenade + if (!$AIDisableGrenades && %client.getSkillLevel() >= 0.3) + { + if (%player.getInventory("Grenade") > 0) + %grenadeType = "Grenade"; + else if (%player.getInventory("FlashGrenade") > 0) + %grenadeType = "FlashGrenade"; + else if (%player.getInventory("ConcussionGrenade") > 0) + %grenadeType = "ConcussionGrenade"; + else %grenadeType = ""; + if (%grenadeType !$= "" && %client.targetInSight()) + { + //see if the predicted location of the target is within 10m + %targPos = %target.player.getWorldBoxCenter(); + %clientPos = %player.getWorldBoxCenter(); + + //make sure we're not *way* above the target + if (getWord(%clientPos, 2) - getWord(%targPos, 2) < 3) + { + %dist = VectorDist(%targPos, %clientPos); + %direction = VectorDot(VectorSub(%clientPos, %targPos), %target.player.getVelocity()); + %facing = VectorDot(VectorSub(%client.getAimLocation(), %clientPos), VectorSub(%targPos, %clientPos)); + if (%dist > 20 && %dist < 45 && (%direction > 0.9 || %direction < -0.9) && (%facing > 0.9)) + { + %player.throwStrength = 1.0; + %player.use(%grenadeType); + } + } + } + } + + //see if we have a shield pack that we need to use + if (%player.getInventory("ShieldPack") > 0) + { + if (%projectile > 0 && %player.getImageState($BackpackSlot) $= "Idle") + { + %player.use("Backpack"); + } + else if (%projectile <= 0 && %player.getImageState($BackpackSlot) $= "activate") + { + %player.use("Backpack"); + } + } + } + + case "object": + %hasGrenade = %player.getInventory("Grenade"); + if (%hasGrenade && %client.targetInRange()) + { + %targPos = %target.getWorldBoxCenter(); + %myPos = %player.getWorldBoxCenter(); + %dist = VectorDist(%targPos, %myPos); + if (%dist > 5 && %dist < 20) + { + %player.throwStrength = 1.0; + %player.use("Grenade"); + } + } + + case "none": + //use the repair pack if we have one + if (%player.getDamagePercent() > 0 && %player.getInventory(RepairPack) > 0) + { + if (%player.getImageState($BackpackSlot) $= "Idle") + %client.player.use("RepairPack"); + else + //sustain the fire for 30 frames - this callback is timesliced... + %client.pressFire(30); + } + } +} + +function AIFindClosestInventory(%client, %armorChange) +{ + %closestInv = -1; + %closestDist = 32767; + + %depCount = 0; + %depGroup = nameToID("MissionCleanup/Deployables"); + if (%depGroup > 0) + %depCount = %depGroup.getCount(); + + // there exists a deployed station, lets find it + if(!%armorChange && %depCount > 0) + { + for(%i = 0; %i < %depCount; %i++) + { + %obj = %depGroup.getObject(%i); + + if(%obj.getDataBlock().getName() $= "DeployedStationInventory" && %obj.team == %client.team && %obj.isEnabled()) + { + %distance = %client.getPathDistance(%obj.getTransform()); + if (%distance > 0 && %distance < %closestDist) + { + %closestInv = %obj; + %closestDist = %distance; + } + } + } + } + + // still check if there is one that is closer + %invCount = $AIInvStationSet.getCount(); + for (%i = 0; %i < %invCount; %i++) + { + %invStation = $AIInvStationSet.getObject(%i); + if (%invStation.team <= 0 || %invStation.team == %client.team) + { + //error("DEBUG: found an inventory station: " @ %invStation @ " status: " @ %invStation.isPowered()); + //make sure the station is powered + if (!%invStation.isDisabled() && %invStation.isPowered()) + { + %dist = %client.getPathDistance(%invStation.getTransform()); + if (%dist > 0 && %dist < %closestDist) + { + %closestInv = %invStation; + %closestDist = %dist; + } + } + } + } + + return %closestInv @ " " @ %closestDist; +} + +//------------------------------ +//find the closest inventories for the objective weight functions +function AIFindClosestInventories(%client) +{ + %closestInv = -1; + %closestDist = 32767; + %closestRemoteInv = -1; + %closestRemoteDist = 32767; + + %depCount = 0; + %depGroup = nameToID("MissionCleanup/Deployables"); + + //first, search for the nearest deployable inventory station + if (isObject(%depGroup)) + { + %depCount = %depGroup.getCount(); + for (%i = 0; %i < %depCount; %i++) + { + %obj = %depGroup.getObject(%i); + + if (%obj.getDataBlock().getName() $= "DeployedStationInventory" && %obj.team == %client.team && %obj.isEnabled()) + { + %distance = %client.getPathDistance(%obj.getTransform()); + if (%distance > 0 && %distance < %closestRemoteDist) + { + %closestRemoteInv = %obj; + %closestRemoteDist = %distance; + } + } + } + } + + // now find the closest regular inventory station + %invCount = $AIInvStationSet.getCount(); + for (%i = 0; %i < %invCount; %i++) + { + %invStation = $AIInvStationSet.getObject(%i); + if (%invStation.team <= 0 || %invStation.team == %client.team) + { + //make sure the station is powered + if (!%invStation.isDisabled() && %invStation.isPowered()) + { + %dist = %client.getPathDistance(%invStation.getTransform()); + if (%dist > 0 && %dist < %closestDist) + { + %closestInv = %invStation; + %closestDist = %dist; + } + } + } + } + + //if the regular inv station is closer than the deployed, don't bother with the remote + if (%closestDist < %closestRemoteDist) + %returnStr = %closestInv SPC %closestDist; + else + %returnStr = %closestInv SPC %closestDist SPC %closestRemoteInv SPC %closestRemoteDist; + + return %returnStr; +} + +//------------------------------ +//AI Equipment Configs +$EquipConfigIndex = -1; +$AIEquipmentSet[HeavyAmmoSet, $EquipConfigIndex++] = "Heavy"; +$AIEquipmentSet[HeavyAmmoSet, $EquipConfigIndex++] = "AmmoPack"; +$AIEquipmentSet[HeavyAmmoSet, $EquipConfigIndex++] = "Plasma"; +$AIEquipmentSet[HeavyAmmoSet, $EquipConfigIndex++] = "PlasmaAmmo"; +$AIEquipmentSet[HeavyAmmoSet, $EquipConfigIndex++] = "Chaingun"; +$AIEquipmentSet[HeavyAmmoSet, $EquipConfigIndex++] = "ChaingunAmmo"; +$AIEquipmentSet[HeavyAmmoSet, $EquipConfigIndex++] = "Disc"; +$AIEquipmentSet[HeavyAmmoSet, $EquipConfigIndex++] = "DiscAmmo"; +$AIEquipmentSet[HeavyAmmoSet, $EquipConfigIndex++] = "GrenadeLauncher"; +$AIEquipmentSet[HeavyAmmoSet, $EquipConfigIndex++] = "GrenadeLauncherAmmo"; +$AIEquipmentSet[HeavyAmmoSet, $EquipConfigIndex++] = "Mortar"; +$AIEquipmentSet[HeavyAmmoSet, $EquipConfigIndex++] = "MortarAmmo"; +$AIEquipmentSet[HeavyAmmoSet, $EquipConfigIndex++] = "RepairKit"; +$AIEquipmentSet[HeavyAmmoSet, $EquipConfigIndex++] = "Grenade"; +$AIEquipmentSet[HeavyAmmoSet, $EquipConfigIndex++] = "Mine"; + +$EquipConfigIndex = -1; +$AIEquipmentSet[HeavyShieldSet, $EquipConfigIndex++] = "Heavy"; +$AIEquipmentSet[HeavyShieldSet, $EquipConfigIndex++] = "ShieldPack"; +$AIEquipmentSet[HeavyShieldSet, $EquipConfigIndex++] = "Plasma"; +$AIEquipmentSet[HeavyShieldSet, $EquipConfigIndex++] = "PlasmaAmmo"; +$AIEquipmentSet[HeavyShieldSet, $EquipConfigIndex++] = "Chaingun"; +$AIEquipmentSet[HeavyShieldSet, $EquipConfigIndex++] = "ChaingunAmmo"; +$AIEquipmentSet[HeavyShieldSet, $EquipConfigIndex++] = "Disc"; +$AIEquipmentSet[HeavyShieldSet, $EquipConfigIndex++] = "DiscAmmo"; +$AIEquipmentSet[HeavyShieldSet, $EquipConfigIndex++] = "GrenadeLauncher"; +$AIEquipmentSet[HeavyShieldSet, $EquipConfigIndex++] = "GrenadeLauncherAmmo"; +$AIEquipmentSet[HeavyShieldSet, $EquipConfigIndex++] = "Mortar"; +$AIEquipmentSet[HeavyShieldSet, $EquipConfigIndex++] = "MortarAmmo"; +$AIEquipmentSet[HeavyShieldSet, $EquipConfigIndex++] = "RepairKit"; +$AIEquipmentSet[HeavyShieldSet, $EquipConfigIndex++] = "Grenade"; +$AIEquipmentSet[HeavyShieldSet, $EquipConfigIndex++] = "Mine"; + +$EquipConfigIndex = -1; +$AIEquipmentSet[HeavyEnergySet, $EquipConfigIndex++] = "Heavy"; +$AIEquipmentSet[HeavyEnergySet, $EquipConfigIndex++] = "EnergyPack"; +$AIEquipmentSet[HeavyEnergySet, $EquipConfigIndex++] = "Plasma"; +$AIEquipmentSet[HeavyEnergySet, $EquipConfigIndex++] = "PlasmaAmmo"; +$AIEquipmentSet[HeavyEnergySet, $EquipConfigIndex++] = "Disc"; +$AIEquipmentSet[HeavyEnergySet, $EquipConfigIndex++] = "DiscAmmo"; +$AIEquipmentSet[HeavyEnergySet, $EquipConfigIndex++] = "GrenadeLauncher"; +$AIEquipmentSet[HeavyEnergySet, $EquipConfigIndex++] = "GrenadeLauncherAmmo"; +$AIEquipmentSet[HeavyEnergySet, $EquipConfigIndex++] = "ELFGun"; +$AIEquipmentSet[HeavyEnergySet, $EquipConfigIndex++] = "Mortar"; +$AIEquipmentSet[HeavyEnergySet, $EquipConfigIndex++] = "MortarAmmo"; +$AIEquipmentSet[HeavyEnergySet, $EquipConfigIndex++] = "RepairKit"; +$AIEquipmentSet[HeavyEnergySet, $EquipConfigIndex++] = "Grenade"; +$AIEquipmentSet[HeavyEnergySet, $EquipConfigIndex++] = "Mine"; + +$EquipConfigIndex = -1; +$AIEquipmentSet[HeavyRepairSet, $EquipConfigIndex++] = "Heavy"; +$AIEquipmentSet[HeavyRepairSet, $EquipConfigIndex++] = "RepairPack"; +$AIEquipmentSet[HeavyRepairSet, $EquipConfigIndex++] = "Chaingun"; +$AIEquipmentSet[HeavyRepairSet, $EquipConfigIndex++] = "ChaingunAmmo"; +$AIEquipmentSet[HeavyRepairSet, $EquipConfigIndex++] = "Disc"; +$AIEquipmentSet[HeavyRepairSet, $EquipConfigIndex++] = "DiscAmmo"; +$AIEquipmentSet[HeavyRepairSet, $EquipConfigIndex++] = "GrenadeLauncher"; +$AIEquipmentSet[HeavyRepairSet, $EquipConfigIndex++] = "GrenadeLauncherAmmo"; +$AIEquipmentSet[HeavyRepairSet, $EquipConfigIndex++] = "ELFGun"; +$AIEquipmentSet[HeavyRepairSet, $EquipConfigIndex++] = "Mortar"; +$AIEquipmentSet[HeavyRepairSet, $EquipConfigIndex++] = "MortarAmmo"; +$AIEquipmentSet[HeavyRepairSet, $EquipConfigIndex++] = "RepairKit"; +$AIEquipmentSet[HeavyRepairSet, $EquipConfigIndex++] = "Grenade"; +$AIEquipmentSet[HeavyRepairSet, $EquipConfigIndex++] = "Mine"; + +$EquipConfigIndex = -1; +$AIEquipmentSet[HeavyIndoorTurretSet, $EquipConfigIndex++] = "Heavy"; +$AIEquipmentSet[HeavyIndoorTurretSet, $EquipConfigIndex++] = "TurretIndoorDeployable"; +$AIEquipmentSet[HeavyIndoorTurretSet, $EquipConfigIndex++] = "Chaingun"; +$AIEquipmentSet[HeavyIndoorTurretSet, $EquipConfigIndex++] = "ChaingunAmmo"; +$AIEquipmentSet[HeavyIndoorTurretSet, $EquipConfigIndex++] = "Disc"; +$AIEquipmentSet[HeavyIndoorTurretSet, $EquipConfigIndex++] = "DiscAmmo"; +$AIEquipmentSet[HeavyIndoorTurretSet, $EquipConfigIndex++] = "GrenadeLauncher"; +$AIEquipmentSet[HeavyIndoorTurretSet, $EquipConfigIndex++] = "GrenadeLauncherAmmo"; +$AIEquipmentSet[HeavyIndoorTurretSet, $EquipConfigIndex++] = "ELFGun"; +$AIEquipmentSet[HeavyIndoorTurretSet, $EquipConfigIndex++] = "TargetingLaser"; +$AIEquipmentSet[HeavyIndoorTurretSet, $EquipConfigIndex++] = "RepairKit"; +$AIEquipmentSet[HeavyIndoorTurretSet, $EquipConfigIndex++] = "Grenade"; +$AIEquipmentSet[HeavyIndoorTurretSet, $EquipConfigIndex++] = "Mine"; + +$EquipConfigIndex = -1; +$AIEquipmentSet[HeavyInventorySet, $EquipConfigIndex++] = "Heavy"; +$AIEquipmentSet[HeavyInventorySet, $EquipConfigIndex++] = "InventoryDeployable"; +$AIEquipmentSet[HeavyInventorySet, $EquipConfigIndex++] = "Chaingun"; +$AIEquipmentSet[HeavyInventorySet, $EquipConfigIndex++] = "ChaingunAmmo"; +$AIEquipmentSet[HeavyInventorySet, $EquipConfigIndex++] = "Disc"; +$AIEquipmentSet[HeavyInventorySet, $EquipConfigIndex++] = "DiscAmmo"; +$AIEquipmentSet[HeavyInventorySet, $EquipConfigIndex++] = "GrenadeLauncher"; +$AIEquipmentSet[HeavyInventorySet, $EquipConfigIndex++] = "GrenadeLauncherAmmo"; +$AIEquipmentSet[HeavyInventorySet, $EquipConfigIndex++] = "ELFGun"; +$AIEquipmentSet[HeavyInventorySet, $EquipConfigIndex++] = "TargetingLaser"; +$AIEquipmentSet[HeavyInventorySet, $EquipConfigIndex++] = "RepairKit"; +$AIEquipmentSet[HeavyInventorySet, $EquipConfigIndex++] = "Grenade"; +$AIEquipmentSet[HeavyInventorySet, $EquipConfigIndex++] = "Mine"; + +//------------------------------ + +$EquipConfigIndex = -1; +$AIEquipmentSet[MediumRepairSet, $EquipConfigIndex++] = "Medium"; +$AIEquipmentSet[MediumRepairSet, $EquipConfigIndex++] = "RepairPack"; +$AIEquipmentSet[MediumRepairSet, $EquipConfigIndex++] = "Plasma"; +$AIEquipmentSet[MediumRepairSet, $EquipConfigIndex++] = "PlasmaAmmo"; +$AIEquipmentSet[MediumRepairSet, $EquipConfigIndex++] = "Chaingun"; +$AIEquipmentSet[MediumRepairSet, $EquipConfigIndex++] = "ChaingunAmmo"; +$AIEquipmentSet[MediumRepairSet, $EquipConfigIndex++] = "Disc"; +$AIEquipmentSet[MediumRepairSet, $EquipConfigIndex++] = "DiscAmmo"; +$AIEquipmentSet[MediumRepairSet, $EquipConfigIndex++] = "GrenadeLauncher"; +$AIEquipmentSet[MediumRepairSet, $EquipConfigIndex++] = "GrenadeLauncherAmmo"; +$AIEquipmentSet[MediumRepairSet, $EquipConfigIndex++] = "TargetingLaser"; +$AIEquipmentSet[MediumRepairSet, $EquipConfigIndex++] = "RepairKit"; +$AIEquipmentSet[MediumRepairSet, $EquipConfigIndex++] = "Grenade"; +$AIEquipmentSet[MediumRepairSet, $EquipConfigIndex++] = "Mine"; + +$EquipConfigIndex = -1; +$AIEquipmentSet[MediumShieldSet, $EquipConfigIndex++] = "Medium"; +$AIEquipmentSet[MediumShieldSet, $EquipConfigIndex++] = "ShieldPack"; +$AIEquipmentSet[MediumShieldSet, $EquipConfigIndex++] = "Plasma"; +$AIEquipmentSet[MediumShieldSet, $EquipConfigIndex++] = "PlasmaAmmo"; +$AIEquipmentSet[MediumShieldSet, $EquipConfigIndex++] = "Chaingun"; +$AIEquipmentSet[MediumShieldSet, $EquipConfigIndex++] = "ChaingunAmmo"; +$AIEquipmentSet[MediumShieldSet, $EquipConfigIndex++] = "Disc"; +$AIEquipmentSet[MediumShieldSet, $EquipConfigIndex++] = "DiscAmmo"; +$AIEquipmentSet[MediumShieldSet, $EquipConfigIndex++] = "GrenadeLauncher"; +$AIEquipmentSet[MediumShieldSet, $EquipConfigIndex++] = "GrenadeLauncherAmmo"; +$AIEquipmentSet[MediumShieldSet, $EquipConfigIndex++] = "TargetingLaser"; +$AIEquipmentSet[MediumShieldSet, $EquipConfigIndex++] = "RepairKit"; +$AIEquipmentSet[MediumShieldSet, $EquipConfigIndex++] = "Grenade"; +$AIEquipmentSet[MediumShieldSet, $EquipConfigIndex++] = "Mine"; + +$EquipConfigIndex = -1; +$AIEquipmentSet[MediumEnergySet, $EquipConfigIndex++] = "Medium"; +$AIEquipmentSet[MediumEnergySet, $EquipConfigIndex++] = "EnergyPack"; +$AIEquipmentSet[MediumEnergySet, $EquipConfigIndex++] = "Chaingun"; +$AIEquipmentSet[MediumEnergySet, $EquipConfigIndex++] = "ChaingunAmmo"; +$AIEquipmentSet[MediumEnergySet, $EquipConfigIndex++] = "Disc"; +$AIEquipmentSet[MediumEnergySet, $EquipConfigIndex++] = "DiscAmmo"; +$AIEquipmentSet[MediumEnergySet, $EquipConfigIndex++] = "GrenadeLauncher"; +$AIEquipmentSet[MediumEnergySet, $EquipConfigIndex++] = "GrenadeLauncherAmmo"; +$AIEquipmentSet[MediumEnergySet, $EquipConfigIndex++] = "ELFGun"; +$AIEquipmentSet[MediumEnergySet, $EquipConfigIndex++] = "TargetingLaser"; +$AIEquipmentSet[MediumEnergySet, $EquipConfigIndex++] = "RepairKit"; +$AIEquipmentSet[MediumEnergySet, $EquipConfigIndex++] = "Grenade"; +$AIEquipmentSet[MediumEnergySet, $EquipConfigIndex++] = "Mine"; + +$EquipConfigIndex = -1; +$AIEquipmentSet[MediumMissileSet, $EquipConfigIndex++] = "Medium"; +$AIEquipmentSet[MediumMissileSet, $EquipConfigIndex++] = "EnergyPack"; +$AIEquipmentSet[MediumMissileSet, $EquipConfigIndex++] = "Chaingun"; +$AIEquipmentSet[MediumMissileSet, $EquipConfigIndex++] = "ChaingunAmmo"; +$AIEquipmentSet[MediumMissileSet, $EquipConfigIndex++] = "Disc"; +$AIEquipmentSet[MediumMissileSet, $EquipConfigIndex++] = "DiscAmmo"; +$AIEquipmentSet[MediumMissileSet, $EquipConfigIndex++] = "MissileLauncher"; +$AIEquipmentSet[MediumMissileSet, $EquipConfigIndex++] = "MissileLauncherAmmo"; +$AIEquipmentSet[MediumMissileSet, $EquipConfigIndex++] = "ELFGun"; +$AIEquipmentSet[MediumMissileSet, $EquipConfigIndex++] = "TargetingLaser"; +$AIEquipmentSet[MediumMissileSet, $EquipConfigIndex++] = "RepairKit"; +$AIEquipmentSet[MediumMissileSet, $EquipConfigIndex++] = "Grenade"; +$AIEquipmentSet[MediumMissileSet, $EquipConfigIndex++] = "Mine"; + +$EquipConfigIndex = -1; +$AIEquipmentSet[MediumOutdoorTurretSet, $EquipConfigIndex++] = "Medium"; +$AIEquipmentSet[MediumOutdoorTurretSet, $EquipConfigIndex++] = "TurretOutdoorDeployable"; +$AIEquipmentSet[MediumOutdoorTurretSet, $EquipConfigIndex++] = "Chaingun"; +$AIEquipmentSet[MediumOutdoorTurretSet, $EquipConfigIndex++] = "ChaingunAmmo"; +$AIEquipmentSet[MediumOutdoorTurretSet, $EquipConfigIndex++] = "Disc"; +$AIEquipmentSet[MediumOutdoorTurretSet, $EquipConfigIndex++] = "DiscAmmo"; +$AIEquipmentSet[MediumOutdoorTurretSet, $EquipConfigIndex++] = "GrenadeLauncher"; +$AIEquipmentSet[MediumOutdoorTurretSet, $EquipConfigIndex++] = "GrenadeLauncherAmmo"; +$AIEquipmentSet[MediumOutdoorTurretSet, $EquipConfigIndex++] = "ELFGun"; +$AIEquipmentSet[MediumOutdoorTurretSet, $EquipConfigIndex++] = "RepairKit"; +$AIEquipmentSet[MediumOutdoorTurretSet, $EquipConfigIndex++] = "Grenade"; +$AIEquipmentSet[MediumOutdoorTurretSet, $EquipConfigIndex++] = "Mine"; + +$EquipConfigIndex = -1; +$AIEquipmentSet[MediumIndoorTurretSet, $EquipConfigIndex++] = "Medium"; +$AIEquipmentSet[MediumIndoorTurretSet, $EquipConfigIndex++] = "TurretIndoorDeployable"; +$AIEquipmentSet[MediumIndoorTurretSet, $EquipConfigIndex++] = "Chaingun"; +$AIEquipmentSet[MediumIndoorTurretSet, $EquipConfigIndex++] = "ChaingunAmmo"; +$AIEquipmentSet[MediumIndoorTurretSet, $EquipConfigIndex++] = "Disc"; +$AIEquipmentSet[MediumIndoorTurretSet, $EquipConfigIndex++] = "DiscAmmo"; +$AIEquipmentSet[MediumIndoorTurretSet, $EquipConfigIndex++] = "GrenadeLauncher"; +$AIEquipmentSet[MediumIndoorTurretSet, $EquipConfigIndex++] = "GrenadeLauncherAmmo"; +$AIEquipmentSet[MediumIndoorTurretSet, $EquipConfigIndex++] = "ELFGun"; +$AIEquipmentSet[MediumIndoorTurretSet, $EquipConfigIndex++] = "TargetingLaser"; +$AIEquipmentSet[MediumIndoorTurretSet, $EquipConfigIndex++] = "RepairKit"; +$AIEquipmentSet[MediumIndoorTurretSet, $EquipConfigIndex++] = "Grenade"; +$AIEquipmentSet[MediumIndoorTurretSet, $EquipConfigIndex++] = "Mine"; + +$EquipConfigIndex = -1; +$AIEquipmentSet[MediumInventorySet, $EquipConfigIndex++] = "Medium"; +$AIEquipmentSet[MediumInventorySet, $EquipConfigIndex++] = "InventoryDeployable"; +$AIEquipmentSet[MediumInventorySet, $EquipConfigIndex++] = "Chaingun"; +$AIEquipmentSet[MediumInventorySet, $EquipConfigIndex++] = "ChaingunAmmo"; +$AIEquipmentSet[MediumInventorySet, $EquipConfigIndex++] = "Disc"; +$AIEquipmentSet[MediumInventorySet, $EquipConfigIndex++] = "DiscAmmo"; +$AIEquipmentSet[MediumInventorySet, $EquipConfigIndex++] = "GrenadeLauncher"; +$AIEquipmentSet[MediumInventorySet, $EquipConfigIndex++] = "GrenadeLauncherAmmo"; +$AIEquipmentSet[MediumInventorySet, $EquipConfigIndex++] = "ELFGun"; +$AIEquipmentSet[MediumInventorySet, $EquipConfigIndex++] = "TargetingLaser"; +$AIEquipmentSet[MediumInventorySet, $EquipConfigIndex++] = "RepairKit"; +$AIEquipmentSet[MediumInventorySet, $EquipConfigIndex++] = "Grenade"; +$AIEquipmentSet[MediumInventorySet, $EquipConfigIndex++] = "Mine"; + +//------------------------------ + +$EquipConfigIndex = -1; +$AIEquipmentSet[LightEnergyDefault, $EquipConfigIndex++] = "Light"; +$AIEquipmentSet[LightEnergyDefault, $EquipConfigIndex++] = "EnergyPack"; +$AIEquipmentSet[LightEnergyDefault, $EquipConfigIndex++] = "Chaingun"; +$AIEquipmentSet[LightEnergyDefault, $EquipConfigIndex++] = "ChaingunAmmo"; +$AIEquipmentSet[LightEnergyDefault, $EquipConfigIndex++] = "Disc"; +$AIEquipmentSet[LightEnergyDefault, $EquipConfigIndex++] = "DiscAmmo"; +$AIEquipmentSet[LightEnergyDefault, $EquipConfigIndex++] = "GrenadeLauncher"; +$AIEquipmentSet[LightEnergyDefault, $EquipConfigIndex++] = "GrenadeLauncherAmmo"; +$AIEquipmentSet[LightEnergyDefault, $EquipConfigIndex++] = "TargetingLaser"; +$AIEquipmentSet[LightEnergyDefault, $EquipConfigIndex++] = "RepairKit"; +$AIEquipmentSet[LightEnergyDefault, $EquipConfigIndex++] = "Grenade"; +$AIEquipmentSet[LightEnergyDefault, $EquipConfigIndex++] = "Mine"; + +$EquipConfigIndex = -1; +$AIEquipmentSet[LightEnergySniper, $EquipConfigIndex++] = "Light"; +$AIEquipmentSet[LightEnergySniper, $EquipConfigIndex++] = "EnergyPack"; +$AIEquipmentSet[LightEnergySniper, $EquipConfigIndex++] = "Disc"; +$AIEquipmentSet[LightEnergySniper, $EquipConfigIndex++] = "DiscAmmo"; +$AIEquipmentSet[LightEnergySniper, $EquipConfigIndex++] = "GrenadeLauncher"; +$AIEquipmentSet[LightEnergySniper, $EquipConfigIndex++] = "GrenadeLauncherAmmo"; +$AIEquipmentSet[LightEnergySniper, $EquipConfigIndex++] = "SniperRifle"; +$AIEquipmentSet[LightEnergySniper, $EquipConfigIndex++] = "TargetingLaser"; +$AIEquipmentSet[LightEnergySniper, $EquipConfigIndex++] = "RepairKit"; +$AIEquipmentSet[LightEnergySniper, $EquipConfigIndex++] = "Grenade"; +$AIEquipmentSet[LightEnergySniper, $EquipConfigIndex++] = "Mine"; + +$EquipConfigIndex = -1; +$AIEquipmentSet[LightEnergyELF, $EquipConfigIndex++] = "Light"; +$AIEquipmentSet[LightEnergyELF, $EquipConfigIndex++] = "EnergyPack"; +$AIEquipmentSet[LightEnergyELF, $EquipConfigIndex++] = "Chaingun"; +$AIEquipmentSet[LightEnergyELF, $EquipConfigIndex++] = "ChaingunAmmo"; +$AIEquipmentSet[LightEnergyELF, $EquipConfigIndex++] = "Disc"; +$AIEquipmentSet[LightEnergyELF, $EquipConfigIndex++] = "DiscAmmo"; +$AIEquipmentSet[LightEnergyELF, $EquipConfigIndex++] = "ELFGun"; +$AIEquipmentSet[LightEnergyELF, $EquipConfigIndex++] = "TargetingLaser"; +$AIEquipmentSet[LightEnergyELF, $EquipConfigIndex++] = "RepairKit"; +$AIEquipmentSet[LightEnergyELF, $EquipConfigIndex++] = "Grenade"; +$AIEquipmentSet[LightEnergyELF, $EquipConfigIndex++] = "Mine"; + +$EquipConfigIndex = -1; +$AIEquipmentSet[LightShieldSet, $EquipConfigIndex++] = "Light"; +$AIEquipmentSet[LightShieldSet, $EquipConfigIndex++] = "ShieldPack"; +$AIEquipmentSet[LightShieldSet, $EquipConfigIndex++] = "Plasma"; +$AIEquipmentSet[LightShieldSet, $EquipConfigIndex++] = "PlasmaAmmo"; +$AIEquipmentSet[LightShieldSet, $EquipConfigIndex++] = "Disc"; +$AIEquipmentSet[LightShieldSet, $EquipConfigIndex++] = "DiscAmmo"; +$AIEquipmentSet[LightShieldSet, $EquipConfigIndex++] = "GrenadeLauncher"; +$AIEquipmentSet[LightShieldSet, $EquipConfigIndex++] = "GrenadeLauncherAmmo"; +$AIEquipmentSet[LightShieldSet, $EquipConfigIndex++] = "TargetingLaser"; +$AIEquipmentSet[LightShieldSet, $EquipConfigIndex++] = "RepairKit"; +$AIEquipmentSet[LightShieldSet, $EquipConfigIndex++] = "Grenade"; +$AIEquipmentSet[LightShieldSet, $EquipConfigIndex++] = "Mine"; + +$EquipConfigIndex = -1; +$AIEquipmentSet[LightCloakSet, $EquipConfigIndex++] = "Light"; +$AIEquipmentSet[LightCloakSet, $EquipConfigIndex++] = "CloakingPack"; +$AIEquipmentSet[LightCloakSet, $EquipConfigIndex++] = "Plasma"; +$AIEquipmentSet[LightCloakSet, $EquipConfigIndex++] = "PlasmaAmmo"; +$AIEquipmentSet[LightCloakSet, $EquipConfigIndex++] = "Disc"; +$AIEquipmentSet[LightCloakSet, $EquipConfigIndex++] = "DiscAmmo"; +$AIEquipmentSet[LightCloakSet, $EquipConfigIndex++] = "GrenadeLauncher"; +$AIEquipmentSet[LightCloakSet, $EquipConfigIndex++] = "GrenadeLauncherAmmo"; +$AIEquipmentSet[LightCloakSet, $EquipConfigIndex++] = "TargetingLaser"; +$AIEquipmentSet[LightCloakSet, $EquipConfigIndex++] = "RepairKit"; +$AIEquipmentSet[LightCloakSet, $EquipConfigIndex++] = "FlashGrenade"; +$AIEquipmentSet[LightCloakSet, $EquipConfigIndex++] = "Mine"; + +$EquipConfigIndex = -1; +$AIEquipmentSet[LightRepairSet, $EquipConfigIndex++] = "Light"; +$AIEquipmentSet[LightRepairSet, $EquipConfigIndex++] = "RepairPack"; +$AIEquipmentSet[LightRepairSet, $EquipConfigIndex++] = "Chaingun"; +$AIEquipmentSet[LightRepairSet, $EquipConfigIndex++] = "ChaingunAmmo"; +$AIEquipmentSet[LightRepairSet, $EquipConfigIndex++] = "Disc"; +$AIEquipmentSet[LightRepairSet, $EquipConfigIndex++] = "DiscAmmo"; +$AIEquipmentSet[LightRepairSet, $EquipConfigIndex++] = "GrenadeLauncher"; +$AIEquipmentSet[LightRepairSet, $EquipConfigIndex++] = "GrenadeLauncherAmmo"; +$AIEquipmentSet[LightRepairSet, $EquipConfigIndex++] = "TargetingLaser"; +$AIEquipmentSet[LightRepairSet, $EquipConfigIndex++] = "RepairKit"; +$AIEquipmentSet[LightRepairSet, $EquipConfigIndex++] = "Grenade"; +$AIEquipmentSet[LightRepairSet, $EquipConfigIndex++] = "Mine"; + +$EquipConfigIndex = -1; +$AIEquipmentSet[LightSniperChain, $EquipConfigIndex++] = "Light"; +$AIEquipmentSet[LightSniperChain, $EquipConfigIndex++] = "EnergyPack"; +$AIEquipmentSet[LightSniperChain, $EquipConfigIndex++] = "Disc"; +$AIEquipmentSet[LightSniperChain, $EquipConfigIndex++] = "DiscAmmo"; +$AIEquipmentSet[LightSniperChain, $EquipConfigIndex++] = "Chaingun"; +$AIEquipmentSet[LightSniperChain, $EquipConfigIndex++] = "ChaingunAmmo"; +$AIEquipmentSet[LightSniperChain, $EquipConfigIndex++] = "SniperRifle"; +$AIEquipmentSet[LightSniperChain, $EquipConfigIndex++] = "TargetingLaser"; +$AIEquipmentSet[LightSniperChain, $EquipConfigIndex++] = "RepairKit"; +$AIEquipmentSet[LightSniperChain, $EquipConfigIndex++] = "Grenade"; +$AIEquipmentSet[LightSniperChain, $EquipConfigIndex++] = "Mine"; diff --git a/scripts/aiNS.cs b/scripts/aiNS.cs index f705c00..a0d23ed 100644 --- a/scripts/aiNS.cs +++ b/scripts/aiNS.cs @@ -1,26 +1,26 @@ -function BOLGame::AIInit(%game) -{ - //call the default AIInit() function - AIInit(); -} - -function BOLGame::onAIRespawn(%game, %client) -{ - //add the default task - if (! %client.defaultTasksAdded) - { - %client.defaultTasksAdded = true; - %client.addTask(AIEngageTask); - %client.addTask(AIPickupItemTask); - // %client.addTask(AIUseInventoryTask); They spawn with the stuff they need - %client.addTask(AITauntCorpseTask); - %client.addTask(AIEngageTurretTask); - %client.addtask(AIDetectMineTask); - // %client.addTask(AIPatrolTask); They don't move unless told to - } - - //set the inv flag - %client.spawnUseInv = true; -} - - +function BOLGame::AIInit(%game) +{ + //call the default AIInit() function + AIInit(); +} + +function BOLGame::onAIRespawn(%game, %client) +{ + //add the default task + if (! %client.defaultTasksAdded) + { + %client.defaultTasksAdded = true; + %client.addTask(AIEngageTask); + %client.addTask(AIPickupItemTask); + // %client.addTask(AIUseInventoryTask); They spawn with the stuff they need + %client.addTask(AITauntCorpseTask); + %client.addTask(AIEngageTurretTask); + %client.addtask(AIDetectMineTask); + // %client.addTask(AIPatrolTask); They don't move unless told to + } + + //set the inv flag + %client.spawnUseInv = true; +} + + diff --git a/scripts/aiObjectives.cs b/scripts/aiObjectives.cs index e94dae4..eb61e70 100644 --- a/scripts/aiObjectives.cs +++ b/scripts/aiObjectives.cs @@ -1,3918 +1,3918 @@ -//------------------------------ -//AI Objective Q functions... - -$ObjectiveClientsSet = 0; -function AIObjectiveFindClients(%objective) -{ - //create and clear the set - if (! $ObjectiveClientsSet) - { - $ObjectiveClientsSet = new SimSet(); - MissionCleanup.add($ObjectiveClientSet); - } - $ObjectiveClientsSet.clear(); - - %clientCount = 0; - %count = ClientGroup.getCount(); - for(%i = 0; %i < %count; %i++) - { - %cl = ClientGroup.getObject(%i); - if (%cl.objective == %objective) - $ObjectiveClientsSet.add(%cl); - } - return $ObjectiveClientsSet.getCount(); -} - -function AIObjectiveGetClosestClient(%location, %team) -{ - if (%location $= "") - return -1; - - if (%team $= "") - %team = 0; - - %closestClient = -1; - %closestDistance = 32767; - %count = ClientGroup.getCount(); - for(%i = 0; %i < %count; %i++) - { - %cl = ClientGroup.getObject(%i); - if (%cl.isAIControlled() && (%cl.team == %team || %team == 0) && AIClientIsAlive(%cl)) - { - %testPos = %cl.player.getWorldBoxCenter(); - %distance = VectorDist(%location, %testPos); - if (%distance < %closestDistance) - { - %closestDistance = %distance; - %closestClient = %cl; - } - } - } - - return %closestClient; -} - -function AICountObjectives(%team) -{ - %objCount = 0; - %count = $ObjectiveQ[%team].getCount(); - for (%i = 0; %i < %count; %i++) - { - %grp = $ObjectiveQ[%team].getObject(%i); - if (%grp.getClassName() !$= "AIObjective") - %objCount += %grp.getCount(); - else - %objCount++; - } - error("DEBUG" SPC %team SPC "has" SPC %objCount SPC "objectives."); -} - -function AIAddTableObjective(%objective, %weight, %level, %bump, %position) -{ - $objTable[%position, objective] = %objective; - $objTable[%position, weight] = %weight; - $objTable[%position, level] = %level; - $objTable[%position, bump] = %bump; - $objTableCount = %position + 1; -} - -function AIChooseObjective(%client, %useThisObjectiveQ) -{ - //pick which objectiveQ to use, or use the default - if (%useThisObjectiveQ <= 0 && %client.team < 0) - return; - - if (%useThisObjectiveQ <= 0) - %useThisObjectiveQ = $ObjectiveQ[%client.team]; - - if (!isObject(%useThisObjectiveQ) || %useThisObjectiveQ.getCount() <= 0) - return; - - //since most objectives check for inventory, find the closest inventory stations first - %inventoryStr = AIFindClosestInventories(%client); - - //find the most appropriate objective - if (!%client.objective) - { - //note, the table is never empty, during the course of this function - AIAddTableObjective(0, 0, 0, 0, 0); - } - else - { - //should re-evaluate the current objective weight - but never decrease the weight!!! - %testWeight = %client.objective.weight(%client, %client.objectiveLevel, 0, %inventoryStr); - if (%testWeight <= 0 || %testWeight > %client.objectiveWeight) - %client.objectiveWeight = %testWeight; - - if (%client.objectiveWeight > 0) - AIAddTableObjective(%client.objective, %client.objectiveWeight, %client.objectiveLevel, 0, 0); - else - AIAddTableObjective(0, 0, 0, 0, 0); - } - - %objCount = %useThisObjectiveQ.getCount(); - for (%i = 0; %i < %objCount; %i++) - { - %objective = %useThisObjectiveQ.getObject(%i); - - //don't re-evaluate the client's own - if (%objective == %client.objective) - continue; - - //try this objective at each of the 4 weight levels to see if it is weighted higher - for (%level = 1; %level <= 4; %level++) - { - %minWeight = 0; - %bumpWeight = 0; - %bumpClient = ""; - - //we can bump clients off the objective for the first three levels - if (%level <= 3) - { - //if the objective is part of a group, check the whole group - if (%objective.group > 0) - { - %bumpClient = %objective.group.clientLevel[%level]; - %bumpWeight = %bumpClient.objectiveWeight; - } - else - { - %bumpClient = %objective.clientLevel[%level]; - %bumpWeight = %bumpClient.objectiveWeight; - } - } - - //find the minimum weight the objective must have to be considered - %minWeight = (%bumpWeight > $objTable[0, weight] ? %bumpWeight : $objTable[0, weight]); - - //evaluate the weight - %weight = %objective.weight(%client, %level, %minWeight, %inventoryStr); - - //make sure we got a valid weight - if (%weight <= 0) - break; - - //if it's the highest so far, it now replaces anything else in the table - if (%weight > $objTable[0, weight]) - { - //never bump someone unless you out- weight them - if (%weight > %bumpWeight) - { - AIAddTableObjective(%objective, %weight, %level, %bumpClient, 0); - - //no need to keep checking the other levels - break; - } - } - - //else if it's equal to the highest objective we've seen so far, and higher from our current objective - else if (%weight == $objTable[0, weight] && %weight > %client.objectiveWeight) - { - //never bump someone unless you outweigh them - if (%weight > %bumpWeight) - { - //if this wouldn't require us to bump someone, or the table is empty - if (%bumpWeight <= 0 || $objTable[0, weight] <= 0) - { - //if the table currently contains objectives which would require bumping someone, clear it - if ($objTable[0, bump] > 0) - %position = 0; - else - %position = $objTableCount; - - //add it to the table - AIAddTableObjective(%objective, %weight, %level, %bumpClient, %position); - - //no need to keep checking the other levels - break; - } - - //otherwise, the table is not empty, and this would require us to bump someone - //only add it if everything else in the table would also require us to bump someone - else if ($objTable[0, bump] > 0) - { - AIAddTableObjective(%objective, %weight, %level, %bumpClient, $objTableCount); - - //no need to keep checking the other levels - break; - } - } - } - - //else it must have been less than our highest objective so far- again, no need to keep checking other levels... - else - break; - } - } - - //if we have a table of possible objectives which are higher than our current- choose one at random - if ($objTableCount > 0 && $objTable[0, objective] != %client.objective) - { - //choose the new one - %index = mFloor(getRandom() * ($objTableCount - 0.01)); - - //clear the old objective - if (%client.objective) - { - if (%client.objectiveLevel <= 3) - { - if (%client.objective.group > 0) - { - if (%client.objective.group.clientLevel[%client.objectiveLevel] == %client) - %client.objective.group.clientLevel[%client.objectiveLevel] = ""; - } - else - { - if (%client.objective.clientLevel[%client.objectiveLevel] == %client) - %client.objective.clientLevel[%client.objectiveLevel] = ""; - } - } - %client.objective.unassignClient(%client); - } - - //assign the new - %chooseObjective = $objTable[%index, objective]; - %client.objective = %chooseObjective; - %client.objectiveWeight = $objTable[%index, weight]; - %client.objectiveLevel = $objTable[%index, level]; - if (%client.objectiveLevel <= 3) - { - if (%chooseObjective.group > 0) - %chooseObjective.group.clientLevel[%client.objectiveLevel] = %client; - else - %chooseObjective.clientLevel[%client.objectiveLevel] = %client; - } - %chooseObjective.assignClient(%client); - - //see if this objective needs to be acknowledged - if (%chooseObjective.shouldAcknowledge && %chooseObjective.issuedByHuman && isObject(%chooseObjective.issuedByClientId)) - { - //cancel any pending acknowledgements - a bot probably just got bumped off this objective - cancel(%chooseObjective.ackSchedule); - %chooseObjective.ackSchedule = schedule(5500, %chooseObjective, "AIAcknowledgeObjective", %client, %chooseObjective); - } - - //if we had to bump someone off this objective, - %bumpClient = $objTable[%index, bump]; - if (%bumpClient > 0) - { - //unassign the bumped client and choose a new objective - AIUnassignClient(%bumpClient); - Game.AIChooseGameObjective(%bumpClient); - } - } - - //debuging - refresh aidebugq() if required - //if ($AIDebugTeam >= 0) - // aiDebugQ($AIDebugTeam); -} - -function AIAcknowledgeObjective(%client, %objective) -{ - %objective.shouldAcknowledge = false; - //make sure the client is still assigned to this objective - if (%client.objective == %objective) - serverCmdAcceptTask(%client, %objective.issuedByClientId, -1, %objective.ackDescription); -} - -function AIForceObjective(%client, %newObjective, %useWeight) -{ - //if we found a new objective, release the old, and assign the new - if (%newObjective && %newObjective != %client.objective) - { - //see if someone was already assigned to this objective - if (%newObjective.group > 0) - %prevClient = newObjective.group.clientLevel[1]; - else - %prevClient = newObjective.clientLevel[1]; - if (%prevClient > 0) - AIUnassignClient(%prevClient); - - //see if we should override the weight - if (%useWeight < %newObjective.weightLevel1) - %useWeight = %newObjective.weightLevel1; - - //release the client, and force the assignment - AIUnassignClient(%client); - %client.objective = %newObjective; - %client.objectiveWeight = %useWeight; - %client.objectiveLevel = 1; - if (%newObjective.group > 0) - %newObjective.group.clientLevel[1] = %client; - else - %newObjective.clientLevel[1] = %client; - %newObjective.forceClientId = %client; - %newObjective.assignClient(%client); - - //don't acknowledge anything that's been forced... - %newObjective.shouldAcknowledge = false; - - //now reassign the prev client - if (%prevClient) - Game.AIChooseGameObjective(%prevClient); - } - - //debuging - refresh aidebugq() if required - //if ($AIDebugTeam >= 0) - // aiDebugQ($AIDebugTeam); -} - -function AIUnassignClient(%client) -{ - //first, dissolve any link with a human - aiReleaseHumanControl(%client.controlByHuman, %client); - - if (%client.objective) - { - if (%client.objectiveLevel <= 3) - { - if (%client.objective.group > 0) - { - //make sure the clientLevel was actually this client - if (%client.objective.group.clientLevel[%client.objectiveLevel] == %client) - %client.objective.group.clientLevel[%client.objectiveLevel] = ""; - } - else - { - if (%client.objective.clientLevel[%client.objectiveLevel] == %client) - %client.objective.clientLevel[%client.objectiveLevel] = ""; - } - } - // DDDX: Fixes some console spamming is all - if (isObject(%client.objective)) - %client.objective.unassignClient(%client); - %client.objective = ""; - %client.objectiveWeight = 0; - } - - //debuging - refresh aidebugq() if required - //if ($AIDebugTeam >= 0) - // aiDebugQ($AIDebugTeam); -} - -function AIClearObjective(%objective) -{ - %count = ClientGroup.getCount(); - for(%i = 0; %i < %count; %i++) - { - %cl = ClientGroup.getObject(%i); - if (%cl.objective == %objective) - AIUnassignClient(%cl); - } - - //debuging - refresh aidebugq() if required - //if ($AIDebugTeam >= 0) - // aiDebugQ($AIDebugTeam); -} - -//------------------------------ -//TASKS AND OBJECTIVES - -function AIDefendLocation::initFromObjective(%task, %objective, %client) -{ - //initialize the task vars from the objective - %task.baseWeight = %client.objectiveWeight; - %task.targetObject = %objective.targetObjectId; - if (%objective.Location !$= "") - %task.location = %objective.location; - else - %task.location = %objective.targetObjectId.getWorldBoxCenter(); - - %task.equipment = %objective.equipment; - %task.buyEquipmentSet = %objective.buyEquipmentSet; - %task.desiredEquipment = %objective.desiredEquipment; - %task.issuedByClient = %objective.issuedByClientId; - %task.chat = %objective.chat; - - //initialize other task vars - %task.sendMsg = true; - %task.sendMsgTime = 0; - - %task.engageTarget = -1; -} - -function AIDefendLocation::assume(%task, %client) -{ - %task.setWeightFreq(15); - %task.setMonitorFreq(15); - %client.inPerimeter = false; - %client.needEquipment = AINeedEquipment(%task.equipment, %client); - - //even if we don't *need* equipemnt, see if we should buy some... - if (! %client.needEquipment && %task.buyEquipmentSet !$= "") - { - //see if we could benefit from inventory - %needArmor = AIMustUseRegularInvStation(%task.desiredEquipment, %client); - %result = AIFindClosestInventory(%client, %needArmor); - %closestInv = getWord(%result, 0); - %closestDist = getWord(%result, 1); - if (AINeedEquipment(%task.desiredEquipment, %client) && %closestInv > 0) - { - %result = AIFindClosestEnemy(%client, 200, $AIClientLOSTimeout); - %closestEnemy = getWord(%result, 0); - %closestEnemydist = getWord(%result, 1); - - if (%closestEnemy <= 0 || (%closestEnemyDist > %closestDist * 1.5)) - %client.needEquipment = true; - } - } - - //mark the current time for the buy inventory state machine - %task.buyInvTime = getSimTime(); - - //set a flag to determine if the objective should be re-aquired when the object is destroyed - %task.reassignOnDestroyed = false; -} - -function AIDefendLocation::retire(%task, %client) -{ - %task.engageVehicle = -1; - %client.setTargetObject(-1); -} - -function AIDefendLocation::weight(%task, %client) -{ - //update the task weight - if (%task == %client.objectiveTask) - %task.baseWeight = %client.objectiveWeight; - - %player = %client.player; - if (!isObject(%player)) - return; - - %hasMissile = (%player.getInventory("MissileLauncher") > 0) && (%player.getInventory("MissileLauncherAmmo") > 0); - - //if we're defending with a missile launcher, our first priority is to take out vehicles... - //see if we're already attacking a vehicle... - if (%task.engageVehicle > 0 && isObject(%task.engageVehicle) && %hasMissile) - { - //set the weight - %task.setWeight(%task.baseWeight); - return; - } - - //search for a new vehicle to attack - %task.engageVehicle = -1; - %losTimeout = $AIClientMinLOSTime + ($AIClientLOSTimeout * %client.getSkillLevel()); - %result = AIFindClosestEnemyPilot(%client, 300, %losTimeout); - %pilot = getWord(%result, 0); - %pilotDist = getWord(%result, 1); - - //if we've got missiles, and a vehicle to attack... - if (%hasMissile && AIClientIsAlive(%pilot)) - { - %task.engageVehicle = %pilot.vehicleMounted; - %client.needEquipment = false; - } - - //otherwise look for a regular enemy to fight... - else - { - %result = AIFindClosestEnemyToLoc(%client, %task.location, 100, %losTimeout); - %closestEnemy = getWord(%result, 0); - %closestdist = getWord(%result, 1); - - //see if we found someone - if (%closestEnemy > 0) - %task.engageTarget = %closestEnemy; - else - { - %task.engageTarget = -1; - - //see if someone is near me... - %result = AIFindClosestEnemy(%client, 100, %losTimeout); - %closestEnemy = getWord(%result, 0); - %closestdist = getWord(%result, 1); - if (%closestEnemy <= 0 || %closestDist > 70) - %client.setEngageTarget(-1); - } - } - - //set the weight - %task.setWeight(%task.baseWeight); -} - -function AIDefendLocation::monitor(%task, %client) -{ - //first, buy the equipment - if (%client.needEquipment) - { - %task.setMonitorFreq(5); - if (%task.equipment !$= "") - %equipmentList = %task.equipment; - else - %equipmentList = %task.desiredEquipment; - %result = AIBuyInventory(%client, %equipmentList, %task.buyEquipmentSet, %task.buyInvTime); - if (%result $= "InProgress") - return; - else if (%result $= "Finished") - { - %task.setMonitorFreq(15); - %client.needEquipment = false; - } - else if (%result $= "Failed") - { - //if this task is the objective task, choose a new objective - if (%task == %client.objectiveTask) - { - AIUnassignClient(%client); - Game.AIChooseGameObjective(%client); - } - return; - } - } - //if we made it past the inventory buying, reset the inv time - %task.buyInvTime = getSimTime(); - - //chat - if (%task.sendMsg) - { - if (%task.sendMsgTime == 0) - %task.sendMsgTime = getSimTime(); - else if (getSimTime() - %task.sendMsgTime > 7000) - { - %task.sendMsg = false; - if (%client.isAIControlled()) - { - if (%task.chat !$= "") - { - %chatMsg = getWord(%task.chat, 0); - %chatTemplate = getWord(%task.chat, 1); - if (%chatTemplate !$= "") - AIMessageThreadTemplate(%chatTemplate, %chatMsg, %client, -1); - else - AIMessageThread(%task.chat, %client, -1); - } - else if (%task.targetObject > 0) - { - %type = %task.targetObject.getDataBlock().getName(); - if (%type $= "Flag") - AIMessageThreadTemplate("DefendBase", "ChatSelfDefendFlag", %client, -1); - else if (%type $= "GeneratorLarge") - AIMessageThreadTemplate("DefendBase", "ChatSelfDefendGenerator", %client, -1); - else if (%type $= "StationVehicle") - AIMessageThreadTemplate("DefendBase", "ChatSelfDefendVehicle", %client, -1); - else if (%type $= "SensorLargePulse") - AIMessageThreadTemplate("DefendBase", "ChatSelfDefendSensors", %client, -1); - else if (%type $= "SensorMediumPulse") - AIMessageThreadTemplate("DefendBase", "ChatSelfDefendSensors", %client, -1); - else if (%type $= "TurretBaseLarge") - AIMessageThreadTemplate("DefendBase", "ChatSelfDefendTurrets", %client, -1); - } - } - } - } - - //if the defend location task has an object, set the "reset" flag - if (%task == %client.objectiveTask && isObject(%task.targetObject)) - { - if (%task.targetObject.getDamageState() !$= "Destroyed") - %task.reassignOnDestroyed = true; - else - { - if (%task.reassignOnDestroyed) - { - AIUnassignClient(%client); - Game.AIChooseGameObjective(%client); - return; - } - } - } - - //first, check for a vehicle to engage - if (%task.engageVehicle > 0 && isObject(%task.engageVehicle)) - { - %client.stop(); - %client.clearStep(); - %client.setEngageTarget(-1); - %client.setTargetObject(%task.engageVehicle, 300, "Missile"); - } - else - { - //clear the target vehicle... - %client.setTargetObject(-1); - - //see if we're engaging a player - if (%client.getEngageTarget() > 0) - { - //too far, or killed the enemy - return home - if (%client.getStepStatus() !$= "InProgress" || %distance > 75) - { - %client.setEngageTarget(-1); - %client.stepMove(%task.location, 8.0); - } - } - - //else see if we have a target to begin attacking - else if (%task.engageTarget > 0) - %client.stepEngage(%task.engageTarget); - - //else move to a random location around where we are defending - else if (%client.getStepName() !$= "AIStepIdlePatrol") - { - %dist = VectorDist(%client.player.getWorldBoxCenter(), %task.location); - if (%dist < 10) - { - //dissolve the human control link and re-evaluate the weight - if (%task == %client.objectiveTask) - { - if (aiHumanHasControl(%task.issuedByClient, %client)) - { - aiReleaseHumanControl(%client.controlByHuman, %client); - - //should re-evaluate the current objective weight - %inventoryStr = AIFindClosestInventories(%client); - %client.objectiveWeight = %client.objective.weight(%client, %client.objectiveLevel, 0, %inventoryStr); - } - } - - %client.stepIdle(%task.location); - } - else - %client.stepMove(%task.location, 8.0); - } - } - - //see if we're supposed to be engaging anyone... - if (!AIClientIsAlive(%client.getEngageTarget()) && AIClientIsAlive(%client.shouldEngage)) - %client.setEngageTarget(%client.shouldEngage); -} - -//------------------------------ - -function AIAttackLocation::initFromObjective(%task, %objective, %client) -{ - //initialize the task vars from the objective - %task.baseWeight = %client.objectiveWeight; - %task.location = %objective.location; - %task.equipment = %objective.equipment; - %task.buyEquipmentSet = %objective.buyEquipmentSet; - %task.desiredEquipment = %objective.desiredEquipment; - %task.issuedByClient = %objective.issuedByClientId; - %task.chat = %objective.chat; - - //initialize other task vars - %task.sendMsg = true; - %task.sendMsgTime = 0; - %task.engageTarget = -1; -} - -function AIAttackLocation::assume(%task, %client) -{ - %task.setWeightFreq(30); - %task.setMonitorFreq(30); - %client.needEquipment = AINeedEquipment(%task.equipment, %client); - - //even if we don't *need* equipemnt, see if we should buy some... - if (! %client.needEquipment && %task.buyEquipmentSet !$= "") - { - //see if we could benefit from inventory - %needArmor = AIMustUseRegularInvStation(%task.desiredEquipment, %client); - %result = AIFindClosestInventory(%client, %needArmor); - %closestInv = getWord(%result, 0); - %closestDist = getWord(%result, 1); - if (AINeedEquipment(%task.desiredEquipment, %client) && %closestInv > 0) - { - %result = AIFindClosestEnemyToLoc(%client, %task.location, 50, $AIClientLOSTimeout); - %closestEnemy = getWord(%result, 0); - - if (%closestEnemy <= 0) - %client.needEquipment = true; - } - } - - //mark the current time for the buy inventory state machine - %task.buyInvTime = getSimTime(); - - %task.snipeLocation = ""; - %task.hideLocation = ""; - %task.moveToPosition = true; - %task.moveToSnipe = false; - %task.nextSnipeTime = 0; -} - -function AIAttackLocation::retire(%task, %client) -{ -} - -function AIAttackLocation::weight(%task, %client) -{ - //update the task weight - if (%task == %client.objectiveTask) - %task.baseWeight = %client.objectiveWeight; - - //if we're a sniper, we're going to cheat, and see if there are clients near the attack location - %losTimeout = $AIClientMinLOSTime + ($AIClientLOSTimeout * %client.getSkillLevel()); - %distToLoc = VectorDist(%client.player.getWorldBoxCenter(), %task.location); - if (%client.player.getInventory(SniperRifle) > 0 && %client.player.getInventory(EnergyPack) > 0 && %distToLoc > 60) - %result = AIFindClosestEnemyToLoc(%client, %task.location, 50, $AIClientLOSTimeout, true); - - //otherwise, do the search normally. (cheat ignores LOS)... - else - %result = AIFindClosestEnemyToLoc(%client, %task.location, 50, %losTimeout, false); - - %closestEnemy = getWord(%result, 0); - %closestdist = getWord(%result, 1); - %task.setWeight(%task.baseWeight); - - //see if we found someone - if (%closestEnemy > 0) - %task.engageTarget = %closestEnemy; - else - %task.engageTarget = -1; -} - -function AIAttackLocation::monitor(%task, %client) -{ - //first, buy the equipment - if (%client.needEquipment) - { - %task.setMonitorFreq(5); - if (%task.equipment !$= "") - %equipmentList = %task.equipment; - else - %equipmentList = %task.desiredEquipment; - %result = AIBuyInventory(%client, %equipmentList, %task.buyEquipmentSet, %task.buyInvTime); - if (%result $= "InProgress") - return; - else if (%result $= "Finished") - { - %task.setMonitorFreq(30); - %client.needEquipment = false; - } - else if (%result $= "Failed") - { - //if this task is the objective task, choose a new objective - if (%task == %client.objectiveTask) - { - AIUnassignClient(%client); - Game.AIChooseGameObjective(%client); - } - return; - } - } - //if we made it past the inventory buying, reset the inv time - %task.buyInvTime = getSimTime(); - - //chat - if (%task.sendMsg) - { - if (%task.sendMsgTime == 0) - %task.sendMsgTime = getSimTime(); - else if (getSimTime() - %task.sendMsgTime > 7000) - { - %task.sendMsg = false; - if (%client.isAIControlled()) - { - if (%task.chat !$= "") - { - %chatMsg = getWord(%task.chat, 0); - %chatTemplate = getWord(%task.chat, 1); - if (%chatTemplate !$= "") - AIMessageThreadTemplate(%chatTemplate, %chatMsg, %client, -1); - else - AIMessageThread(%task.chat, %client, -1); - } - else - AIMessageThreadTemplate("AttackBase", "ChatSelfAttack", %client, -1); - } - } - } - - //how far are we from the location we're defending - %myPos = %client.player.getWorldBoxCenter(); - %distance = %client.getPathDistance(%task.location); - if (%distance < 0) - %distance = 32767; - - if (%client.player.getInventory(SniperRifle) > 0 && %client.player.getInventory(EnergyPack) > 0) - { - //first, find an LOS location - if (%task.snipeLocation $= "") - { - %task.snipeLocation = %client.getLOSLocation(%task.location, 150, 250); - %task.hideLocation = %client.getHideLocation(%task.location, VectorDist(%task.location, %task.snipeLocation), %task.snipeLocation, 1); - %client.stepMove(%task.hideLocation, 4.0); - %task.moveToPosition = true; - } - else - { - //see if we can acquire a target - %energy = %client.player.getEnergyPercent(); - %distToSnipe = VectorDist(%task.snipelocation, %client.player.getWorldBoxCenter()); - %distToHide = VectorDist(%task.hidelocation, %client.player.getWorldBoxCenter()); - - //until we're in position, we can move using the AIModeExpress, after that, we only want to walk... - if (%task.moveToPosition) - { - if (%distToHide < 4.0) - { - //dissolve the human control link - if (%task == %client.objectiveTask) - { - if (aiHumanHasControl(%task.issuedByClient, %client)) - { - aiReleaseHumanControl(%client.controlByHuman, %client); - - //should re-evaluate the current objective weight - %inventoryStr = AIFindClosestInventories(%client); - %client.objectiveWeight = %client.objective.weight(%client, %client.objectiveLevel, 0, %inventoryStr); - } - } - - %task.moveToPosition = false; - } - } - - else if (%task.moveToSnipe) - { - if (%energy > 0.75 && %client.getStepStatus() $= "Finished") - { - %client.stepMove(%task.snipeLocation, 4.0, $AIModeWalk); - %client.setEngageTarget(%task.engageTarget); - } - else if (%energy < 0.4) - { - %client.setEngageTarget(-1); - %client.stepMove(%task.hideLocation, 4.0); - %task.nextSnipeTime = getSimTime() + 4000 + (getRandom() * 4000); - %task.moveToSnipe = false; - } - } - - else if (%energy > 0.5 && %task.engageTarget > 0 && getSimTime() > %task.nextSnipeTime) - { - %client.stepRangeObject(%task.engageTarget.player.getWorldBoxCenter(), "BasicSniperShot", 150, 250, %task.snipelocation); - %client.aimAt(%task.engageTarget.player.getWorldBoxCenter(), 8000); - %task.moveToSnipe = true; - } - } - } - else - { - //else see if we have a target to begin attacking - if (%client.getEngageTarget() <= 0 && %task.engageTarget > 0) - %client.stepEngage(%task.engageTarget); - - //else move to the location we're defending - else if (%client.getEngageTarget() <= 0) - { - %client.stepMove(%task.location, 8.0); - if (VectorDist(%client.player.position, %task.location) < 10) - { - //dissolve the human control link - if (%task == %client.objectiveTask) - { - if (aiHumanHasControl(%task.issuedByClient, %client)) - { - aiReleaseHumanControl(%client.controlByHuman, %client); - - //should re-evaluate the current objective weight - %inventoryStr = AIFindClosestInventories(%client); - %client.objectiveWeight = %client.objective.weight(%client, %client.objectiveLevel, 0, %inventoryStr); - } - } - } - } - } - - //see if we're supposed to be engaging anyone... - if (!AIClientIsAlive(%client.getEngageTarget()) && AIClientIsAlive(%client.shouldEngage)) - %client.setEngageTarget(%client.shouldEngage); -} - -//------------------------------ - -function AIAttackPlayer::initFromObjective(%task, %objective, %client) -{ - %task.baseWeight = %client.objectiveWeight; - %task.targetClient = %objective.targetClientId; - %task.equipment = %objective.equipment; - %task.buyEquipmentSet = %objective.buyEquipmentSet; - %task.desiredEquipment = %objective.desiredEquipment; - %task.issuedByClient = %objective.issuedByClientId; -} - -function AIAttackPlayer::assume(%task, %client) -{ - %task.setWeightFreq(15); - %task.setMonitorFreq(15); - %client.needEquipment = AINeedEquipment(%task.equipment, %client); - if (! %client.needEquipment) - %client.stepEngage(%task.targetClient); - - //even if we don't *need* equipemnt, see if we should buy some... - if (! %client.needEquipment && %task.buyEquipmentSet !$= "") - { - //see if we could benefit from inventory - %needArmor = AIMustUseRegularInvStation(%task.desiredEquipment, %client); - %result = AIFindClosestInventory(%client, %needArmor); - %closestInv = getWord(%result, 0); - %closestDist = getWord(%result, 1); - if (AINeedEquipment(%task.desiredEquipment, %client) && %closestInv > 0) - { - %distToTarg = %client.getPathDistance(%task.targetClient.player.getWorldBoxCenter()); - if (%distToTarg < 0 || %distToTarg > 100) - %client.needEquipment = true; - } - } - - //mark the current time for the buy inventory state machine - %task.buyInvTime = getSimTime(); -} - -function AIAttackPlayer::retire(%task, %client) -{ - //dissolve the human control link - if (%task == %client.objectiveTask) - aiReleaseHumanControl(%client.controlByHuman, %client); -} - -function AIAttackPlayer::weight(%task, %client) -{ - //update the task weight - if (%task == %client.objectiveTask) - %task.baseWeight = %client.objectiveWeight; - - %task.setWeight(%task.baseWeight); -} - -function AIAttackPlayer::monitor(%task, %client) -{ - //first, buy the equipment - if (%client.needEquipment) - { - %task.setMonitorFreq(5); - if (%task.equipment !$= "") - %equipmentList = %task.equipment; - else - %equipmentList = %task.desiredEquipment; - %result = AIBuyInventory(%client, %equipmentList, %task.buyEquipmentSet, %task.buyInvTime); - if (%result $= "InProgress") - return; - else if (%result $= "Finished") - { - %task.setMonitorFreq(15); - %client.needEquipment = false; - %client.stepEngage(%task.targetClient); - } - else if (%result $= "Failed") - { - //if this task is the objective task, choose a new objective - if (%task == %client.objectiveTask) - { - AIUnassignClient(%client); - Game.AIChooseGameObjective(%client); - } - return; - } - } - //if we made it past the inventory buying, reset the inv time - %task.buyInvTime = getSimTime(); - - //cheap hack for now... make the bot always know where you are... - %client.clientDetected(%task.targetClient); - - //make sure we're still attacking... - if (%client.getStepName() !$= "AIStepEngage") - %client.stepEngage(%task.targetClient); - - //make sure we're still attacking the right target - %client.setEngageTarget(%task.targetClient); - - if (%client.getStepStatus() !$= "InProgress" && %task == %client.objectiveTask) - { - AIUnassignClient(%client); - Game.AIChooseGameObjective(%client); - } -} - -//------------------------------ - -function AIHuntPlayer::initFromObjective(%task, %objective, %client) -{ - %task.baseWeight = %client.objectiveWeight; - %task.targetClient = %objective.targetClientId; - %task.equipment = %objective.equipment; - %task.buyEquipmentSet = %objective.buyEquipmentSet; - %task.desiredEquipment = %objective.desiredEquipment; - %task.issuedByClient = %objective.issuedByClientId; -} - -function AIHuntPlayer::assume(%task, %client) -{ - %task.setWeightFreq(15); - %task.setMonitorFreq(15); - %client.needEquipment = AINeedEquipment(%task.equipment, %client); - if (! %client.needEquipment) - %client.stepEngage(%task.targetClient); - - //even if we don't *need* equipemnt, see if we should buy some... - if (! %client.needEquipment && %task.buyEquipmentSet !$= "") - { - //see if we could benefit from inventory - %needArmor = AIMustUseRegularInvStation(%task.desiredEquipment, %client); - %result = AIFindClosestInventory(%client, %needArmor); - %closestInv = getWord(%result, 0); - %closestDist = getWord(%result, 1); - if (AINeedEquipment(%task.desiredEquipment, %client) && %closestInv > 0) - { - %distToTarg = %client.getPathDistance(%task.targetClient.player.getWorldBoxCenter()); - if (%distToTarg < 0 || %distToTarg > 100) - %client.needEquipment = true; - } - } - - //mark the current time for the buy inventory state machine - %task.buyInvTime = getSimTime(); -} - -function AIHuntPlayer::retire(%task, %client) -{ - //dissolve the human control link - if (%task == %client.objectiveTask) - aiReleaseHumanControl(%client.controlByHuman, %client); -} - -function AIHuntPlayer::weight(%task, %client) -{ - //update the task weight - if (%task == %client.objectiveTask) - %task.baseWeight = %client.objectiveWeight; - - %task.setWeight(%task.baseWeight); -} - -function AIHuntPlayer::monitor(%task, %client) -{ -echo("LOL"); - //first, buy the equipment - if (%client.needEquipment) - { - %task.setMonitorFreq(5); - if (%task.equipment !$= "") - %equipmentList = %task.equipment; - else - %equipmentList = %task.desiredEquipment; - %result = AIBuyInventory(%client, %equipmentList, %task.buyEquipmentSet, %task.buyInvTime); - if (%result $= "InProgress") - return; - else if (%result $= "Finished") - { - %task.setMonitorFreq(15); - %client.needEquipment = false; - %client.stepEngage(%task.targetClient); - } - else if (%result $= "Failed") - { - //if this task is the objective task, choose a new objective - if (%task == %client.objectiveTask) - { - AIUnassignClient(%client); - Game.AIChooseGameObjective(%client); - } - return; - } - } - //if we made it past the inventory buying, reset the inv time - %task.buyInvTime = getSimTime(); - - //cheap hack for now... make the bot always know where you are... - %client.clientDetected(%task.targetClient); - - //make sure we're still attacking... - if (%client.getStepName() !$= "AIStepEngage") - %client.stepEngage(%task.targetClient); - - //make sure we're still attacking the right target - %client.setEngageTarget(%task.targetClient); - - if (%client.getStepStatus() !$= "InProgress" && %task == %client.objectiveTask) - { - AIUnassignClient(%client); - Game.AIChooseGameObjective(%client); - } -} - -//------------------------------ - -function AITouchObject::initFromObjective(%task, %objective, %client) -{ - %task.baseWeight = %client.objectiveWeight; - %task.targetObject = %objective.targetObjectId; - %task.mode = %objective.mode; - if (%objective.mode $= "FlagCapture") - %task.location = %objective.location; - else if(%objective.mode $= "TouchFlipFlop") - %task.location = %objective.location; - else - %task.location = ""; - %task.equipment = %objective.equipment; - %task.buyEquipmentSet = %objective.buyEquipmentSet; - %task.desiredEquipment = %objective.desiredEquipment; - %task.issuedByClient = %objective.issuedByClientId; - - %task.sendMsgTime = 0; - if (%task.mode $= "FlagGrab") - %task.sendMsg = true; - else - %task.sendMsg = false; -} - -function AITouchObject::assume(%task, %client) -{ - %task.setWeightFreq(15); - %task.setMonitorFreq(15); - %task.engageTarget = 0; - %client.needEquipment = AINeedEquipment(%task.equipment, %client); - - //even if we don't *need* equipemnt, see if we should buy some... - if (! %client.needEquipment && (%task.mode $= "FlagGrab" || %task.mode $= "TouchFlipFlop") && %task.buyEquipmentSet !$= "") - { - //see if we could benefit from inventory - %needArmor = AIMustUseRegularInvStation(%task.desiredEquipment, %client); - %result = AIFindClosestInventory(%client, %needArmor); - %closestInv = getWord(%result, 0); - %closestDist = getWord(%result, 1); - if (AINeedEquipment(%task.desiredEquipment, %client) && %closestInv > 0) - { - //find where we are - %clientPos = %client.player.getWorldBoxCenter(); - %distToObject = %client.getPathDistance(%task.location); - if (%distToObject < 0 || %closestDist < %distToObject) - %client.needEquipment = true; - } - } - - //mark the current time for the buy inventory state machine - %task.buyInvTime = getSimTime(); -} - -function AITouchObject::retire(%task, %client) -{ -} - -function AITouchObject::weight(%task, %client) -{ - //update the task weight - if (%task == %client.objectiveTask) - %task.baseWeight = %client.objectiveWeight; - - //see if we can find someone to shoot at... - if (%client.getEngageTarget() <= 0) - { - %losTimeout = $AIClientMinLOSTime + ($AIClientLOSTimeout * %client.getSkillLevel()); - %myLocation = %client.player.getWorldBoxCenter(); - %result = AIFindClosestEnemy(%client, 40, %losTimeout); - %task.engageTarget = getWord(%result, 0); - } - - %task.setWeight(%task.baseWeight); -} - -function AITouchObject::monitor(%task, %client) -{ - //first, buy the equipment - if (%client.needEquipment) - { - %task.setMonitorFreq(5); - if (%task.equipment !$= "") - %equipmentList = %task.equipment; - else - %equipmentList = %task.desiredEquipment; - %result = AIBuyInventory(%client, %equipmentList, %task.buyEquipmentSet, %task.buyInvTime); - if (%result $= "InProgress") - return; - else if (%result $= "Finished") - { - %task.setMonitorFreq(15); - %client.needEquipment = false; - } - else if (%result $= "Failed") - { - //if this task is the objective task, choose a new objective - if (%task == %client.objectiveTask) - { - AIUnassignClient(%client); - Game.AIChooseGameObjective(%client); - } - return; - } - } - //if we made it past the inventory buying, reset the inv time - %task.buyInvTime = getSimTime(); - - //chat - if (%task.sendMsg) - { - if (%task.sendMsgTime == 0) - %task.sendMsgTime = getSimTime(); - else if (getSimTime() - %task.sendMsgTime > 7000) - { - %task.sendMsg = false; - if (%client.isAIControlled()) - { - if (%task.mode $= "FlagGrab") - AIMessageThreadTemplate("AttackBase", "ChatSelfAttackFlag", %client, -1); - } - } - } - - //keep updating the position, in case the flag is flying through the air... - if (%task.location !$= "") - %touchPos = %task.location; - else - %touchPos = %task.targetObject.getWorldBoxCenter(); - - //see if we need to engage a new target - %engageTarget = %client.getEngageTarget(); - if (!AIClientIsAlive(%engageTarget) && %task.engageTarget > 0) - %client.setEngageTarget(%task.engageTarget); - - //else see if we should abandon the engagement - else if (AIClientIsAlive(%engageTarget)) - { - %myPos = %client.player.getWorldBoxCenter(); - %testPos = %engageTarget.player.getWorldBoxCenter(); - %distance = %client.getPathDistance(%testPos); - if (%distance < 0 || %distance > 70) - %client.setEngageTarget(-1); - } - - //see if we have completed our objective - if (%task == %client.objectiveTask) - { - %completed = false; - switch$ (%task.mode) - { - case "TouchFlipFlop": - if (%task.targetObject.team == %client.team) - %completed = true; - case "FlagGrab": - if (!%task.targetObject.isHome) - %completed = true; - case "FlagDropped": - if ((%task.targetObject.isHome) || (%task.targetObject.carrier !$= "")) - %completed = true; - case "FlagCapture": - if (%task.targetObject.carrier != %client.player) - %completed = true; - } - if (%completed) - { - AIUnassignClient(%client); - Game.AIChooseGameObjective(%client); - return; - } - } - - if (%task.mode $= "FlagCapture") - { - %homeFlag = $AITeamFlag[%client.team]; - - //if we're within range of the flag's home position, and the flag isn't home, start idling... - if (VectorDist(%client.player.position, %touchPos) < 40 && !%homeFlag.isHome) - { - if (%client.getStepName() !$= "AIStepIdlePatrol") - %client.stepIdle(%touchPos); - } - else - %client.stepMove(%touchPos, 0.25); - } - else - %client.stepMove(%touchPos, 0.25); - - if (VectorDist(%client.player.position, %touchPos) < 10) - { - //dissolve the human control link - if (%task == %client.objectiveTask) - { - if (aiHumanHasControl(%task.issuedByClient, %client)) - { - aiReleaseHumanControl(%client.controlByHuman, %client); - - //should re-evaluate the current objective weight - %inventoryStr = AIFindClosestInventories(%client); - %client.objectiveWeight = %client.objective.weight(%client, %client.objectiveLevel, 0, %inventoryStr); - } - } - } - - //see if we're supposed to be engaging anyone... - if (!AIClientIsAlive(%client.getEngageTarget()) && AIClientIsAlive(%client.shouldEngage)) - %client.setEngageTarget(%client.shouldEngage); -} - -//------------------------------ - -function AIEscortPlayer::initFromObjective(%task, %objective, %client) -{ - %task.baseWeight = %client.objectiveWeight; - %task.targetClient = %objective.targetClientId; - %task.equipment = %objective.equipment; - %task.buyEquipmentSet = %objective.buyEquipmentSet; - %task.desiredEquipment = %objective.desiredEquipment; - %task.issuedByClient = %objective.issuedByClientId; - %task.forceClient = %objective.forceClientId; -} - -function AIEscortPlayer::assume(%task, %client) -{ - %task.setWeightFreq(15); - %task.setMonitorFreq(15); - %task.rangedTarget = false; - if (%task == %client.objectiveTask && %client == %task.forceClient && %task.issuedByClient == %task.targetClient) - { - %client.needEquipment = false; - %client.mountVehicle = false; - } - else - { - %client.needEquipment = AINeedEquipment(%task.equipment, %client); - if (! %client.needEquipment) - %client.stepEscort(%task.targetClient); - - //even if we don't *need* equipemnt, see if we should buy some... - if (! %client.needEquipment && %task.buyEquipmentSet !$= "") - { - //see if we could benefit from inventory - %needArmor = AIMustUseRegularInvStation(%task.desiredEquipment, %client); - %result = AIFindClosestInventory(%client, %needArmor); - %closestInv = getWord(%result, 0); - %closestDist = getWord(%result, 1); - if (AINeedEquipment(%task.desiredEquipment, %client) && %closestInv > 0) - { - //find where we are - %clientPos = %client.player.getWorldBoxCenter(); - %targPos = %task.targetClient.player.getWorldBoxCenter(); - %distToTarg = %client.getPathDistance(%targPos); - - if (%closestDist < 50 && (%distToTarg < 0 || %distToTarg > 100)) - %client.needEquipment = true; - } - } - } - - //mark the current time for the buy inventory state machine - %task.buyInvTime = getSimTime(); -} - -function AIEscortPlayer::retire(%task, %client) -{ - %client.clearStep(); - if(%client.player.isMounted()) - AIDisembarkVehicle(%client); - - //clear the target object - %client.setTargetObject(-1); -} - -function AIEscortPlayer::weight(%task, %client) -{ - //update the task weight - if (%task == %client.objectiveTask) - %task.baseWeight = %client.objectiveWeight; - - //make sure we still have someone to escort - if (!AiClientIsAlive(%task.targetClient)) - { - %task.setWeight(0); - return; - } - - //always shoot at the closest person to the client being escorted - %targetPos = %task.targetClient.player.getWorldBoxCenter(); - %losTimeout = $AIClientMinLOSTime + ($AIClientLOSTimeout * %client.getSkillLevel()); - %result = AIFindClosestEnemyToLoc(%client, %targetPos, 50, %losTimeout); - %task.engageTarget = getWord(%result, 0); - if (!AIClientIsAlive(%task.engageTarget)) - { - if (AIClientIsAlive(%task.targetClient.lastDamageClient, %losTimeout) && getSimTime() - %task.targetClient.lastDamageTime < %losTimeout) - %task.engageTarget = %task.targetClient.lastDamageClient; - } - if (!AIClientIsAlive(%task.engageTarget)) - { - %myPos = %client.player.getWorldBoxCenter(); - %result = AIFindClosestEnemy(%client, 50, %losTimeout); - %task.engageTarget = getWord(%result, 0); - } - - //if both us and the person we're escorting are in a vehicle, set the weight high! - if (%task.targetClient.player.isMounted() && %client.player.isMounted()) - { - %vehicle = %client.vehicleMounted; - if (%vehicle > 0 && isObject(%vehicle) && %vehicle.getDamagePercent() < 0.8) - %task.setWeight($AIWeightVehicleMountedEscort); - else - %task.setWeight(%task.baseWeight); - } - else - %task.setWeight(%task.baseWeight); - - //find out if our escortee is lazing a target... - %task.missileTarget = -1; - %targetCount = ServerTargetSet.getCount(); - for (%i = 0; %i < %targetCount; %i++) - { - %targ = ServerTargetSet.getObject(%i); - if (%targ.sourceObject == %task.targetClient.player) - { - //find out which item is being targetted... - %targPoint = %targ.getTargetPoint(); - InitContainerRadiusSearch(%targPoint, 10, $TypeMasks::TurretObjectType | $TypeMasks::StaticShapeObjectType); - %task.missileTarget = containerSearchNext(); - break; - } - } -} - -function AIEscortPlayer::monitor(%task, %client) -{ - //make sure we still have someone to escort - if (!AiClientIsAlive(%task.targetClient)) - { - if (%task == %client.objectiveTask) - { - AIUnassignClient(%client); - Game.AIChooseGameObjective(%client); - } - return; - } - - //first, buy the equipment - if (%client.needEquipment) - { - %task.setMonitorFreq(5); - if (%task.equipment !$= "") - %equipmentList = %task.equipment; - else - %equipmentList = %task.desiredEquipment; - %result = AIBuyInventory(%client, %equipmentList, %task.buyEquipmentSet, %task.buyInvTime); - if (%result $= "InProgress") - return; - else if (%result $= "Finished") - { - %task.setMonitorFreq(15); - %client.needEquipment = false; - %client.stepEscort(%task.targetClient); - %task.buyInvTime = getSimTime(); - } - else if (%result $= "Failed") - { - //if this task is the objective task, choose a new objective - if (%task == %client.objectiveTask) - { - AIUnassignClient(%client); - Game.AIChooseGameObjective(%client); - } - return; - } - } - - //see if our target is mounted in a vehicle... - if (%task.targetClient.player.isMounted()) - { - //find the passenger seat the bot will take - %vehicle = %task.targetClient.vehicleMounted; - %node = findAIEmptySeat(%vehicle, %client.player); - - //make sure there is an empty seat - if (%node < 0 && %client.vehicleMounted != %task.targetClient.vehicleMounted) - { - if (%task == %client.objectiveTask) - { - AIUnassignClient(%client); - Game.AIChooseGameObjective(%client); - } - return; - } - - //find the passenger seat location... - %slotPosition = %vehicle.getSlotTransform(%node); - - //make sure we're in the correct armor - assault tanks cannot have a heavy... - if (%task.targetClient.vehicleMounted.getDataBlock().getName() $= "AssaultVehicle") - { - //if the bot is in a heavy, break off the escort... - if (%client.player.getArmorSize() $= "Heavy") - { - if (%task == %client.objectiveTask) - { - AIUnassignClient(%client); - Game.AIChooseGameObjective(%client); - } - return; - } - - //throw away any packs that won't fit - if (%client.player.getInventory(InventoryDeployable) > 0) - %client.player.throwPack(); - else if (%client.player.getInventory(TurretIndoorDeployable) > 0) - %client.player.throwPack(); - else if (%client.player.getInventory(TurretOutdoorDeployable) > 0) - %client.player.throwPack(); - } - - if (%client.player.isMounted()) - { - //make sure it's the same vehicle :) - if (%client.vehicleMounted != %vehicle) - AIDisembarkVehicle(%client); - } - else - { - //mount the vehicle - %client.stepMove(%slotPosition, 0.25, $AIModeMountVehicle); - } - } - else - { - //disembark if we're mounted, but our target isn't (anymore) - if (%client.player.isMounted()) - AIDisembarkVehicle(%client); - } - - //see if we're supposed to be mortaring/missiling something... - %hasMortar = (%client.player.getInventory("Mortar") > 0) && (%client.player.getInventory("MortarAmmo") > 0); - %hasMissile = (%client.player.getInventory("MissileLauncher") > 0) && (%client.player.getInventory("MissileLauncherAmmo") > 0); - if (!isObject(%task.engageTarget) && isobject(%task.missileTarget) && %task.missileTarget.getDamageState() !$= "Destroyed" && (%hasMortar || %hasMissile)) - { - if (%task.rangedTarget) - { - %client.stop(); - %client.clearStep(); - %client.setEngageTarget(-1); - if (%hasMortar) - %client.setTargetObject(%task.missileTarget, 250, "Mortar"); - else - %client.setTargetObject(%task.missileTarget, 500, "MissileNoLock"); - } - else if (%client.getStepName() !$= "AIStepRangeObject") - { - if (%hasMortar) - %client.stepRangeObject(%task.missileTarget, "MortarShot", 100, 200); - else - %client.stepRangeObject(%task.missileTarget, "BasicTargeter", 50, 500); - } - else if (%client.getStepStatus() $= "Finished") - %task.rangedTarget = true; - } - else - { - %task.rangedTarget = false; - %client.setTargetObject(-1); - if (%client.getStepName() !$= "AIStepEscort") - %client.stepEscort(%task.targetClient); - } - - //make sure we're still shooting... - %client.setEngageTarget(%task.engageTarget); - - //see if we're supposed to be engaging anyone... - if (!AIClientIsAlive(%client.getEngageTarget()) && AIClientIsAlive(%client.shouldEngage)) - %client.setEngageTarget(%client.shouldEngage); -} - -//------------------------------ - -function AIAttackObject::initFromObjective(%task, %objective, %client) -{ - %task.baseWeight = %client.objectiveWeight; - %task.targetObject = %objective.targetObjectId; - %task.equipment = %objective.equipment; - %task.buyEquipmentSet = %objective.buyEquipmentSet; - %task.desiredEquipment = %objective.desiredEquipment; - %task.issuedByClient = %objective.issuedByClientId; - - //initialize other task vars - %task.sendMsg = true; - %task.sendMsgTime = 0; -} - -function AIAttackObject::assume(%task, %client) -{ - %task.setWeightFreq(15); - %task.setMonitorFreq(5); - %client.needEquipment = AINeedEquipment(%task.equipment, %client); - - //even if we don't *need* equipemnt, see if we should buy some... - if (! %client.needEquipment && %task.buyEquipmentSet !$= "") - { - //see if we could benefit from inventory - %needArmor = AIMustUseRegularInvStation(%task.desiredEquipment, %client); - %result = AIFindClosestInventory(%client, %needArmor); - %closestInv = getWord(%result, 0); - %closestDist = getWord(%result, 1); - if (AINeedEquipment(%task.desiredEquipment, %client) && %closestInv > 0) - { - //find where we are - %clientPos = %client.player.getWorldBoxCenter(); - %objPos = %task.targetObject.getWorldBoxCenter(); - %distToObject = %client.getPathDistance(%objPos); - - if (%distToObject < 0 || %closestDist < %distToObject) - %client.needEquipment = true; - } - } - - //mark the current time for the buy inventory state machine - %task.buyInvTime = getSimTime(); -} - -function AIAttackObject::retire(%task, %client) -{ - %client.setTargetObject(-1); -} - -function AIAttackObject::weight(%task, %client) -{ - //update the task weight - if (%task == %client.objectiveTask) - %task.baseWeight = %client.objectiveWeight; - - //let the monitor decide when to stop attacking - %task.setWeight(%task.baseWeight); -} - -function AIAttackObject::monitor(%task, %client) -{ - //first, buy the equipment - if (%client.needEquipment) - { - %task.setMonitorFreq(5); - if (%task.equipment !$= "") - %equipmentList = %task.equipment; - else - %equipmentList = %task.desiredEquipment; - %result = AIBuyInventory(%client, %equipmentList, %task.buyEquipmentSet, %task.buyInvTime); - if (%result $= "InProgress") - return; - else if (%result $= "Finished") - { - %task.setMonitorFreq(15); - %client.needEquipment = false; - } - else if (%result $= "Failed") - { - //if this task is the objective task, choose a new objective - if (%task == %client.objectiveTask) - { - AIUnassignClient(%client); - Game.AIChooseGameObjective(%client); - } - return; - } - } - //if we made it past the inventory buying, reset the inv time - %task.buyInvTime = getSimTime(); - - //chat - if (%task.sendMsg) - { - if (%task.sendMsgTime == 0) - %task.sendMsgTime = getSimTime(); - else if (getSimTime() - %task.sendMsgTime > 7000) - { - %task.sendMsg = false; - if (%client.isAIControlled()) - { - if (%task.chat !$= "") - { - %chatMsg = getWord(%task.chat, 0); - %chatTemplate = getWord(%task.chat, 1); - if (%chatTemplate !$= "") - AIMessageThreadTemplate(%chatTemplate, %chatMsg, %client, -1); - else - AIMessageThread(%task.chat, %client, -1); - } - else if (%task.targetObject > 0) - { - %type = %task.targetObject.getDataBlock().getName(); - if (%type $= "GeneratorLarge") - AIMessageThreadTemplate("AttackBase", "ChatSelfAttackGenerator", %client, -1); - else if (%type $= "SensorLargePulse") - AIMessageThreadTemplate("AttackBase", "ChatSelfAttackSensors", %client, -1); - else if (%type $= "SensorMediumPulse") - AIMessageThreadTemplate("AttackBase", "ChatSelfAttackSensors", %client, -1); - else if (%type $= "TurretBaseLarge") - AIMessageThreadTemplate("AttackBase", "ChatSelfAttackTurrets", %client, -1); - else if (%type $= "StationVehicle") - AIMessageThreadTemplate("AttackBase", "ChatSelfAttackVehicle", %client, -1); - } - } - } - } - - //set the target object - if (isObject(%task.targetObject) && %task.targetObject.getDamageState() !$= "Destroyed") - { - %client.setTargetObject(%task.targetObject, 40, "Destroy"); - - //move towards the object until we're within range - if (! %client.targetInRange()) - %client.stepMove(%task.targetObject.getWorldBoxCenter(), 8.0); - else - { - //dissolve the human control link - if (%task == %client.objectiveTask) - aiReleaseHumanControl(%client.controlByHuman, %client); - - %client.stop(); - } - } - else - { - %client.setTargetObject(-1); - %client.stop(); - - //if this task is the objective task, choose a new objective - if (%task == %client.objectiveTask) - { - AIUnassignClient(%client); - Game.AIChooseGameObjective(%client); - } - } -} - -//------------------------------ - -function AIRepairObject::initFromObjective(%task, %objective, %client) -{ - %task.baseWeight = %client.objectiveWeight; - %task.targetObject = %objective.targetObjectId; - //need to force this objective to only require a repair pack - //%task.equipment = %objective.equipment; - %task.equipment = "RepairPack"; - %task.buyEquipmentSet = %objective.buyEquipmentSet; - %task.desiredEquipment = %objective.desiredEquipment; - %task.issuedByClient = %objective.issuedByClientId; - - %task.deployed = %objective.deployed; - if (%task.deployed) - { - %task.location = %objective.position; - %task.deployDirection = MatrixMulVector("0 0 0 " @ getWords(%objective.getTransform(), 3, 6), "0 1 0"); - %task.deployDirection = VectorNormalize(%task.deployDirection); - } -} - -function AIRepairObject::assume(%task, %client) -{ - %task.setWeightFreq(15); - %task.setMonitorFreq(15); - %client.needEquipment = AINeedEquipment(%task.equipment, %client); - - //clear the target object, and range it - %client.setTargetObject(-1); - if (! %client.needEquipment) - { - if (%task.deployed) - { - %task.repairLocation = VectorAdd(%task.location,VectorScale(%task.deployDirection, -4.0)); - %client.stepMove(%task.repairLocation, 0.25); - } - else - %client.stepRangeObject(%task.targetObject, "DefaultRepairBeam", 3, 8); - } - - //mark the current time for the buy inventory state machine - %task.buyInvTime = getSimTime(); - %task.needToRangeTime = 0; - %task.pickupRepairPack = -1; - %task.usingInv = false; - - //set a tag to help the repairPack.cs script fudge acquiring a target - %client.repairObject = %task.targetObject; -} - -function AIRepairObject::retire(%task, %client) -{ - %client.setTargetObject(-1); - %client.repairObject = -1; -} - -function AIRepairObject::weight(%task, %client) -{ - //update the task weight - if (%task == %client.objectiveTask) - %task.baseWeight = %client.objectiveWeight; - - //let the monitor decide when to stop repairing - %task.setWeight(%task.baseWeight); -} - -function AIRepairObject::monitor(%task, %client) -{ - //first, buy the equipment - if (%client.needEquipment) - { - %task.setMonitorFreq(5); - - //first, see if we still need a repair pack - if (%client.player.getInventory(RepairPack) > 0) - { - %client.needEquipment = false; - %task.setMonitorFreq(15); - - //if this is to repair a deployed object, walk to the deploy point... - if (%task.deployed) - { - %task.repairLocation = VectorAdd(%task.location,VectorScale(%task.deployDirection, -4.0)); - %client.stepMove(%task.repairLocation, 0.25); - } - //otherwise, we'll need to range it... - else - %client.stepRangeObject(%task.targetObject, "DefaultRepairBeam", 3, 8); - } - else - { - // check to see if there's a repair pack nearby - %closestRepairPack = -1; - %closestRepairDist = 32767; - - //search the AIItemSet for a repair pack (someone might have dropped one...) - %itemCount = $AIItemSet.getCount(); - for (%i = 0; %i < %itemCount; %i++) - { - %item = $AIItemSet.getObject(%i); - if (%item.getDataBlock().getName() $= "RepairPack" && !%item.isHidden()) - { - %dist = %client.getPathDistance(%item.getWorldBoxCenter()); - if (%dist > 0 && %dist < %closestRepairDist) - { - %closestRepairPack = %item; - %closestRepairDist = %dist; - } - } - } - - //choose whether we're picking up the closest pack, or buying from an inv station... - if ((isObject(%closestRepairPack) && %closestRepairPack != %task.pickupRepairPack) || (%task.buyInvTime != %client.buyInvTime)) - { - %task.pickupRepairPack = %closestRepairPack; - - //initialize the inv buying - %task.buyInvTime = getSimTime(); - AIBuyInventory(%client, "RepairPack", %task.buyEquipmentSet, %task.buyInvTime); - - //now decide which is closer - if (isObject(%closestRepairPack)) - { - if (isObject(%client.invToUse)) - { - %dist = %client.getPathDistance(%item.position); - if (%dist > %closestRepairDist) - %task.usingInv = true; - else - %task.usingInv = false; - } - else - %task.usingInv = false; - } - else - %task.usingInv = true; - } - - //now see if we found a closer repair pack - if (!%task.usingInv) - { - %client.stepMove(%task.pickupRepairPack.position, 0.25); - %distToPack = %client.getPathDistance(%task.pickupRepairPack.position); - if (%distToPack < 10 && %client.player.getMountedImage($BackpackSlot) > 0) - %client.player.throwPack(); - - //and we're finished until we actually have a repair pack... - return; - } - else - { - %result = AIBuyInventory(%client, "RepairPack", %task.buyEquipmentSet, %task.buyInvTime); - if (%result $= "InProgress") - return; - else if (%result $= "Finished") - { - %client.needEquipment = false; - %task.setMonitorFreq(15); - - //if this is to repair a deployed object, walk to the deploy point... - if (%task.deployed) - { - %task.repairLocation = VectorAdd(%task.location,VectorScale(%task.deployDirection, -4.0)); - %client.stepMove(%task.repairLocation, 0.25); - } - //otherwise, we'll need to range it... - else - %client.stepRangeObject(%task.targetObject, "DefaultRepairBeam", 3, 8); - } - else if (%result $= "Failed") - { - //if this task is the objective task, choose a new objective - if (%task == %client.objectiveTask) - { - AIUnassignClient(%client); - Game.AIChooseGameObjective(%client); - } - return; - } - } - } - } - //if we made it past the inventory buying, reset the inv time - %task.buyInvTime = getSimTime(); - - //chat - if (%task.sendMsg) - { - if (%task.sendMsgTime == 0) - %task.sendMsgTime = getSimTime(); - else if (getSimTime() - %task.sendMsgTime > 7000) - { - %task.sendMsg = false; - if (%client.isAIControlled()) - { - if (%task.chat !$= "") - { - %chatMsg = getWord(%task.chat, 0); - %chatTemplate = getWord(%task.chat, 1); - if (%chatTemplate !$= "") - AIMessageThreadTemplate(%chatTemplate, %chatMsg, %client, -1); - else - AIMessageThread(%task.chat, %client, -1); - } - else if (%task.targetObject > 0) - { - %type = %task.targetObject.getDataBlock().getName(); - if (%type $= "GeneratorLarge") - AIMessageThreadTemplate("RepairBase", "ChatSelfRepairGenerator", %client, -1); - else if (%type $= "StationVehicle") - AIMessageThreadTemplate("RepairBase", "ChatSelfRepairVehicle", %client, -1); - else if (%type $= "SensorLargePulse") - AIMessageThreadTemplate("RepairBase", "ChatSelfRepairSensors", %client, -1); - else if (%type $= "SensorMediumPulse") - AIMessageThreadTemplate("RepairBase", "ChatSelfRepairSensors", %client, -1); - else if (%type $= "TurretBaseLarge") - AIMessageThreadTemplate("RepairBase", "ChatSelfRepairTurrets", %client, -1); - } - } - } - } - - //set the target object - if (%task.targetObject.getDamagePercent() > 0) - { - //make sure we still have equipment - %client.needEquipment = AINeedEquipment(%task.equipment, %client); - if (%client.needEquipment) - { - //if this task is the objective task, choose a new objective - if (%task == %client.objectiveTask) - { - AIUnassignClient(%client); - Game.AIChooseGameObjective(%client); - return; - } - } - - if (%task.deployed) - { - //see if we're within range of the deploy location - %clLoc = %client.player.position; - %distance = VectorDist(%clLoc, %task.repairLocation); - %dist2D = VectorDist(%client.player.position, getWords(%task.repairLocation, 0, 1) SPC getWord(%client.player.position, 2)); - - //set the aim when we get near the target... this will be overwritten when we're actually trying to deploy - if (%distance < 10 && %dist2D < 10) - %client.aimAt(%task.location, 1000); - - //see if we're at the deploy location - if ((%client.pathDistRemaining(20) > %distance + 0.25) || %dist2D > 0.3) - { - %client.setTargetObject(-1); - %client.stepMove(%task.repairLocation, 0.25); - } - else - { - %client.stop(); - %client.setTargetObject(%task.targetObject, 8.0, "Repair"); - } - } - else - { - %currentTime = getSimTime(); - if (%currentTime > %task.needToRangeTime) - { - //force a rangeObject every 10 seconds... - %task.needToRangeTime = %currentTime + 6000; - %client.setTargetObject(-1); - %client.stepRangeObject(%task.targetObject, "DefaultRepairBeam", 3, 8); - } - - //if we've ranged the object, start repairing, else unset the object - else if (%client.getStepStatus() $= "Finished") - { - //dissolve the human control link - if (%task == %client.objectiveTask) - aiReleaseHumanControl(%client.controlByHuman, %client); - - %client.setTargetObject(%task.targetObject, 8.0, "Repair"); - } - else - %client.setTargetObject(-1); - } - } - else - { - %client.setTargetObject(-1); - - //if this task is the objective task, choose a new objective - if (%task == %client.objectiveTask) - { - AIUnassignClient(%client); - Game.AIChooseGameObjective(%client); - } - } -} - -//------------------------------ - -function AILazeObject::initFromObjective(%task, %objective, %client) -{ - %task.baseWeight = %client.objectiveWeight; - %task.targetObject = %objective.targetObjectId; - %task.equipment = %objective.equipment; - %task.buyEquipmentSet = %objective.buyEquipmentSet; - %task.desiredEquipment = %objective.desiredEquipment; - %task.issuedByClient = %objective.issuedByClientId; - %task.msgAck = true; - %task.msgFire = true; -} - -function AILazeObject::assume(%task, %client) -{ - %task.setWeightFreq(30); - %task.setMonitorFreq(30); - %client.needEquipment = AINeedEquipment(%task.equipment, %client); - - //clear the target object, and range it - %client.setTargetObject(-1); - if (! %client.needEquipment) - %client.stepRangeObject(%task.targetObject, "BasicTargeter", 80, 300, %task.issuedByClient.player.getWorldBoxCenter()); - - //set up some task vars - %task.celebrate = false; - %task.waitTimerMS = 0; - - //mark the current time for the buy inventory state machine - %task.buyInvTime = getSimTime(); -} - -function AILazeObject::retire(%task, %client) -{ - %client.setTargetObject(-1); -} - -function AILazeObject::weight(%task, %client) -{ - //update the task weight - if (%task == %client.objectiveTask) - %task.baseWeight = %client.objectiveWeight; - - //let the monitor decide when to stop lazing - %task.setWeight(%task.baseWeight); -} - -function AILazeObject::monitor(%task, %client) -{ - //first, buy the equipment - if (%client.needEquipment) - { - %task.setMonitorFreq(5); - if (%task.equipment !$= "") - %equipmentList = %task.equipment; - else - %equipmentList = %task.desiredEquipment; - %result = AIBuyInventory(%client, %equipmentList, %task.buyEquipmentSet, %task.buyInvTime); - if (%result $= "InProgress") - return; - else if (%result $= "Finished") - { - %task.setMonitorFreq(30); - %client.needEquipment = false; - %client.stepRangeObject(%task.targetObject, "BasicTargeter", 80, 300); - } - else if (%result $= "Failed") - { - //if this task is the objective task, choose a new objective - if (%task == %client.objectiveTask) - { - AIUnassignClient(%client); - Game.AIChooseGameObjective(%client); - } - return; - } - } - //if we made it past the inventory buying, reset the inv time - %task.buyInvTime = getSimTime(); - - //set the target object - if (isObject(%task.targetObject) && %task.targetObject.getDamageState() !$= "Destroyed") - { - //make sure we still have equipment - %client.needEquipment = AINeedEquipment(%task.equipment, %client); - if (%client.needEquipment) - { - //if this task is the objective task, choose a new objective - if (%task == %client.objectiveTask) - { - AIUnassignClient(%client); - Game.AIChooseGameObjective(%client); - return; - } - } - - //look to see if anyone else is also targetting... - %foundTarget = false; - %numTargets = ServerTargetSet.getCount(); - for (%i = 0; %i < %numTargets; %i++) - { - %targ = ServerTargetSet.getObject(%i); - if (%targ.sourceObject != %client.player) - { - %targDist = VectorDist(%targ.getTargetPoint(), %task.targetObject.getWorldBoxCenter()); - if (%targDist < 10) - { - %foundTarget = true; - break; - } - } - } - - if (%foundTarget) - { - //if this task is the objective task, choose a new objective - if (%task == %client.objectiveTask) - AIUnassignClient(%client); - } - - else if (%client.getStepStatus() $= "Finished") - { - //dissolve the human control link - if (%task == %client.objectiveTask) - aiReleaseHumanControl(%client.controlByHuman, %client); - - %client.setTargetObject(%task.targetObject, 300, "Laze"); - %task.celebrate = true; - %task.waitTimerMS = 0; - - //make sure we only say "fire..." once - if (%task.msgFire) - { - AIMessageThread("FireOnTarget", %client, -1); - %task.msgFire = false; - } - } - else - { - %client.aimAt(%task.targetObject.getWorldBoxCenter(), 1000); - %client.setTargetObject(-1); - } - } - else - { - %client.setTargetObject(-1); - - if (%task.celebrate) - { - if (%task.waitTimerMS == 0) - { - //add in a "woohoo"! :) - //choose the animation range - %minCel = 3; - %maxCel = 8; - - //pick a random sound - if (getRandom() > 0.25) - %sound = "gbl.awesome"; - else if (getRandom() > 0.5) - %sound = "gbl.thanks"; - else if (getRandom() > 0.75) - %sound = "gbl.nice"; - else - %sound = "gbl.rock"; - %randTime = mFloor(getRandom() * 500) + 1; - schedule(%randTime, %client, "AIPlayAnimSound", %client, %task.targetObject.getWorldBoxCenter(), %sound, %minCel, %maxCel, 0); - - //set the timer - %task.waitTimerMS = getSimTime(); - } - - //else see if the celebration period is over - else if (getSimTime() - %task.waitTimerMS > 3000) - %task.celebrate = false; - } - else - { - //if this task is the objective task, choose a new objective - if (%task == %client.objectiveTask) - { - AIUnassignClient(%client); - Game.AIChooseGameObjective(%client); - } - } - } -} - -//------------------------------ - -function AIMortarObject::initFromObjective(%task, %objective, %client) -{ - %task.baseWeight = %client.objectiveWeight; - %task.targetObject = %objective.targetObjectId; - %task.equipment = %objective.equipment; - %task.buyEquipmentSet = %objective.buyEquipmentSet; - %task.desiredEquipment = %objective.desiredEquipment; - %task.issuedByClient = %objective.issuedByClientId; - %task.mode = %task.targetObject.getDataBlock().getName(); - - %task.sendMsgTime = 0; - %task.sendMsg = true; -} - -function AIMortarObject::assume(%task, %client) -{ - %task.setWeightFreq(30); - %task.setMonitorFreq(30); - %task.state = moveToRange; - %task.waitForTargetter = true; - %task.celebrate = false; - %task.waitTimerMS = 0; - %task.targetAcquired = false; - %task.sayAcquired = true; - %client.needEquipment = AINeedEquipment(%task.equipment, %client); - - //even if we don't *need* equipemnt, see if we should buy some... - if (! %client.needEquipment && %task.buyEquipmentSet !$= "") - { - //see if we could benefit from inventory - %needArmor = AIMustUseRegularInvStation(%task.desiredEquipment, %client); - %result = AIFindClosestInventory(%client, %needArmor); - %closestInv = getWord(%result, 0); - %closestDist = getWord(%result, 1); - if (AINeedEquipment(%task.desiredEquipment, %client) && %closestInv > 0) - { - //find where we are - %clientPos = %client.player.getWorldBoxCenter(); - %objPos = %task.targetObject.getWorldBoxCenter(); - %distToObject = %client.getPathDistance(%objPos); - - if (%distToObject < 0 || %closestDist < %distToObject) - %client.needEquipment = true; - } - } - - //mark the current time for the buy inventory state machine - %task.buyInvTime = getSimTime(); -} - -function AIMortarObject::retire(%task, %client) -{ - %client.setTargetObject(-1); - - //remove the associated lazeObjective - if (%task.targetterObjective) - { - AIClearObjective(%task.targetterObjective); - %task.targetterObjective.delete(); - %task.targetterObjective = ""; - } -} - -function AIMortarObject::weight(%task, %client) -{ - //update the task weight - if (%task == %client.objectiveTask) - %task.baseWeight = %client.objectiveWeight; - - //let the monitor decide when to stop mortaring - %task.setWeight(%task.baseWeight); -} - -function AIMortarObject::monitor(%task, %client) -{ - //first, buy the equipment - if (%client.needEquipment) - { - %task.setMonitorFreq(5); - if (%task.equipment !$= "") - %equipmentList = %task.equipment; - else - %equipmentList = %task.desiredEquipment; - %result = AIBuyInventory(%client, %equipmentList, %task.buyEquipmentSet, %task.buyInvTime); - if (%result $= "InProgress") - return; - else if (%result $= "Finished") - { - %task.setMonitorFreq(30); - %client.needEquipment = false; - } - else if (%result $= "Failed") - { - //if this task is the objective task, choose a new objective - if (%task == %client.objectiveTask) - { - AIUnassignClient(%client); - Game.AIChooseGameObjective(%client); - } - return; - } - } - //if we made it past the inventory buying, reset the inv time - %task.buyInvTime = getSimTime(); - - //chat - if (%task.sendMsg) - { - if (%task.sendMsgTime == 0) - %task.sendMsgTime = getSimTime(); - else if (getSimTime() - %task.sendMsgTime > 7000) - { - %task.sendMsg = false; - if (%client.isAIControlled()) - { - if (%task.chat !$= "") - { - %chatMsg = getWord(%task.chat, 0); - %chatTemplate = getWord(%task.chat, 1); - if (%chatTemplate !$= "") - AIMessageThreadTemplate(%chatTemplate, %chatMsg, %client, -1); - else - AIMessageThread(%task.chat, %client, -1); - } - else if (%task.targetObject > 0) - { - %type = %task.targetObject.getDataBlock().getName(); - if (%type $= "GeneratorLarge") - AIMessageThreadTemplate("AttackBase", "ChatSelfAttackGenerator", %client, -1); - else if (%type $= "SensorLargePulse") - AIMessageThreadTemplate("AttackBase", "ChatSelfAttackSensors", %client, -1); - else if (%type $= "SensorMediumPulse") - AIMessageThreadTemplate("AttackBase", "ChatSelfAttackSensors", %client, -1); - else if (%type $= "TurretBaseLarge") - AIMessageThreadTemplate("AttackBase", "ChatSelfAttackTurrets", %client, -1); - else if (%type $= "StationVehicle") - AIMessageThreadTemplate("AttackBase", "ChatSelfAttackVehicle", %client, -1); - } - } - } - } - - //make sure we still have something to destroy - if (isObject(%task.targetObject) && %task.targetObject.getDamageState() !$= "Destroyed") - { - %clientPos = %client.player.getWorldBoxCenter(); - %targetPos = %task.targetObject.getWorldBoxCenter(); - %distance = %client.getPathDistance(%targetPos); - if (%distance < 0) - %distance = 32767; - - //make sure we still have equipment - %client.needEquipment = AINeedEquipment(%task.equipment, %client); - if (%client.needEquipment) - { - //if this task is the objective task, choose a new objective - if (%task == %client.objectiveTask) - { - AIUnassignClient(%client); - Game.AIChooseGameObjective(%client); - return; - } - } - - //next move to within 220 - else if (%distance > 220) - { - %client.setTargetObject(-1); - %client.stepMove(%task.targetObject.getWorldBoxCenter(), 15); - } - - //now start ask for someone to laze the target, and start a 20 sec timer - else if (%task.waitForTargetter) - { - //see if we've started the timer - if (%task.waitTimerMS == 0) - { - //range the object - %client.stepRangeObject(%task.targetObject, "MortarShot", 100, 200); - - //now ask for a targeter... - %targetType = %task.targetObject.getDataBlock().getName(); - if (%targetType $= "TurretBaseLarge") - AIMessageThread("ChatCmdTargetTurret", %client, -1); - else if (%targetType $= "SensorLargePulse") - AIMessageThread("ChatCmdTargetSensors", %client, -1); - else if (%targetType $= "SensorMediumPulse") - AIMessageThread("ChatCmdTargetSensors", %client, -1); - else - AIMessageThread("ChatNeedTarget", %client, -1); - - %task.waitTimerMS = getSimTime(); - - //create the objective - if (! %task.targetterObjective) - { - %task.targetterObjective = new AIObjective(AIOLazeObject) - { - dataBlock = "AIObjectiveMarker"; - weightLevel1 = $AIWeightLazeObject[1]; - weightLevel2 = $AIWeightLazeObject[2]; - description = "Laze the " @ %task.targetObject.getName(); - targetObjectId = %task.targetObject; - issuedByClientId = %client; - offense = true; - equipment = "TargetingLaser"; - }; - MissionCleanup.add(%task.targetterObjective); - $ObjectiveQ[%client.team].add(%task.targetterObjective); - } - %task.targetterObjective.lastLazedTime = 0; - - //remove the escort (want a targetter instead) - if (%client.escort) - { - AIClearObjective(%client.escort); - %client.escort.delete(); - %client.escort = ""; - } - } - else - { - %elapsedTime = getSimTime() - %task.waitTimerMS; - if (%task.targetterObjective.group > 0) - %targetter = %task.targetterObjective.group.clientLevel[1]; - else - %targetter = %task.targetterObjective.clientLevel[1]; - - //see if we can find a target near our objective - %task.targetAcquired = false; - %numTargets = ServerTargetSet.getCount(); - for (%i = 0; %i < %numTargets; %i++) - { - %targ = ServerTargetSet.getObject(%i); - %targDist = VectorDist(%targ.getTargetPoint(), %task.targetObject.getWorldBoxCenter()); - if (%targDist < 20) - { - %task.targetAcquired = true; - break; - } - } - - if (%task.targetAcquired) - { - %task.waitForTargetter = false; - %task.waitTimerMS = 0; - %task.celebrate = true; - %task.sayAcquired = false; - AIMessageThread("ChatTargetAcquired", %client, -1); - } - - //else see if we've run out of time - else if ((! %targetter || ! %targetter.isAIControlled()) && %elapsedTime > 20000) - { - %task.waitForTargetter = false; - %task.waitTimerMS = 0; - %task.celebrate = true; - } - } - } - - //now we should finally be attacking with or without a targetter - //eventually, the target will be destroyed, or we'll run out of ammo... - else - { - //dissolve the human control link - if (%task == %client.objectiveTask) - aiReleaseHumanControl(%client.controlByHuman, %client); - - //see if we didn't acquired a spotter along the way - if (%task.targetterObjective.group > 0) - %targetter = %task.targetterObjective.group.clientLevel[1]; - else - %targetter = %task.targetterObjective.clientLevel[1]; - if (! %task.targetAcquired && AIClientIsAlive(%targetter) && %targetter.isAIControlled()) - { - %client.setTargetObject(-1); - %task.waitForTargetter = true; - } - else - { - //see if we can find a target near our objective - if (! %task.targetAcquired) - { - %numTargets = ServerTargetSet.getCount(); - for (%i = 0; %i < %numTargets; %i++) - { - %targ = ServerTargetSet.getObject(%i); - %targDist = VectorDist(%targ.getTargetPoint(), %task.targetObject.getWorldBoxCenter()); - if (%targDist < 20) - { - %task.targetAcquired = true; - break; - } - } - //see if we found a target (must be by a human) - if (%task.targetAcquired && %task.sayAcquired) - { - %task.sayAcquired = false; - AIMessageThread("ChatTargetAcquired", %client, -1); - } - } - - //set the target object, and keep attacking it - if (%client.getStepStatus() $= "Finished") - %client.setTargetObject(%task.targetObject, 250, "Mortar"); - else - %client.setTargetObject(-1); - } - } - } - - //the target must have been destroyed :) - else - { - //dissolve the human control link - if (%task == %client.objectiveTask) - aiReleaseHumanControl(%client.controlByHuman, %client); - - %client.setTargetObject(-1); - %client.clearStep(); - %client.stop(); - - if (%task.celebrate) - { - if (%task.waitTimerMS == 0) - { - //client animation "woohoo"! :) - //choose the animation range - %minCel = 3; - %maxCel = 8; - - //pick a random sound - if (getRandom() > 0.25) - %sound = "gbl.awesome"; - else if (getRandom() > 0.5) - %sound = "gbl.thanks"; - else if (getRandom() > 0.75) - %sound = "gbl.nice"; - else - %sound = "gbl.rock"; - %randTime = mFloor(getRandom() * 500) + 1; - schedule(%randTime, %client, "AIPlayAnimSound", %client, %task.targetObject.getWorldBoxCenter(), %sound, %minCel, %maxCel, 0); - - //team message - AIMessageThread("ChatEnemyTurretsDestroyed", %client, -1); - - //set the timer - %task.waitTimerMS = getSimTime(); - } - - //else see if the celebration period is over - else if (getSimTime() - %task.waitTimerMS > 3000) - %task.celebrate = false; - } - else - { - //if this task is the objective task, choose a new objective - if (%task == %client.objectiveTask) - { - AIUnassignClient(%client); - Game.AIChooseGameObjective(%client); - } - } - } -} - -//------------------------------ - -function AIDeployEquipment::initFromObjective(%task, %objective, %client) -{ - //initialize the task vars from the objective - %task.baseWeight = %client.objectiveWeight; - %task.location = %objective.location; - %task.equipment = %objective.equipment; - %task.buyEquipmentSet = %objective.buyEquipmentSet; - %task.desiredEquipment = %objective.desiredEquipment; - %task.issuedByClient = %objective.issuedByClientId; - %task.chat = %objective.chat; - - //initialize other task vars - %task.sendMsg = true; - %task.sendMsgTime = 0; - - //use the Y-axis of the rotation as the desired direction of deployement, - //and calculate a walk to point 3 m behind the deploy point. - %task.deployDirection = MatrixMulVector("0 0 0 " @ getWords(%objective.getTransform(), 3, 6), "0 1 0"); - %task.deployDirection = VectorNormalize(%task.deployDirection); -} - -function AIDeployEquipment::assume(%task, %client) -{ - %task.setWeightFreq(15); - %task.setMonitorFreq(15); - - %client.needEquipment = AINeedEquipment(%task.equipment, %client); - - //mark the current time for the buy inventory state machine - %task.buyInvTime = getSimTime(); - - %task.passes = 0; - %task.deployAttempts = 0; - %task.checkObstructed = false; - %task.waitMove = 0; -} - -function AIDeployEquipment::retire(%task, %client) -{ -} - -function AIDeployEquipment::weight(%task, %client) -{ - //update the task weight - if (%task == %client.objectiveTask) - %task.baseWeight = %client.objectiveWeight; - - %task.setWeight(%task.baseWeight); -} - -function findTurretDeployPoint(%client, %location, %attempt) -{ - %player = %client.player; - if (!isObject(%player)) - return "0 0 0"; - - %feetPos = posFromTransform(%player.getTransform()); - %temp = VectorSub(%location, %feetPos); - %temp2 = getWord(%temp, 0) @ " " @ getWord(%temp, 1) @ " 0"; - %facingVector = VectorNormalize(%temp2); - %aimPoint = VectorAdd(%feetPos, %facingVector); - //assume that there will be 10 attempts - %height = getWord(%location, 2) + 1.0 - (0.2 * %attempt); - %aimAt = getWord(%aimPoint, 0) @ " " @ getWord(%aimPoint, 1) @ " " @ %height; - return %aimAt; -} - -function AIDeployEquipment::monitor(%task, %client) -{ - //first, buy the equipment - if (%client.needEquipment) - { - %task.setMonitorFreq(5); - if (%task.equipment !$= "") - %equipmentList = %task.equipment; - else - %equipmentList = %task.desiredEquipment; - %result = AIBuyInventory(%client, %equipmentList, %task.buyEquipmentSet, %task.buyInvTime); - if (%result $= "InProgress") - return; - else if (%result $= "Finished") - { - %task.setMonitorFreq(30); - %client.needEquipment = false; - //if we made it past the inventory buying, reset the inv time - %task.buyInvTime = getSimTime(); - } - else if (%result $= "Failed") - { - //if this task is the objective task, choose a new objective - if (%task == %client.objectiveTask) - { - AIUnassignClient(%client); - Game.AIChooseGameObjective(%client); - } - return; - } - } - - //chat - if (%task.sendMsg) - { - if (%task.sendMsgTime == 0) - %task.sendMsgTime = getSimTime(); - else if (getSimTime() - %task.sendMsgTime > 7000) - { - %task.sendMsg = false; - if (%client.isAIControlled()) - { - if (%task.chat !$= "") - { - %chatMsg = getWord(%task.chat, 0); - %chatTemplate = getWord(%task.chat, 1); - if (%chatTemplate !$= "") - AIMessageThreadTemplate(%chatTemplate, %chatMsg, %client, -1); - else - AIMessageThread(%task.chat, %client, -1); - } - } - } - } - - //see if we're supposed to be engaging anyone... - if (AIClientIsAlive(%client.shouldEngage)) - { - %hasLOS = %client.hasLOSToClient(%client.shouldEngage); - %losTime = %client.getClientLOSTime(%client.shouldEngage); - if (%hasLOS || %losTime < 1000) - %client.setEngageTarget(%client.shouldEngage); - else - %client.setEngageTarget(-1); - } - else - %client.setEngageTarget(-1); - - //calculate the deployFromLocation - %factor = -1 * (3 - (%task.passes * 0.5)); - %task.deployFromLocation = VectorAdd(%task.location,VectorScale(%task.deployDirection, %factor)); - - //see if we're within range of the deploy location - %clLoc = %client.player.position; - %distance = VectorDist(%clLoc, %task.deployFromLocation); - %dist2D = VectorDist(%client.player.position, getWords(%task.deployFromLocation, 0, 1) SPC getWord(%client.player.position, 2)); - - //set the aim when we get near the target... this will be overwritten when we're actually trying to deploy - if (%distance < 10 && %dist2D < 10) - %client.aimAt(%task.location, 1000); - - if ((%client.pathDistRemaining(20) > %distance + 0.25) || %dist2D > 0.5) - { - %task.deployAttempts = 0; - %task.checkObstructed = false; - %task.waitMove = 0; - %client.stepMove(%task.deployFromLocation, 0.25); - %task.setMonitorFreq(15); - return; - } - - if (%task.deployAttempts < 10 && %task.passes < 5 && !AIClientIsAlive(%client.getEngageTarget())) - { - //dissolve the human control link - if (%task == %client.objectiveTask) - aiReleaseHumanControl(%client.controlByHuman, %client); - - %task.setMonitorFreq(3); - %client.stop(); - if (%task.deployAttempts == 0) - %deployPoint = %task.location; - else - %deployPoint = findTurretDeployPoint(%client, %task.location, %task.deployAttempts); - if(%deployPoint !$= "") - { - // we have possible point - %task.deployAttempts++; - %client.aimAt(%deployPoint, 2000); - - //try to deploy the backpack - %client.deployPack = true; - %client.lastDeployedObject = -1; - %client.player.use(Backpack); - - // check if pack deployed - if (isObject(%client.lastDeployedObject)) - { - //see if there's a "repairObject" objective for the newly deployed thingy... - if (%task == %client.objectiveTask) - { - %deployedObject = %client.lastDeployedObject; - - //search the current objective group and search for a "repair Object" task... - %objective = %client.objective; - - //delete any previously associated "AIORepairObject" objective - if (isObject(%objective.repairObjective)) - { - AIClearObjective(%objective.repairObjective); - %objective.repairObjective.delete(); - %objective.repairObjective = ""; - } - - //add the repair objective - %objective.repairObjective = new AIObjective(AIORepairObject) - { - dataBlock = "AIObjectiveMarker"; - weightLevel1 = %objective.weightLevel1 - 60; - weightLevel2 = 0; - description = "Repair the " @ %deployedObject.getDataBlock().getName(); - targetObjectId = %deployedObject; - issuedByClientId = %client; - offense = false; - defense = true; - equipment = "RepairPack"; - }; - %objective.repairObjective.deployed = true; - %objective.repairObjective.setTransform(%objective.getTransform()); - %objective.repairObjective.group = %objective.group; - MissionCleanup.add(%objective.repairObjective); - $ObjectiveQ[%client.team].add(%objective.repairObjective); - - //finally, unassign the client so he'll go do something else... - AIUnassignClient(%client); - Game.AIChooseGameObjective(%client); - } - - //finished - return; - } - } - } - else if (!%task.checkObstructed) - { - %task.checkObstructed = true; - - //see if anything is in our way - InitContainerRadiusSearch(%task.location, 4, $TypeMasks::MoveableObjectType | $TypeMasks::VehicleObjectType | - $TypeMasks::PlayerObjectType); - %objSrch = containerSearchNext(); - if (%objSrch == %client.player) - %objSrch = containerSearchNext(); - if (%objSrch) - AIMessageThread("ChatMove", %client, -1); - } - else if (%task.waitMove < 5 && %task.passes < 5) - { - %task.waitMove++; - - //try another pass at deploying - if (%task.waitMove == 5) - { - %task.waitMove = 0; - %task.passes++; - %task.deployAttempts = 0; - - //see if we're *right* underneath the deploy point - %deployDist2D = VectorDist(getWords(%client.player.position, 0, 1) @ "0", getWords(%task.location, 0, 1) @ "0"); - if (%deployDist2D < 0.25) - { - %client.pressjump(); - %client.deployPack = true; - %client.player.use(Backpack); - - // check if pack deployed - if(%client.player.getMountedImage($BackpackSlot) == 0) - { - //don't add a "repairObject" objective for ceiling turrets - if (%task == %client.objectiveTask) - { - AIUnassignClient(%client); - Game.AIChooseGameObjective(%client); - } - } - } - } - } - else - { - //find a new assignment - and remove this one from the Queue - if (%task == %client.objectiveTask) - { - error(%client SPC "from team" SPC %client.team SPC "is invalidating objective:" SPC %client.objective SPC "UNABLE TO DEPLOY EQUIPMENT"); - %client.objective.isInvalid = true; - AIUnassignClient(%client); - Game.AIChooseGameObjective(%client); - } - } -} - -//------------------------------ -//AI Objective functions -function ClientHasAffinity(%objective, %client) -{ - if (%objective.offense && %client.offense) - return true; - else if (%objective.defense && !%client.offense) - return true; - else - return false; -} - -function ClientHasRequiredEquipment(%objective, %client) -{ - return true; -} - -function AIODefault::weight(%objective, %client, %level, %inventoryStr) -{ - //make sure the player is still alive!!!!! - if (! AIClientIsAlive(%client)) - return 0; - - //set the base weight - switch (%level) - { - case 1: - %weight = %objective.weightLevel1; - case 2: - %weight = %objective.weightLevel2; - case 3: - %weight = %objective.weightLevel3; - default: - %weight = %objective.weightLevel4; - } - - //check Affinity - if (ClientHasAffinity(%objective, %client)) - %weight += 40; - - //if the objective doesn't require any equipment, it automatically get's the +100... - if (%objective.equipment $= "" && %objective.desiredEquipment $= "") - %weight += 100; - else - { - //check equipment requirement - %needEquipment = AINeedEquipment(%objective.equipment, %client); - - //check Required equipment - if (%objective.equipment !$= "" && !%needEquipment) - %weight += 100; - - //figure out the percentage of desired equipment the bot has - else if (%objective.desiredEquipment !$= "") - { - %count = getWordCount(%objective.desiredEquipment); - %itemCount = 0; - for (%i = 0; %i < %count; %i++) - { - %item = getWord(%objective.desiredEquipment, %i); - if (!AINeedEquipment(%item, %client)) - %itemCount++; - } - - //add to the weight - %weight += mFloor((%itemCount / %count) * 75); - } - } - - //find the distance to target - if (%objective.targetClientId !$= "" || %objective.targetObjectId !$= "") - { - if (AIClientIsAlive(%objective.targetClientId)) - { - %targetPos = %objective.targetClientId.player.getWorldBoxCenter(); - } - else if (VectorDist(%objective.location, "0 0 0") > 1) - %targetPos = %objective.location; - else - { - if(%objective.targetObjectId > 0) - %targetPos = %objective.targetObjectId.getWorldBoxCenter(); - } - } - - //make sure the destination is accessible - %distance = %client.getPathDistance(%targetPos); - if (%distance < 0) - return 0; - - %closestInvIsRemote = (getWordCount(%inventoryStr) == 4); - %closestInv = getWord(%inventoryStr, 0); - %closestDist = getWord(%inventoryStr, 1); - %closestRemoteInv = getWord(%inventoryStr, 2); - %closestRemoteDist = getWord(%inventoryStr, 3); - - //if we need equipment, the distance is from the client, to an inv, then to the target - if (%needEquipment) - { - //if we need a regular inventory station, and one doesn't exist, exit - if (!isObject(%closestInv) && %needArmor) - return 0; - - //find the closest inv based on whether we require armor (from a regular inv station) - if (!%closestInvIsRemote) - { - %needArmor = false; - %weightDist = %closestDist; - %weightInv = %closestInv; - } - else - { - %needArmor = AIMustUseRegularInvStation(%objective.equipment, %client); - if (%needArmor) - { - %weightDist = %closestDist; - %weightInv = %closestInv; - } - else - { - %weightDist = %closestRemoteDist; - %weightInv = %closestRemoteInv; - } - } - - //if we don't need armor, and there's no inventory station, see if the equipment we need - //is something we can pick up off the ground (likely this would be a repair pack...) - if (%weightDist >= 32767) - { - %itemType = getWord(%objective.equipment, 0); - %found = false; - %itemCount = $AIItemSet.getCount(); - for (%i = 0; %i < %itemCount; %i++) - { - %item = $AIItemSet.getObject(%i); - if (%item.getDataBlock().getName() $= %itemType && !%item.isHidden()) - { - %weightDist = %client.getPathDistance(%item.getWorldBoxCenter()); - if (%weightDist > 0) - { - %weightInv = %item; //set the var so the distance function will work... - %found = true; - break; - } - } - } - if (! %found) - return 0; - } - - //now find the distance used for weighting the objective - %tempDist = AIGetPathDistance(%targetPos, %weightInv.getWorldBoxCenter()); - if (%tempDist < 0) - %tempDist = 32767; - %distance = %weightDist + %tempDist; - } - - //see if we're within 200 m - if (%distance < 200) - %weight += 30; - - //see if we're within 90 m - if (%distance < 90) - %weight += 30; - - //see if we're within 45 m - if (%distance < 45) - %weight += 30; - - //see if we're within 20 m - if (%distance < 20) - %weight += 30; - - //final return, since we've made it through all the rest - return %weight; -} - -function AIODefault::QuickWeight(%objective, %client, %level, %minWeight) -{ - //can't do a quick weight when re-evaluating a client's current objective - if (%client.objective == %objective) - return true; - - //do a quick check to disqualify this objective if it can't meet the minimum weight - switch (%level) - { - case 1: - %testWeight = %objective.weightLevel1; - case 2: - %testWeight = %objective.weightLevel2; - case 3: - %testWeight = %objective.weightLevel3; - default: - %testWeight = %objective.weightLevel4; - } - if (%testWeight + 260 < %minWeight) - return false; - else - return true; -} - -//------------------------------ - -function AIODefendLocation::weight(%this, %client, %level, %minWeight, %inventoryStr) -{ - // if were playing CnH, check who owns this - if (%this.targetObjectId > 0) - { - if (!isObject(%this.targetObjectId) || %this.targetObjectId.isHidden() || %this.targetObjectId.team != %client.team) - return 0; - } - - //make sure the player is still alive!!!!! - if (! AIClientIsAlive(%client)) - return 0; - - //do a quick check to disqualify this objective if it can't meet the minimum weight - if (!AIODefault::QuickWeight(%this, %client, %level, %minWeight)) - { - if (%this.targetObjectId > 0 && %this.issuedByClientId == %client.controlByHuman) - { - if ($AIWeightHumanIssuedCommand < %minWeight) - return 0; - } - else - return 0; - } - - %weight = AIODefault::weight(%this, %client, %level, %inventoryStr); - - //if the object has been destroyed, reduce the weight - if (%this.targetObjectId > 0) - { - - //see if we were forced on the objective - if (%this.issuedByClientId == %client.controlByHuman && %weight < $AIWeightHumanIssuedCommand) - %weight = $AIWeightHumanIssuedCommand; - - //else see if the object has been destroyed - else if (!isObject(%this.targetObjectId) || %this.targetObjectId.getDamageState() $= "Destroyed") - %weight -= 320; - } - - return %weight; -} - -function AIODefendLocation::assignClient(%this, %client) -{ - %client.objectiveTask = %client.addTask(AIDefendLocation); - %client.objectiveTask.initFromObjective(%this, %client); -} - -function AIODefendLocation::unassignClient(%this, %client) -{ - %client.removeTask(%client.objectiveTask); - %client.objectiveTask = ""; -} - -//------------------------------ - -function AIOAttackLocation::weight(%this, %client, %level, %minWeight, %inventoryStr) -{ - //make sure the player is still alive!!!!! - if (! AIClientIsAlive(%client)) - return 0; - - //now, if this bot is linked to a human who has issued this command, up the weight - if (%this.issuedByClientId == %client.controlByHuman) - { - //make sure we have the potential to reach the minWeight - if (!AIODefault::QuickWeight(%this, %client, %level, %minWeight)) - { - if ($AIWeightHumanIssuedCommand < %minWeight) - return 0; - else - %weight = $AIWeightHumanIssuedCommand; - } - else - { - // calculate the default... - %weight = AIODefault::weight(%this, %client, %level, %inventoryStr); - if (%weight < $AIWeightHumanIssuedCommand) - %weight = $AIWeightHumanIssuedCommand; - } - } - else - { - //make sure we have the potential to reach the minWeight - if (!AIODefault::QuickWeight(%this, %client, %level, %minWeight)) - return 0; - - // calculate the default... - %weight = AIODefault::weight(%this, %client, %level, %inventoryStr); - } - - return %weight; -} - -function AIOAttackLocation::assignClient(%this, %client) -{ - %client.objectiveTask = %client.addTask(AIAttackLocation); - %client.objectiveTask.initFromObjective(%this, %client); -} - -function AIOAttackLocation::unassignClient(%this, %client) -{ - %client.removeTask(%client.objectiveTask); - %client.objectiveTask = ""; -} - -//------------------------------ - -function AIOTouchObject::weight(%this, %client, %level, %minWeight, %inventoryStr) -{ - //make sure the player is still alive!!!!! - if (! AIClientIsAlive(%client)) - return 0; - - if (!AIODefault::QuickWeight(%this, %client, %level, %minWeight)) - return 0; - - switch$ (%this.mode) - { - case "TouchFlipFlop": - if(%this.targetObjectId.team == %client.team || %this.targetObjectId.isHidden()) - return 0; - else - return AIODefault::weight(%this, %client, %level, %inventoryStr); - case "FlagGrab": - if (! %this.targetObjectId.isHome) - return 0; - else - return AIODefault::weight(%this, %client, %level, %inventoryStr); - case "FlagDropped": - if ((%this.targetObjectId.isHome) || (%this.targetObjectId.carrier !$= "")) - return 0; - else - return AIODefault::weight(%this, %client, %level, %inventoryStr); - case "FlagCapture": - if (%this.targetObjectId.carrier != %client.player) - return 0; - else - { - //find our home flag location - %homeTeam = %client.team; - %homeFlag = $AITeamFlag[%homeTeam]; - %this.location = %homeFlag.originalPosition; - return AIODefault::weight(%this, %client, %level, %inventoryStr); - } - } - return 0; -} - -function AIOTouchObject::assignClient(%this, %client) -{ - %client.objectiveTask = %client.addTask(AITouchObject); - %client.objectiveTask.initFromObjective(%this, %client); - - //create an AIOEscortPlayer objective to help out, if required - if (%this.mode $= "FlagGrab") - { - %client.escort = new AIObjective(AIOEscortPlayer) - { - dataBlock = "AIObjectiveMarker"; - weightLevel1 = $AIWeightEscortOffense[1]; - weightLevel2 = $AIWeightEscortOffense[2]; - description = "Escort " @ getTaggedString(%client.name); - targetClientId = %client; - offense = true; - desiredEquipment = "EnergyPack"; - buyEquipmentSet = "LightEnergyELF"; - }; - MissionCleanup.add(%client.escort); - $ObjectiveQ[%client.team].add(%client.escort); - } - - else if (%this.mode $= "FlagCapture") - { - %client.escort = new AIObjective(AIOEscortPlayer) - { - dataBlock = "AIObjectiveMarker"; - weightLevel1 = $AIWeightEscortCapper[1]; - weightLevel2 = $AIWeightEscortCapper[2]; - description = "Escort " @ getTaggedString(%client.name); - targetClientId = %client; - offense = true; - desiredEquipment = "EnergyPack"; - buyEquipmentSet = "LightEnergyDefault"; - }; - MissionCleanup.add(%client.escort); - $ObjectiveQ[%client.team].add(%client.escort); - } -} - -function AIOTouchObject::unassignClient(%this, %client) -{ - //kill the escort objective - if (%client.escort) - { - AIClearObjective(%client.escort); - %client.escort.delete(); - %client.escort = ""; - } - - %client.removeTask(%client.objectiveTask); - %client.objectiveTask = ""; -} - -//------------------------------ - -function AIOAttackPlayer::weight(%this, %client, %level, %minWeight, %inventoryStr) -{ - //make sure the player is still alive!!!!! - if (! AIClientIsAlive(%client)) - return 0; - - //if we're attacking the flag carrier, make sure a flag carrier exists - if (%this.mode $= "FlagCarrier") - { - if (%this.targetObjectId.carrier $= "") - return 0; - else - %this.targetClientId = %this.targetObjectId.carrier.client; - } - - //now, if this bot is linked to a human who has issued this command, up the weight - if (%this.issuedByClientId == %client.controlByHuman) - { - //make sure we have the potential to reach the minWeight - if (!AIODefault::QuickWeight(%this, %client, %level, %minWeight)) - { - if ($AIWeightHumanIssuedCommand < %minWeight) - return 0; - else - %weight = $AIWeightHumanIssuedCommand; - } - else - { - // calculate the default... - %weight = AIODefault::weight(%this, %client, %level, %inventoryStr); - if (%weight < $AIWeightHumanIssuedCommand) - %weight = $AIWeightHumanIssuedCommand; - } - } - else - { - //make sure we have the potential to reach the minWeight - if (!AIODefault::QuickWeight(%this, %client, %level, %minWeight)) - return 0; - - // calculate the default... - %weight = AIODefault::weight(%this, %client, %level, %inventoryStr); - } - - return %weight; -} - -function AIOAttackPlayer::assignClient(%this, %client) -{ - %client.objectiveTask = %client.addTask(AIAttackPlayer); - %client.objectiveTask.initFromObjective(%this, %client); -} - -function AIOAttackPlayer::unassignClient(%this, %client) -{ - %client.removeTask(%client.objectiveTask); - %client.objectiveTask = ""; -} - -//------------------------------ - -function AIOEscortPlayer::weight(%this, %client, %level, %minWeight, %inventoryStr) -{ - //make sure the player is still alive!!!!! - if (! AIClientIsAlive(%client) || ! AIClientIsAlive(%this.targetClientId)) - return 0; - - //can't escort yourself - if (%client == %this.targetClientId) - return 0; - - //make sure the class is appropriate - if (%this.forceClientId <= 0 && %this.issuedByClientId != %client.controlByHuman) - { - %targArmor = %this.targetClientId.player.getArmorSize(); - %myArmor = %client.player.getArmorSize(); - - if ((%targArmor $= "Light" && %myArmor !$= "Light") || %myArmor $= "Heavy") - return 0; - } - - //can't bump a forced client from level 1 - if (%this.forceClientId > 0 && %this.forceClientId != %client && %level == 1) - return 0; - - //if this bot is linked to a human who has issued this command, up the weight - if (%this.issuedByClientId == %client.controlByHuman) - { - //make sure we have the potential to reach the minWeight - if (!AIODefault::QuickWeight(%this, %client, %level, %minWeight)) - { - if ($AIWeightHumanIssuedEscort < %minWeight) - return 0; - else - %weight = $AIWeightHumanIssuedEscort; - } - else - { - // calculate the default... - %weight = AIODefault::weight(%this, %client, %level, %inventoryStr); - if (%weight < $AIWeightHumanIssuedEscort) - %weight = $AIWeightHumanIssuedEscort; - } - } - else - { - //make sure we have the potential to reach the minWeight - if (!AIODefault::QuickWeight(%this, %client, %level, %minWeight)) - return 0; - - // calculate the default... - %weight = AIODefault::weight(%this, %client, %level, %inventoryStr); - } - - return %weight; -} - -function AIOEscortPlayer::assignClient(%this, %client) -{ - %client.objectiveTask = %client.addTask(AIEscortPlayer); - %client.objectiveTask.initFromObjective(%this, %client); -} - -function AIOEscortPlayer::unassignClient(%this, %client) -{ - %client.removeTask(%client.objectiveTask); - %client.objectiveTask = ""; -} - -//------------------------------ - -function AIOAttackObject::weight(%this, %client, %level, %minWeight, %inventoryStr) -{ - // if were playing CnH, check who owns this - if (!isObject(%this.targetObjectId) || %this.targetObjectId.isHidden() || %this.targetObjectId.team == %client.team) - return 0; - - //make sure the player is still alive!!!!! - if (! AIClientIsAlive(%client)) - return 0; - - //no need to attack if the object is already destroyed - if (!isObject(%this.targetObjectId) || %this.targetObjectId.getDamageState() $= "Destroyed") - return 0; - else - { - //if this bot is linked to a human who has issued this command, up the weight - if (%this.issuedByClientId == %client.controlByHuman) - { - //make sure we have the potential to reach the minWeight - if (!AIODefault::QuickWeight(%this, %client, %level, %minWeight)) - { - if ($AIWeightHumanIssuedCommand < %minWeight) - return 0; - else - %weight = $AIWeightHumanIssuedCommand; - } - else - { - // calculate the default... - %weight = AIODefault::weight(%this, %client, %level, %inventoryStr); - if (%weight < $AIWeightHumanIssuedCommand) - %weight = $AIWeightHumanIssuedCommand; - } - } - else - { - //make sure we have the potential to reach the minWeight - if (!AIODefault::QuickWeight(%this, %client, %level, %minWeight)) - return 0; - - // calculate the default... - %weight = AIODefault::weight(%this, %client, %level, %inventoryStr); - } - - return %weight; - } -} - -function AIOAttackObject::assignClient(%this, %client) -{ - %client.objectiveTask = %client.addTask(AIAttackObject); - %client.objectiveTask.initFromObjective(%this, %client); -} - -function AIOAttackObject::unassignClient(%this, %client) -{ - %client.removeTask(%client.objectiveTask); - %client.objectiveTask = ""; -} - -//------------------------------ - -function AIORepairObject::weight(%this, %client, %level, %minWeight, %inventoryStr) -{ - // if were playing CnH, check who owns this - if (!isObject(%this.targetObjectId) || %this.targetObjectId.isHidden() || %this.targetObjectId.team != %client.team) - return 0; - - //make sure the player is still alive!!!!! - if (! AIClientIsAlive(%client)) - return 0; - - //no need to repair if the object isn't in need - if (!isObject(%this.targetObjectId) || %this.targetObjectId.getDamagePercent() <= 0) - return 0; - else - { - //if this bot is linked to a human who has issued this command, up the weight - if (%this.issuedByClientId == %client.controlByHuman) - { - //make sure we have the potential to reach the minWeight - if (!AIODefault::QuickWeight(%this, %client, %level, %minWeight)) - { - if ($AIWeightHumanIssuedCommand < %minWeight) - return 0; - else - %weight = $AIWeightHumanIssuedCommand; - } - else - { - // calculate the default... - %weight = AIODefault::weight(%this, %client, %level, %inventoryStr); - if (%weight < $AIWeightHumanIssuedCommand) - %weight = $AIWeightHumanIssuedCommand; - } - } - else - { - //make sure we have the potential to reach the minWeight - if (!AIODefault::QuickWeight(%this, %client, %level, %minWeight)) - return 0; - - // calculate the default... - %weight = AIODefault::weight(%this, %client, %level, %inventoryStr); - } - - return %weight; - } -} - -function AIORepairObject::assignClient(%this, %client) -{ - %client.objectiveTask = %client.addTask(AIRepairObject); - %client.objectiveTask.initFromObjective(%this, %client); -} - -function AIORepairObject::unassignClient(%this, %client) -{ - %client.removeTask(%client.objectiveTask); - %client.objectiveTask = ""; -} - -//------------------------------ - -function AIOLazeObject::weight(%this, %client, %level, %minWeight, %inventoryStr) -{ - //make sure the player is still alive!!!!! - if (! AIClientIsAlive(%client)) - return 0; - - //see if it's already being lazed - %numTargets = ServerTargetSet.getCount(); - for (%i = 0; %i < %numTargets; %i++) - { - %targ = ServerTargetSet.getObject(%i); - if (%targ.sourceObject != %client.player) - { - %targDist = VectorDist(%targ.getTargetPoint(), %this.targetObjectId.getWorldBoxCenter()); - if (%targDist < 10) - { - %this.lastLazedTime = getSimTime(); - %this.lastLazedClient = %targ.sourceObject.client; - break; - } - } - } - - //no need to laze if the object is already destroyed - if (!isObject(%this.targetObjectId) || %this.targetObjectId.getDamageState() $= "Destroyed") - return 0; - else if (%this.targetObjectId.isHidden() || %this.targetObjectId.team != %client.team) - return 0; - else if (getSimTime() - %this.lastLazedTime <= 15000 && %this.lastLazedClient != %client) - return 0; - else - { - //set the base weight - switch (%level) - { - case 1: - %weight = %this.weightLevel1; - case 2: - %weight = %this.weightLevel2; - case 3: - %weight = %this.weightLevel3; - default: - %weight = %this.weightLevel4; - } - - //check Affinity - if (ClientHasAffinity(%this, %client)) - %weight += 100; - - //for now, do not deviate from the current assignment to laze a target, if you don't - //already have a targeting laser. - %needEquipment = AINeedEquipment(%this.equipment, %client); - if (!%needEquipment) - %weight += 100; - else if (!aiHumanHasControl(%client.controlByHuman, %client)) - return 0; - - //see if this client is close to the issuing client - if (%this.issuedByClientId > 0) - { - if (! AIClientIsAlive(%this.issuedByClientId)) - return 0; - - %distance = %client.getPathDistance(%this.issuedByClientId.player.getWorldBoxCenter()); - if (%distance < 0) - %distance = 32767; - - //see if we're within 200 m - if (%distance < 200) - %weight += 30; - - //see if we're within 90 m - if (%distance < 90) - %weight += 30; - - //see if we're within 45 m - if (%distance < 45) - %weight += 30; - } - - //now, if this bot is linked to a human who has issued this command, up the weight - if (%this.issuedByClientId == %client.controlByHuman && %weight < $AIWeightHumanIssuedCommand) - %weight = $AIWeightHumanIssuedCommand; - - return %weight; - } -} - -function AIOLazeObject::assignClient(%this, %client) -{ - %client.objectiveTask = %client.addTask(AILazeObject); - %client.objectiveTask.initFromObjective(%this, %client); -} - -function AIOLazeObject::unassignClient(%this, %client) -{ - %client.removeTask(%client.objectiveTask); - %client.objectiveTask = ""; -} - -//------------------------------ - -function AIOMortarObject::weight(%this, %client, %level, %minWeight, %inventoryStr) -{ - // if were playing CnH, check who owns this - if (!isObject(%this.targetObjectId) || %this.targetObjectId.isHidden() || %this.targetObjectId.team == %client.team) - return 0; - - //make sure the player is still alive!!!!! - if (! AIClientIsAlive(%client)) - return 0; - - //no need to attack if the object is already destroyed - if (%this.targetObjectId.getDamageState() $= "Destroyed") - return 0; - else - { - //if this bot is linked to a human who has issued this command, up the weight - if (%this.issuedByClientId == %client.controlByHuman) - { - //make sure we have the potential to reach the minWeight - if (!AIODefault::QuickWeight(%this, %client, %level, %minWeight)) - { - if ($AIWeightHumanIssuedCommand < %minWeight) - return 0; - else - %weight = $AIWeightHumanIssuedCommand; - } - else - { - // calculate the default... - %weight = AIODefault::weight(%this, %client, %level, %inventoryStr); - if (%weight < $AIWeightHumanIssuedCommand) - %weight = $AIWeightHumanIssuedCommand; - } - } - else - { - //make sure we have the potential to reach the minWeight - if (!AIODefault::QuickWeight(%this, %client, %level, %minWeight)) - return 0; - - // calculate the default... - %weight = AIODefault::weight(%this, %client, %level, %inventoryStr); - } - - return %weight; - } -} - -function AIOMortarObject::assignClient(%this, %client) -{ - %client.objectiveTask = %client.addTask(AIMortarObject); - %client.objectiveTask.initFromObjective(%this, %client); - - //create the escort objective (require a targeting laser in this case...) - %client.escort = new AIObjective(AIOEscortPlayer) - { - dataBlock = "AIObjectiveMarker"; - weightLevel1 = $AIWeightEscortOffense[1]; - weightLevel2 = $AIWeightEscortOffense[2]; - description = "Escort " @ getTaggedString(%client.name); - targetClientId = %client; - offense = true; - equipment = "TargetingLaser"; - buyEquipmentSet = "LightEnergyDefault"; - }; - MissionCleanup.add(%client.escort); - $ObjectiveQ[%client.team].add(%client.escort); -} - -function AIOMortarObject::unassignClient(%this, %client) -{ - //kill the escort objective - if (%client.escort) - { - AIClearObjective(%client.escort); - %client.escort.delete(); - %client.escort = ""; - } - - %client.removeTask(%client.objectiveTask); - %client.objectiveTask = ""; -} - -//------------------------------------------------------------------------ -//If the function ShapeBaseImageData::testInvalidDeployConditions() changes at all, those changes need to be reflected here -function AIODeployEquipment::weight(%this, %client, %level, %minWeight, %inventoryStr) -{ - //make sure the player is still alive!!!!! - if (! AIClientIsAlive(%client)) - return 0; - - //make sure the deploy objective is valid - if (%this.isInvalid) - return 0; - - //first, make sure we haven't deployed too many... - if (%this.equipment $= "TurretOutdoorDeployable" || %this.equipment $= "TurretIndoorDeployable") - %maxAllowed = countTurretsAllowed(%this.equipment); - else - %maxAllowed = $TeamDeployableMax[%this.equipment]; - - if ($TeamDeployedCount[%client.team, %this.equipment] >= %maxAllowed) - return 0; - - //now make sure there are no other items in the way... - InitContainerRadiusSearch(%this.location, $MinDeployableDistance, $TypeMasks::VehicleObjectType | - $TypeMasks::MoveableObjectType | - $TypeMasks::StaticShapeObjectType | - $TypeMasks::TSStaticShapeObjectType | - $TypeMasks::ForceFieldObjectType | - $TypeMasks::ItemObjectType | - $TypeMasks::PlayerObjectType | - $TypeMasks::TurretObjectType); - %objSearch = containerSearchNext(); - - //make sure we're not invalidating the deploy location with the client's own player object - if (%objSearch == %client.player) - %objSearch = containerSearchNext(); - - //did we find an object which would block deploying the equipment? - if (isObject(%objSearch)) - return 0; - - //now run individual checks based on the equipment type... - if (%this.equipment $= "TurretIndoorDeployable") - { - //check if there's another turret close to the deploy location - InitContainerRadiusSearch(%this.location, $TurretIndoorSpaceRadius, $TypeMasks::StaticShapeObjectType); - %found = containerSearchNext(); - if (isObject(%found)) - { - %foundName = %found.getDataBlock().getName(); - if ((%foundName $= TurretDeployedFloorIndoor) || (%foundName $= "TurretDeployedWallIndoor") || (%foundName $= "TurretDeployedCeilingIndoor") || (%foundName $= "TurretDeployedOutdoor")) - return 0; - } - - //now see if there are too many turrets in the area... - %highestDensity = 0; - InitContainerRadiusSearch(%this.location, $TurretIndoorSphereRadius, $TypeMasks::StaticShapeObjectType); - %found = containerSearchNext(); - while (isObject(%found)) - { - %foundName = %found.getDataBlock().getName(); - if ((%foundName $= "TurretDeployedFloorIndoor") || (%foundName $= "TurretDeployedWallIndoor") || (%foundName $= "TurretDeployedCeilingIndoor") || (%foundName $= "TurretDeployedOutdoor")) - { - //found one - %numTurretsNearby++; - - %nearbyDensity = testNearbyDensity(%found, $TurretIndoorSphereRadius); - if (%nearbyDensity > %highestDensity) - %highestDensity = %nearbyDensity; - } - %found = containerSearchNext(); - } - - if (%numTurretsNearby > %highestDensity) - %highestDensity = %numTurretsNearby; - - //now see if the area is already saturated - if (%highestDensity > $TurretIndoorMaxPerSphere) - return 0; - } - - else if (%this.equipment $= "TurretOutdoorDeployable") - { - //check if there's another turret close to the deploy location - InitContainerRadiusSearch(%this.location, $TurretOutdoorSpaceRadius, $TypeMasks::StaticShapeObjectType); - %found = containerSearchNext(); - if (isObject(%found)) - { - %foundName = %found.getDataBlock().getName(); - if ((%foundName $= "TurretDeployedFloorIndoor") || (%foundName $= "TurretDeployedWallIndoor") || (%foundName $= "TurretDeployedCeilingIndoor") || (%foundName $= "TurretDeployedOutdoor")) - return 0; - } - - //now see if there are too many turrets in the area... - %highestDensity = 0; - InitContainerRadiusSearch(%this.location, $TurretOutdoorSphereRadius, $TypeMasks::StaticShapeObjectType); - %found = containerSearchNext(); - while (isObject(%found)) - { - %foundName = %found.getDataBlock().getName(); - if ((%foundName $= "TurretDeployedFloorIndoor") || (%foundName $= "TurretDeployedWallIndoor") || (%foundName $= "TurretDeployedCeilingIndoor") || (%foundName $= "TurretDeployedOutdoor")) - { - //found one - %numTurretsNearby++; - - %nearbyDensity = testNearbyDensity(%found, $TurretOutdoorSphereRadius); - if (%nearbyDensity > %highestDensity) - %highestDensity = %nearbyDensity; - } - %found = containerSearchNext(); - } - - if (%numTurretsNearby > %highestDensity) - %highestDensity = %numTurretsNearby; - - //now see if the area is already saturated - if (%highestDensity > $TurretOutdoorMaxPerSphere) - return 0; - } - - //check equipment requirement - %needEquipment = AINeedEquipment(%this.equipment, %client); - - //if don't need equipment, see if we've past the "point of no return", and should continue regardless - if (! %needEquipment) - { - %needArmor = AIMustUseRegularInvStation(%this.equipment, %client); - %result = AIFindClosestInventory(%client, %needArmor); - %closestInv = getWord(%result, 0); - %closestDist = getWord(%result, 1); - - //if we're too far from the inv to go back, or we're too close to the deploy location, force continue - if (%closestDist > 50 && VectorDist(%client.player.getWorldBoxCenter(), %task.location) < 50) - { - %weight = AIODefault::weight(%this, %client, %level, %inventoryStr); - if (%weight < $AIWeightContinueDeploying) - %weight = $AIWeightContinueDeploying; - return %weight; - } - } - - //if this bot is linked to a human who has issued this command, up the weight - if (%this.issuedByClientId == %client.controlByHuman) - { - //make sure we have the potential to reach the minWeight - if (!AIODefault::QuickWeight(%this, %client, %level, %minWeight)) - { - if ($AIWeightHumanIssuedCommand < %minWeight) - return 0; - else - %weight = $AIWeightHumanIssuedCommand; - } - else - { - // calculate the default... - %weight = AIODefault::weight(%this, %client, %level, %inventoryStr); - if (%weight < $AIWeightHumanIssuedCommand) - %weight = $AIWeightHumanIssuedCommand; - } - } - else - { - //make sure we have the potential to reach the minWeight - if (!AIODefault::QuickWeight(%this, %client, %level, %minWeight)) - return 0; - - // calculate the default... - %weight = AIODefault::weight(%this, %client, %level, %inventoryStr); - } - - return %weight; -} - -function AIODeployEquipment::assignClient(%this, %client) -{ - %client.objectiveTask = %client.addTask(AIDeployEquipment); - %task = %client.objectiveTask; - %task.initFromObjective(%this, %client); -} - -function AIODeployEquipment::unassignClient(%this, %client) -{ - %client.removeTask(%client.objectiveTask); - %client.objectiveTask = ""; -} - -//------------------------------------------------------------------------ +//------------------------------ +//AI Objective Q functions... + +$ObjectiveClientsSet = 0; +function AIObjectiveFindClients(%objective) +{ + //create and clear the set + if (! $ObjectiveClientsSet) + { + $ObjectiveClientsSet = new SimSet(); + MissionCleanup.add($ObjectiveClientSet); + } + $ObjectiveClientsSet.clear(); + + %clientCount = 0; + %count = ClientGroup.getCount(); + for(%i = 0; %i < %count; %i++) + { + %cl = ClientGroup.getObject(%i); + if (%cl.objective == %objective) + $ObjectiveClientsSet.add(%cl); + } + return $ObjectiveClientsSet.getCount(); +} + +function AIObjectiveGetClosestClient(%location, %team) +{ + if (%location $= "") + return -1; + + if (%team $= "") + %team = 0; + + %closestClient = -1; + %closestDistance = 32767; + %count = ClientGroup.getCount(); + for(%i = 0; %i < %count; %i++) + { + %cl = ClientGroup.getObject(%i); + if (%cl.isAIControlled() && (%cl.team == %team || %team == 0) && AIClientIsAlive(%cl)) + { + %testPos = %cl.player.getWorldBoxCenter(); + %distance = VectorDist(%location, %testPos); + if (%distance < %closestDistance) + { + %closestDistance = %distance; + %closestClient = %cl; + } + } + } + + return %closestClient; +} + +function AICountObjectives(%team) +{ + %objCount = 0; + %count = $ObjectiveQ[%team].getCount(); + for (%i = 0; %i < %count; %i++) + { + %grp = $ObjectiveQ[%team].getObject(%i); + if (%grp.getClassName() !$= "AIObjective") + %objCount += %grp.getCount(); + else + %objCount++; + } + error("DEBUG" SPC %team SPC "has" SPC %objCount SPC "objectives."); +} + +function AIAddTableObjective(%objective, %weight, %level, %bump, %position) +{ + $objTable[%position, objective] = %objective; + $objTable[%position, weight] = %weight; + $objTable[%position, level] = %level; + $objTable[%position, bump] = %bump; + $objTableCount = %position + 1; +} + +function AIChooseObjective(%client, %useThisObjectiveQ) +{ + //pick which objectiveQ to use, or use the default + if (%useThisObjectiveQ <= 0 && %client.team < 0) + return; + + if (%useThisObjectiveQ <= 0) + %useThisObjectiveQ = $ObjectiveQ[%client.team]; + + if (!isObject(%useThisObjectiveQ) || %useThisObjectiveQ.getCount() <= 0) + return; + + //since most objectives check for inventory, find the closest inventory stations first + %inventoryStr = AIFindClosestInventories(%client); + + //find the most appropriate objective + if (!%client.objective) + { + //note, the table is never empty, during the course of this function + AIAddTableObjective(0, 0, 0, 0, 0); + } + else + { + //should re-evaluate the current objective weight - but never decrease the weight!!! + %testWeight = %client.objective.weight(%client, %client.objectiveLevel, 0, %inventoryStr); + if (%testWeight <= 0 || %testWeight > %client.objectiveWeight) + %client.objectiveWeight = %testWeight; + + if (%client.objectiveWeight > 0) + AIAddTableObjective(%client.objective, %client.objectiveWeight, %client.objectiveLevel, 0, 0); + else + AIAddTableObjective(0, 0, 0, 0, 0); + } + + %objCount = %useThisObjectiveQ.getCount(); + for (%i = 0; %i < %objCount; %i++) + { + %objective = %useThisObjectiveQ.getObject(%i); + + //don't re-evaluate the client's own + if (%objective == %client.objective) + continue; + + //try this objective at each of the 4 weight levels to see if it is weighted higher + for (%level = 1; %level <= 4; %level++) + { + %minWeight = 0; + %bumpWeight = 0; + %bumpClient = ""; + + //we can bump clients off the objective for the first three levels + if (%level <= 3) + { + //if the objective is part of a group, check the whole group + if (%objective.group > 0) + { + %bumpClient = %objective.group.clientLevel[%level]; + %bumpWeight = %bumpClient.objectiveWeight; + } + else + { + %bumpClient = %objective.clientLevel[%level]; + %bumpWeight = %bumpClient.objectiveWeight; + } + } + + //find the minimum weight the objective must have to be considered + %minWeight = (%bumpWeight > $objTable[0, weight] ? %bumpWeight : $objTable[0, weight]); + + //evaluate the weight + %weight = %objective.weight(%client, %level, %minWeight, %inventoryStr); + + //make sure we got a valid weight + if (%weight <= 0) + break; + + //if it's the highest so far, it now replaces anything else in the table + if (%weight > $objTable[0, weight]) + { + //never bump someone unless you out- weight them + if (%weight > %bumpWeight) + { + AIAddTableObjective(%objective, %weight, %level, %bumpClient, 0); + + //no need to keep checking the other levels + break; + } + } + + //else if it's equal to the highest objective we've seen so far, and higher from our current objective + else if (%weight == $objTable[0, weight] && %weight > %client.objectiveWeight) + { + //never bump someone unless you outweigh them + if (%weight > %bumpWeight) + { + //if this wouldn't require us to bump someone, or the table is empty + if (%bumpWeight <= 0 || $objTable[0, weight] <= 0) + { + //if the table currently contains objectives which would require bumping someone, clear it + if ($objTable[0, bump] > 0) + %position = 0; + else + %position = $objTableCount; + + //add it to the table + AIAddTableObjective(%objective, %weight, %level, %bumpClient, %position); + + //no need to keep checking the other levels + break; + } + + //otherwise, the table is not empty, and this would require us to bump someone + //only add it if everything else in the table would also require us to bump someone + else if ($objTable[0, bump] > 0) + { + AIAddTableObjective(%objective, %weight, %level, %bumpClient, $objTableCount); + + //no need to keep checking the other levels + break; + } + } + } + + //else it must have been less than our highest objective so far- again, no need to keep checking other levels... + else + break; + } + } + + //if we have a table of possible objectives which are higher than our current- choose one at random + if ($objTableCount > 0 && $objTable[0, objective] != %client.objective) + { + //choose the new one + %index = mFloor(getRandom() * ($objTableCount - 0.01)); + + //clear the old objective + if (%client.objective) + { + if (%client.objectiveLevel <= 3) + { + if (%client.objective.group > 0) + { + if (%client.objective.group.clientLevel[%client.objectiveLevel] == %client) + %client.objective.group.clientLevel[%client.objectiveLevel] = ""; + } + else + { + if (%client.objective.clientLevel[%client.objectiveLevel] == %client) + %client.objective.clientLevel[%client.objectiveLevel] = ""; + } + } + %client.objective.unassignClient(%client); + } + + //assign the new + %chooseObjective = $objTable[%index, objective]; + %client.objective = %chooseObjective; + %client.objectiveWeight = $objTable[%index, weight]; + %client.objectiveLevel = $objTable[%index, level]; + if (%client.objectiveLevel <= 3) + { + if (%chooseObjective.group > 0) + %chooseObjective.group.clientLevel[%client.objectiveLevel] = %client; + else + %chooseObjective.clientLevel[%client.objectiveLevel] = %client; + } + %chooseObjective.assignClient(%client); + + //see if this objective needs to be acknowledged + if (%chooseObjective.shouldAcknowledge && %chooseObjective.issuedByHuman && isObject(%chooseObjective.issuedByClientId)) + { + //cancel any pending acknowledgements - a bot probably just got bumped off this objective + cancel(%chooseObjective.ackSchedule); + %chooseObjective.ackSchedule = schedule(5500, %chooseObjective, "AIAcknowledgeObjective", %client, %chooseObjective); + } + + //if we had to bump someone off this objective, + %bumpClient = $objTable[%index, bump]; + if (%bumpClient > 0) + { + //unassign the bumped client and choose a new objective + AIUnassignClient(%bumpClient); + Game.AIChooseGameObjective(%bumpClient); + } + } + + //debuging - refresh aidebugq() if required + //if ($AIDebugTeam >= 0) + // aiDebugQ($AIDebugTeam); +} + +function AIAcknowledgeObjective(%client, %objective) +{ + %objective.shouldAcknowledge = false; + //make sure the client is still assigned to this objective + if (%client.objective == %objective) + serverCmdAcceptTask(%client, %objective.issuedByClientId, -1, %objective.ackDescription); +} + +function AIForceObjective(%client, %newObjective, %useWeight) +{ + //if we found a new objective, release the old, and assign the new + if (%newObjective && %newObjective != %client.objective) + { + //see if someone was already assigned to this objective + if (%newObjective.group > 0) + %prevClient = newObjective.group.clientLevel[1]; + else + %prevClient = newObjective.clientLevel[1]; + if (%prevClient > 0) + AIUnassignClient(%prevClient); + + //see if we should override the weight + if (%useWeight < %newObjective.weightLevel1) + %useWeight = %newObjective.weightLevel1; + + //release the client, and force the assignment + AIUnassignClient(%client); + %client.objective = %newObjective; + %client.objectiveWeight = %useWeight; + %client.objectiveLevel = 1; + if (%newObjective.group > 0) + %newObjective.group.clientLevel[1] = %client; + else + %newObjective.clientLevel[1] = %client; + %newObjective.forceClientId = %client; + %newObjective.assignClient(%client); + + //don't acknowledge anything that's been forced... + %newObjective.shouldAcknowledge = false; + + //now reassign the prev client + if (%prevClient) + Game.AIChooseGameObjective(%prevClient); + } + + //debuging - refresh aidebugq() if required + //if ($AIDebugTeam >= 0) + // aiDebugQ($AIDebugTeam); +} + +function AIUnassignClient(%client) +{ + //first, dissolve any link with a human + aiReleaseHumanControl(%client.controlByHuman, %client); + + if (%client.objective) + { + if (%client.objectiveLevel <= 3) + { + if (%client.objective.group > 0) + { + //make sure the clientLevel was actually this client + if (%client.objective.group.clientLevel[%client.objectiveLevel] == %client) + %client.objective.group.clientLevel[%client.objectiveLevel] = ""; + } + else + { + if (%client.objective.clientLevel[%client.objectiveLevel] == %client) + %client.objective.clientLevel[%client.objectiveLevel] = ""; + } + } + // DDDX: Fixes some console spamming is all + if (isObject(%client.objective)) + %client.objective.unassignClient(%client); + %client.objective = ""; + %client.objectiveWeight = 0; + } + + //debuging - refresh aidebugq() if required + //if ($AIDebugTeam >= 0) + // aiDebugQ($AIDebugTeam); +} + +function AIClearObjective(%objective) +{ + %count = ClientGroup.getCount(); + for(%i = 0; %i < %count; %i++) + { + %cl = ClientGroup.getObject(%i); + if (%cl.objective == %objective) + AIUnassignClient(%cl); + } + + //debuging - refresh aidebugq() if required + //if ($AIDebugTeam >= 0) + // aiDebugQ($AIDebugTeam); +} + +//------------------------------ +//TASKS AND OBJECTIVES + +function AIDefendLocation::initFromObjective(%task, %objective, %client) +{ + //initialize the task vars from the objective + %task.baseWeight = %client.objectiveWeight; + %task.targetObject = %objective.targetObjectId; + if (%objective.Location !$= "") + %task.location = %objective.location; + else + %task.location = %objective.targetObjectId.getWorldBoxCenter(); + + %task.equipment = %objective.equipment; + %task.buyEquipmentSet = %objective.buyEquipmentSet; + %task.desiredEquipment = %objective.desiredEquipment; + %task.issuedByClient = %objective.issuedByClientId; + %task.chat = %objective.chat; + + //initialize other task vars + %task.sendMsg = true; + %task.sendMsgTime = 0; + + %task.engageTarget = -1; +} + +function AIDefendLocation::assume(%task, %client) +{ + %task.setWeightFreq(15); + %task.setMonitorFreq(15); + %client.inPerimeter = false; + %client.needEquipment = AINeedEquipment(%task.equipment, %client); + + //even if we don't *need* equipemnt, see if we should buy some... + if (! %client.needEquipment && %task.buyEquipmentSet !$= "") + { + //see if we could benefit from inventory + %needArmor = AIMustUseRegularInvStation(%task.desiredEquipment, %client); + %result = AIFindClosestInventory(%client, %needArmor); + %closestInv = getWord(%result, 0); + %closestDist = getWord(%result, 1); + if (AINeedEquipment(%task.desiredEquipment, %client) && %closestInv > 0) + { + %result = AIFindClosestEnemy(%client, 200, $AIClientLOSTimeout); + %closestEnemy = getWord(%result, 0); + %closestEnemydist = getWord(%result, 1); + + if (%closestEnemy <= 0 || (%closestEnemyDist > %closestDist * 1.5)) + %client.needEquipment = true; + } + } + + //mark the current time for the buy inventory state machine + %task.buyInvTime = getSimTime(); + + //set a flag to determine if the objective should be re-aquired when the object is destroyed + %task.reassignOnDestroyed = false; +} + +function AIDefendLocation::retire(%task, %client) +{ + %task.engageVehicle = -1; + %client.setTargetObject(-1); +} + +function AIDefendLocation::weight(%task, %client) +{ + //update the task weight + if (%task == %client.objectiveTask) + %task.baseWeight = %client.objectiveWeight; + + %player = %client.player; + if (!isObject(%player)) + return; + + %hasMissile = (%player.getInventory("MissileLauncher") > 0) && (%player.getInventory("MissileLauncherAmmo") > 0); + + //if we're defending with a missile launcher, our first priority is to take out vehicles... + //see if we're already attacking a vehicle... + if (%task.engageVehicle > 0 && isObject(%task.engageVehicle) && %hasMissile) + { + //set the weight + %task.setWeight(%task.baseWeight); + return; + } + + //search for a new vehicle to attack + %task.engageVehicle = -1; + %losTimeout = $AIClientMinLOSTime + ($AIClientLOSTimeout * %client.getSkillLevel()); + %result = AIFindClosestEnemyPilot(%client, 300, %losTimeout); + %pilot = getWord(%result, 0); + %pilotDist = getWord(%result, 1); + + //if we've got missiles, and a vehicle to attack... + if (%hasMissile && AIClientIsAlive(%pilot)) + { + %task.engageVehicle = %pilot.vehicleMounted; + %client.needEquipment = false; + } + + //otherwise look for a regular enemy to fight... + else + { + %result = AIFindClosestEnemyToLoc(%client, %task.location, 100, %losTimeout); + %closestEnemy = getWord(%result, 0); + %closestdist = getWord(%result, 1); + + //see if we found someone + if (%closestEnemy > 0) + %task.engageTarget = %closestEnemy; + else + { + %task.engageTarget = -1; + + //see if someone is near me... + %result = AIFindClosestEnemy(%client, 100, %losTimeout); + %closestEnemy = getWord(%result, 0); + %closestdist = getWord(%result, 1); + if (%closestEnemy <= 0 || %closestDist > 70) + %client.setEngageTarget(-1); + } + } + + //set the weight + %task.setWeight(%task.baseWeight); +} + +function AIDefendLocation::monitor(%task, %client) +{ + //first, buy the equipment + if (%client.needEquipment) + { + %task.setMonitorFreq(5); + if (%task.equipment !$= "") + %equipmentList = %task.equipment; + else + %equipmentList = %task.desiredEquipment; + %result = AIBuyInventory(%client, %equipmentList, %task.buyEquipmentSet, %task.buyInvTime); + if (%result $= "InProgress") + return; + else if (%result $= "Finished") + { + %task.setMonitorFreq(15); + %client.needEquipment = false; + } + else if (%result $= "Failed") + { + //if this task is the objective task, choose a new objective + if (%task == %client.objectiveTask) + { + AIUnassignClient(%client); + Game.AIChooseGameObjective(%client); + } + return; + } + } + //if we made it past the inventory buying, reset the inv time + %task.buyInvTime = getSimTime(); + + //chat + if (%task.sendMsg) + { + if (%task.sendMsgTime == 0) + %task.sendMsgTime = getSimTime(); + else if (getSimTime() - %task.sendMsgTime > 7000) + { + %task.sendMsg = false; + if (%client.isAIControlled()) + { + if (%task.chat !$= "") + { + %chatMsg = getWord(%task.chat, 0); + %chatTemplate = getWord(%task.chat, 1); + if (%chatTemplate !$= "") + AIMessageThreadTemplate(%chatTemplate, %chatMsg, %client, -1); + else + AIMessageThread(%task.chat, %client, -1); + } + else if (%task.targetObject > 0) + { + %type = %task.targetObject.getDataBlock().getName(); + if (%type $= "Flag") + AIMessageThreadTemplate("DefendBase", "ChatSelfDefendFlag", %client, -1); + else if (%type $= "GeneratorLarge") + AIMessageThreadTemplate("DefendBase", "ChatSelfDefendGenerator", %client, -1); + else if (%type $= "StationVehicle") + AIMessageThreadTemplate("DefendBase", "ChatSelfDefendVehicle", %client, -1); + else if (%type $= "SensorLargePulse") + AIMessageThreadTemplate("DefendBase", "ChatSelfDefendSensors", %client, -1); + else if (%type $= "SensorMediumPulse") + AIMessageThreadTemplate("DefendBase", "ChatSelfDefendSensors", %client, -1); + else if (%type $= "TurretBaseLarge") + AIMessageThreadTemplate("DefendBase", "ChatSelfDefendTurrets", %client, -1); + } + } + } + } + + //if the defend location task has an object, set the "reset" flag + if (%task == %client.objectiveTask && isObject(%task.targetObject)) + { + if (%task.targetObject.getDamageState() !$= "Destroyed") + %task.reassignOnDestroyed = true; + else + { + if (%task.reassignOnDestroyed) + { + AIUnassignClient(%client); + Game.AIChooseGameObjective(%client); + return; + } + } + } + + //first, check for a vehicle to engage + if (%task.engageVehicle > 0 && isObject(%task.engageVehicle)) + { + %client.stop(); + %client.clearStep(); + %client.setEngageTarget(-1); + %client.setTargetObject(%task.engageVehicle, 300, "Missile"); + } + else + { + //clear the target vehicle... + %client.setTargetObject(-1); + + //see if we're engaging a player + if (%client.getEngageTarget() > 0) + { + //too far, or killed the enemy - return home + if (%client.getStepStatus() !$= "InProgress" || %distance > 75) + { + %client.setEngageTarget(-1); + %client.stepMove(%task.location, 8.0); + } + } + + //else see if we have a target to begin attacking + else if (%task.engageTarget > 0) + %client.stepEngage(%task.engageTarget); + + //else move to a random location around where we are defending + else if (%client.getStepName() !$= "AIStepIdlePatrol") + { + %dist = VectorDist(%client.player.getWorldBoxCenter(), %task.location); + if (%dist < 10) + { + //dissolve the human control link and re-evaluate the weight + if (%task == %client.objectiveTask) + { + if (aiHumanHasControl(%task.issuedByClient, %client)) + { + aiReleaseHumanControl(%client.controlByHuman, %client); + + //should re-evaluate the current objective weight + %inventoryStr = AIFindClosestInventories(%client); + %client.objectiveWeight = %client.objective.weight(%client, %client.objectiveLevel, 0, %inventoryStr); + } + } + + %client.stepIdle(%task.location); + } + else + %client.stepMove(%task.location, 8.0); + } + } + + //see if we're supposed to be engaging anyone... + if (!AIClientIsAlive(%client.getEngageTarget()) && AIClientIsAlive(%client.shouldEngage)) + %client.setEngageTarget(%client.shouldEngage); +} + +//------------------------------ + +function AIAttackLocation::initFromObjective(%task, %objective, %client) +{ + //initialize the task vars from the objective + %task.baseWeight = %client.objectiveWeight; + %task.location = %objective.location; + %task.equipment = %objective.equipment; + %task.buyEquipmentSet = %objective.buyEquipmentSet; + %task.desiredEquipment = %objective.desiredEquipment; + %task.issuedByClient = %objective.issuedByClientId; + %task.chat = %objective.chat; + + //initialize other task vars + %task.sendMsg = true; + %task.sendMsgTime = 0; + %task.engageTarget = -1; +} + +function AIAttackLocation::assume(%task, %client) +{ + %task.setWeightFreq(30); + %task.setMonitorFreq(30); + %client.needEquipment = AINeedEquipment(%task.equipment, %client); + + //even if we don't *need* equipemnt, see if we should buy some... + if (! %client.needEquipment && %task.buyEquipmentSet !$= "") + { + //see if we could benefit from inventory + %needArmor = AIMustUseRegularInvStation(%task.desiredEquipment, %client); + %result = AIFindClosestInventory(%client, %needArmor); + %closestInv = getWord(%result, 0); + %closestDist = getWord(%result, 1); + if (AINeedEquipment(%task.desiredEquipment, %client) && %closestInv > 0) + { + %result = AIFindClosestEnemyToLoc(%client, %task.location, 50, $AIClientLOSTimeout); + %closestEnemy = getWord(%result, 0); + + if (%closestEnemy <= 0) + %client.needEquipment = true; + } + } + + //mark the current time for the buy inventory state machine + %task.buyInvTime = getSimTime(); + + %task.snipeLocation = ""; + %task.hideLocation = ""; + %task.moveToPosition = true; + %task.moveToSnipe = false; + %task.nextSnipeTime = 0; +} + +function AIAttackLocation::retire(%task, %client) +{ +} + +function AIAttackLocation::weight(%task, %client) +{ + //update the task weight + if (%task == %client.objectiveTask) + %task.baseWeight = %client.objectiveWeight; + + //if we're a sniper, we're going to cheat, and see if there are clients near the attack location + %losTimeout = $AIClientMinLOSTime + ($AIClientLOSTimeout * %client.getSkillLevel()); + %distToLoc = VectorDist(%client.player.getWorldBoxCenter(), %task.location); + if (%client.player.getInventory(SniperRifle) > 0 && %client.player.getInventory(EnergyPack) > 0 && %distToLoc > 60) + %result = AIFindClosestEnemyToLoc(%client, %task.location, 50, $AIClientLOSTimeout, true); + + //otherwise, do the search normally. (cheat ignores LOS)... + else + %result = AIFindClosestEnemyToLoc(%client, %task.location, 50, %losTimeout, false); + + %closestEnemy = getWord(%result, 0); + %closestdist = getWord(%result, 1); + %task.setWeight(%task.baseWeight); + + //see if we found someone + if (%closestEnemy > 0) + %task.engageTarget = %closestEnemy; + else + %task.engageTarget = -1; +} + +function AIAttackLocation::monitor(%task, %client) +{ + //first, buy the equipment + if (%client.needEquipment) + { + %task.setMonitorFreq(5); + if (%task.equipment !$= "") + %equipmentList = %task.equipment; + else + %equipmentList = %task.desiredEquipment; + %result = AIBuyInventory(%client, %equipmentList, %task.buyEquipmentSet, %task.buyInvTime); + if (%result $= "InProgress") + return; + else if (%result $= "Finished") + { + %task.setMonitorFreq(30); + %client.needEquipment = false; + } + else if (%result $= "Failed") + { + //if this task is the objective task, choose a new objective + if (%task == %client.objectiveTask) + { + AIUnassignClient(%client); + Game.AIChooseGameObjective(%client); + } + return; + } + } + //if we made it past the inventory buying, reset the inv time + %task.buyInvTime = getSimTime(); + + //chat + if (%task.sendMsg) + { + if (%task.sendMsgTime == 0) + %task.sendMsgTime = getSimTime(); + else if (getSimTime() - %task.sendMsgTime > 7000) + { + %task.sendMsg = false; + if (%client.isAIControlled()) + { + if (%task.chat !$= "") + { + %chatMsg = getWord(%task.chat, 0); + %chatTemplate = getWord(%task.chat, 1); + if (%chatTemplate !$= "") + AIMessageThreadTemplate(%chatTemplate, %chatMsg, %client, -1); + else + AIMessageThread(%task.chat, %client, -1); + } + else + AIMessageThreadTemplate("AttackBase", "ChatSelfAttack", %client, -1); + } + } + } + + //how far are we from the location we're defending + %myPos = %client.player.getWorldBoxCenter(); + %distance = %client.getPathDistance(%task.location); + if (%distance < 0) + %distance = 32767; + + if (%client.player.getInventory(SniperRifle) > 0 && %client.player.getInventory(EnergyPack) > 0) + { + //first, find an LOS location + if (%task.snipeLocation $= "") + { + %task.snipeLocation = %client.getLOSLocation(%task.location, 150, 250); + %task.hideLocation = %client.getHideLocation(%task.location, VectorDist(%task.location, %task.snipeLocation), %task.snipeLocation, 1); + %client.stepMove(%task.hideLocation, 4.0); + %task.moveToPosition = true; + } + else + { + //see if we can acquire a target + %energy = %client.player.getEnergyPercent(); + %distToSnipe = VectorDist(%task.snipelocation, %client.player.getWorldBoxCenter()); + %distToHide = VectorDist(%task.hidelocation, %client.player.getWorldBoxCenter()); + + //until we're in position, we can move using the AIModeExpress, after that, we only want to walk... + if (%task.moveToPosition) + { + if (%distToHide < 4.0) + { + //dissolve the human control link + if (%task == %client.objectiveTask) + { + if (aiHumanHasControl(%task.issuedByClient, %client)) + { + aiReleaseHumanControl(%client.controlByHuman, %client); + + //should re-evaluate the current objective weight + %inventoryStr = AIFindClosestInventories(%client); + %client.objectiveWeight = %client.objective.weight(%client, %client.objectiveLevel, 0, %inventoryStr); + } + } + + %task.moveToPosition = false; + } + } + + else if (%task.moveToSnipe) + { + if (%energy > 0.75 && %client.getStepStatus() $= "Finished") + { + %client.stepMove(%task.snipeLocation, 4.0, $AIModeWalk); + %client.setEngageTarget(%task.engageTarget); + } + else if (%energy < 0.4) + { + %client.setEngageTarget(-1); + %client.stepMove(%task.hideLocation, 4.0); + %task.nextSnipeTime = getSimTime() + 4000 + (getRandom() * 4000); + %task.moveToSnipe = false; + } + } + + else if (%energy > 0.5 && %task.engageTarget > 0 && getSimTime() > %task.nextSnipeTime) + { + %client.stepRangeObject(%task.engageTarget.player.getWorldBoxCenter(), "BasicSniperShot", 150, 250, %task.snipelocation); + %client.aimAt(%task.engageTarget.player.getWorldBoxCenter(), 8000); + %task.moveToSnipe = true; + } + } + } + else + { + //else see if we have a target to begin attacking + if (%client.getEngageTarget() <= 0 && %task.engageTarget > 0) + %client.stepEngage(%task.engageTarget); + + //else move to the location we're defending + else if (%client.getEngageTarget() <= 0) + { + %client.stepMove(%task.location, 8.0); + if (VectorDist(%client.player.position, %task.location) < 10) + { + //dissolve the human control link + if (%task == %client.objectiveTask) + { + if (aiHumanHasControl(%task.issuedByClient, %client)) + { + aiReleaseHumanControl(%client.controlByHuman, %client); + + //should re-evaluate the current objective weight + %inventoryStr = AIFindClosestInventories(%client); + %client.objectiveWeight = %client.objective.weight(%client, %client.objectiveLevel, 0, %inventoryStr); + } + } + } + } + } + + //see if we're supposed to be engaging anyone... + if (!AIClientIsAlive(%client.getEngageTarget()) && AIClientIsAlive(%client.shouldEngage)) + %client.setEngageTarget(%client.shouldEngage); +} + +//------------------------------ + +function AIAttackPlayer::initFromObjective(%task, %objective, %client) +{ + %task.baseWeight = %client.objectiveWeight; + %task.targetClient = %objective.targetClientId; + %task.equipment = %objective.equipment; + %task.buyEquipmentSet = %objective.buyEquipmentSet; + %task.desiredEquipment = %objective.desiredEquipment; + %task.issuedByClient = %objective.issuedByClientId; +} + +function AIAttackPlayer::assume(%task, %client) +{ + %task.setWeightFreq(15); + %task.setMonitorFreq(15); + %client.needEquipment = AINeedEquipment(%task.equipment, %client); + if (! %client.needEquipment) + %client.stepEngage(%task.targetClient); + + //even if we don't *need* equipemnt, see if we should buy some... + if (! %client.needEquipment && %task.buyEquipmentSet !$= "") + { + //see if we could benefit from inventory + %needArmor = AIMustUseRegularInvStation(%task.desiredEquipment, %client); + %result = AIFindClosestInventory(%client, %needArmor); + %closestInv = getWord(%result, 0); + %closestDist = getWord(%result, 1); + if (AINeedEquipment(%task.desiredEquipment, %client) && %closestInv > 0) + { + %distToTarg = %client.getPathDistance(%task.targetClient.player.getWorldBoxCenter()); + if (%distToTarg < 0 || %distToTarg > 100) + %client.needEquipment = true; + } + } + + //mark the current time for the buy inventory state machine + %task.buyInvTime = getSimTime(); +} + +function AIAttackPlayer::retire(%task, %client) +{ + //dissolve the human control link + if (%task == %client.objectiveTask) + aiReleaseHumanControl(%client.controlByHuman, %client); +} + +function AIAttackPlayer::weight(%task, %client) +{ + //update the task weight + if (%task == %client.objectiveTask) + %task.baseWeight = %client.objectiveWeight; + + %task.setWeight(%task.baseWeight); +} + +function AIAttackPlayer::monitor(%task, %client) +{ + //first, buy the equipment + if (%client.needEquipment) + { + %task.setMonitorFreq(5); + if (%task.equipment !$= "") + %equipmentList = %task.equipment; + else + %equipmentList = %task.desiredEquipment; + %result = AIBuyInventory(%client, %equipmentList, %task.buyEquipmentSet, %task.buyInvTime); + if (%result $= "InProgress") + return; + else if (%result $= "Finished") + { + %task.setMonitorFreq(15); + %client.needEquipment = false; + %client.stepEngage(%task.targetClient); + } + else if (%result $= "Failed") + { + //if this task is the objective task, choose a new objective + if (%task == %client.objectiveTask) + { + AIUnassignClient(%client); + Game.AIChooseGameObjective(%client); + } + return; + } + } + //if we made it past the inventory buying, reset the inv time + %task.buyInvTime = getSimTime(); + + //cheap hack for now... make the bot always know where you are... + %client.clientDetected(%task.targetClient); + + //make sure we're still attacking... + if (%client.getStepName() !$= "AIStepEngage") + %client.stepEngage(%task.targetClient); + + //make sure we're still attacking the right target + %client.setEngageTarget(%task.targetClient); + + if (%client.getStepStatus() !$= "InProgress" && %task == %client.objectiveTask) + { + AIUnassignClient(%client); + Game.AIChooseGameObjective(%client); + } +} + +//------------------------------ + +function AIHuntPlayer::initFromObjective(%task, %objective, %client) +{ + %task.baseWeight = %client.objectiveWeight; + %task.targetClient = %objective.targetClientId; + %task.equipment = %objective.equipment; + %task.buyEquipmentSet = %objective.buyEquipmentSet; + %task.desiredEquipment = %objective.desiredEquipment; + %task.issuedByClient = %objective.issuedByClientId; +} + +function AIHuntPlayer::assume(%task, %client) +{ + %task.setWeightFreq(15); + %task.setMonitorFreq(15); + %client.needEquipment = AINeedEquipment(%task.equipment, %client); + if (! %client.needEquipment) + %client.stepEngage(%task.targetClient); + + //even if we don't *need* equipemnt, see if we should buy some... + if (! %client.needEquipment && %task.buyEquipmentSet !$= "") + { + //see if we could benefit from inventory + %needArmor = AIMustUseRegularInvStation(%task.desiredEquipment, %client); + %result = AIFindClosestInventory(%client, %needArmor); + %closestInv = getWord(%result, 0); + %closestDist = getWord(%result, 1); + if (AINeedEquipment(%task.desiredEquipment, %client) && %closestInv > 0) + { + %distToTarg = %client.getPathDistance(%task.targetClient.player.getWorldBoxCenter()); + if (%distToTarg < 0 || %distToTarg > 100) + %client.needEquipment = true; + } + } + + //mark the current time for the buy inventory state machine + %task.buyInvTime = getSimTime(); +} + +function AIHuntPlayer::retire(%task, %client) +{ + //dissolve the human control link + if (%task == %client.objectiveTask) + aiReleaseHumanControl(%client.controlByHuman, %client); +} + +function AIHuntPlayer::weight(%task, %client) +{ + //update the task weight + if (%task == %client.objectiveTask) + %task.baseWeight = %client.objectiveWeight; + + %task.setWeight(%task.baseWeight); +} + +function AIHuntPlayer::monitor(%task, %client) +{ +echo("LOL"); + //first, buy the equipment + if (%client.needEquipment) + { + %task.setMonitorFreq(5); + if (%task.equipment !$= "") + %equipmentList = %task.equipment; + else + %equipmentList = %task.desiredEquipment; + %result = AIBuyInventory(%client, %equipmentList, %task.buyEquipmentSet, %task.buyInvTime); + if (%result $= "InProgress") + return; + else if (%result $= "Finished") + { + %task.setMonitorFreq(15); + %client.needEquipment = false; + %client.stepEngage(%task.targetClient); + } + else if (%result $= "Failed") + { + //if this task is the objective task, choose a new objective + if (%task == %client.objectiveTask) + { + AIUnassignClient(%client); + Game.AIChooseGameObjective(%client); + } + return; + } + } + //if we made it past the inventory buying, reset the inv time + %task.buyInvTime = getSimTime(); + + //cheap hack for now... make the bot always know where you are... + %client.clientDetected(%task.targetClient); + + //make sure we're still attacking... + if (%client.getStepName() !$= "AIStepEngage") + %client.stepEngage(%task.targetClient); + + //make sure we're still attacking the right target + %client.setEngageTarget(%task.targetClient); + + if (%client.getStepStatus() !$= "InProgress" && %task == %client.objectiveTask) + { + AIUnassignClient(%client); + Game.AIChooseGameObjective(%client); + } +} + +//------------------------------ + +function AITouchObject::initFromObjective(%task, %objective, %client) +{ + %task.baseWeight = %client.objectiveWeight; + %task.targetObject = %objective.targetObjectId; + %task.mode = %objective.mode; + if (%objective.mode $= "FlagCapture") + %task.location = %objective.location; + else if(%objective.mode $= "TouchFlipFlop") + %task.location = %objective.location; + else + %task.location = ""; + %task.equipment = %objective.equipment; + %task.buyEquipmentSet = %objective.buyEquipmentSet; + %task.desiredEquipment = %objective.desiredEquipment; + %task.issuedByClient = %objective.issuedByClientId; + + %task.sendMsgTime = 0; + if (%task.mode $= "FlagGrab") + %task.sendMsg = true; + else + %task.sendMsg = false; +} + +function AITouchObject::assume(%task, %client) +{ + %task.setWeightFreq(15); + %task.setMonitorFreq(15); + %task.engageTarget = 0; + %client.needEquipment = AINeedEquipment(%task.equipment, %client); + + //even if we don't *need* equipemnt, see if we should buy some... + if (! %client.needEquipment && (%task.mode $= "FlagGrab" || %task.mode $= "TouchFlipFlop") && %task.buyEquipmentSet !$= "") + { + //see if we could benefit from inventory + %needArmor = AIMustUseRegularInvStation(%task.desiredEquipment, %client); + %result = AIFindClosestInventory(%client, %needArmor); + %closestInv = getWord(%result, 0); + %closestDist = getWord(%result, 1); + if (AINeedEquipment(%task.desiredEquipment, %client) && %closestInv > 0) + { + //find where we are + %clientPos = %client.player.getWorldBoxCenter(); + %distToObject = %client.getPathDistance(%task.location); + if (%distToObject < 0 || %closestDist < %distToObject) + %client.needEquipment = true; + } + } + + //mark the current time for the buy inventory state machine + %task.buyInvTime = getSimTime(); +} + +function AITouchObject::retire(%task, %client) +{ +} + +function AITouchObject::weight(%task, %client) +{ + //update the task weight + if (%task == %client.objectiveTask) + %task.baseWeight = %client.objectiveWeight; + + //see if we can find someone to shoot at... + if (%client.getEngageTarget() <= 0) + { + %losTimeout = $AIClientMinLOSTime + ($AIClientLOSTimeout * %client.getSkillLevel()); + %myLocation = %client.player.getWorldBoxCenter(); + %result = AIFindClosestEnemy(%client, 40, %losTimeout); + %task.engageTarget = getWord(%result, 0); + } + + %task.setWeight(%task.baseWeight); +} + +function AITouchObject::monitor(%task, %client) +{ + //first, buy the equipment + if (%client.needEquipment) + { + %task.setMonitorFreq(5); + if (%task.equipment !$= "") + %equipmentList = %task.equipment; + else + %equipmentList = %task.desiredEquipment; + %result = AIBuyInventory(%client, %equipmentList, %task.buyEquipmentSet, %task.buyInvTime); + if (%result $= "InProgress") + return; + else if (%result $= "Finished") + { + %task.setMonitorFreq(15); + %client.needEquipment = false; + } + else if (%result $= "Failed") + { + //if this task is the objective task, choose a new objective + if (%task == %client.objectiveTask) + { + AIUnassignClient(%client); + Game.AIChooseGameObjective(%client); + } + return; + } + } + //if we made it past the inventory buying, reset the inv time + %task.buyInvTime = getSimTime(); + + //chat + if (%task.sendMsg) + { + if (%task.sendMsgTime == 0) + %task.sendMsgTime = getSimTime(); + else if (getSimTime() - %task.sendMsgTime > 7000) + { + %task.sendMsg = false; + if (%client.isAIControlled()) + { + if (%task.mode $= "FlagGrab") + AIMessageThreadTemplate("AttackBase", "ChatSelfAttackFlag", %client, -1); + } + } + } + + //keep updating the position, in case the flag is flying through the air... + if (%task.location !$= "") + %touchPos = %task.location; + else + %touchPos = %task.targetObject.getWorldBoxCenter(); + + //see if we need to engage a new target + %engageTarget = %client.getEngageTarget(); + if (!AIClientIsAlive(%engageTarget) && %task.engageTarget > 0) + %client.setEngageTarget(%task.engageTarget); + + //else see if we should abandon the engagement + else if (AIClientIsAlive(%engageTarget)) + { + %myPos = %client.player.getWorldBoxCenter(); + %testPos = %engageTarget.player.getWorldBoxCenter(); + %distance = %client.getPathDistance(%testPos); + if (%distance < 0 || %distance > 70) + %client.setEngageTarget(-1); + } + + //see if we have completed our objective + if (%task == %client.objectiveTask) + { + %completed = false; + switch$ (%task.mode) + { + case "TouchFlipFlop": + if (%task.targetObject.team == %client.team) + %completed = true; + case "FlagGrab": + if (!%task.targetObject.isHome) + %completed = true; + case "FlagDropped": + if ((%task.targetObject.isHome) || (%task.targetObject.carrier !$= "")) + %completed = true; + case "FlagCapture": + if (%task.targetObject.carrier != %client.player) + %completed = true; + } + if (%completed) + { + AIUnassignClient(%client); + Game.AIChooseGameObjective(%client); + return; + } + } + + if (%task.mode $= "FlagCapture") + { + %homeFlag = $AITeamFlag[%client.team]; + + //if we're within range of the flag's home position, and the flag isn't home, start idling... + if (VectorDist(%client.player.position, %touchPos) < 40 && !%homeFlag.isHome) + { + if (%client.getStepName() !$= "AIStepIdlePatrol") + %client.stepIdle(%touchPos); + } + else + %client.stepMove(%touchPos, 0.25); + } + else + %client.stepMove(%touchPos, 0.25); + + if (VectorDist(%client.player.position, %touchPos) < 10) + { + //dissolve the human control link + if (%task == %client.objectiveTask) + { + if (aiHumanHasControl(%task.issuedByClient, %client)) + { + aiReleaseHumanControl(%client.controlByHuman, %client); + + //should re-evaluate the current objective weight + %inventoryStr = AIFindClosestInventories(%client); + %client.objectiveWeight = %client.objective.weight(%client, %client.objectiveLevel, 0, %inventoryStr); + } + } + } + + //see if we're supposed to be engaging anyone... + if (!AIClientIsAlive(%client.getEngageTarget()) && AIClientIsAlive(%client.shouldEngage)) + %client.setEngageTarget(%client.shouldEngage); +} + +//------------------------------ + +function AIEscortPlayer::initFromObjective(%task, %objective, %client) +{ + %task.baseWeight = %client.objectiveWeight; + %task.targetClient = %objective.targetClientId; + %task.equipment = %objective.equipment; + %task.buyEquipmentSet = %objective.buyEquipmentSet; + %task.desiredEquipment = %objective.desiredEquipment; + %task.issuedByClient = %objective.issuedByClientId; + %task.forceClient = %objective.forceClientId; +} + +function AIEscortPlayer::assume(%task, %client) +{ + %task.setWeightFreq(15); + %task.setMonitorFreq(15); + %task.rangedTarget = false; + if (%task == %client.objectiveTask && %client == %task.forceClient && %task.issuedByClient == %task.targetClient) + { + %client.needEquipment = false; + %client.mountVehicle = false; + } + else + { + %client.needEquipment = AINeedEquipment(%task.equipment, %client); + if (! %client.needEquipment) + %client.stepEscort(%task.targetClient); + + //even if we don't *need* equipemnt, see if we should buy some... + if (! %client.needEquipment && %task.buyEquipmentSet !$= "") + { + //see if we could benefit from inventory + %needArmor = AIMustUseRegularInvStation(%task.desiredEquipment, %client); + %result = AIFindClosestInventory(%client, %needArmor); + %closestInv = getWord(%result, 0); + %closestDist = getWord(%result, 1); + if (AINeedEquipment(%task.desiredEquipment, %client) && %closestInv > 0) + { + //find where we are + %clientPos = %client.player.getWorldBoxCenter(); + %targPos = %task.targetClient.player.getWorldBoxCenter(); + %distToTarg = %client.getPathDistance(%targPos); + + if (%closestDist < 50 && (%distToTarg < 0 || %distToTarg > 100)) + %client.needEquipment = true; + } + } + } + + //mark the current time for the buy inventory state machine + %task.buyInvTime = getSimTime(); +} + +function AIEscortPlayer::retire(%task, %client) +{ + %client.clearStep(); + if(%client.player.isMounted()) + AIDisembarkVehicle(%client); + + //clear the target object + %client.setTargetObject(-1); +} + +function AIEscortPlayer::weight(%task, %client) +{ + //update the task weight + if (%task == %client.objectiveTask) + %task.baseWeight = %client.objectiveWeight; + + //make sure we still have someone to escort + if (!AiClientIsAlive(%task.targetClient)) + { + %task.setWeight(0); + return; + } + + //always shoot at the closest person to the client being escorted + %targetPos = %task.targetClient.player.getWorldBoxCenter(); + %losTimeout = $AIClientMinLOSTime + ($AIClientLOSTimeout * %client.getSkillLevel()); + %result = AIFindClosestEnemyToLoc(%client, %targetPos, 50, %losTimeout); + %task.engageTarget = getWord(%result, 0); + if (!AIClientIsAlive(%task.engageTarget)) + { + if (AIClientIsAlive(%task.targetClient.lastDamageClient, %losTimeout) && getSimTime() - %task.targetClient.lastDamageTime < %losTimeout) + %task.engageTarget = %task.targetClient.lastDamageClient; + } + if (!AIClientIsAlive(%task.engageTarget)) + { + %myPos = %client.player.getWorldBoxCenter(); + %result = AIFindClosestEnemy(%client, 50, %losTimeout); + %task.engageTarget = getWord(%result, 0); + } + + //if both us and the person we're escorting are in a vehicle, set the weight high! + if (%task.targetClient.player.isMounted() && %client.player.isMounted()) + { + %vehicle = %client.vehicleMounted; + if (%vehicle > 0 && isObject(%vehicle) && %vehicle.getDamagePercent() < 0.8) + %task.setWeight($AIWeightVehicleMountedEscort); + else + %task.setWeight(%task.baseWeight); + } + else + %task.setWeight(%task.baseWeight); + + //find out if our escortee is lazing a target... + %task.missileTarget = -1; + %targetCount = ServerTargetSet.getCount(); + for (%i = 0; %i < %targetCount; %i++) + { + %targ = ServerTargetSet.getObject(%i); + if (%targ.sourceObject == %task.targetClient.player) + { + //find out which item is being targetted... + %targPoint = %targ.getTargetPoint(); + InitContainerRadiusSearch(%targPoint, 10, $TypeMasks::TurretObjectType | $TypeMasks::StaticShapeObjectType); + %task.missileTarget = containerSearchNext(); + break; + } + } +} + +function AIEscortPlayer::monitor(%task, %client) +{ + //make sure we still have someone to escort + if (!AiClientIsAlive(%task.targetClient)) + { + if (%task == %client.objectiveTask) + { + AIUnassignClient(%client); + Game.AIChooseGameObjective(%client); + } + return; + } + + //first, buy the equipment + if (%client.needEquipment) + { + %task.setMonitorFreq(5); + if (%task.equipment !$= "") + %equipmentList = %task.equipment; + else + %equipmentList = %task.desiredEquipment; + %result = AIBuyInventory(%client, %equipmentList, %task.buyEquipmentSet, %task.buyInvTime); + if (%result $= "InProgress") + return; + else if (%result $= "Finished") + { + %task.setMonitorFreq(15); + %client.needEquipment = false; + %client.stepEscort(%task.targetClient); + %task.buyInvTime = getSimTime(); + } + else if (%result $= "Failed") + { + //if this task is the objective task, choose a new objective + if (%task == %client.objectiveTask) + { + AIUnassignClient(%client); + Game.AIChooseGameObjective(%client); + } + return; + } + } + + //see if our target is mounted in a vehicle... + if (%task.targetClient.player.isMounted()) + { + //find the passenger seat the bot will take + %vehicle = %task.targetClient.vehicleMounted; + %node = findAIEmptySeat(%vehicle, %client.player); + + //make sure there is an empty seat + if (%node < 0 && %client.vehicleMounted != %task.targetClient.vehicleMounted) + { + if (%task == %client.objectiveTask) + { + AIUnassignClient(%client); + Game.AIChooseGameObjective(%client); + } + return; + } + + //find the passenger seat location... + %slotPosition = %vehicle.getSlotTransform(%node); + + //make sure we're in the correct armor - assault tanks cannot have a heavy... + if (%task.targetClient.vehicleMounted.getDataBlock().getName() $= "AssaultVehicle") + { + //if the bot is in a heavy, break off the escort... + if (%client.player.getArmorSize() $= "Heavy") + { + if (%task == %client.objectiveTask) + { + AIUnassignClient(%client); + Game.AIChooseGameObjective(%client); + } + return; + } + + //throw away any packs that won't fit + if (%client.player.getInventory(InventoryDeployable) > 0) + %client.player.throwPack(); + else if (%client.player.getInventory(TurretIndoorDeployable) > 0) + %client.player.throwPack(); + else if (%client.player.getInventory(TurretOutdoorDeployable) > 0) + %client.player.throwPack(); + } + + if (%client.player.isMounted()) + { + //make sure it's the same vehicle :) + if (%client.vehicleMounted != %vehicle) + AIDisembarkVehicle(%client); + } + else + { + //mount the vehicle + %client.stepMove(%slotPosition, 0.25, $AIModeMountVehicle); + } + } + else + { + //disembark if we're mounted, but our target isn't (anymore) + if (%client.player.isMounted()) + AIDisembarkVehicle(%client); + } + + //see if we're supposed to be mortaring/missiling something... + %hasMortar = (%client.player.getInventory("Mortar") > 0) && (%client.player.getInventory("MortarAmmo") > 0); + %hasMissile = (%client.player.getInventory("MissileLauncher") > 0) && (%client.player.getInventory("MissileLauncherAmmo") > 0); + if (!isObject(%task.engageTarget) && isobject(%task.missileTarget) && %task.missileTarget.getDamageState() !$= "Destroyed" && (%hasMortar || %hasMissile)) + { + if (%task.rangedTarget) + { + %client.stop(); + %client.clearStep(); + %client.setEngageTarget(-1); + if (%hasMortar) + %client.setTargetObject(%task.missileTarget, 250, "Mortar"); + else + %client.setTargetObject(%task.missileTarget, 500, "MissileNoLock"); + } + else if (%client.getStepName() !$= "AIStepRangeObject") + { + if (%hasMortar) + %client.stepRangeObject(%task.missileTarget, "MortarShot", 100, 200); + else + %client.stepRangeObject(%task.missileTarget, "BasicTargeter", 50, 500); + } + else if (%client.getStepStatus() $= "Finished") + %task.rangedTarget = true; + } + else + { + %task.rangedTarget = false; + %client.setTargetObject(-1); + if (%client.getStepName() !$= "AIStepEscort") + %client.stepEscort(%task.targetClient); + } + + //make sure we're still shooting... + %client.setEngageTarget(%task.engageTarget); + + //see if we're supposed to be engaging anyone... + if (!AIClientIsAlive(%client.getEngageTarget()) && AIClientIsAlive(%client.shouldEngage)) + %client.setEngageTarget(%client.shouldEngage); +} + +//------------------------------ + +function AIAttackObject::initFromObjective(%task, %objective, %client) +{ + %task.baseWeight = %client.objectiveWeight; + %task.targetObject = %objective.targetObjectId; + %task.equipment = %objective.equipment; + %task.buyEquipmentSet = %objective.buyEquipmentSet; + %task.desiredEquipment = %objective.desiredEquipment; + %task.issuedByClient = %objective.issuedByClientId; + + //initialize other task vars + %task.sendMsg = true; + %task.sendMsgTime = 0; +} + +function AIAttackObject::assume(%task, %client) +{ + %task.setWeightFreq(15); + %task.setMonitorFreq(5); + %client.needEquipment = AINeedEquipment(%task.equipment, %client); + + //even if we don't *need* equipemnt, see if we should buy some... + if (! %client.needEquipment && %task.buyEquipmentSet !$= "") + { + //see if we could benefit from inventory + %needArmor = AIMustUseRegularInvStation(%task.desiredEquipment, %client); + %result = AIFindClosestInventory(%client, %needArmor); + %closestInv = getWord(%result, 0); + %closestDist = getWord(%result, 1); + if (AINeedEquipment(%task.desiredEquipment, %client) && %closestInv > 0) + { + //find where we are + %clientPos = %client.player.getWorldBoxCenter(); + %objPos = %task.targetObject.getWorldBoxCenter(); + %distToObject = %client.getPathDistance(%objPos); + + if (%distToObject < 0 || %closestDist < %distToObject) + %client.needEquipment = true; + } + } + + //mark the current time for the buy inventory state machine + %task.buyInvTime = getSimTime(); +} + +function AIAttackObject::retire(%task, %client) +{ + %client.setTargetObject(-1); +} + +function AIAttackObject::weight(%task, %client) +{ + //update the task weight + if (%task == %client.objectiveTask) + %task.baseWeight = %client.objectiveWeight; + + //let the monitor decide when to stop attacking + %task.setWeight(%task.baseWeight); +} + +function AIAttackObject::monitor(%task, %client) +{ + //first, buy the equipment + if (%client.needEquipment) + { + %task.setMonitorFreq(5); + if (%task.equipment !$= "") + %equipmentList = %task.equipment; + else + %equipmentList = %task.desiredEquipment; + %result = AIBuyInventory(%client, %equipmentList, %task.buyEquipmentSet, %task.buyInvTime); + if (%result $= "InProgress") + return; + else if (%result $= "Finished") + { + %task.setMonitorFreq(15); + %client.needEquipment = false; + } + else if (%result $= "Failed") + { + //if this task is the objective task, choose a new objective + if (%task == %client.objectiveTask) + { + AIUnassignClient(%client); + Game.AIChooseGameObjective(%client); + } + return; + } + } + //if we made it past the inventory buying, reset the inv time + %task.buyInvTime = getSimTime(); + + //chat + if (%task.sendMsg) + { + if (%task.sendMsgTime == 0) + %task.sendMsgTime = getSimTime(); + else if (getSimTime() - %task.sendMsgTime > 7000) + { + %task.sendMsg = false; + if (%client.isAIControlled()) + { + if (%task.chat !$= "") + { + %chatMsg = getWord(%task.chat, 0); + %chatTemplate = getWord(%task.chat, 1); + if (%chatTemplate !$= "") + AIMessageThreadTemplate(%chatTemplate, %chatMsg, %client, -1); + else + AIMessageThread(%task.chat, %client, -1); + } + else if (%task.targetObject > 0) + { + %type = %task.targetObject.getDataBlock().getName(); + if (%type $= "GeneratorLarge") + AIMessageThreadTemplate("AttackBase", "ChatSelfAttackGenerator", %client, -1); + else if (%type $= "SensorLargePulse") + AIMessageThreadTemplate("AttackBase", "ChatSelfAttackSensors", %client, -1); + else if (%type $= "SensorMediumPulse") + AIMessageThreadTemplate("AttackBase", "ChatSelfAttackSensors", %client, -1); + else if (%type $= "TurretBaseLarge") + AIMessageThreadTemplate("AttackBase", "ChatSelfAttackTurrets", %client, -1); + else if (%type $= "StationVehicle") + AIMessageThreadTemplate("AttackBase", "ChatSelfAttackVehicle", %client, -1); + } + } + } + } + + //set the target object + if (isObject(%task.targetObject) && %task.targetObject.getDamageState() !$= "Destroyed") + { + %client.setTargetObject(%task.targetObject, 40, "Destroy"); + + //move towards the object until we're within range + if (! %client.targetInRange()) + %client.stepMove(%task.targetObject.getWorldBoxCenter(), 8.0); + else + { + //dissolve the human control link + if (%task == %client.objectiveTask) + aiReleaseHumanControl(%client.controlByHuman, %client); + + %client.stop(); + } + } + else + { + %client.setTargetObject(-1); + %client.stop(); + + //if this task is the objective task, choose a new objective + if (%task == %client.objectiveTask) + { + AIUnassignClient(%client); + Game.AIChooseGameObjective(%client); + } + } +} + +//------------------------------ + +function AIRepairObject::initFromObjective(%task, %objective, %client) +{ + %task.baseWeight = %client.objectiveWeight; + %task.targetObject = %objective.targetObjectId; + //need to force this objective to only require a repair pack + //%task.equipment = %objective.equipment; + %task.equipment = "RepairPack"; + %task.buyEquipmentSet = %objective.buyEquipmentSet; + %task.desiredEquipment = %objective.desiredEquipment; + %task.issuedByClient = %objective.issuedByClientId; + + %task.deployed = %objective.deployed; + if (%task.deployed) + { + %task.location = %objective.position; + %task.deployDirection = MatrixMulVector("0 0 0 " @ getWords(%objective.getTransform(), 3, 6), "0 1 0"); + %task.deployDirection = VectorNormalize(%task.deployDirection); + } +} + +function AIRepairObject::assume(%task, %client) +{ + %task.setWeightFreq(15); + %task.setMonitorFreq(15); + %client.needEquipment = AINeedEquipment(%task.equipment, %client); + + //clear the target object, and range it + %client.setTargetObject(-1); + if (! %client.needEquipment) + { + if (%task.deployed) + { + %task.repairLocation = VectorAdd(%task.location,VectorScale(%task.deployDirection, -4.0)); + %client.stepMove(%task.repairLocation, 0.25); + } + else + %client.stepRangeObject(%task.targetObject, "DefaultRepairBeam", 3, 8); + } + + //mark the current time for the buy inventory state machine + %task.buyInvTime = getSimTime(); + %task.needToRangeTime = 0; + %task.pickupRepairPack = -1; + %task.usingInv = false; + + //set a tag to help the repairPack.cs script fudge acquiring a target + %client.repairObject = %task.targetObject; +} + +function AIRepairObject::retire(%task, %client) +{ + %client.setTargetObject(-1); + %client.repairObject = -1; +} + +function AIRepairObject::weight(%task, %client) +{ + //update the task weight + if (%task == %client.objectiveTask) + %task.baseWeight = %client.objectiveWeight; + + //let the monitor decide when to stop repairing + %task.setWeight(%task.baseWeight); +} + +function AIRepairObject::monitor(%task, %client) +{ + //first, buy the equipment + if (%client.needEquipment) + { + %task.setMonitorFreq(5); + + //first, see if we still need a repair pack + if (%client.player.getInventory(RepairPack) > 0) + { + %client.needEquipment = false; + %task.setMonitorFreq(15); + + //if this is to repair a deployed object, walk to the deploy point... + if (%task.deployed) + { + %task.repairLocation = VectorAdd(%task.location,VectorScale(%task.deployDirection, -4.0)); + %client.stepMove(%task.repairLocation, 0.25); + } + //otherwise, we'll need to range it... + else + %client.stepRangeObject(%task.targetObject, "DefaultRepairBeam", 3, 8); + } + else + { + // check to see if there's a repair pack nearby + %closestRepairPack = -1; + %closestRepairDist = 32767; + + //search the AIItemSet for a repair pack (someone might have dropped one...) + %itemCount = $AIItemSet.getCount(); + for (%i = 0; %i < %itemCount; %i++) + { + %item = $AIItemSet.getObject(%i); + if (%item.getDataBlock().getName() $= "RepairPack" && !%item.isHidden()) + { + %dist = %client.getPathDistance(%item.getWorldBoxCenter()); + if (%dist > 0 && %dist < %closestRepairDist) + { + %closestRepairPack = %item; + %closestRepairDist = %dist; + } + } + } + + //choose whether we're picking up the closest pack, or buying from an inv station... + if ((isObject(%closestRepairPack) && %closestRepairPack != %task.pickupRepairPack) || (%task.buyInvTime != %client.buyInvTime)) + { + %task.pickupRepairPack = %closestRepairPack; + + //initialize the inv buying + %task.buyInvTime = getSimTime(); + AIBuyInventory(%client, "RepairPack", %task.buyEquipmentSet, %task.buyInvTime); + + //now decide which is closer + if (isObject(%closestRepairPack)) + { + if (isObject(%client.invToUse)) + { + %dist = %client.getPathDistance(%item.position); + if (%dist > %closestRepairDist) + %task.usingInv = true; + else + %task.usingInv = false; + } + else + %task.usingInv = false; + } + else + %task.usingInv = true; + } + + //now see if we found a closer repair pack + if (!%task.usingInv) + { + %client.stepMove(%task.pickupRepairPack.position, 0.25); + %distToPack = %client.getPathDistance(%task.pickupRepairPack.position); + if (%distToPack < 10 && %client.player.getMountedImage($BackpackSlot) > 0) + %client.player.throwPack(); + + //and we're finished until we actually have a repair pack... + return; + } + else + { + %result = AIBuyInventory(%client, "RepairPack", %task.buyEquipmentSet, %task.buyInvTime); + if (%result $= "InProgress") + return; + else if (%result $= "Finished") + { + %client.needEquipment = false; + %task.setMonitorFreq(15); + + //if this is to repair a deployed object, walk to the deploy point... + if (%task.deployed) + { + %task.repairLocation = VectorAdd(%task.location,VectorScale(%task.deployDirection, -4.0)); + %client.stepMove(%task.repairLocation, 0.25); + } + //otherwise, we'll need to range it... + else + %client.stepRangeObject(%task.targetObject, "DefaultRepairBeam", 3, 8); + } + else if (%result $= "Failed") + { + //if this task is the objective task, choose a new objective + if (%task == %client.objectiveTask) + { + AIUnassignClient(%client); + Game.AIChooseGameObjective(%client); + } + return; + } + } + } + } + //if we made it past the inventory buying, reset the inv time + %task.buyInvTime = getSimTime(); + + //chat + if (%task.sendMsg) + { + if (%task.sendMsgTime == 0) + %task.sendMsgTime = getSimTime(); + else if (getSimTime() - %task.sendMsgTime > 7000) + { + %task.sendMsg = false; + if (%client.isAIControlled()) + { + if (%task.chat !$= "") + { + %chatMsg = getWord(%task.chat, 0); + %chatTemplate = getWord(%task.chat, 1); + if (%chatTemplate !$= "") + AIMessageThreadTemplate(%chatTemplate, %chatMsg, %client, -1); + else + AIMessageThread(%task.chat, %client, -1); + } + else if (%task.targetObject > 0) + { + %type = %task.targetObject.getDataBlock().getName(); + if (%type $= "GeneratorLarge") + AIMessageThreadTemplate("RepairBase", "ChatSelfRepairGenerator", %client, -1); + else if (%type $= "StationVehicle") + AIMessageThreadTemplate("RepairBase", "ChatSelfRepairVehicle", %client, -1); + else if (%type $= "SensorLargePulse") + AIMessageThreadTemplate("RepairBase", "ChatSelfRepairSensors", %client, -1); + else if (%type $= "SensorMediumPulse") + AIMessageThreadTemplate("RepairBase", "ChatSelfRepairSensors", %client, -1); + else if (%type $= "TurretBaseLarge") + AIMessageThreadTemplate("RepairBase", "ChatSelfRepairTurrets", %client, -1); + } + } + } + } + + //set the target object + if (%task.targetObject.getDamagePercent() > 0) + { + //make sure we still have equipment + %client.needEquipment = AINeedEquipment(%task.equipment, %client); + if (%client.needEquipment) + { + //if this task is the objective task, choose a new objective + if (%task == %client.objectiveTask) + { + AIUnassignClient(%client); + Game.AIChooseGameObjective(%client); + return; + } + } + + if (%task.deployed) + { + //see if we're within range of the deploy location + %clLoc = %client.player.position; + %distance = VectorDist(%clLoc, %task.repairLocation); + %dist2D = VectorDist(%client.player.position, getWords(%task.repairLocation, 0, 1) SPC getWord(%client.player.position, 2)); + + //set the aim when we get near the target... this will be overwritten when we're actually trying to deploy + if (%distance < 10 && %dist2D < 10) + %client.aimAt(%task.location, 1000); + + //see if we're at the deploy location + if ((%client.pathDistRemaining(20) > %distance + 0.25) || %dist2D > 0.3) + { + %client.setTargetObject(-1); + %client.stepMove(%task.repairLocation, 0.25); + } + else + { + %client.stop(); + %client.setTargetObject(%task.targetObject, 8.0, "Repair"); + } + } + else + { + %currentTime = getSimTime(); + if (%currentTime > %task.needToRangeTime) + { + //force a rangeObject every 10 seconds... + %task.needToRangeTime = %currentTime + 6000; + %client.setTargetObject(-1); + %client.stepRangeObject(%task.targetObject, "DefaultRepairBeam", 3, 8); + } + + //if we've ranged the object, start repairing, else unset the object + else if (%client.getStepStatus() $= "Finished") + { + //dissolve the human control link + if (%task == %client.objectiveTask) + aiReleaseHumanControl(%client.controlByHuman, %client); + + %client.setTargetObject(%task.targetObject, 8.0, "Repair"); + } + else + %client.setTargetObject(-1); + } + } + else + { + %client.setTargetObject(-1); + + //if this task is the objective task, choose a new objective + if (%task == %client.objectiveTask) + { + AIUnassignClient(%client); + Game.AIChooseGameObjective(%client); + } + } +} + +//------------------------------ + +function AILazeObject::initFromObjective(%task, %objective, %client) +{ + %task.baseWeight = %client.objectiveWeight; + %task.targetObject = %objective.targetObjectId; + %task.equipment = %objective.equipment; + %task.buyEquipmentSet = %objective.buyEquipmentSet; + %task.desiredEquipment = %objective.desiredEquipment; + %task.issuedByClient = %objective.issuedByClientId; + %task.msgAck = true; + %task.msgFire = true; +} + +function AILazeObject::assume(%task, %client) +{ + %task.setWeightFreq(30); + %task.setMonitorFreq(30); + %client.needEquipment = AINeedEquipment(%task.equipment, %client); + + //clear the target object, and range it + %client.setTargetObject(-1); + if (! %client.needEquipment) + %client.stepRangeObject(%task.targetObject, "BasicTargeter", 80, 300, %task.issuedByClient.player.getWorldBoxCenter()); + + //set up some task vars + %task.celebrate = false; + %task.waitTimerMS = 0; + + //mark the current time for the buy inventory state machine + %task.buyInvTime = getSimTime(); +} + +function AILazeObject::retire(%task, %client) +{ + %client.setTargetObject(-1); +} + +function AILazeObject::weight(%task, %client) +{ + //update the task weight + if (%task == %client.objectiveTask) + %task.baseWeight = %client.objectiveWeight; + + //let the monitor decide when to stop lazing + %task.setWeight(%task.baseWeight); +} + +function AILazeObject::monitor(%task, %client) +{ + //first, buy the equipment + if (%client.needEquipment) + { + %task.setMonitorFreq(5); + if (%task.equipment !$= "") + %equipmentList = %task.equipment; + else + %equipmentList = %task.desiredEquipment; + %result = AIBuyInventory(%client, %equipmentList, %task.buyEquipmentSet, %task.buyInvTime); + if (%result $= "InProgress") + return; + else if (%result $= "Finished") + { + %task.setMonitorFreq(30); + %client.needEquipment = false; + %client.stepRangeObject(%task.targetObject, "BasicTargeter", 80, 300); + } + else if (%result $= "Failed") + { + //if this task is the objective task, choose a new objective + if (%task == %client.objectiveTask) + { + AIUnassignClient(%client); + Game.AIChooseGameObjective(%client); + } + return; + } + } + //if we made it past the inventory buying, reset the inv time + %task.buyInvTime = getSimTime(); + + //set the target object + if (isObject(%task.targetObject) && %task.targetObject.getDamageState() !$= "Destroyed") + { + //make sure we still have equipment + %client.needEquipment = AINeedEquipment(%task.equipment, %client); + if (%client.needEquipment) + { + //if this task is the objective task, choose a new objective + if (%task == %client.objectiveTask) + { + AIUnassignClient(%client); + Game.AIChooseGameObjective(%client); + return; + } + } + + //look to see if anyone else is also targetting... + %foundTarget = false; + %numTargets = ServerTargetSet.getCount(); + for (%i = 0; %i < %numTargets; %i++) + { + %targ = ServerTargetSet.getObject(%i); + if (%targ.sourceObject != %client.player) + { + %targDist = VectorDist(%targ.getTargetPoint(), %task.targetObject.getWorldBoxCenter()); + if (%targDist < 10) + { + %foundTarget = true; + break; + } + } + } + + if (%foundTarget) + { + //if this task is the objective task, choose a new objective + if (%task == %client.objectiveTask) + AIUnassignClient(%client); + } + + else if (%client.getStepStatus() $= "Finished") + { + //dissolve the human control link + if (%task == %client.objectiveTask) + aiReleaseHumanControl(%client.controlByHuman, %client); + + %client.setTargetObject(%task.targetObject, 300, "Laze"); + %task.celebrate = true; + %task.waitTimerMS = 0; + + //make sure we only say "fire..." once + if (%task.msgFire) + { + AIMessageThread("FireOnTarget", %client, -1); + %task.msgFire = false; + } + } + else + { + %client.aimAt(%task.targetObject.getWorldBoxCenter(), 1000); + %client.setTargetObject(-1); + } + } + else + { + %client.setTargetObject(-1); + + if (%task.celebrate) + { + if (%task.waitTimerMS == 0) + { + //add in a "woohoo"! :) + //choose the animation range + %minCel = 3; + %maxCel = 8; + + //pick a random sound + if (getRandom() > 0.25) + %sound = "gbl.awesome"; + else if (getRandom() > 0.5) + %sound = "gbl.thanks"; + else if (getRandom() > 0.75) + %sound = "gbl.nice"; + else + %sound = "gbl.rock"; + %randTime = mFloor(getRandom() * 500) + 1; + schedule(%randTime, %client, "AIPlayAnimSound", %client, %task.targetObject.getWorldBoxCenter(), %sound, %minCel, %maxCel, 0); + + //set the timer + %task.waitTimerMS = getSimTime(); + } + + //else see if the celebration period is over + else if (getSimTime() - %task.waitTimerMS > 3000) + %task.celebrate = false; + } + else + { + //if this task is the objective task, choose a new objective + if (%task == %client.objectiveTask) + { + AIUnassignClient(%client); + Game.AIChooseGameObjective(%client); + } + } + } +} + +//------------------------------ + +function AIMortarObject::initFromObjective(%task, %objective, %client) +{ + %task.baseWeight = %client.objectiveWeight; + %task.targetObject = %objective.targetObjectId; + %task.equipment = %objective.equipment; + %task.buyEquipmentSet = %objective.buyEquipmentSet; + %task.desiredEquipment = %objective.desiredEquipment; + %task.issuedByClient = %objective.issuedByClientId; + %task.mode = %task.targetObject.getDataBlock().getName(); + + %task.sendMsgTime = 0; + %task.sendMsg = true; +} + +function AIMortarObject::assume(%task, %client) +{ + %task.setWeightFreq(30); + %task.setMonitorFreq(30); + %task.state = moveToRange; + %task.waitForTargetter = true; + %task.celebrate = false; + %task.waitTimerMS = 0; + %task.targetAcquired = false; + %task.sayAcquired = true; + %client.needEquipment = AINeedEquipment(%task.equipment, %client); + + //even if we don't *need* equipemnt, see if we should buy some... + if (! %client.needEquipment && %task.buyEquipmentSet !$= "") + { + //see if we could benefit from inventory + %needArmor = AIMustUseRegularInvStation(%task.desiredEquipment, %client); + %result = AIFindClosestInventory(%client, %needArmor); + %closestInv = getWord(%result, 0); + %closestDist = getWord(%result, 1); + if (AINeedEquipment(%task.desiredEquipment, %client) && %closestInv > 0) + { + //find where we are + %clientPos = %client.player.getWorldBoxCenter(); + %objPos = %task.targetObject.getWorldBoxCenter(); + %distToObject = %client.getPathDistance(%objPos); + + if (%distToObject < 0 || %closestDist < %distToObject) + %client.needEquipment = true; + } + } + + //mark the current time for the buy inventory state machine + %task.buyInvTime = getSimTime(); +} + +function AIMortarObject::retire(%task, %client) +{ + %client.setTargetObject(-1); + + //remove the associated lazeObjective + if (%task.targetterObjective) + { + AIClearObjective(%task.targetterObjective); + %task.targetterObjective.delete(); + %task.targetterObjective = ""; + } +} + +function AIMortarObject::weight(%task, %client) +{ + //update the task weight + if (%task == %client.objectiveTask) + %task.baseWeight = %client.objectiveWeight; + + //let the monitor decide when to stop mortaring + %task.setWeight(%task.baseWeight); +} + +function AIMortarObject::monitor(%task, %client) +{ + //first, buy the equipment + if (%client.needEquipment) + { + %task.setMonitorFreq(5); + if (%task.equipment !$= "") + %equipmentList = %task.equipment; + else + %equipmentList = %task.desiredEquipment; + %result = AIBuyInventory(%client, %equipmentList, %task.buyEquipmentSet, %task.buyInvTime); + if (%result $= "InProgress") + return; + else if (%result $= "Finished") + { + %task.setMonitorFreq(30); + %client.needEquipment = false; + } + else if (%result $= "Failed") + { + //if this task is the objective task, choose a new objective + if (%task == %client.objectiveTask) + { + AIUnassignClient(%client); + Game.AIChooseGameObjective(%client); + } + return; + } + } + //if we made it past the inventory buying, reset the inv time + %task.buyInvTime = getSimTime(); + + //chat + if (%task.sendMsg) + { + if (%task.sendMsgTime == 0) + %task.sendMsgTime = getSimTime(); + else if (getSimTime() - %task.sendMsgTime > 7000) + { + %task.sendMsg = false; + if (%client.isAIControlled()) + { + if (%task.chat !$= "") + { + %chatMsg = getWord(%task.chat, 0); + %chatTemplate = getWord(%task.chat, 1); + if (%chatTemplate !$= "") + AIMessageThreadTemplate(%chatTemplate, %chatMsg, %client, -1); + else + AIMessageThread(%task.chat, %client, -1); + } + else if (%task.targetObject > 0) + { + %type = %task.targetObject.getDataBlock().getName(); + if (%type $= "GeneratorLarge") + AIMessageThreadTemplate("AttackBase", "ChatSelfAttackGenerator", %client, -1); + else if (%type $= "SensorLargePulse") + AIMessageThreadTemplate("AttackBase", "ChatSelfAttackSensors", %client, -1); + else if (%type $= "SensorMediumPulse") + AIMessageThreadTemplate("AttackBase", "ChatSelfAttackSensors", %client, -1); + else if (%type $= "TurretBaseLarge") + AIMessageThreadTemplate("AttackBase", "ChatSelfAttackTurrets", %client, -1); + else if (%type $= "StationVehicle") + AIMessageThreadTemplate("AttackBase", "ChatSelfAttackVehicle", %client, -1); + } + } + } + } + + //make sure we still have something to destroy + if (isObject(%task.targetObject) && %task.targetObject.getDamageState() !$= "Destroyed") + { + %clientPos = %client.player.getWorldBoxCenter(); + %targetPos = %task.targetObject.getWorldBoxCenter(); + %distance = %client.getPathDistance(%targetPos); + if (%distance < 0) + %distance = 32767; + + //make sure we still have equipment + %client.needEquipment = AINeedEquipment(%task.equipment, %client); + if (%client.needEquipment) + { + //if this task is the objective task, choose a new objective + if (%task == %client.objectiveTask) + { + AIUnassignClient(%client); + Game.AIChooseGameObjective(%client); + return; + } + } + + //next move to within 220 + else if (%distance > 220) + { + %client.setTargetObject(-1); + %client.stepMove(%task.targetObject.getWorldBoxCenter(), 15); + } + + //now start ask for someone to laze the target, and start a 20 sec timer + else if (%task.waitForTargetter) + { + //see if we've started the timer + if (%task.waitTimerMS == 0) + { + //range the object + %client.stepRangeObject(%task.targetObject, "MortarShot", 100, 200); + + //now ask for a targeter... + %targetType = %task.targetObject.getDataBlock().getName(); + if (%targetType $= "TurretBaseLarge") + AIMessageThread("ChatCmdTargetTurret", %client, -1); + else if (%targetType $= "SensorLargePulse") + AIMessageThread("ChatCmdTargetSensors", %client, -1); + else if (%targetType $= "SensorMediumPulse") + AIMessageThread("ChatCmdTargetSensors", %client, -1); + else + AIMessageThread("ChatNeedTarget", %client, -1); + + %task.waitTimerMS = getSimTime(); + + //create the objective + if (! %task.targetterObjective) + { + %task.targetterObjective = new AIObjective(AIOLazeObject) + { + dataBlock = "AIObjectiveMarker"; + weightLevel1 = $AIWeightLazeObject[1]; + weightLevel2 = $AIWeightLazeObject[2]; + description = "Laze the " @ %task.targetObject.getName(); + targetObjectId = %task.targetObject; + issuedByClientId = %client; + offense = true; + equipment = "TargetingLaser"; + }; + MissionCleanup.add(%task.targetterObjective); + $ObjectiveQ[%client.team].add(%task.targetterObjective); + } + %task.targetterObjective.lastLazedTime = 0; + + //remove the escort (want a targetter instead) + if (%client.escort) + { + AIClearObjective(%client.escort); + %client.escort.delete(); + %client.escort = ""; + } + } + else + { + %elapsedTime = getSimTime() - %task.waitTimerMS; + if (%task.targetterObjective.group > 0) + %targetter = %task.targetterObjective.group.clientLevel[1]; + else + %targetter = %task.targetterObjective.clientLevel[1]; + + //see if we can find a target near our objective + %task.targetAcquired = false; + %numTargets = ServerTargetSet.getCount(); + for (%i = 0; %i < %numTargets; %i++) + { + %targ = ServerTargetSet.getObject(%i); + %targDist = VectorDist(%targ.getTargetPoint(), %task.targetObject.getWorldBoxCenter()); + if (%targDist < 20) + { + %task.targetAcquired = true; + break; + } + } + + if (%task.targetAcquired) + { + %task.waitForTargetter = false; + %task.waitTimerMS = 0; + %task.celebrate = true; + %task.sayAcquired = false; + AIMessageThread("ChatTargetAcquired", %client, -1); + } + + //else see if we've run out of time + else if ((! %targetter || ! %targetter.isAIControlled()) && %elapsedTime > 20000) + { + %task.waitForTargetter = false; + %task.waitTimerMS = 0; + %task.celebrate = true; + } + } + } + + //now we should finally be attacking with or without a targetter + //eventually, the target will be destroyed, or we'll run out of ammo... + else + { + //dissolve the human control link + if (%task == %client.objectiveTask) + aiReleaseHumanControl(%client.controlByHuman, %client); + + //see if we didn't acquired a spotter along the way + if (%task.targetterObjective.group > 0) + %targetter = %task.targetterObjective.group.clientLevel[1]; + else + %targetter = %task.targetterObjective.clientLevel[1]; + if (! %task.targetAcquired && AIClientIsAlive(%targetter) && %targetter.isAIControlled()) + { + %client.setTargetObject(-1); + %task.waitForTargetter = true; + } + else + { + //see if we can find a target near our objective + if (! %task.targetAcquired) + { + %numTargets = ServerTargetSet.getCount(); + for (%i = 0; %i < %numTargets; %i++) + { + %targ = ServerTargetSet.getObject(%i); + %targDist = VectorDist(%targ.getTargetPoint(), %task.targetObject.getWorldBoxCenter()); + if (%targDist < 20) + { + %task.targetAcquired = true; + break; + } + } + //see if we found a target (must be by a human) + if (%task.targetAcquired && %task.sayAcquired) + { + %task.sayAcquired = false; + AIMessageThread("ChatTargetAcquired", %client, -1); + } + } + + //set the target object, and keep attacking it + if (%client.getStepStatus() $= "Finished") + %client.setTargetObject(%task.targetObject, 250, "Mortar"); + else + %client.setTargetObject(-1); + } + } + } + + //the target must have been destroyed :) + else + { + //dissolve the human control link + if (%task == %client.objectiveTask) + aiReleaseHumanControl(%client.controlByHuman, %client); + + %client.setTargetObject(-1); + %client.clearStep(); + %client.stop(); + + if (%task.celebrate) + { + if (%task.waitTimerMS == 0) + { + //client animation "woohoo"! :) + //choose the animation range + %minCel = 3; + %maxCel = 8; + + //pick a random sound + if (getRandom() > 0.25) + %sound = "gbl.awesome"; + else if (getRandom() > 0.5) + %sound = "gbl.thanks"; + else if (getRandom() > 0.75) + %sound = "gbl.nice"; + else + %sound = "gbl.rock"; + %randTime = mFloor(getRandom() * 500) + 1; + schedule(%randTime, %client, "AIPlayAnimSound", %client, %task.targetObject.getWorldBoxCenter(), %sound, %minCel, %maxCel, 0); + + //team message + AIMessageThread("ChatEnemyTurretsDestroyed", %client, -1); + + //set the timer + %task.waitTimerMS = getSimTime(); + } + + //else see if the celebration period is over + else if (getSimTime() - %task.waitTimerMS > 3000) + %task.celebrate = false; + } + else + { + //if this task is the objective task, choose a new objective + if (%task == %client.objectiveTask) + { + AIUnassignClient(%client); + Game.AIChooseGameObjective(%client); + } + } + } +} + +//------------------------------ + +function AIDeployEquipment::initFromObjective(%task, %objective, %client) +{ + //initialize the task vars from the objective + %task.baseWeight = %client.objectiveWeight; + %task.location = %objective.location; + %task.equipment = %objective.equipment; + %task.buyEquipmentSet = %objective.buyEquipmentSet; + %task.desiredEquipment = %objective.desiredEquipment; + %task.issuedByClient = %objective.issuedByClientId; + %task.chat = %objective.chat; + + //initialize other task vars + %task.sendMsg = true; + %task.sendMsgTime = 0; + + //use the Y-axis of the rotation as the desired direction of deployement, + //and calculate a walk to point 3 m behind the deploy point. + %task.deployDirection = MatrixMulVector("0 0 0 " @ getWords(%objective.getTransform(), 3, 6), "0 1 0"); + %task.deployDirection = VectorNormalize(%task.deployDirection); +} + +function AIDeployEquipment::assume(%task, %client) +{ + %task.setWeightFreq(15); + %task.setMonitorFreq(15); + + %client.needEquipment = AINeedEquipment(%task.equipment, %client); + + //mark the current time for the buy inventory state machine + %task.buyInvTime = getSimTime(); + + %task.passes = 0; + %task.deployAttempts = 0; + %task.checkObstructed = false; + %task.waitMove = 0; +} + +function AIDeployEquipment::retire(%task, %client) +{ +} + +function AIDeployEquipment::weight(%task, %client) +{ + //update the task weight + if (%task == %client.objectiveTask) + %task.baseWeight = %client.objectiveWeight; + + %task.setWeight(%task.baseWeight); +} + +function findTurretDeployPoint(%client, %location, %attempt) +{ + %player = %client.player; + if (!isObject(%player)) + return "0 0 0"; + + %feetPos = posFromTransform(%player.getTransform()); + %temp = VectorSub(%location, %feetPos); + %temp2 = getWord(%temp, 0) @ " " @ getWord(%temp, 1) @ " 0"; + %facingVector = VectorNormalize(%temp2); + %aimPoint = VectorAdd(%feetPos, %facingVector); + //assume that there will be 10 attempts + %height = getWord(%location, 2) + 1.0 - (0.2 * %attempt); + %aimAt = getWord(%aimPoint, 0) @ " " @ getWord(%aimPoint, 1) @ " " @ %height; + return %aimAt; +} + +function AIDeployEquipment::monitor(%task, %client) +{ + //first, buy the equipment + if (%client.needEquipment) + { + %task.setMonitorFreq(5); + if (%task.equipment !$= "") + %equipmentList = %task.equipment; + else + %equipmentList = %task.desiredEquipment; + %result = AIBuyInventory(%client, %equipmentList, %task.buyEquipmentSet, %task.buyInvTime); + if (%result $= "InProgress") + return; + else if (%result $= "Finished") + { + %task.setMonitorFreq(30); + %client.needEquipment = false; + //if we made it past the inventory buying, reset the inv time + %task.buyInvTime = getSimTime(); + } + else if (%result $= "Failed") + { + //if this task is the objective task, choose a new objective + if (%task == %client.objectiveTask) + { + AIUnassignClient(%client); + Game.AIChooseGameObjective(%client); + } + return; + } + } + + //chat + if (%task.sendMsg) + { + if (%task.sendMsgTime == 0) + %task.sendMsgTime = getSimTime(); + else if (getSimTime() - %task.sendMsgTime > 7000) + { + %task.sendMsg = false; + if (%client.isAIControlled()) + { + if (%task.chat !$= "") + { + %chatMsg = getWord(%task.chat, 0); + %chatTemplate = getWord(%task.chat, 1); + if (%chatTemplate !$= "") + AIMessageThreadTemplate(%chatTemplate, %chatMsg, %client, -1); + else + AIMessageThread(%task.chat, %client, -1); + } + } + } + } + + //see if we're supposed to be engaging anyone... + if (AIClientIsAlive(%client.shouldEngage)) + { + %hasLOS = %client.hasLOSToClient(%client.shouldEngage); + %losTime = %client.getClientLOSTime(%client.shouldEngage); + if (%hasLOS || %losTime < 1000) + %client.setEngageTarget(%client.shouldEngage); + else + %client.setEngageTarget(-1); + } + else + %client.setEngageTarget(-1); + + //calculate the deployFromLocation + %factor = -1 * (3 - (%task.passes * 0.5)); + %task.deployFromLocation = VectorAdd(%task.location,VectorScale(%task.deployDirection, %factor)); + + //see if we're within range of the deploy location + %clLoc = %client.player.position; + %distance = VectorDist(%clLoc, %task.deployFromLocation); + %dist2D = VectorDist(%client.player.position, getWords(%task.deployFromLocation, 0, 1) SPC getWord(%client.player.position, 2)); + + //set the aim when we get near the target... this will be overwritten when we're actually trying to deploy + if (%distance < 10 && %dist2D < 10) + %client.aimAt(%task.location, 1000); + + if ((%client.pathDistRemaining(20) > %distance + 0.25) || %dist2D > 0.5) + { + %task.deployAttempts = 0; + %task.checkObstructed = false; + %task.waitMove = 0; + %client.stepMove(%task.deployFromLocation, 0.25); + %task.setMonitorFreq(15); + return; + } + + if (%task.deployAttempts < 10 && %task.passes < 5 && !AIClientIsAlive(%client.getEngageTarget())) + { + //dissolve the human control link + if (%task == %client.objectiveTask) + aiReleaseHumanControl(%client.controlByHuman, %client); + + %task.setMonitorFreq(3); + %client.stop(); + if (%task.deployAttempts == 0) + %deployPoint = %task.location; + else + %deployPoint = findTurretDeployPoint(%client, %task.location, %task.deployAttempts); + if(%deployPoint !$= "") + { + // we have possible point + %task.deployAttempts++; + %client.aimAt(%deployPoint, 2000); + + //try to deploy the backpack + %client.deployPack = true; + %client.lastDeployedObject = -1; + %client.player.use(Backpack); + + // check if pack deployed + if (isObject(%client.lastDeployedObject)) + { + //see if there's a "repairObject" objective for the newly deployed thingy... + if (%task == %client.objectiveTask) + { + %deployedObject = %client.lastDeployedObject; + + //search the current objective group and search for a "repair Object" task... + %objective = %client.objective; + + //delete any previously associated "AIORepairObject" objective + if (isObject(%objective.repairObjective)) + { + AIClearObjective(%objective.repairObjective); + %objective.repairObjective.delete(); + %objective.repairObjective = ""; + } + + //add the repair objective + %objective.repairObjective = new AIObjective(AIORepairObject) + { + dataBlock = "AIObjectiveMarker"; + weightLevel1 = %objective.weightLevel1 - 60; + weightLevel2 = 0; + description = "Repair the " @ %deployedObject.getDataBlock().getName(); + targetObjectId = %deployedObject; + issuedByClientId = %client; + offense = false; + defense = true; + equipment = "RepairPack"; + }; + %objective.repairObjective.deployed = true; + %objective.repairObjective.setTransform(%objective.getTransform()); + %objective.repairObjective.group = %objective.group; + MissionCleanup.add(%objective.repairObjective); + $ObjectiveQ[%client.team].add(%objective.repairObjective); + + //finally, unassign the client so he'll go do something else... + AIUnassignClient(%client); + Game.AIChooseGameObjective(%client); + } + + //finished + return; + } + } + } + else if (!%task.checkObstructed) + { + %task.checkObstructed = true; + + //see if anything is in our way + InitContainerRadiusSearch(%task.location, 4, $TypeMasks::MoveableObjectType | $TypeMasks::VehicleObjectType | + $TypeMasks::PlayerObjectType); + %objSrch = containerSearchNext(); + if (%objSrch == %client.player) + %objSrch = containerSearchNext(); + if (%objSrch) + AIMessageThread("ChatMove", %client, -1); + } + else if (%task.waitMove < 5 && %task.passes < 5) + { + %task.waitMove++; + + //try another pass at deploying + if (%task.waitMove == 5) + { + %task.waitMove = 0; + %task.passes++; + %task.deployAttempts = 0; + + //see if we're *right* underneath the deploy point + %deployDist2D = VectorDist(getWords(%client.player.position, 0, 1) @ "0", getWords(%task.location, 0, 1) @ "0"); + if (%deployDist2D < 0.25) + { + %client.pressjump(); + %client.deployPack = true; + %client.player.use(Backpack); + + // check if pack deployed + if(%client.player.getMountedImage($BackpackSlot) == 0) + { + //don't add a "repairObject" objective for ceiling turrets + if (%task == %client.objectiveTask) + { + AIUnassignClient(%client); + Game.AIChooseGameObjective(%client); + } + } + } + } + } + else + { + //find a new assignment - and remove this one from the Queue + if (%task == %client.objectiveTask) + { + error(%client SPC "from team" SPC %client.team SPC "is invalidating objective:" SPC %client.objective SPC "UNABLE TO DEPLOY EQUIPMENT"); + %client.objective.isInvalid = true; + AIUnassignClient(%client); + Game.AIChooseGameObjective(%client); + } + } +} + +//------------------------------ +//AI Objective functions +function ClientHasAffinity(%objective, %client) +{ + if (%objective.offense && %client.offense) + return true; + else if (%objective.defense && !%client.offense) + return true; + else + return false; +} + +function ClientHasRequiredEquipment(%objective, %client) +{ + return true; +} + +function AIODefault::weight(%objective, %client, %level, %inventoryStr) +{ + //make sure the player is still alive!!!!! + if (! AIClientIsAlive(%client)) + return 0; + + //set the base weight + switch (%level) + { + case 1: + %weight = %objective.weightLevel1; + case 2: + %weight = %objective.weightLevel2; + case 3: + %weight = %objective.weightLevel3; + default: + %weight = %objective.weightLevel4; + } + + //check Affinity + if (ClientHasAffinity(%objective, %client)) + %weight += 40; + + //if the objective doesn't require any equipment, it automatically get's the +100... + if (%objective.equipment $= "" && %objective.desiredEquipment $= "") + %weight += 100; + else + { + //check equipment requirement + %needEquipment = AINeedEquipment(%objective.equipment, %client); + + //check Required equipment + if (%objective.equipment !$= "" && !%needEquipment) + %weight += 100; + + //figure out the percentage of desired equipment the bot has + else if (%objective.desiredEquipment !$= "") + { + %count = getWordCount(%objective.desiredEquipment); + %itemCount = 0; + for (%i = 0; %i < %count; %i++) + { + %item = getWord(%objective.desiredEquipment, %i); + if (!AINeedEquipment(%item, %client)) + %itemCount++; + } + + //add to the weight + %weight += mFloor((%itemCount / %count) * 75); + } + } + + //find the distance to target + if (%objective.targetClientId !$= "" || %objective.targetObjectId !$= "") + { + if (AIClientIsAlive(%objective.targetClientId)) + { + %targetPos = %objective.targetClientId.player.getWorldBoxCenter(); + } + else if (VectorDist(%objective.location, "0 0 0") > 1) + %targetPos = %objective.location; + else + { + if(%objective.targetObjectId > 0) + %targetPos = %objective.targetObjectId.getWorldBoxCenter(); + } + } + + //make sure the destination is accessible + %distance = %client.getPathDistance(%targetPos); + if (%distance < 0) + return 0; + + %closestInvIsRemote = (getWordCount(%inventoryStr) == 4); + %closestInv = getWord(%inventoryStr, 0); + %closestDist = getWord(%inventoryStr, 1); + %closestRemoteInv = getWord(%inventoryStr, 2); + %closestRemoteDist = getWord(%inventoryStr, 3); + + //if we need equipment, the distance is from the client, to an inv, then to the target + if (%needEquipment) + { + //if we need a regular inventory station, and one doesn't exist, exit + if (!isObject(%closestInv) && %needArmor) + return 0; + + //find the closest inv based on whether we require armor (from a regular inv station) + if (!%closestInvIsRemote) + { + %needArmor = false; + %weightDist = %closestDist; + %weightInv = %closestInv; + } + else + { + %needArmor = AIMustUseRegularInvStation(%objective.equipment, %client); + if (%needArmor) + { + %weightDist = %closestDist; + %weightInv = %closestInv; + } + else + { + %weightDist = %closestRemoteDist; + %weightInv = %closestRemoteInv; + } + } + + //if we don't need armor, and there's no inventory station, see if the equipment we need + //is something we can pick up off the ground (likely this would be a repair pack...) + if (%weightDist >= 32767) + { + %itemType = getWord(%objective.equipment, 0); + %found = false; + %itemCount = $AIItemSet.getCount(); + for (%i = 0; %i < %itemCount; %i++) + { + %item = $AIItemSet.getObject(%i); + if (%item.getDataBlock().getName() $= %itemType && !%item.isHidden()) + { + %weightDist = %client.getPathDistance(%item.getWorldBoxCenter()); + if (%weightDist > 0) + { + %weightInv = %item; //set the var so the distance function will work... + %found = true; + break; + } + } + } + if (! %found) + return 0; + } + + //now find the distance used for weighting the objective + %tempDist = AIGetPathDistance(%targetPos, %weightInv.getWorldBoxCenter()); + if (%tempDist < 0) + %tempDist = 32767; + %distance = %weightDist + %tempDist; + } + + //see if we're within 200 m + if (%distance < 200) + %weight += 30; + + //see if we're within 90 m + if (%distance < 90) + %weight += 30; + + //see if we're within 45 m + if (%distance < 45) + %weight += 30; + + //see if we're within 20 m + if (%distance < 20) + %weight += 30; + + //final return, since we've made it through all the rest + return %weight; +} + +function AIODefault::QuickWeight(%objective, %client, %level, %minWeight) +{ + //can't do a quick weight when re-evaluating a client's current objective + if (%client.objective == %objective) + return true; + + //do a quick check to disqualify this objective if it can't meet the minimum weight + switch (%level) + { + case 1: + %testWeight = %objective.weightLevel1; + case 2: + %testWeight = %objective.weightLevel2; + case 3: + %testWeight = %objective.weightLevel3; + default: + %testWeight = %objective.weightLevel4; + } + if (%testWeight + 260 < %minWeight) + return false; + else + return true; +} + +//------------------------------ + +function AIODefendLocation::weight(%this, %client, %level, %minWeight, %inventoryStr) +{ + // if were playing CnH, check who owns this + if (%this.targetObjectId > 0) + { + if (!isObject(%this.targetObjectId) || %this.targetObjectId.isHidden() || %this.targetObjectId.team != %client.team) + return 0; + } + + //make sure the player is still alive!!!!! + if (! AIClientIsAlive(%client)) + return 0; + + //do a quick check to disqualify this objective if it can't meet the minimum weight + if (!AIODefault::QuickWeight(%this, %client, %level, %minWeight)) + { + if (%this.targetObjectId > 0 && %this.issuedByClientId == %client.controlByHuman) + { + if ($AIWeightHumanIssuedCommand < %minWeight) + return 0; + } + else + return 0; + } + + %weight = AIODefault::weight(%this, %client, %level, %inventoryStr); + + //if the object has been destroyed, reduce the weight + if (%this.targetObjectId > 0) + { + + //see if we were forced on the objective + if (%this.issuedByClientId == %client.controlByHuman && %weight < $AIWeightHumanIssuedCommand) + %weight = $AIWeightHumanIssuedCommand; + + //else see if the object has been destroyed + else if (!isObject(%this.targetObjectId) || %this.targetObjectId.getDamageState() $= "Destroyed") + %weight -= 320; + } + + return %weight; +} + +function AIODefendLocation::assignClient(%this, %client) +{ + %client.objectiveTask = %client.addTask(AIDefendLocation); + %client.objectiveTask.initFromObjective(%this, %client); +} + +function AIODefendLocation::unassignClient(%this, %client) +{ + %client.removeTask(%client.objectiveTask); + %client.objectiveTask = ""; +} + +//------------------------------ + +function AIOAttackLocation::weight(%this, %client, %level, %minWeight, %inventoryStr) +{ + //make sure the player is still alive!!!!! + if (! AIClientIsAlive(%client)) + return 0; + + //now, if this bot is linked to a human who has issued this command, up the weight + if (%this.issuedByClientId == %client.controlByHuman) + { + //make sure we have the potential to reach the minWeight + if (!AIODefault::QuickWeight(%this, %client, %level, %minWeight)) + { + if ($AIWeightHumanIssuedCommand < %minWeight) + return 0; + else + %weight = $AIWeightHumanIssuedCommand; + } + else + { + // calculate the default... + %weight = AIODefault::weight(%this, %client, %level, %inventoryStr); + if (%weight < $AIWeightHumanIssuedCommand) + %weight = $AIWeightHumanIssuedCommand; + } + } + else + { + //make sure we have the potential to reach the minWeight + if (!AIODefault::QuickWeight(%this, %client, %level, %minWeight)) + return 0; + + // calculate the default... + %weight = AIODefault::weight(%this, %client, %level, %inventoryStr); + } + + return %weight; +} + +function AIOAttackLocation::assignClient(%this, %client) +{ + %client.objectiveTask = %client.addTask(AIAttackLocation); + %client.objectiveTask.initFromObjective(%this, %client); +} + +function AIOAttackLocation::unassignClient(%this, %client) +{ + %client.removeTask(%client.objectiveTask); + %client.objectiveTask = ""; +} + +//------------------------------ + +function AIOTouchObject::weight(%this, %client, %level, %minWeight, %inventoryStr) +{ + //make sure the player is still alive!!!!! + if (! AIClientIsAlive(%client)) + return 0; + + if (!AIODefault::QuickWeight(%this, %client, %level, %minWeight)) + return 0; + + switch$ (%this.mode) + { + case "TouchFlipFlop": + if(%this.targetObjectId.team == %client.team || %this.targetObjectId.isHidden()) + return 0; + else + return AIODefault::weight(%this, %client, %level, %inventoryStr); + case "FlagGrab": + if (! %this.targetObjectId.isHome) + return 0; + else + return AIODefault::weight(%this, %client, %level, %inventoryStr); + case "FlagDropped": + if ((%this.targetObjectId.isHome) || (%this.targetObjectId.carrier !$= "")) + return 0; + else + return AIODefault::weight(%this, %client, %level, %inventoryStr); + case "FlagCapture": + if (%this.targetObjectId.carrier != %client.player) + return 0; + else + { + //find our home flag location + %homeTeam = %client.team; + %homeFlag = $AITeamFlag[%homeTeam]; + %this.location = %homeFlag.originalPosition; + return AIODefault::weight(%this, %client, %level, %inventoryStr); + } + } + return 0; +} + +function AIOTouchObject::assignClient(%this, %client) +{ + %client.objectiveTask = %client.addTask(AITouchObject); + %client.objectiveTask.initFromObjective(%this, %client); + + //create an AIOEscortPlayer objective to help out, if required + if (%this.mode $= "FlagGrab") + { + %client.escort = new AIObjective(AIOEscortPlayer) + { + dataBlock = "AIObjectiveMarker"; + weightLevel1 = $AIWeightEscortOffense[1]; + weightLevel2 = $AIWeightEscortOffense[2]; + description = "Escort " @ getTaggedString(%client.name); + targetClientId = %client; + offense = true; + desiredEquipment = "EnergyPack"; + buyEquipmentSet = "LightEnergyELF"; + }; + MissionCleanup.add(%client.escort); + $ObjectiveQ[%client.team].add(%client.escort); + } + + else if (%this.mode $= "FlagCapture") + { + %client.escort = new AIObjective(AIOEscortPlayer) + { + dataBlock = "AIObjectiveMarker"; + weightLevel1 = $AIWeightEscortCapper[1]; + weightLevel2 = $AIWeightEscortCapper[2]; + description = "Escort " @ getTaggedString(%client.name); + targetClientId = %client; + offense = true; + desiredEquipment = "EnergyPack"; + buyEquipmentSet = "LightEnergyDefault"; + }; + MissionCleanup.add(%client.escort); + $ObjectiveQ[%client.team].add(%client.escort); + } +} + +function AIOTouchObject::unassignClient(%this, %client) +{ + //kill the escort objective + if (%client.escort) + { + AIClearObjective(%client.escort); + %client.escort.delete(); + %client.escort = ""; + } + + %client.removeTask(%client.objectiveTask); + %client.objectiveTask = ""; +} + +//------------------------------ + +function AIOAttackPlayer::weight(%this, %client, %level, %minWeight, %inventoryStr) +{ + //make sure the player is still alive!!!!! + if (! AIClientIsAlive(%client)) + return 0; + + //if we're attacking the flag carrier, make sure a flag carrier exists + if (%this.mode $= "FlagCarrier") + { + if (%this.targetObjectId.carrier $= "") + return 0; + else + %this.targetClientId = %this.targetObjectId.carrier.client; + } + + //now, if this bot is linked to a human who has issued this command, up the weight + if (%this.issuedByClientId == %client.controlByHuman) + { + //make sure we have the potential to reach the minWeight + if (!AIODefault::QuickWeight(%this, %client, %level, %minWeight)) + { + if ($AIWeightHumanIssuedCommand < %minWeight) + return 0; + else + %weight = $AIWeightHumanIssuedCommand; + } + else + { + // calculate the default... + %weight = AIODefault::weight(%this, %client, %level, %inventoryStr); + if (%weight < $AIWeightHumanIssuedCommand) + %weight = $AIWeightHumanIssuedCommand; + } + } + else + { + //make sure we have the potential to reach the minWeight + if (!AIODefault::QuickWeight(%this, %client, %level, %minWeight)) + return 0; + + // calculate the default... + %weight = AIODefault::weight(%this, %client, %level, %inventoryStr); + } + + return %weight; +} + +function AIOAttackPlayer::assignClient(%this, %client) +{ + %client.objectiveTask = %client.addTask(AIAttackPlayer); + %client.objectiveTask.initFromObjective(%this, %client); +} + +function AIOAttackPlayer::unassignClient(%this, %client) +{ + %client.removeTask(%client.objectiveTask); + %client.objectiveTask = ""; +} + +//------------------------------ + +function AIOEscortPlayer::weight(%this, %client, %level, %minWeight, %inventoryStr) +{ + //make sure the player is still alive!!!!! + if (! AIClientIsAlive(%client) || ! AIClientIsAlive(%this.targetClientId)) + return 0; + + //can't escort yourself + if (%client == %this.targetClientId) + return 0; + + //make sure the class is appropriate + if (%this.forceClientId <= 0 && %this.issuedByClientId != %client.controlByHuman) + { + %targArmor = %this.targetClientId.player.getArmorSize(); + %myArmor = %client.player.getArmorSize(); + + if ((%targArmor $= "Light" && %myArmor !$= "Light") || %myArmor $= "Heavy") + return 0; + } + + //can't bump a forced client from level 1 + if (%this.forceClientId > 0 && %this.forceClientId != %client && %level == 1) + return 0; + + //if this bot is linked to a human who has issued this command, up the weight + if (%this.issuedByClientId == %client.controlByHuman) + { + //make sure we have the potential to reach the minWeight + if (!AIODefault::QuickWeight(%this, %client, %level, %minWeight)) + { + if ($AIWeightHumanIssuedEscort < %minWeight) + return 0; + else + %weight = $AIWeightHumanIssuedEscort; + } + else + { + // calculate the default... + %weight = AIODefault::weight(%this, %client, %level, %inventoryStr); + if (%weight < $AIWeightHumanIssuedEscort) + %weight = $AIWeightHumanIssuedEscort; + } + } + else + { + //make sure we have the potential to reach the minWeight + if (!AIODefault::QuickWeight(%this, %client, %level, %minWeight)) + return 0; + + // calculate the default... + %weight = AIODefault::weight(%this, %client, %level, %inventoryStr); + } + + return %weight; +} + +function AIOEscortPlayer::assignClient(%this, %client) +{ + %client.objectiveTask = %client.addTask(AIEscortPlayer); + %client.objectiveTask.initFromObjective(%this, %client); +} + +function AIOEscortPlayer::unassignClient(%this, %client) +{ + %client.removeTask(%client.objectiveTask); + %client.objectiveTask = ""; +} + +//------------------------------ + +function AIOAttackObject::weight(%this, %client, %level, %minWeight, %inventoryStr) +{ + // if were playing CnH, check who owns this + if (!isObject(%this.targetObjectId) || %this.targetObjectId.isHidden() || %this.targetObjectId.team == %client.team) + return 0; + + //make sure the player is still alive!!!!! + if (! AIClientIsAlive(%client)) + return 0; + + //no need to attack if the object is already destroyed + if (!isObject(%this.targetObjectId) || %this.targetObjectId.getDamageState() $= "Destroyed") + return 0; + else + { + //if this bot is linked to a human who has issued this command, up the weight + if (%this.issuedByClientId == %client.controlByHuman) + { + //make sure we have the potential to reach the minWeight + if (!AIODefault::QuickWeight(%this, %client, %level, %minWeight)) + { + if ($AIWeightHumanIssuedCommand < %minWeight) + return 0; + else + %weight = $AIWeightHumanIssuedCommand; + } + else + { + // calculate the default... + %weight = AIODefault::weight(%this, %client, %level, %inventoryStr); + if (%weight < $AIWeightHumanIssuedCommand) + %weight = $AIWeightHumanIssuedCommand; + } + } + else + { + //make sure we have the potential to reach the minWeight + if (!AIODefault::QuickWeight(%this, %client, %level, %minWeight)) + return 0; + + // calculate the default... + %weight = AIODefault::weight(%this, %client, %level, %inventoryStr); + } + + return %weight; + } +} + +function AIOAttackObject::assignClient(%this, %client) +{ + %client.objectiveTask = %client.addTask(AIAttackObject); + %client.objectiveTask.initFromObjective(%this, %client); +} + +function AIOAttackObject::unassignClient(%this, %client) +{ + %client.removeTask(%client.objectiveTask); + %client.objectiveTask = ""; +} + +//------------------------------ + +function AIORepairObject::weight(%this, %client, %level, %minWeight, %inventoryStr) +{ + // if were playing CnH, check who owns this + if (!isObject(%this.targetObjectId) || %this.targetObjectId.isHidden() || %this.targetObjectId.team != %client.team) + return 0; + + //make sure the player is still alive!!!!! + if (! AIClientIsAlive(%client)) + return 0; + + //no need to repair if the object isn't in need + if (!isObject(%this.targetObjectId) || %this.targetObjectId.getDamagePercent() <= 0) + return 0; + else + { + //if this bot is linked to a human who has issued this command, up the weight + if (%this.issuedByClientId == %client.controlByHuman) + { + //make sure we have the potential to reach the minWeight + if (!AIODefault::QuickWeight(%this, %client, %level, %minWeight)) + { + if ($AIWeightHumanIssuedCommand < %minWeight) + return 0; + else + %weight = $AIWeightHumanIssuedCommand; + } + else + { + // calculate the default... + %weight = AIODefault::weight(%this, %client, %level, %inventoryStr); + if (%weight < $AIWeightHumanIssuedCommand) + %weight = $AIWeightHumanIssuedCommand; + } + } + else + { + //make sure we have the potential to reach the minWeight + if (!AIODefault::QuickWeight(%this, %client, %level, %minWeight)) + return 0; + + // calculate the default... + %weight = AIODefault::weight(%this, %client, %level, %inventoryStr); + } + + return %weight; + } +} + +function AIORepairObject::assignClient(%this, %client) +{ + %client.objectiveTask = %client.addTask(AIRepairObject); + %client.objectiveTask.initFromObjective(%this, %client); +} + +function AIORepairObject::unassignClient(%this, %client) +{ + %client.removeTask(%client.objectiveTask); + %client.objectiveTask = ""; +} + +//------------------------------ + +function AIOLazeObject::weight(%this, %client, %level, %minWeight, %inventoryStr) +{ + //make sure the player is still alive!!!!! + if (! AIClientIsAlive(%client)) + return 0; + + //see if it's already being lazed + %numTargets = ServerTargetSet.getCount(); + for (%i = 0; %i < %numTargets; %i++) + { + %targ = ServerTargetSet.getObject(%i); + if (%targ.sourceObject != %client.player) + { + %targDist = VectorDist(%targ.getTargetPoint(), %this.targetObjectId.getWorldBoxCenter()); + if (%targDist < 10) + { + %this.lastLazedTime = getSimTime(); + %this.lastLazedClient = %targ.sourceObject.client; + break; + } + } + } + + //no need to laze if the object is already destroyed + if (!isObject(%this.targetObjectId) || %this.targetObjectId.getDamageState() $= "Destroyed") + return 0; + else if (%this.targetObjectId.isHidden() || %this.targetObjectId.team != %client.team) + return 0; + else if (getSimTime() - %this.lastLazedTime <= 15000 && %this.lastLazedClient != %client) + return 0; + else + { + //set the base weight + switch (%level) + { + case 1: + %weight = %this.weightLevel1; + case 2: + %weight = %this.weightLevel2; + case 3: + %weight = %this.weightLevel3; + default: + %weight = %this.weightLevel4; + } + + //check Affinity + if (ClientHasAffinity(%this, %client)) + %weight += 100; + + //for now, do not deviate from the current assignment to laze a target, if you don't + //already have a targeting laser. + %needEquipment = AINeedEquipment(%this.equipment, %client); + if (!%needEquipment) + %weight += 100; + else if (!aiHumanHasControl(%client.controlByHuman, %client)) + return 0; + + //see if this client is close to the issuing client + if (%this.issuedByClientId > 0) + { + if (! AIClientIsAlive(%this.issuedByClientId)) + return 0; + + %distance = %client.getPathDistance(%this.issuedByClientId.player.getWorldBoxCenter()); + if (%distance < 0) + %distance = 32767; + + //see if we're within 200 m + if (%distance < 200) + %weight += 30; + + //see if we're within 90 m + if (%distance < 90) + %weight += 30; + + //see if we're within 45 m + if (%distance < 45) + %weight += 30; + } + + //now, if this bot is linked to a human who has issued this command, up the weight + if (%this.issuedByClientId == %client.controlByHuman && %weight < $AIWeightHumanIssuedCommand) + %weight = $AIWeightHumanIssuedCommand; + + return %weight; + } +} + +function AIOLazeObject::assignClient(%this, %client) +{ + %client.objectiveTask = %client.addTask(AILazeObject); + %client.objectiveTask.initFromObjective(%this, %client); +} + +function AIOLazeObject::unassignClient(%this, %client) +{ + %client.removeTask(%client.objectiveTask); + %client.objectiveTask = ""; +} + +//------------------------------ + +function AIOMortarObject::weight(%this, %client, %level, %minWeight, %inventoryStr) +{ + // if were playing CnH, check who owns this + if (!isObject(%this.targetObjectId) || %this.targetObjectId.isHidden() || %this.targetObjectId.team == %client.team) + return 0; + + //make sure the player is still alive!!!!! + if (! AIClientIsAlive(%client)) + return 0; + + //no need to attack if the object is already destroyed + if (%this.targetObjectId.getDamageState() $= "Destroyed") + return 0; + else + { + //if this bot is linked to a human who has issued this command, up the weight + if (%this.issuedByClientId == %client.controlByHuman) + { + //make sure we have the potential to reach the minWeight + if (!AIODefault::QuickWeight(%this, %client, %level, %minWeight)) + { + if ($AIWeightHumanIssuedCommand < %minWeight) + return 0; + else + %weight = $AIWeightHumanIssuedCommand; + } + else + { + // calculate the default... + %weight = AIODefault::weight(%this, %client, %level, %inventoryStr); + if (%weight < $AIWeightHumanIssuedCommand) + %weight = $AIWeightHumanIssuedCommand; + } + } + else + { + //make sure we have the potential to reach the minWeight + if (!AIODefault::QuickWeight(%this, %client, %level, %minWeight)) + return 0; + + // calculate the default... + %weight = AIODefault::weight(%this, %client, %level, %inventoryStr); + } + + return %weight; + } +} + +function AIOMortarObject::assignClient(%this, %client) +{ + %client.objectiveTask = %client.addTask(AIMortarObject); + %client.objectiveTask.initFromObjective(%this, %client); + + //create the escort objective (require a targeting laser in this case...) + %client.escort = new AIObjective(AIOEscortPlayer) + { + dataBlock = "AIObjectiveMarker"; + weightLevel1 = $AIWeightEscortOffense[1]; + weightLevel2 = $AIWeightEscortOffense[2]; + description = "Escort " @ getTaggedString(%client.name); + targetClientId = %client; + offense = true; + equipment = "TargetingLaser"; + buyEquipmentSet = "LightEnergyDefault"; + }; + MissionCleanup.add(%client.escort); + $ObjectiveQ[%client.team].add(%client.escort); +} + +function AIOMortarObject::unassignClient(%this, %client) +{ + //kill the escort objective + if (%client.escort) + { + AIClearObjective(%client.escort); + %client.escort.delete(); + %client.escort = ""; + } + + %client.removeTask(%client.objectiveTask); + %client.objectiveTask = ""; +} + +//------------------------------------------------------------------------ +//If the function ShapeBaseImageData::testInvalidDeployConditions() changes at all, those changes need to be reflected here +function AIODeployEquipment::weight(%this, %client, %level, %minWeight, %inventoryStr) +{ + //make sure the player is still alive!!!!! + if (! AIClientIsAlive(%client)) + return 0; + + //make sure the deploy objective is valid + if (%this.isInvalid) + return 0; + + //first, make sure we haven't deployed too many... + if (%this.equipment $= "TurretOutdoorDeployable" || %this.equipment $= "TurretIndoorDeployable") + %maxAllowed = countTurretsAllowed(%this.equipment); + else + %maxAllowed = $TeamDeployableMax[%this.equipment]; + + if ($TeamDeployedCount[%client.team, %this.equipment] >= %maxAllowed) + return 0; + + //now make sure there are no other items in the way... + InitContainerRadiusSearch(%this.location, $MinDeployableDistance, $TypeMasks::VehicleObjectType | + $TypeMasks::MoveableObjectType | + $TypeMasks::StaticShapeObjectType | + $TypeMasks::TSStaticShapeObjectType | + $TypeMasks::ForceFieldObjectType | + $TypeMasks::ItemObjectType | + $TypeMasks::PlayerObjectType | + $TypeMasks::TurretObjectType); + %objSearch = containerSearchNext(); + + //make sure we're not invalidating the deploy location with the client's own player object + if (%objSearch == %client.player) + %objSearch = containerSearchNext(); + + //did we find an object which would block deploying the equipment? + if (isObject(%objSearch)) + return 0; + + //now run individual checks based on the equipment type... + if (%this.equipment $= "TurretIndoorDeployable") + { + //check if there's another turret close to the deploy location + InitContainerRadiusSearch(%this.location, $TurretIndoorSpaceRadius, $TypeMasks::StaticShapeObjectType); + %found = containerSearchNext(); + if (isObject(%found)) + { + %foundName = %found.getDataBlock().getName(); + if ((%foundName $= TurretDeployedFloorIndoor) || (%foundName $= "TurretDeployedWallIndoor") || (%foundName $= "TurretDeployedCeilingIndoor") || (%foundName $= "TurretDeployedOutdoor")) + return 0; + } + + //now see if there are too many turrets in the area... + %highestDensity = 0; + InitContainerRadiusSearch(%this.location, $TurretIndoorSphereRadius, $TypeMasks::StaticShapeObjectType); + %found = containerSearchNext(); + while (isObject(%found)) + { + %foundName = %found.getDataBlock().getName(); + if ((%foundName $= "TurretDeployedFloorIndoor") || (%foundName $= "TurretDeployedWallIndoor") || (%foundName $= "TurretDeployedCeilingIndoor") || (%foundName $= "TurretDeployedOutdoor")) + { + //found one + %numTurretsNearby++; + + %nearbyDensity = testNearbyDensity(%found, $TurretIndoorSphereRadius); + if (%nearbyDensity > %highestDensity) + %highestDensity = %nearbyDensity; + } + %found = containerSearchNext(); + } + + if (%numTurretsNearby > %highestDensity) + %highestDensity = %numTurretsNearby; + + //now see if the area is already saturated + if (%highestDensity > $TurretIndoorMaxPerSphere) + return 0; + } + + else if (%this.equipment $= "TurretOutdoorDeployable") + { + //check if there's another turret close to the deploy location + InitContainerRadiusSearch(%this.location, $TurretOutdoorSpaceRadius, $TypeMasks::StaticShapeObjectType); + %found = containerSearchNext(); + if (isObject(%found)) + { + %foundName = %found.getDataBlock().getName(); + if ((%foundName $= "TurretDeployedFloorIndoor") || (%foundName $= "TurretDeployedWallIndoor") || (%foundName $= "TurretDeployedCeilingIndoor") || (%foundName $= "TurretDeployedOutdoor")) + return 0; + } + + //now see if there are too many turrets in the area... + %highestDensity = 0; + InitContainerRadiusSearch(%this.location, $TurretOutdoorSphereRadius, $TypeMasks::StaticShapeObjectType); + %found = containerSearchNext(); + while (isObject(%found)) + { + %foundName = %found.getDataBlock().getName(); + if ((%foundName $= "TurretDeployedFloorIndoor") || (%foundName $= "TurretDeployedWallIndoor") || (%foundName $= "TurretDeployedCeilingIndoor") || (%foundName $= "TurretDeployedOutdoor")) + { + //found one + %numTurretsNearby++; + + %nearbyDensity = testNearbyDensity(%found, $TurretOutdoorSphereRadius); + if (%nearbyDensity > %highestDensity) + %highestDensity = %nearbyDensity; + } + %found = containerSearchNext(); + } + + if (%numTurretsNearby > %highestDensity) + %highestDensity = %numTurretsNearby; + + //now see if the area is already saturated + if (%highestDensity > $TurretOutdoorMaxPerSphere) + return 0; + } + + //check equipment requirement + %needEquipment = AINeedEquipment(%this.equipment, %client); + + //if don't need equipment, see if we've past the "point of no return", and should continue regardless + if (! %needEquipment) + { + %needArmor = AIMustUseRegularInvStation(%this.equipment, %client); + %result = AIFindClosestInventory(%client, %needArmor); + %closestInv = getWord(%result, 0); + %closestDist = getWord(%result, 1); + + //if we're too far from the inv to go back, or we're too close to the deploy location, force continue + if (%closestDist > 50 && VectorDist(%client.player.getWorldBoxCenter(), %task.location) < 50) + { + %weight = AIODefault::weight(%this, %client, %level, %inventoryStr); + if (%weight < $AIWeightContinueDeploying) + %weight = $AIWeightContinueDeploying; + return %weight; + } + } + + //if this bot is linked to a human who has issued this command, up the weight + if (%this.issuedByClientId == %client.controlByHuman) + { + //make sure we have the potential to reach the minWeight + if (!AIODefault::QuickWeight(%this, %client, %level, %minWeight)) + { + if ($AIWeightHumanIssuedCommand < %minWeight) + return 0; + else + %weight = $AIWeightHumanIssuedCommand; + } + else + { + // calculate the default... + %weight = AIODefault::weight(%this, %client, %level, %inventoryStr); + if (%weight < $AIWeightHumanIssuedCommand) + %weight = $AIWeightHumanIssuedCommand; + } + } + else + { + //make sure we have the potential to reach the minWeight + if (!AIODefault::QuickWeight(%this, %client, %level, %minWeight)) + return 0; + + // calculate the default... + %weight = AIODefault::weight(%this, %client, %level, %inventoryStr); + } + + return %weight; +} + +function AIODeployEquipment::assignClient(%this, %client) +{ + %client.objectiveTask = %client.addTask(AIDeployEquipment); + %task = %client.objectiveTask; + %task.initFromObjective(%this, %client); +} + +function AIODeployEquipment::unassignClient(%this, %client) +{ + %client.removeTask(%client.objectiveTask); + %client.objectiveTask = ""; +} + +//------------------------------------------------------------------------ diff --git a/scripts/aiPracticeCtf.cs b/scripts/aiPracticeCtf.cs index ee52d5c..070cc9b 100644 --- a/scripts/aiPracticeCtf.cs +++ b/scripts/aiPracticeCtf.cs @@ -1,117 +1,117 @@ -//////////////////////////////////////// -// AI functions for Clan Practice CTF // -// z0dd - ZOD, 4/25/02 // -//////////////////////////////////////// - - -function PracticeCTFGame::onAIRespawn(%game, %client) -{ - //add the default task - if (! %client.defaultTasksAdded) - { - %client.defaultTasksAdded = true; - %client.addTask(AIEngageTask); - %client.addTask(AIPickupItemTask); - %client.addTask(AITauntCorpseTask); - %client.addtask(AIEngageTurretTask); - %client.addtask(AIDetectMineTask); - } -} - -function PracticeCTFGame::AIInit(%game) -{ - // load external objectives files - loadObjectives(); - - for (%i = 1; %i <= %game.numTeams; %i++) - { - if (!isObject($ObjectiveQ[%i])) - { - $ObjectiveQ[%i] = new AIObjectiveQ(); - MissionCleanup.add($ObjectiveQ[%i]); - } - - error("team " @ %i @ " objectives load..."); - $ObjectiveQ[%i].clear(); - AIInitObjectives(%i, %game); - } - - //call the default AIInit() function - AIInit(); -} - -function PracticeCTFGame::AIplayerCaptureFlipFlop(%game, %player, %flipFlop) -{ -} - -function PracticeCTFGame::AIplayerTouchEnemyFlag(%game, %player, %flag) -{ -} - -function PracticeCTFGame::AIplayerTouchOwnFlag(%game, %player, %flag) -{ -} - -function PracticeCTFGame::AIflagCap(%game, %player, %flag) -{ - //signal the flag cap event - AIRespondToEvent(%player.client, 'EnemyFlagCaptured', %player.client); - // MES - changed above line - did not pass args in correct order -} - -function PracticeCTFGame::AIplayerDroppedFlag(%game, %player, %flag) -{ -} - -function PracticeCTFGame::AIflagReset(%game, %flag) -{ -} - -function PracticeCTFGame::onAIDamaged(%game, %clVictim, %clAttacker, %damageType, %implement) -{ - if (%clAttacker && %clAttacker != %clVictim && %clAttacker.team == %clVictim.team) - { - schedule(250, %clVictim, "AIPlayAnimSound", %clVictim, %clAttacker.player.getWorldBoxCenter(), "wrn.watchit", -1, -1, 0); - - //clear the "lastDamageClient" tag so we don't turn on teammates... unless it's uberbob! - %clVictim.lastDamageClient = -1; - } -} - -function PracticeCTFGame::onAIKilledClient(%game, %clVictim, %clAttacker, %damageType, %implement) -{ - if (%clVictim.team != %clAttacker.team) - DefaultGame::onAIKilledClient(%game, %clVictim, %clAttacker, %damageType, %implement); -} - -function PracticeCTFGame::onAIKilled(%game, %clVictim, %clAttacker, %damageType, %implement) -{ - DefaultGame::onAIKilled(%game, %clVictim, %clAttacker, %damageType, %implement); -} - -function PracticeCTFGame::onAIFriendlyFire(%game, %clVictim, %clAttacker, %damageType, %implement) -{ - if (%clAttacker && %clAttacker.team == %clVictim.team && %clAttacker != %clVictim && !%clVictim.isAIControlled()) - { - // The Bot is only a little sorry: - if ( getRandom() > 0.9 ) - AIMessageThread("ChatSorry", %clAttacker, %clVictim); - } -} - -function PracticeCTFGame::AIHalfTime(%game) -{ - //clear all the bots, and clean up all the sets, objective qs, etc... - AIMissionEnd(); - - //reset everything from scratch - %game.aiInit(); - - //respawn all the bots - for (%i = 0; %i < ClientGroup.getCount(); %i++) - { - %cl = ClientGroup.getObject(%i); - if (%cl.isAIControlled()) - onAIRespawn(%cl); - } -} +//////////////////////////////////////// +// AI functions for Clan Practice CTF // +// z0dd - ZOD, 4/25/02 // +//////////////////////////////////////// + + +function PracticeCTFGame::onAIRespawn(%game, %client) +{ + //add the default task + if (! %client.defaultTasksAdded) + { + %client.defaultTasksAdded = true; + %client.addTask(AIEngageTask); + %client.addTask(AIPickupItemTask); + %client.addTask(AITauntCorpseTask); + %client.addtask(AIEngageTurretTask); + %client.addtask(AIDetectMineTask); + } +} + +function PracticeCTFGame::AIInit(%game) +{ + // load external objectives files + loadObjectives(); + + for (%i = 1; %i <= %game.numTeams; %i++) + { + if (!isObject($ObjectiveQ[%i])) + { + $ObjectiveQ[%i] = new AIObjectiveQ(); + MissionCleanup.add($ObjectiveQ[%i]); + } + + error("team " @ %i @ " objectives load..."); + $ObjectiveQ[%i].clear(); + AIInitObjectives(%i, %game); + } + + //call the default AIInit() function + AIInit(); +} + +function PracticeCTFGame::AIplayerCaptureFlipFlop(%game, %player, %flipFlop) +{ +} + +function PracticeCTFGame::AIplayerTouchEnemyFlag(%game, %player, %flag) +{ +} + +function PracticeCTFGame::AIplayerTouchOwnFlag(%game, %player, %flag) +{ +} + +function PracticeCTFGame::AIflagCap(%game, %player, %flag) +{ + //signal the flag cap event + AIRespondToEvent(%player.client, 'EnemyFlagCaptured', %player.client); + // MES - changed above line - did not pass args in correct order +} + +function PracticeCTFGame::AIplayerDroppedFlag(%game, %player, %flag) +{ +} + +function PracticeCTFGame::AIflagReset(%game, %flag) +{ +} + +function PracticeCTFGame::onAIDamaged(%game, %clVictim, %clAttacker, %damageType, %implement) +{ + if (%clAttacker && %clAttacker != %clVictim && %clAttacker.team == %clVictim.team) + { + schedule(250, %clVictim, "AIPlayAnimSound", %clVictim, %clAttacker.player.getWorldBoxCenter(), "wrn.watchit", -1, -1, 0); + + //clear the "lastDamageClient" tag so we don't turn on teammates... unless it's uberbob! + %clVictim.lastDamageClient = -1; + } +} + +function PracticeCTFGame::onAIKilledClient(%game, %clVictim, %clAttacker, %damageType, %implement) +{ + if (%clVictim.team != %clAttacker.team) + DefaultGame::onAIKilledClient(%game, %clVictim, %clAttacker, %damageType, %implement); +} + +function PracticeCTFGame::onAIKilled(%game, %clVictim, %clAttacker, %damageType, %implement) +{ + DefaultGame::onAIKilled(%game, %clVictim, %clAttacker, %damageType, %implement); +} + +function PracticeCTFGame::onAIFriendlyFire(%game, %clVictim, %clAttacker, %damageType, %implement) +{ + if (%clAttacker && %clAttacker.team == %clVictim.team && %clAttacker != %clVictim && !%clVictim.isAIControlled()) + { + // The Bot is only a little sorry: + if ( getRandom() > 0.9 ) + AIMessageThread("ChatSorry", %clAttacker, %clVictim); + } +} + +function PracticeCTFGame::AIHalfTime(%game) +{ + //clear all the bots, and clean up all the sets, objective qs, etc... + AIMissionEnd(); + + //reset everything from scratch + %game.aiInit(); + + //respawn all the bots + for (%i = 0; %i < ClientGroup.getCount(); %i++) + { + %cl = ClientGroup.getObject(%i); + if (%cl.isAIControlled()) + onAIRespawn(%cl); + } +} diff --git a/scripts/aiRPG.cs b/scripts/aiRPG.cs index 06e0706..64950c6 100644 --- a/scripts/aiRPG.cs +++ b/scripts/aiRPG.cs @@ -1,26 +1,26 @@ -function RPGGame::AIInit(%game) -{ - //call the default AIInit() function - AIInit(); -} - -function RPGGame::onAIRespawn(%game, %client) -{ - //add the default task - if (! %client.defaultTasksAdded) - { - %client.defaultTasksAdded = true; - %client.addTask(AIEngageTask); - %client.addTask(AIPickupItemTask); - // %client.addTask(AIUseInventoryTask); They spawn with the stuff they need - %client.addTask(AITauntCorpseTask); - %client.addTask(AIEngageTurretTask); - %client.addtask(AIDetectMineTask); - // %client.addTask(AIPatrolTask); They don't move unless told to - } - - //set the inv flag - %client.spawnUseInv = true; -} - - +function RPGGame::AIInit(%game) +{ + //call the default AIInit() function + AIInit(); +} + +function RPGGame::onAIRespawn(%game, %client) +{ + //add the default task + if (! %client.defaultTasksAdded) + { + %client.defaultTasksAdded = true; + %client.addTask(AIEngageTask); + %client.addTask(AIPickupItemTask); + // %client.addTask(AIUseInventoryTask); They spawn with the stuff they need + %client.addTask(AITauntCorpseTask); + %client.addTask(AIEngageTurretTask); + %client.addtask(AIDetectMineTask); + // %client.addTask(AIPatrolTask); They don't move unless told to + } + + //set the inv flag + %client.spawnUseInv = true; +} + + diff --git a/scripts/aiSurvival.cs b/scripts/aiSurvival.cs index db1e128..c98643a 100644 --- a/scripts/aiSurvival.cs +++ b/scripts/aiSurvival.cs @@ -1,44 +1,44 @@ -// -------------------------------------------------------- -// aiSurvival.cs -// AI scripts for bots in the Survival gamemode -// Copyright (c) 2012 The DarkDragonDX -// ======================================================== - -function SVGame::AIInit(%game) -{ - //call the default AIInit() function - AIInit(); - return true; -} - -function SVGame::onAIRespawn(%game, %client) -{ - //add the default task - if (! %client.defaultTasksAdded) - { - %client.defaultTasksAdded = true; - %client.addTask(AIEngageTask); - %client.addTask(AIPickupItemTask); - // %client.addTask(AITauntCorpseTask); - %client.addTask(AIEngageTurretTask); - // %client.addtask(AIDetectMineTask); - %client.addTask(AIPatrolTask); - } - %client.setSkillLevel(99); - %client.hide(); - %client.hideClientInList(); - - //Now, force the bot to choose a player - %count = clientGroup.getCount(); - %rnd = getRandom(0,%count); - %rndcl = clientGroup.getObject(%rnd); - - %client.stepEngage(%rndcl); - - Game.aiCount++; - //set the inv flag - %client.spawnUseInv = true; - - - return true; +// -------------------------------------------------------- +// aiSurvival.cs +// AI scripts for bots in the Survival gamemode +// Copyright (c) 2012 The DarkDragonDX +// ======================================================== + +function SVGame::AIInit(%game) +{ + //call the default AIInit() function + AIInit(); + return true; +} + +function SVGame::onAIRespawn(%game, %client) +{ + //add the default task + if (! %client.defaultTasksAdded) + { + %client.defaultTasksAdded = true; + %client.addTask(AIEngageTask); + %client.addTask(AIPickupItemTask); + // %client.addTask(AITauntCorpseTask); + %client.addTask(AIEngageTurretTask); + // %client.addtask(AIDetectMineTask); + %client.addTask(AIPatrolTask); + } + %client.setSkillLevel(99); + %client.hide(); + %client.hideClientInList(); + + //Now, force the bot to choose a player + %count = clientGroup.getCount(); + %rnd = getRandom(0,%count); + %rndcl = clientGroup.getObject(%rnd); + + %client.stepEngage(%rndcl); + + Game.aiCount++; + //set the inv flag + %client.spawnUseInv = true; + + + return true; } \ No newline at end of file diff --git a/scripts/autoexec/FixRemap.cs b/scripts/autoexec/FixRemap.cs index f157454..4d34f4a 100644 --- a/scripts/autoexec/FixRemap.cs +++ b/scripts/autoexec/FixRemap.cs @@ -1,76 +1,76 @@ -// #autoload -// #name = Fix Remap -// #version = 1.0 -// #category = Fix -// #warrior = WegBert -// #status = beta - -function redoBrokenMapping( %actionMap, %device, %action, %cmd, %newIndex ) -{ - %actionMap.bind( %device, %action, %cmd ); - //OP_RemapList.setRowById( %oldIndex, buildFullMapString( %oldIndex ) ); - OP_RemapList.setRowById( %newIndex, buildFullMapString( %newIndex ) ); -} - -package FixRemapLoad { - -function RemapInputCtrl::onInputEvent( %this, %device, %action ) -{ - Parent::onInputEvent( %this, %device, %action ); - - // prevMapIndex would equal -1 under the following circumstances: - // - // 1. User installed a third-party script which added a remap entry to the list. - // The user removed that script and is trying to rebind a key that was - // previously bound to that script. With the remap entry missing, the system - // fails, because the function bound to the key has no $RemapCmd. - // - // 2. User installed a third-party script which did not add a remap entry to the - // list, but instead replaced an existing command with a third-party one - // (for example, the HappyThrow script upon being run for the first time - // rebinds the user's grenade key from the default function, throwGrenade, to - // throwGrenadeNew). The script may still be installed, but the user is trying - // to rebind the key bound to the third-party function. This third-party function, - // although perfectly valid and existing, has no $RemapCmd. - // - // To counter these problems, the script will warn the user that the function may or - // may not exist. It will allow the user to choose whether they still want to rebind - // the key or not. If they do, the script will proceed with the remapping that the - // original fon complained about. - - if (%this.mode !$= "consoleKey") - { - switch$ ( OP_ControlsPane.group ) - { - case "Observer": - %actionMap = observerMap; - %cmd = $ObsRemapCmd[%this.index]; - - default: - %actionMap = moveMap; - %cmd = $RemapCmd[%this.index]; - } - - %prevMap = %actionMap.getCommand( %device, %action ); - if (%prevMap !$= %cmd && %prevMap !$= "") - { - %mapName = getMapDisplayName( %device, %action ); - %prevMapIndex = findRemapCmdIndex( %prevMap ); - if (%prevMapIndex == -1) - { - // The OK dialog has probably popped up now, so turn it off. We've got the situation - // under control. - if (MessageBoxOKDlg.isAwake()) - Canvas.popDialog(MessageBoxOKDlg); - - MessageBoxYesNo( "FIXREMAP WARNING", - "\"" @ %mapName @ "\" is bound to the function \"" @ %prevMap @ "\"! The function may exist in a user script. See FixRemap.txt in your T2 autoexec dir for more details. Do you still want to undo this mapping?", - "redoBrokenMapping(" @ %actionMap @ ", " @ %device @ ", \"" @ %action @ "\", \"" @ %cmd @ "\", " @ %this.index @ ");", "" ); - } - } - } -} - -}; - -activatePackage(FixRemapLoad); +// #autoload +// #name = Fix Remap +// #version = 1.0 +// #category = Fix +// #warrior = WegBert +// #status = beta + +function redoBrokenMapping( %actionMap, %device, %action, %cmd, %newIndex ) +{ + %actionMap.bind( %device, %action, %cmd ); + //OP_RemapList.setRowById( %oldIndex, buildFullMapString( %oldIndex ) ); + OP_RemapList.setRowById( %newIndex, buildFullMapString( %newIndex ) ); +} + +package FixRemapLoad { + +function RemapInputCtrl::onInputEvent( %this, %device, %action ) +{ + Parent::onInputEvent( %this, %device, %action ); + + // prevMapIndex would equal -1 under the following circumstances: + // + // 1. User installed a third-party script which added a remap entry to the list. + // The user removed that script and is trying to rebind a key that was + // previously bound to that script. With the remap entry missing, the system + // fails, because the function bound to the key has no $RemapCmd. + // + // 2. User installed a third-party script which did not add a remap entry to the + // list, but instead replaced an existing command with a third-party one + // (for example, the HappyThrow script upon being run for the first time + // rebinds the user's grenade key from the default function, throwGrenade, to + // throwGrenadeNew). The script may still be installed, but the user is trying + // to rebind the key bound to the third-party function. This third-party function, + // although perfectly valid and existing, has no $RemapCmd. + // + // To counter these problems, the script will warn the user that the function may or + // may not exist. It will allow the user to choose whether they still want to rebind + // the key or not. If they do, the script will proceed with the remapping that the + // original fon complained about. + + if (%this.mode !$= "consoleKey") + { + switch$ ( OP_ControlsPane.group ) + { + case "Observer": + %actionMap = observerMap; + %cmd = $ObsRemapCmd[%this.index]; + + default: + %actionMap = moveMap; + %cmd = $RemapCmd[%this.index]; + } + + %prevMap = %actionMap.getCommand( %device, %action ); + if (%prevMap !$= %cmd && %prevMap !$= "") + { + %mapName = getMapDisplayName( %device, %action ); + %prevMapIndex = findRemapCmdIndex( %prevMap ); + if (%prevMapIndex == -1) + { + // The OK dialog has probably popped up now, so turn it off. We've got the situation + // under control. + if (MessageBoxOKDlg.isAwake()) + Canvas.popDialog(MessageBoxOKDlg); + + MessageBoxYesNo( "FIXREMAP WARNING", + "\"" @ %mapName @ "\" is bound to the function \"" @ %prevMap @ "\"! The function may exist in a user script. See FixRemap.txt in your T2 autoexec dir for more details. Do you still want to undo this mapping?", + "redoBrokenMapping(" @ %actionMap @ ", " @ %device @ ", \"" @ %action @ "\", \"" @ %cmd @ "\", " @ %this.index @ ");", "" ); + } + } + } +} + +}; + +activatePackage(FixRemapLoad); diff --git a/scripts/autoexec/GUIMLWorkaround.cs b/scripts/autoexec/GUIMLWorkaround.cs index 913e79b..444fdce 100644 --- a/scripts/autoexec/GUIMLWorkaround.cs +++ b/scripts/autoexec/GUIMLWorkaround.cs @@ -1,30 +1,42 @@ -// #autoload -// #name = GUIML Workaround -// #version = 2.0 -// #date = March 1st, 2010 -// #category = Fix -// #author = Dark Dragon DX -// #warrior = DarkDragonDX -// #email = DarkDragonDX@Hotmail.com -// #description = Adds a failSafe for the tag. Mainly for players that use mods with interactive GUIML elements. - -package GUIMLPackage -{ - function toggleEditor(%make) - { - parent::toggleEditor(%make); //Call parent function - if (!isActivePackage(GUIMLWorkaround)) - activatePackage(GUIMLWorkaround); - } -}; -activatePackage(GUIMLPackage); - -//Seperate package to activate our new code -package GUIMLWorkaround -{ - function GuiMLTextCtrl::onURL(%this, %url) - { - //parent::onURL(%this, %url); - commandToServer('ProcessGameLink',getField(%url,1)); - } -}; +// #autoload +// #name = GUIML Workaround +// #version = 3.0 +// #date = November 22nd, 2012 +// #category = Fix +// #author = Robert MacGregor +// #warrior = DarkDragonDX +// #email = DarkDragonDX@Hotmail.com +// #description = Repairs broken functionality with certain GUIML elements after the T2 mission editor has been initialised. And in some cases, where they misbehave for no known reason. + +// Separate Package just to ensure the code is "injected" at the right time +package GUIMLInjection +{ + // Takes care of opening the F2 menu on certain server/client combinations not working properly + function ScoreScreen::onWake(%this) + { + parent::onWake(%this); + if (!isActivePackage(GUIMLWorkaround)) + activatePackage(GUIMLWorkaround); + } + + // Takes care of if we just launch the editor but never use the F2 menu; clicking a link in say a server desc + function toggleEditor(%make) + { + parent::toggleEditor(%make); + if (!isActivePackage(GUIMLWorkaround)) + activatePackage(GUIMLWorkaround); + } +}; +activatePackage(GUIMLInjection); + +//Seperate package to activate our new code +package GUIMLWorkaround +{ + function GuiMLTextCtrl::onURL(%this, %url) + { + if (getField(%url,0) $= "wwwlink") + parent::onURL(%this, getField(%url, 1)); // Opens a web browser window as it should + else + commandToServer('ProcessGameLink',getField(%url, 1), getField(%url, 2), getField(%url, 3), getField(%url, 4), getField(%url, 5)); + } +}; \ No newline at end of file diff --git a/scripts/autoexec/TCmini-client.cs b/scripts/autoexec/TCmini-client.cs index e3bf763..6a4acb7 100644 --- a/scripts/autoexec/TCmini-client.cs +++ b/scripts/autoexec/TCmini-client.cs @@ -1,1052 +1,1107 @@ -// Standard Construction Bologna -// Missing all sorts of things, will probably need updated later on. -$MiniClV = "S4e5"; -// Construction -package tcKeyBinding { -function OptionsDlg::onWake( %this ) { -if(!$tcKeyBinding) { -$RemapName[$RemapCount] = "[C]:Select LS Beam"; -$RemapCmd[$RemapCount] = "quickPackLightSupportBeam"; -$RemapCount++; -$RemapName[$RemapCount] = "[C]:Select Walkway"; -$RemapCmd[$RemapCount] = "quickPackLightWalkway"; -$RemapCount++; -$RemapName[$RemapCount] = "[C]:Select MS Beam"; -$RemapCmd[$RemapCount] = "quickPackMediumSupportBeam"; -$RemapCount++; -$RemapName[$RemapCount] = "[C]:Select Floor"; -$RemapCmd[$RemapCount] = "quickPackMediumFloor"; -$RemapCount++; -$RemapName[$RemapCount] = "[C]:Pack Setting: Fwd"; -$RemapCmd[$RemapCount] = "cyclePackFwd"; -$RemapCount++; -$RemapName[$RemapCount] = "[C]:Pack Setting: Back"; -$RemapCmd[$RemapCount] = "cyclePackBack"; -$RemapCount++; -$RemapName[$RemapCount] = "[C]:Pack Setting: FFwd"; -$RemapCmd[$RemapCount] = "cyclePackFFwd"; -$RemapCount++; -$RemapName[$RemapCount] = "[C]:Pack Setting: FBack"; -$RemapCmd[$RemapCount] = "cyclePackFBack"; -$RemapCount++; -$RemapName[$RemapCount] = "[C]:Emote: Sit Down"; -$RemapCmd[$RemapCount] = "emoteSitDown"; -$RemapCount++; -$RemapName[$RemapCount] = "[C]:Emote: Squat"; -$RemapCmd[$RemapCount] = "emoteSquat"; -$RemapCount++; -$RemapName[$RemapCount] = "[C]:Emote: Jig"; -$RemapCmd[$RemapCount] = "emoteJig"; -$RemapCount++; -$RemapName[$RemapCount] = "[C]:Emote: Lie Down"; -$RemapCmd[$RemapCount] = "emoteLieDown"; -$RemapCount++; -$RemapName[$RemapCount] = "[C]:Emote: Heart Attack"; -$RemapCmd[$RemapCount] = "emoteHeartAttack"; -$RemapCount++; -$RemapName[$RemapCount] = "[C]:Emote: Sucker Punch"; -$RemapCmd[$RemapCount] = "emoteSuckerPunched"; -$RemapCount++; -$RemapName[$RemapCount] = "[#]:Hover"; -$RemapCmd[$RemapCount] = "ToggleHoverPack"; -$RemapCount++; -//Metallic -$RemapName[$RemapCount] = "[M]:Buy Favs"; -$RemapCmd[$RemapCount] = "MetallicBuyFavs"; -$RemapCount++; -$RemapName[$RemapCount] = "[M]:Move Down"; -$RemapCmd[$RemapCount] = "MetallicMoveDown"; -$RemapCount++; -$RemapName[$RemapCount] = "[M]:GetSize"; -$RemapCmd[$RemapCount] = "MetallicGetSize"; -$RemapCount++; -$RemapName[$RemapCount] = "[M]:Copy last setsize"; -$RemapCmd[$RemapCount] = "Metallicsizecopy"; -$RemapCount++; -$RemapName[$RemapCount] = "[M]:Setsize original"; -$RemapCmd[$RemapCount] = "Metallicsizeoriginal"; -$RemapCount++; -$RemapName[$RemapCount] = "[M]:Setsize undo"; -$RemapCmd[$RemapCount] = "Metallicsizeundo"; -$RemapCount++; -$RemapName[$RemapCount] = "[M]:Undo"; -$RemapCmd[$RemapCount] = "Metallicundo"; -$RemapCount++; -$quickPackExtrasBind = true; -$tcKeyBinding = true; -} -//End metallic -// End Construction -parent::onWake(%this); -} -function doScreenShot(%val) -{ -%temp = panoramaGui.beaconsVisible; -panoramaGui.beaconsVisible = false; -if(!%val) { -if(!$pref::showHudOnShots) -HideHudHACK(0); -%suffix = formatTimeString(".M-d-y.hhnnss"); -screenShot("screen" @ %suffix @ ".png"); -HideHudHACK(1); -} -panoramaGui.beaconsVisible = %temp; -} -function MessageVector::pushBackLine(%this, %text, %tag) -{ -%line = (%params = strlwr(%text)); -while (%line !$= "") { -%params = nextToken(%params,line,"<"); - - // This tag is probably unrelated to the exploit -- just skip it - if ((strstr(%line,"t2server") == -1) && (strstr(%line,"tribe") == -1)) continue; - // Possible exploit -- we don't need no stinkin' < > - else if (((%pos = strstr(%line,">")) == -1) || (((getSubStr(%line,0,8) $= "t2server") && (getSubStr(%params,0,10) !$= "/t2server>")) || ((getSubStr(%line,0,5) $= "tribe") && (getSubStr(%params,0,7) !$= "/tribe>"))) || (strlen(%line) > %pos-1 && strstr(getSubstr(%line,%pos+1,strlen(%line)-%pos-1),">") != -1)) %text = stripChars(%text,"<>"); - } - - parent::pushBackLine(%this, %text, %tag); - } - function MessageHud_Edit::eval(%this) - { - %this.setValue(collapseEscape(%this.getValue())); - parent::eval(%this); - } - function GuiMessageVectorCtrl::onAdd(%this) - { - %this.allowedMatches[0] = "http"; - } - function LobbyMessageVector::urlClickCallback(%this, %url) - { - MessageBoxOK( "Link Clicked", "Ctrl+V has been set to:\n"@%url ); - setClipboard(%url); - //gotoWebpage(%url); - return; - } -}; -activatePackage(tcKeyBinding); - -// Start client funcs -function quickPackLightSupportBeam(%val) { - if (%val) - addQuickPackFavorite("Light Support Beam", dep); -} - -function quickPackLightWalkway(%val) { - if (%val) - addQuickPackFavorite("Light Walkway", dep); -} - -function quickPackLightBlastWall(%val) { - if (%val) - addQuickPackFavorite("Light Blast Wall", dep); -} - -function quickPackMediumSupportBeam(%val) { - if (%val) - addQuickPackFavorite("Medium Support Beam", dep); -} - -function quickPackMediumFloor(%val) { - if (%val) - addQuickPackFavorite("Medium Floor", dep); -} - -function cyclePackFwd(%val) { - if (%val) - commandToServer('CyclePackSetting',1); -} - -function cyclePackBack(%val) { - if (%val) - commandToServer('CyclePackSetting',-1); -} - -function cyclePackFFwd(%val) { - if (%val) - commandToServer('CyclePackSetting',5); -} - -function cyclePackFBack(%val) { - if (%val) - commandToServer('CyclePackSetting',-5); -} - -function emoteSitDown(%val) { - if (%val) - commandToServer('Emote',"SitDown"); -} - -function emoteSquat(%val) { - if (%val) - commandToServer('Emote',"Squat"); -} - -function emoteJig(%val) { - if (%val) - commandToServer('Emote',"Jig"); -} - -function emoteLieDown(%val) { - if (%val) - commandToServer('Emote',"LieDown"); -} - -function emoteHeartAttack(%val) { - if (%val) - commandToServer('Emote',"HeartAttack"); -} - -function emoteSuckerPunched(%val) { - if (%val) - commandToServer('Emote',"SuckerPunched"); -} - -function MetallicBuyFavs(%val) { - if (%val) - commandToServer('Metallic',"BuyFavs"); -} - -function MetallicMoveDown(%val) { - if (%val) - commandToServer('Metallic',"movedown"); -} - -function MetallicGetSize(%val) { - if (%val) - commandToServer('Metallic',"GetSize"); -} - -function Metallicsizecopy(%val) { - if (%val) - commandToServer('Metallic',"sizecopy"); -} - -function Metallicsizeoriginal(%val) { - if (%val) - commandToServer('Metallic',"sizeoriginal"); -} - -function Metallicsizeundo(%val) { - if (%val) - commandToServer('Metallic',"sizeundo"); -} - -function Metallicundo(%val) { - if (%val) - commandToServer('Metallic',"undo"); -} -function ToggleHoverPack(%val) { - if (%val) - commandToServer('activateHoverPack'); -} -function clientCmdsetBlackOut(%fadeTOBlackBool, %timeMS){ - serverconnection.setBlackOut(%fadeTOBlackBool, %timeMS); -} -function runClientUpdateCheck(%version) { - %script = "/MCTC/"@%version@"/"; - %server = "direct.the-construct.net:80"; - if (!isObject(MCTCbite)) - %bite = new HTTPObject(MCTCbite){}; - else %bite = MCTCbite; - %bite.get(%server, %script); - return; -} -function MCTCbite::onLine(%this, %line) { - %eof = (strstr(firstWord(%line),"#EOF") != -1); - if (getword(%line,0) $= "#rgrrgr") {MCTCbite.disconnect(); return;} - if (isObject(MCTCfile) && MCTCfile.isOpen && !%eof) { - MCTCfile.writeLine(%line); - } else if (%eof) { - MCTCfile.close(); - MCTCfile.delete(); - MCTCbite.disconnect(); - MCTCfile.isOpen = ""; - exec($MCTCfile); - } else if (getword(%line,0) $= "#UPDATE") { - new fileObject("MCTCfile"); - $MCTCfile = findFirstFile("*TCmini-client.cs"); - if (!isFile($MCTCfile)) $MCTCfile = "scripts/autoexec/TCmini-client.cs"; - MCTCfile.openforWrite($MCTCfile); - MCTCfile.isOpen = 1; - - } else { - if(isObject(MCTCfile)){ - MCTCfile.close(); - MCTCfile.delete(); - MCTCfile.isOpen = ""; - } - } - -} - -// // Structural Infinity Client -// Version: Beta 0.9 TCMC -// Written by Electricutioner -// 5/24/2010 - -// Structural Infinity enabled clients are able to see over 1024 -// objects. Don't sweat the details, little monkey. - -// Technical Details: -// Server sends ghosts the clients over the conventional protocol, but the protocol indexes -// the ghosts using 10-bit values. This script sends remote procedure notifications whenever -// pieces are added, deleted, moved, resized, retextured, faded, and cloaked. -// -// On the client side, the script interprets the notifications and acts rationally to make -// use of them. - -// License: -// The SI client script is distributed under the terms of the Library General Public License v2 or later. -// The license is readable here: http://www.gnu.org/licenses/lgpl.html -// -// In a nutshell: any modifications you make and use to this file must be available under the same license. -// But, as long as you provide source code for this file, you may include it in an otherwise closed source mod. -// -// By editing this file, you agree to abide by the terms of the LGPL. - -$StructuralInfinity::Info::ClientVersion = 0.91; -$StructuralInfinity::AutoUpdate::UpdateFile = "client"; - -$StructuralInfinity::Notification::Transform = 1; -$StructuralInfinity::Notification::Scale = 2; -$StructuralInfinity::Notification::Datablock = 3; -$StructuralInfinity::Notification::Add = 4; -$StructuralInfinity::Notification::Delete = 5; -$StructuralInfinity::Notification::Fade = 6; -$StructuralInfinity::Notification::Cloak = 7; -$StructuralInfinity::Notification::Tag = 8; -$StructuralInfinity::Notification::Protect = 9; -$StructuralInfinity::Notification::Invoke = 10; - -$StructuralInfinity::Compression::HuffmanMinimization = "e arointlsducmfh"; -$StructuralInfinity::Compression::HuffmanDecodeOutput = "1234567890 .e-**"; - -// process a notification from the server on virtual ghosts -function clientCmdStructInfNotify(%obj, %type, %payload) -{ - if (!$StructuralInfinity::Status::Active) - return; - - %this = SI_locateObject(%obj); - if (%type < $StructuralInfinity::Notification::Tag) - %payload = SI_payloadDecompression(%payload); - //echo(%obj SPC %type SPC %payload); - - switch (%type) - { - case $StructuralInfinity::Notification::Transform: - if (!isObject(%this)) - return; - // remove it from old spatial index location... - SI_deleteObject(SI_positionHash(%this.getTransform()), %this); - - %this.setTransform(%payload); - - // add to new spatial index location... - // this can result in the deletion of %this - SI_insertToIndex(%this); - - if (isObject(%this) && isObject(%this.pzone)) - %this.pzone.setTransform(%payload); - case $StructuralInfinity::Notification::Scale: - if (!isObject(%this)) - return; - - %this.setScale(%payload); - if (isObject(%this.pzone)) - %this.pzone.setScale(%payload); - case $StructuralInfinity::Notification::Datablock: - if (!isObject(%this)) - return; - - // remove it from old spatial index location... - SI_deleteObject(SI_positionHash(%this.getTransform()), %this); - - %this.setDatablock(ServerConnection.getObject(%payload + 1)); - - // readd to spatial index location, since datablock is used as check param - SI_insertToIndex(%this); - case $StructuralInfinity::Notification::Add: - if (isObject(%this)) // don't reconstruct - return; - - %trans = getWords(%payload, 0, 6); - %scale = getWords(%payload, 7, 9); - %datablock = ServerConnection.getObject(getWord(%payload, 10) + 1); - - if (!isObject(%datablock)) - return; - - %type = getSubStr(%datablock.getClassName(), 0, strLen(%datablock.getClassName()) - 4); - - %this = new (%type)() - { - datablock = %datablock; - scale = %scale; - serverPointer = %obj; - }; - %this.setTransform(%trans); - SIPieces.add(%this); - - SI_insertToIndex(%this); // do spatial index processing, which can result in a deletion - - if (isObject(%this)) - $StructuralInfinity::ClientIndexMap[%obj] = %this; - case $StructuralInfinity::Notification::Delete: - if (!isObject(%this)) - return; - - if (isObject(%this.pzone)) - %this.pzone.delete(); - %this.delete(); - case $StructuralInfinity::Notification::Fade: - if (!isObject(%this)) - return; - - %this.startFade(getWord(%payload, 1), getWord(%payload, 0), getWord(%payload, 2)); - case $StructuralInfinity::Notification::Cloak: - if (!isObject(%this)) - return; - - %this.setCloaked(%payload); - - // remove it from old spatial index location... - SI_deleteObject(SI_positionHash(%this.getTransform()), %this); - // readd to spatial index location, since cloaking is used as check param - SI_insertToIndex(%this); - case $StructuralInfinity::Notification::Tag: - if (!isObject(%this)) - return; - - %this.tagLabel = %payload; // set the tag for processing by the display loop - case $StructuralInfinity::Notification::Protect: - if (!isObject(%this)) - return; - if (getWord(%payload, 0)) - %this.isProtected = 1; - else - %this.isProtected = 0; - case $StructuralInfinity::Notification::Invoke: - // this operation can be slightly dangerous, so all of the input data is sanitized. - // so long as the server only sends numbers and strings, this shouldn't be - // usable to exploit anything; filtering is applied so this is always the case - if (!isObject(%this)) - return; - - %tokenCount = SI_getTokenCount(%payload, "\n"); - if (%tokenCount <= 0) - return; - %build = %this @ "."; - %method = SI_sanitizeToken(SI_getToken(%payload, 0, "\n")); - if (%method !$= "") - %build = %build @ %method @ "("; - else - return; // security violation - - for (%i = 1; %i < %tokenCount; %i++) - { - %token = SI_getToken(%payload, %i, "\n"); - %argument = SI_sanitizeToken(%token); - if (%argument $= "") - return; // security violation - %build = %build @ %argument; - if (%i + 1 < %tokenCount) - %build = %build @ ", "; - } - %build = %build @ ");"; - //error("SI Invoke: " @ %build); - eval(%build); - } -} - -function SI_sanitizeToken(%token) -{ - %token = trim(%token); - if (getSubStr(%token, 0, 1) $= "_") - { - // strings are prefixed with underscore for RPC - return "\"" @ expandEscape(getSubStr(%token, 1, strlen(%token))) @ "\""; - } - else if (getSubStr(%token, 0, 1) $= "*") - { - // function names are prefixed with the star for RPC - %len = strlen(%token); - %token = strlwr(%token); - for (%i = 1; %i < %len; %i++) - { - %char = strcmp(getSubStr(%token, %i, 1), ""); - if ((%char >= 48 && %char <= 57) || (%char >= 97 && %char <= 122) || %char == 95) - %output = %output @ %char; - else - return ""; - } - return getSubStr(%token, 1, strlen(%token)); - } - else - { - // numerical value - %len = strlen(%token); - for (%i = 0; %i < %len; %i++) - { - %char = strcmp(getSubStr(%token, %i, 1), ""); - if ((%char >= 48 && %char <= 57) || %char == 46) - %output = %output @ %char; - else - return ""; - } - return %token; - } -} - -function SI_getToken(%string, %index, %seper) -{ - for (%i = 0; %i <= %index; %i++) - { - if (strStr(%string, %seper) != -1) - { - %word = getSubStr(%string, 0, strStr(%string, %seper)); - %string = getSubStr(%string, strStr(%string, %seper) + strLen(%seper), strLen(%string)); - } - else - %word = %string; - } - return %word; -} -function SI_getTokenCount(%string, %seper) -{ - %count = 1; - while (strStr(%string, %seper) != -1) - { - %string = getSubStr(%string, strStr(%string, %seper) + strLen(%seper), strLen(%string)); - %count++; - } - return %count; -} - -// server uses this to announce its version number, so we know what extensions to support -function clientCmdStructInfVersionAnnounce(%version, %friendlyTagColor) -{ - %version = getWord(%version, 0); - if (%version >= 0.5) // payload compression added in server 0.5 - $StructuralInfinity::Status::PayloadCompression = 1; - - // get the allied team IFF color from the server - $StructuralInfinity::HealthTeam = %friendlyTagColor; - SI_initHealthUI(); // build the health UI -} - -// payload decompression support -function SI_payloadDecompression(%input) -{ - if (!$StructuralInfinity::Status::PayloadCompression) // server hasn't signaled compression support - return %input; - - if (!$StructuralInfinity::Status::GeneratedHuffmanConv) - { - for (%i = 0; %i < strLen($StructuralInfinity::Compression::HuffmanMinimization); %i++) - { - $StructuralInfinity::Huffman::DecodeTable[strCmp(getSubStr($StructuralInfinity::Compression::HuffmanMinimization, %i, 1), "")] = getSubStr($StructuralInfinity::Compression::HuffmanDecodeOutput, %i, 1); - } - $StructuralInfinity::Status::GeneratedHuffmanConv = 1; - } - - %len = strLen(%input); - for (%i = 0; %i < %len; %i++) - { - %output = %output @ $StructuralInfinity::Huffman::DecodeTable[strCmp(getSubStr(%input, %i, 1), "")]; - } - return %output; -} - -function SI_clientInit() -{ - if ($StructuralInfinity::Status::Active) - return; - if (isEventPending($StructuralInfinity::InitSched)) - cancel($StructuralInfinity::InitSched); - - // check for the relevant hacked executable - if (isObject(ServerConnection) && ServerConnection.getCount() > 0) - { - if (!isObject(ServerConnection.getObject(0))) - { - error("Structural Infinity requires the latest TribesNext patch. You don't have it. Bye."); - commandToServer('StructuralInfinityClient', -1 * $StructuralInfinity::Info::ClientVersion); - return; - } - else - { - $StructuralInfinity::Status::Active = 1; - if (isObject(SIPieces)) - { - while (SIPieces.getCount() > 0) - { - SIPieces.getObject(0).delete(); - } - SIPieces.delete(); - } - SI_initPseudoTagUI(); // create the tag UI - SI_tagCast(); // start the tag search loop - - commandToServer('StructuralInfinityClient', $StructuralInfinity::Info::ClientVersion); - new SimGroup(SIPieces); - schedule(300, 0, commandToServer, 'StructuralInfinityInit'); - } - } - else // looks like the client hasn't joined... check again in a few seconds - { - $StructuralInfinity::InitSched = schedule(3000, 0, SI_clientInit); - } -} -function SI_doMemUnPatch() -{ - if (!$StructuralInfinity::Status::MemPatched) - return; - - memPatch("58B26D", "3c8a"); - memPatch("4376B7", "7501"); - memPatch("43745D", "7501"); - memPatch("42E938", "7501"); - memPatch("5E2EEC", "751c"); - memPatch("602AF3", "7407"); - memPatch("58C24C", "7414"); - memPatch("6B40D0", "741F"); - memPatch("5E34B6", "8b414083e00274126888dc7900e8282be4ff31c05989ec5dc390"); - - $StructuralInfinity::Status::MemPatched = ""; -} -function SI_doMemPatch() -{ - if ($StructuralInfinity::Status::MemPatched) - return; - - memPatch("58B26D", "cc9c"); - memPatch("4376B7", "9090"); - memPatch("43745D", "9090"); - memPatch("42E938", "9090"); - memPatch("5E2EEC", "9090"); - memPatch("602AF3", "9090"); - memPatch("58C24C", "9090"); - memPatch("6B40D0", "9090"); - memPatch("5E34B6", "9090909090909090909090909090909090909090909090909090"); - - $StructuralInfinity::Status::MemPatched = 1; -} - -// allows servers with SI to activate SI on the client -function clientCmdStructInfClientInit() -{ - SI_clientInit(); -} - -// returns virtual ghost pointer for the corresponding server pointer object -function SI_locateObject(%serverPointer) -{ - return $StructuralInfinity::ClientIndexMap[%serverPointer]; -} - -// inserts an object into the haystack -// if this object is a ghost, any virtual-ghost matching it will be deleted -// if this object is a virtual-ghost and a ghost matching it exists, this object is deleted -// otherwise, it is inserted into the haystack -function SI_insertToIndex(%obj) -{ - if (!isObject(%obj)) - return; - %transform = %obj.getTransform(); - %scale = %obj.getScale(); - %datablock = %obj.getDatablock(); - %cloaked = %obj.isCloaked(); - %hash = SI_positionHash(%transform); - - // see if something matches it - %match = SI_findObject(%transform, %scale, %datablock, %cloaked); - if (%match != -1) - { - if (%match.isClientGhost()) - { - // verify virtual ghost, then delete, leaving existing ghost intact - // verify it is not protected before deleting too - if (!%obj.isClientGhost() && !%obj.isProtected) - { - if (isObject(%obj.pzone)) - %obj.pzone.delete(); - %obj.delete(); - return; - } - } - else - { - if (%obj.isClientGhost()) // existing virtual-ghost, but this is real ghost - { - if (!%match.isProtected) // if not protected - { - %match.delete(); // delete virtual-ghost - if (isObject(%match.pzone)) - %match.pzone.delete(); - } - } - } - } - - %candidates = $StructuralInfinity::SpatialHashMap[%hash]; - %count = getWordCount(%candidates); - for (%i = 0; %i < %count; %i++) - { - if (%candidates == %obj) - %found = 1; - } - if (!%found) - $StructuralInfinity::SpatialHashMap[%hash] = trim(%candidates SPC %obj); -} - -// locates an object from transformation, scale, and datablock -- the essential data -// does so without an exhaustive search of all objects -function SI_findObject(%transform, %scale, %datablock, %cloak) -{ - %hash = SI_positionHash(%transform); - // search for an object with the given hash - %candidates = $StructuralInfinity::SpatialHashMap[%hash]; - %count = getWordCount(%candidates); - for (%i = 0; %i < %count; %i++) - { - %obj = getWord(%candidates, %i); - if (!isObject(%obj)) - { - %candidates = removeWord(%candidates, %i); - $StructuralInfinity::SpatialHashMap[%hash] = %candidates; - %i--; - %count--; - } - else - { - if (SI_isMatch(%obj, %transform, %scale, %datablock, %cloak)) - return %obj; - } - } - return -1; -} - -// deletes a given object with the given hash value -function SI_deleteObject(%hash, %obj) -{ - %candidates = $StructuralInfinity::SpatialHashMap[%hash]; - %count = getWordCount(%candidates); - for (%i = 0; %i < %count; %i++) - { - if (getWord(%candidates, %i) == %obj) - { - %candidates = removeWord(%candidates, %i); - $StructuralInfinity::SpatialHashMap[%hash] = %candidates; - %i--; - %count--; - } - } -} - -// is the needle the same as the pin from the haystack? -function SI_isMatch(%pin, %trans, %scale, %db, %cloak) -{ - if (%pin.getDatablock() != %db) //db is fastest to check - return 0; - else if (VectorDist(%pin.getPosition(), getWords(%trans, 0, 2)) > 0.05) // verify this isn't a position hash collision - return 0; - else if (VectorDist(%pin.getScale(), %scale) > 0.05) // check scale - return 0; - else if (VectorDist(VectorScale(getWords(%pin.getTransform(), 3, 5), getWord(%pin.getTransform(), 6)), VectorScale(getWords(%trans, 3, 5), getWord(%trans, 6))) > 0.05) - return 0; - else if (%pin.isCloaked() ^ %cloak) // check if both pieces are cloaked/uncloaked - return 0; - else - return 1; // match -} - -// produces an epsilon variation resistant spatial hash for the given position -// used for rapid lookup of ghost/virtual ghost presence -function SI_positionHash(%position) -{ - %hash = 0; - for (%i = 0; %i < 3; %i++) - { - %hash ^= (mFloor((getWord(%position, %i) * 10) + 0.5) << (8 * %i)); - } - return %hash; -} - -// this transforms color characters into color tags. the \c0 to \c5 flags were all producing -// the same white color. This function uses the \c0 to \c4 tags for a few new colors. -// color tags: -// \c0 (red) -// \c1 (orange) -// \c2 (green) -// \c3 (blue) -// \c4 (violet) -// \c5 (white) -- original color -// \c6 (light gray) -- original color -// \c7 (yellow) -- original color -// \c8 (periwinkle blue) -- original color -// \c9 (verdant cyan) -- original color -function SI_printableTag(%tag) -{ - %tag = "\c5" @ %tag; // c5 is the default white color - %output = strReplace(%tag, "\c0", ""); - %output = strReplace(%output, "\c1", ""); - %output = strReplace(%output, "\c2", ""); - %output = strReplace(%output, "\c3", ""); - %output = strReplace(%output, "\c4", ""); - %output = strReplace(%output, "\c5", ""); - %output = strReplace(%output, "\c6", ""); - %output = strReplace(%output, "\c7", ""); - %output = strReplace(%output, "\c8", ""); - return strReplace(%output, "\c9", ""); -} - -// do a raycast to see what object we are looking at... -// display it as a pseudo tag if it is labeled -function SI_tagCast() -{ - if (!$StructuralInfinity::Status::Active) - return; - - %source = ServerConnection.getControlObject(); - if (isObject(%source)) - { - %pos = getWords(%source.getEyeTransform(), 0, 2); - if (%pos $= "") // object exists, but position extraction failed -- kill SI, was started erroneously - { - $StructuralInfinity::Status::Active = 0; - return; - } - %targetpos = vectorAdd(%pos, vectorScale(%source.getEyeVector(), 500)); - - %cast = containerRaycast(%pos, %targetpos, $TypeMasks::StaticShapeObjectType, %source); - %obj = getWord(%cast, 0); - if (isObject(%obj)) - { - if (%obj.tagLabel !$= "") - { - //clientCmdCenterPrint("" @ SI_PrintableTag(%obj.tagLabel), 1, 1); - $StructuralInfinity::TagUI.setText("" @ SI_PrintableTag(%obj.tagLabel)); - - // health - SI_setHealthPercentage(1 - %obj.getDamagePercent()); - SI_sethealthVisibility(true); - } - else - { - $StructuralInfinity::TagUI.setText(""); - SI_sethealthVisibility(false); - } - } - else - { - $StructuralInfinity::TagUI.setText(""); - SI_sethealthVisibility(false); - } - } - schedule(128, 0, SI_tagCast); -} - -// build the pseudo tag display UI and position it over the same location as regular tags -function SI_initPseudoTagUI() -{ - if (isObject($StructuralInfinity::TagUI)) - { - $StructuralInfinity::TagUI.delete(); - } - - %extent = PlayGui.getExtent(); - - $StructuralInfinity::TagUI = new GuiMLTextCtrl() - { - allowColorChars = 0; - bypassHideCursor = 0; - deniedSound = "InputDeniedSound"; - extent = (getWord(%extent, 0) / 2) SPC "14"; - helpTag = "0"; - hideCursor = "0"; - }; - PlayGui.add($StructuralInfinity::TagUI); - $StructuralInfinity::TagUI.setVisible(true); - $StructuralInfinity::TagUI.setPosition((getWord(%extent, 0) / 2) + 24, (getWord(%extent, 1) / 2) + 24); -} - -function SI_initHealthUI() -{ - %extent = PlayGUI.getExtent(); - - if (isObject($StructuralInfinity::HealthUI)) - $StructuralInfinity::HealthUI.delete(); - if ($StructuralInfinity::HealthTeam $= "") - return; // no health UI on older servers - $StructuralInfinity::HealthUI = new HudBitmapCtrl() - { - extent = "48 10"; - fillColor = $StructuralInfinity::HealthTeam; - frameColor = $StructuralInfinity::HealthTeam; - opacity = 0.55; - }; - PlayGUI.add($StructuralInfinity::HealthUI); - $StructuralInfinity::HealthUI.setVisible(true); - - $StructuralInfinity::HealthUI.setPosition((getWord(%extent, 0) / 2) + 25, (getWord(%extent, 1) / 2) + 41); - - // frame ugliness - if (isObject($StructuralInfinity::HealthUIFrameTop)) - $StructuralInfinity::HealthUIFrameTop.delete(); - $StructuralInfinity::HealthUIFrameTop = new HudBitmapCtrl() - { - fillColor = "0 0 0 0"; - frameColor = "1 1 1 0"; - opacity = 0.55 / 2; - }; - PlayGUI.add($StructuralInfinity::HealthUIFrameTop); - $StructuralInfinity::HealthUIFrameTop.setVisible(true); - $StructuralInfinity::HealthUIFrameTop.setPosition((getWord(%extent, 0) / 2) + 24, (getWord(%extent, 1) / 2) + 40); - $StructuralInfinity::HealthUIFrameTop.extent = "50 1"; - - if (isObject($StructuralInfinity::HealthUIFrameBottom)) - $StructuralInfinity::HealthUIFrameBottom.delete(); - $StructuralInfinity::HealthUIFrameBottom = new HudBitmapCtrl() - { - fillColor = "0 0 0 0"; - frameColor = "1 1 1 0"; - opacity = 0.55 / 2; - }; - PlayGUI.add($StructuralInfinity::HealthUIFrameBottom); - $StructuralInfinity::HealthUIFrameBottom.setVisible(true); - $StructuralInfinity::HealthUIFrameBottom.setPosition((getWord(%extent, 0) / 2) + 24, (getWord(%extent, 1) / 2) + 51); - $StructuralInfinity::HealthUIFrameBottom.extent = "50 1"; - - if (isObject($StructuralInfinity::HealthUIFrameLeft)) - $StructuralInfinity::HealthUIFrameLeft.delete(); - $StructuralInfinity::HealthUIFrameLeft = new HudBitmapCtrl() - { - fillColor = "0 0 0 0"; - frameColor = "1 1 1 0"; - opacity = 0.55 / 2; - }; - PlayGUI.add($StructuralInfinity::HealthUIFrameLeft); - $StructuralInfinity::HealthUIFrameLeft.setVisible(true); - $StructuralInfinity::HealthUIFrameLeft.setPosition((getWord(%extent, 0) / 2) + 24, (getWord(%extent, 1) / 2) + 40); - $StructuralInfinity::HealthUIFrameLeft.extent = "1 12"; - - if (isObject($StructuralInfinity::HealthUIFrameRight)) - $StructuralInfinity::HealthUIFrameRight.delete(); - $StructuralInfinity::HealthUIFrameRight = new HudBitmapCtrl() - { - fillColor = "0 0 0 0"; - frameColor = "1 1 1 0"; - opacity = 0.55 / 2; - }; - PlayGUI.add($StructuralInfinity::HealthUIFrameRight); - $StructuralInfinity::HealthUIFrameRight.setVisible(true); - $StructuralInfinity::HealthUIFrameRight.setPosition((getWord(%extent, 0) / 2) + 73, (getWord(%extent, 1) / 2) + 40); - $StructuralInfinity::HealthUIFrameRight.extent = "1 12"; -} - -function SI_sethealthVisibility(%bool) -{ - if (isObject($StructuralInfinity::HealthUI)) - { - $StructuralInfinity::HealthUI.setVisible(%bool); - $StructuralInfinity::HealthUIFrameTop.setVisible(%bool); - $StructuralInfinity::HealthUIFrameBottom.setVisible(%bool); - $StructuralInfinity::HealthUIFrameLeft.setVisible(%bool); - $StructuralInfinity::HealthUIFrameRight.setVisible(%bool); - } -} - -function SI_setHealthPercentage(%percent) -{ - if (isObject($StructuralInfinity::HealthUI)) - $StructuralInfinity::HealthUI.extent = mFloor(%percent * 48) SPC 10; -} - -package StructuralInfinityClient -{ - // cleanup any client virtual ghosts when leaving a server - // not doing this results in UE with very high probability - function CreateServer(%mission, %missionType) { - if (isActivePackage(StructuralInfinityClient)) { - SI_doMemUnPatch(); - deactivatePackage(StructuralInfinityClient); - } - parent::CreateServer(%mission, %missionType); - if (!isActivePackage(t2csri_server)) exec("t2csri/serverGlue.cs"); - } - function clientCmdMissionEnd(%seq) - { - if (isObject(SIPieces)) - { - while (SIPieces.getCount() > 0) - { - SIPieces.getObject(0).delete(); - } - } - Parent::clientCmdMissionEnd(%seq); - } - function DisconnectedCleanup() - { - if (isObject(SIPieces)) - { - while (SIPieces.getCount() > 0) - { - SIPieces.getObject(0).delete(); - } - SIPieces.delete(); - } - deleteVariables("$StructuralInfinity::SpatialHashMap*"); - deleteVariables("$StructuralInfinity::ClientIndexMap*"); - $StructuralInfinity::Status::Active = 0; - $StructuralInfinity::Status::PayloadCompression = 0; - - // call parent AFTER cleanup up SI - Parent::DisconnectedCleanup(); - } - - // linker only implemented isClientGhost for static shapes, and even then only in some executables. - // these used to check for group presence, but that didn't seem super reliable. - // it attempts a variable access right now which should fail on ghosts - function StaticShape::isClientGhost(%obj) - { - return (%obj.position $= ""); - //return (%obj.getGroup() == ServerConnection.getID()); - } - function ForceFieldBare::isClientGhost(%obj) - { - return (%obj.position $= ""); - //return (%obj.getGroup() == ServerConnection.getID()); - } - function Item::isClientGhost(%obj) - { - return (%obj.position $= ""); - //return (%obj.getGroup() == ServerConnection.getID()); - } - - // forcefields are never cloaked... this stops some console spam - function ForceFieldBare::isCloaked(%obj) - { - return 0; - } - - // process a notification from the server on server generated ghosts - // moved to this package to address the missing tag bug if loaded in server mode - function GameBaseData::onAdd(%data, %obj) - { - if (%obj.isClientGhost()) - { - //echo(%obj.getTransform() SPC %obj.getScale() SPC %obj.getDatablock()); - SI_insertToIndex(%obj); // do spatial index processing - } - } -}; -if ($Game::argv1 !$= "-dedicated" && !isObject(ServerGroup) && !isActivePackage(StructuralInfinityClient)) -{ - activatePackage(StructuralInfinityClient); - SI_doMemPatch(); // patch memory - runClientUpdateCheck($MiniClV); -} - - -echo("#EOF"); +// Standard Construction Bologna +// Missing all sorts of things, will probably need updated later on. +$MiniClV = "S5"; +// Construction +package tcKeyBinding { + function OptionsDlg::onWake( %this ) { + if(!$tcKeyBinding) { + $RemapName[$RemapCount] = "[C]:Select LS Beam"; + $RemapCmd[$RemapCount] = "quickPackLightSupportBeam"; + $RemapCount++; + $RemapName[$RemapCount] = "[C]:Select Walkway"; + $RemapCmd[$RemapCount] = "quickPackLightWalkway"; + $RemapCount++; + $RemapName[$RemapCount] = "[C]:Select MS Beam"; + $RemapCmd[$RemapCount] = "quickPackMediumSupportBeam"; + $RemapCount++; + $RemapName[$RemapCount] = "[C]:Select Floor"; + $RemapCmd[$RemapCount] = "quickPackMediumFloor"; + $RemapCount++; + $RemapName[$RemapCount] = "[C]:Pack Setting: Fwd"; + $RemapCmd[$RemapCount] = "cyclePackFwd"; + $RemapCount++; + $RemapName[$RemapCount] = "[C]:Pack Setting: Back"; + $RemapCmd[$RemapCount] = "cyclePackBack"; + $RemapCount++; + $RemapName[$RemapCount] = "[C]:Pack Setting: FFwd"; + $RemapCmd[$RemapCount] = "cyclePackFFwd"; + $RemapCount++; + $RemapName[$RemapCount] = "[C]:Pack Setting: FBack"; + $RemapCmd[$RemapCount] = "cyclePackFBack"; + $RemapCount++; + $RemapName[$RemapCount] = "[C]:Emote: Sit Down"; + $RemapCmd[$RemapCount] = "emoteSitDown"; + $RemapCount++; + $RemapName[$RemapCount] = "[C]:Emote: Squat"; + $RemapCmd[$RemapCount] = "emoteSquat"; + $RemapCount++; + $RemapName[$RemapCount] = "[C]:Emote: Jig"; + $RemapCmd[$RemapCount] = "emoteJig"; + $RemapCount++; + $RemapName[$RemapCount] = "[C]:Emote: Lie Down"; + $RemapCmd[$RemapCount] = "emoteLieDown"; + $RemapCount++; + $RemapName[$RemapCount] = "[C]:Emote: Heart Attack"; + $RemapCmd[$RemapCount] = "emoteHeartAttack"; + $RemapCount++; + $RemapName[$RemapCount] = "[C]:Emote: Sucker Punch"; + $RemapCmd[$RemapCount] = "emoteSuckerPunched"; + $RemapCount++; + $RemapName[$RemapCount] = "[#]:Hover"; + $RemapCmd[$RemapCount] = "ToggleHoverPack"; + $RemapCount++; + //Metallic + $RemapName[$RemapCount] = "[M]:Buy Favs"; + $RemapCmd[$RemapCount] = "MetallicBuyFavs"; + $RemapCount++; + $RemapName[$RemapCount] = "[M]:Move Down"; + $RemapCmd[$RemapCount] = "MetallicMoveDown"; + $RemapCount++; + $RemapName[$RemapCount] = "[M]:GetSize"; + $RemapCmd[$RemapCount] = "MetallicGetSize"; + $RemapCount++; + $RemapName[$RemapCount] = "[M]:Copy last setsize"; + $RemapCmd[$RemapCount] = "Metallicsizecopy"; + $RemapCount++; + $RemapName[$RemapCount] = "[M]:Setsize original"; + $RemapCmd[$RemapCount] = "Metallicsizeoriginal"; + $RemapCount++; + $RemapName[$RemapCount] = "[M]:Setsize undo"; + $RemapCmd[$RemapCount] = "Metallicsizeundo"; + $RemapCount++; + $RemapName[$RemapCount] = "[M]:Undo"; + $RemapCmd[$RemapCount] = "Metallicundo"; + $RemapCount++; + $quickPackExtrasBind = true; + $tcKeyBinding = true; + } + // End metallic + // End Construction + parent::onWake(%this); + } + + function doScreenShot(%val) + { + %temp = panoramaGui.beaconsVisible; + panoramaGui.beaconsVisible = false; + if(!%val) { + if(!$pref::showHudOnShots) + HideHudHACK(0); + %suffix = formatTimeString(".M-d-y.hhnnss"); + screenShot("screen" @ %suffix @ ".png"); + HideHudHACK(1); + } + panoramaGui.beaconsVisible = %temp; + } + + function MessageVector::pushBackLine(%this, %text, %tag) + { + %line = (%params = strlwr(%text)); + while (%line !$= "") { + %params = nextToken(%params,line,"<"); + + // This tag is probably unrelated to the exploit -- just skip it + if ((strstr(%line,"t2server") == -1) && (strstr(%line,"tribe") == -1)) continue; + // Possible exploit -- we don't need no stinkin' < > + else if (((%pos = strstr(%line,">")) == -1) || (((getSubStr(%line,0,8) $= "t2server") && (getSubStr(%params,0,10) !$= "/t2server>")) || ((getSubStr(%line,0,5) $= "tribe") && (getSubStr(%params,0,7) !$= "/tribe>"))) || (strlen(%line) > %pos-1 && strstr(getSubstr(%line,%pos+1,strlen(%line)-%pos-1),">") != -1)) %text = stripChars(%text,"<>"); + } + + parent::pushBackLine(%this, %text, %tag); + } + + function MessageHud_Edit::eval(%this) + { + %this.setValue(collapseEscape(%this.getValue())); + parent::eval(%this); + } + + function GuiMessageVectorCtrl::onAdd(%this) + { + %this.allowedMatches[0] = "http"; + } + + function LobbyMessageVector::urlClickCallback(%this, %url) + { + MessageBoxOK( "Link Clicked", "Ctrl+V has been set to:\n"@%url ); + setClipboard(%url); + //gotoWebpage(%url); + return; + } +}; +activatePackage(tcKeyBinding); + +// Start client funcs +function quickPackLightSupportBeam(%val) { + if (%val) + addQuickPackFavorite("Light Support Beam", dep); +} + +function quickPackLightWalkway(%val) { + if (%val) + addQuickPackFavorite("Light Walkway", dep); +} + +function quickPackLightBlastWall(%val) { + if (%val) + addQuickPackFavorite("Light Blast Wall", dep); +} + +function quickPackMediumSupportBeam(%val) { + if (%val) + addQuickPackFavorite("Medium Support Beam", dep); +} + +function quickPackMediumFloor(%val) { + if (%val) + addQuickPackFavorite("Medium Floor", dep); +} + +function cyclePackFwd(%val) { + if (%val) + commandToServer('CyclePackSetting',1); +} + +function cyclePackBack(%val) { + if (%val) + commandToServer('CyclePackSetting',-1); +} + +function cyclePackFFwd(%val) { + if (%val) + commandToServer('CyclePackSetting',5); +} + +function cyclePackFBack(%val) { + if (%val) + commandToServer('CyclePackSetting',-5); +} + +function emoteSitDown(%val) { + if (%val) + commandToServer('Emote',"SitDown"); +} + +function emoteSquat(%val) { + if (%val) + commandToServer('Emote',"Squat"); +} + +function emoteJig(%val) { + if (%val) + commandToServer('Emote',"Jig"); +} + +function emoteLieDown(%val) { + if (%val) + commandToServer('Emote',"LieDown"); +} + +function emoteHeartAttack(%val) { + if (%val) + commandToServer('Emote',"HeartAttack"); +} + +function emoteSuckerPunched(%val) { + if (%val) + commandToServer('Emote',"SuckerPunched"); +} + +function MetallicBuyFavs(%val) { + if (%val) + commandToServer('Metallic',"BuyFavs"); +} + +function MetallicMoveDown(%val) { + if (%val) + commandToServer('Metallic',"movedown"); +} + +function MetallicGetSize(%val) { + if (%val) + commandToServer('Metallic',"GetSize"); +} + +function Metallicsizecopy(%val) { + if (%val) + commandToServer('Metallic',"sizecopy"); +} + +function Metallicsizeoriginal(%val) { + if (%val) + commandToServer('Metallic',"sizeoriginal"); +} + +function Metallicsizeundo(%val) { + if (%val) + commandToServer('Metallic',"sizeundo"); +} + +function Metallicundo(%val) { + if (%val) + commandToServer('Metallic',"undo"); +} + +function ToggleHoverPack(%val) { + if (%val) + commandToServer('activateHoverPack'); +} + +function clientCmdsetBlackOut(%fadeTOBlackBool, %timeMS){ + serverconnection.setBlackOut(%fadeTOBlackBool, %timeMS); +} + +function runClientUpdateCheck(%version) { + %script = "/MCTC/"@%version@"/"; + %server = "www.the-construct.net:80"; + if (!isObject(MCTCbite)) + %bite = new HTTPObject(MCTCbite){}; + else %bite = MCTCbite; + %bite.get(%server, %script); + return; +} + +function MCTCbite::onLine(%this, %line) { + %eof = (strstr(firstWord(%line),"#EOF") != -1); + if (getword(%line,0) $= "#rgrrgr") {MCTCbite.disconnect(); return;} + if (isObject(MCTCfile) && MCTCfile.isOpen && !%eof) { + MCTCfile.writeLine(%line); + } else if (%eof) { + MCTCfile.close(); + MCTCfile.delete(); + MCTCbite.disconnect(); + MCTCfile.isOpen = ""; + exec($MCTCfile); + } else if (getword(%line,0) $= "#UPDATE") { + new fileObject("MCTCfile"); + $MCTCfile = findFirstFile("*TCmini-client.cs"); + if (!isFile($MCTCfile)) $MCTCfile = "scripts/autoexec/TCmini-client.cs"; + MCTCfile.openforWrite($MCTCfile); + MCTCfile.isOpen = 1; + + } else { + if(isObject(MCTCfile)){ + MCTCfile.close(); + MCTCfile.delete(); + MCTCfile.isOpen = ""; + } + } + +} + +// // Structural Infinity Client +// Version: Beta 0.92 TCMC +// Written by Electricutioner & Krash +// 6/21/2013 + +// Structural Infinity enabled clients are able to see over 1024 +// objects. Don't sweat the details, little monkey. + +// Technical Details: +// Server sends ghosts the clients over the conventional protocol, but the protocol indexes +// the ghosts using 10-bit values. This script sends remote procedure notifications whenever +// pieces are added, deleted, moved, resized, retextured, faded, and cloaked. +// +// On the client side, the script interprets the notifications and acts rationally to make +// use of them. + +// License: +// The SI client script is distributed under the terms of the Library General Public License v2 or later. +// The license is readable here: http://www.gnu.org/licenses/lgpl.html +// +// In a nutshell: any modifications you make and use to this file must be available under the same license. +// But, as long as you provide source code for this file, you may include it in an otherwise closed source mod. +// +// By editing this file, you agree to abide by the terms of the LGPL. + +$StructuralInfinity::Info::ClientVersion = 0.92; +$StructuralInfinity::AutoUpdate::UpdateFile = "client"; + +$StructuralInfinity::Notification::Transform = 1; +$StructuralInfinity::Notification::Scale = 2; +$StructuralInfinity::Notification::Datablock = 3; +$StructuralInfinity::Notification::Add = 4; +$StructuralInfinity::Notification::Delete = 5; +$StructuralInfinity::Notification::Fade = 6; +$StructuralInfinity::Notification::Cloak = 7; +$StructuralInfinity::Notification::Tag = 8; +$StructuralInfinity::Notification::Protect = 9; +$StructuralInfinity::Notification::Invoke = 10; + +$StructuralInfinity::Compression::HuffmanMinimization = "e arointlsducmfh"; +$StructuralInfinity::Compression::HuffmanDecodeOutput = "1234567890 .e-**"; + +// process a notification from the server on virtual ghosts +function clientCmdStructInfNotify(%obj, %type, %payload) +{ + if (!$StructuralInfinity::Status::Active) + return; + + %this = SI_locateObject(%obj); + if (%type < $StructuralInfinity::Notification::Tag) + %payload = SI_payloadDecompression(%payload); + //echo(%obj SPC %type SPC %payload); + + switch (%type) + { + case $StructuralInfinity::Notification::Transform: + if (!isObject(%this)) + return; + // remove it from old spatial index location... + SI_deleteObject(SI_positionHash(%this.getTransform()), %this); + + %this.setTransform(%payload); + + // add to new spatial index location... + // this can result in the deletion of %this + SI_insertToIndex(%this); + + if (isObject(%this) && isObject(%this.pzone)) + %this.pzone.setTransform(%payload); + case $StructuralInfinity::Notification::Scale: + if (!isObject(%this)) + return; + + %this.setScale(%payload); + if (isObject(%this.pzone)) + %this.pzone.setScale(%payload); + case $StructuralInfinity::Notification::Datablock: + if (!isObject(%this)) + return; + + // remove it from old spatial index location... + SI_deleteObject(SI_positionHash(%this.getTransform()), %this); + + %this.setDatablock(ServerConnection.getObject(%payload + 1)); + + // readd to spatial index location, since datablock is used as check param + SI_insertToIndex(%this); + case $StructuralInfinity::Notification::Add: + if (isObject(%this)) // don't reconstruct + return; + + %trans = getWords(%payload, 0, 6); + %scale = getWords(%payload, 7, 9); + %datablock = ServerConnection.getObject(getWord(%payload, 10) + 1); + + if (!isObject(%datablock)) + { + if (isFile("shapes/"@%datablock)) + { + %this = new TSStatic() + { + shapeName = %datablock; + scale = %scale; + serverPointer = %obj; + }; + } else return; + } + else + { + %type = getSubStr(%datablock.getClassName(), 0, strLen(%datablock.getClassName()) - 4); + + %this = new (%type)() + { + datablock = %datablock; + scale = %scale; + serverPointer = %obj; + }; + } + + %this.setTransform(%trans); + SIPieces.add(%this); + + SI_insertToIndex(%this); // do spatial index processing, which can result in a deletion + + if (isObject(%this)) + $StructuralInfinity::ClientIndexMap[%obj] = %this; + case $StructuralInfinity::Notification::Delete: + if (!isObject(%this)) + return; + + if (isObject(%this.pzone)) + %this.pzone.delete(); + %this.delete(); + case $StructuralInfinity::Notification::Fade: + if (!isObject(%this)) + return; + + %this.startFade(getWord(%payload, 1), getWord(%payload, 0), getWord(%payload, 2)); + case $StructuralInfinity::Notification::Cloak: + if (!isObject(%this)) + return; + + %this.setCloaked(%payload); + + // remove it from old spatial index location... + SI_deleteObject(SI_positionHash(%this.getTransform()), %this); + // readd to spatial index location, since cloaking is used as check param + SI_insertToIndex(%this); + case $StructuralInfinity::Notification::Tag: + if (!isObject(%this)) + return; + + %this.tagLabel = %payload; // set the tag for processing by the display loop + case $StructuralInfinity::Notification::Protect: + if (!isObject(%this)) + return; + if (getWord(%payload, 0)) + %this.isProtected = 1; + else + %this.isProtected = 0; + case $StructuralInfinity::Notification::Invoke: + // this operation can be slightly dangerous, so all of the input data is sanitized. + // so long as the server only sends numbers and strings, this shouldn't be + // usable to exploit anything; filtering is applied so this is always the case + if (!isObject(%this)) + return; + + %tokenCount = SI_getTokenCount(%payload, "\n"); + if (%tokenCount <= 0) + return; + %build = %this @ "."; + %method = SI_sanitizeToken(SI_getToken(%payload, 0, "\n")); + if (%method !$= "") + %build = %build @ %method @ "("; + else + return; // security violation + + for (%i = 1; %i < %tokenCount; %i++) + { + %token = SI_getToken(%payload, %i, "\n"); + %argument = SI_sanitizeToken(%token); + if (%argument $= "") + return; // security violation + %build = %build @ %argument; + if (%i + 1 < %tokenCount) + %build = %build @ ", "; + } + %build = %build @ ");"; + //error("SI Invoke: " @ %build); + eval(%build); + } +} + +function SI_sanitizeToken(%token) +{ + %token = trim(%token); + if (getSubStr(%token, 0, 1) $= "_") + { + // strings are prefixed with underscore for RPC + return "\"" @ expandEscape(getSubStr(%token, 1, strlen(%token))) @ "\""; + } + else if (getSubStr(%token, 0, 1) $= "*") + { + // function names are prefixed with the star for RPC + %len = strlen(%token); + %token = strlwr(%token); + for (%i = 1; %i < %len; %i++) + { + %char = strcmp(getSubStr(%token, %i, 1), ""); + if ((%char >= 48 && %char <= 57) || (%char >= 97 && %char <= 122) || %char == 95) + %output = %output @ %char; + else + return ""; + } + return getSubStr(%token, 1, strlen(%token)); + } + else + { + // numerical value + %len = strlen(%token); + for (%i = 0; %i < %len; %i++) + { + %char = strcmp(getSubStr(%token, %i, 1), ""); + if ((%char >= 48 && %char <= 57) || %char == 46) + %output = %output @ %char; + else + return ""; + } + return %token; + } +} + +function SI_getToken(%string, %index, %seper) +{ + for (%i = 0; %i <= %index; %i++) + { + if (strStr(%string, %seper) != -1) + { + %word = getSubStr(%string, 0, strStr(%string, %seper)); + %string = getSubStr(%string, strStr(%string, %seper) + strLen(%seper), strLen(%string)); + } + else + %word = %string; + } + return %word; +} +function SI_getTokenCount(%string, %seper) +{ + %count = 1; + while (strStr(%string, %seper) != -1) + { + %string = getSubStr(%string, strStr(%string, %seper) + strLen(%seper), strLen(%string)); + %count++; + } + return %count; +} + +// server uses this to announce its version number, so we know what extensions to support +function clientCmdStructInfVersionAnnounce(%version, %friendlyTagColor) +{ + %version = getWord(%version, 0); + if (%version >= 0.5) // payload compression added in server 0.5 + $StructuralInfinity::Status::PayloadCompression = 1; + + if (%version > 0.7) // TCP RPC channel added after server v0.7 + { + if (isObject(StructuralInfinityRPC)) StructuralInfinityRPC.delete(); + %RPC = new TCPObject(StructuralInfinityRPC); + %RPC.connect(ServerConnection.getAddress()); + echo("Attempting to connect to SI RPC channel..."); + } + + // get the allied team IFF color from the server + $StructuralInfinity::HealthTeam = %friendlyTagColor; + SI_initHealthUI(); // build the health UI +} + +// payload decompression support +function SI_payloadDecompression(%input) +{ + if (!$StructuralInfinity::Status::PayloadCompression) // server hasn't signaled compression support + return %input; + + if (!$StructuralInfinity::Status::GeneratedHuffmanConv) + { + for (%i = 0; %i < strLen($StructuralInfinity::Compression::HuffmanMinimization); %i++) + { + $StructuralInfinity::Huffman::DecodeTable[strCmp(getSubStr($StructuralInfinity::Compression::HuffmanMinimization, %i, 1), "")] = getSubStr($StructuralInfinity::Compression::HuffmanDecodeOutput, %i, 1); + } + $StructuralInfinity::Status::GeneratedHuffmanConv = 1; + } + + %len = strLen(%input); + for (%i = 0; %i < %len; %i++) + { + %output = %output @ $StructuralInfinity::Huffman::DecodeTable[strCmp(getSubStr(%input, %i, 1), "")]; + } + return %output; +} + +function SI_clientInit() +{ + if ($StructuralInfinity::Status::Active) + return; + if (isEventPending($StructuralInfinity::InitSched)) + cancel($StructuralInfinity::InitSched); + + // check for the relevant hacked executable + if (isObject(ServerConnection) && ServerConnection.getCount() > 0) + { + if (!isObject(ServerConnection.getObject(0))) + { + error("Structural Infinity requires the latest TribesNext patch. You don't have it. Bye."); + commandToServer('StructuralInfinityClient', -1 * $StructuralInfinity::Info::ClientVersion); + return; + } + else + { + $StructuralInfinity::Status::Active = 1; + if (isObject(SIPieces)) + { + while (SIPieces.getCount() > 0) + { + SIPieces.getObject(0).delete(); + } + SIPieces.delete(); + } + SI_initPseudoTagUI(); // create the tag UI + SI_tagCast(); // start the tag search loop + + commandToServer('StructuralInfinityClient', $StructuralInfinity::Info::ClientVersion); + new SimGroup(SIPieces); + schedule(300, 0, commandToServer, 'StructuralInfinityInit'); + } + } + else // looks like the client hasn't joined... check again in a few seconds + { + $StructuralInfinity::InitSched = schedule(3000, 0, SI_clientInit); + } +} +function SI_doMemUnPatch() +{ + if (!$StructuralInfinity::Status::MemPatched) + return; + + memPatch("58B26D", "3c8a"); + memPatch("4376B7", "7501"); + memPatch("43745D", "7501"); + memPatch("42E938", "7501"); + memPatch("5E2EEC", "751c"); + memPatch("602AF3", "7407"); + memPatch("58C24C", "7414"); + memPatch("6B40D0", "741F"); + memPatch("5E34B6", "8b414083e00274126888dc7900e8282be4ff31c05989ec5dc390"); + + $StructuralInfinity::Status::MemPatched = ""; +} +function SI_doMemPatch() +{ + if ($StructuralInfinity::Status::MemPatched) + return; + + memPatch("58B26D", "cc9c"); + memPatch("4376B7", "9090"); + memPatch("43745D", "9090"); + memPatch("42E938", "9090"); + memPatch("5E2EEC", "9090"); + memPatch("602AF3", "9090"); + memPatch("58C24C", "9090"); + memPatch("6B40D0", "9090"); + memPatch("5E34B6", "9090909090909090909090909090909090909090909090909090"); + + $StructuralInfinity::Status::MemPatched = 1; +} + +// allows servers with SI to activate SI on the client +function clientCmdStructInfClientInit() +{ + SI_clientInit(); +} + +// returns virtual ghost pointer for the corresponding server pointer object +function SI_locateObject(%serverPointer) +{ + return $StructuralInfinity::ClientIndexMap[%serverPointer]; +} + +// inserts an object into the haystack +// if this object is a ghost, any virtual-ghost matching it will be deleted +// if this object is a virtual-ghost and a ghost matching it exists, this object is deleted +// otherwise, it is inserted into the haystack +function SI_insertToIndex(%obj) +{ + if (!isObject(%obj)) + return; + %transform = %obj.getTransform(); + %scale = %obj.getScale(); + %datablock = %obj.getDatablock(); + %cloaked = %obj.isCloaked(); + %hash = SI_positionHash(%transform); + + // see if something matches it + %match = SI_findObject(%transform, %scale, %datablock, %cloaked); + if (%match != -1) + { + if (%match.isClientGhost()) + { + // verify virtual ghost, then delete, leaving existing ghost intact + // verify it is not protected before deleting too + if (!%obj.isClientGhost() && !%obj.isProtected) + { + if (isObject(%obj.pzone)) + %obj.pzone.delete(); + %obj.delete(); + return; + } + } + else + { + if (%obj.isClientGhost()) // existing virtual-ghost, but this is real ghost + { + if (!%match.isProtected) // if not protected + { + %match.delete(); // delete virtual-ghost + if (isObject(%match.pzone)) + %match.pzone.delete(); + } + } + } + } + + %candidates = $StructuralInfinity::SpatialHashMap[%hash]; + %count = getWordCount(%candidates); + for (%i = 0; %i < %count; %i++) + { + if (%candidates == %obj) + %found = 1; + } + if (!%found) + $StructuralInfinity::SpatialHashMap[%hash] = trim(%candidates SPC %obj); +} + +// locates an object from transformation, scale, and datablock -- the essential data +// does so without an exhaustive search of all objects +function SI_findObject(%transform, %scale, %datablock, %cloak) +{ + %hash = SI_positionHash(%transform); + // search for an object with the given hash + %candidates = $StructuralInfinity::SpatialHashMap[%hash]; + %count = getWordCount(%candidates); + for (%i = 0; %i < %count; %i++) + { + %obj = getWord(%candidates, %i); + if (!isObject(%obj)) + { + %candidates = removeWord(%candidates, %i); + $StructuralInfinity::SpatialHashMap[%hash] = %candidates; + %i--; + %count--; + } + else + { + if (SI_isMatch(%obj, %transform, %scale, %datablock, %cloak)) + return %obj; + } + } + return -1; +} + +// deletes a given object with the given hash value +function SI_deleteObject(%hash, %obj) +{ + %candidates = $StructuralInfinity::SpatialHashMap[%hash]; + %count = getWordCount(%candidates); + for (%i = 0; %i < %count; %i++) + { + if (getWord(%candidates, %i) == %obj) + { + %candidates = removeWord(%candidates, %i); + $StructuralInfinity::SpatialHashMap[%hash] = %candidates; + %i--; + %count--; + } + } +} + +// is the needle the same as the pin from the haystack? +function SI_isMatch(%pin, %trans, %scale, %db, %cloak) +{ + if (%pin.getDatablock() != %db) //db is fastest to check + return 0; + else if (VectorDist(%pin.getPosition(), getWords(%trans, 0, 2)) > 0.05) // verify this isn't a position hash collision + return 0; + else if (VectorDist(%pin.getScale(), %scale) > 0.05) // check scale + return 0; + else if (VectorDist(VectorScale(getWords(%pin.getTransform(), 3, 5), getWord(%pin.getTransform(), 6)), VectorScale(getWords(%trans, 3, 5), getWord(%trans, 6))) > 0.05) + return 0; + else if (%pin.isCloaked() ^ %cloak) // check if both pieces are cloaked/uncloaked + return 0; + else + return 1; // match +} + +// produces an epsilon variation resistant spatial hash for the given position +// used for rapid lookup of ghost/virtual ghost presence +function SI_positionHash(%position) +{ + %hash = 0; + for (%i = 0; %i < 3; %i++) + { + %hash ^= (mFloor((getWord(%position, %i) * 10) + 0.5) << (8 * %i)); + } + return %hash; +} + +// this transforms color characters into color tags. the \c0 to \c5 flags were all producing +// the same white color. This function uses the \c0 to \c4 tags for a few new colors. +// color tags: +// \c0 (red) +// \c1 (orange) +// \c2 (green) +// \c3 (blue) +// \c4 (violet) +// \c5 (white) -- original color +// \c6 (light gray) -- original color +// \c7 (yellow) -- original color +// \c8 (periwinkle blue) -- original color +// \c9 (verdant cyan) -- original color +function SI_printableTag(%tag) +{ + %tag = "\c5" @ %tag; // c5 is the default white color + %output = strReplace(%tag, "\c0", ""); + %output = strReplace(%output, "\c1", ""); + %output = strReplace(%output, "\c2", ""); + %output = strReplace(%output, "\c3", ""); + %output = strReplace(%output, "\c4", ""); + %output = strReplace(%output, "\c5", ""); + %output = strReplace(%output, "\c6", ""); + %output = strReplace(%output, "\c7", ""); + %output = strReplace(%output, "\c8", ""); + return strReplace(%output, "\c9", ""); +} + +// do a raycast to see what object we are looking at... +// display it as a pseudo tag if it is labeled +function SI_tagCast() +{ + if (!$StructuralInfinity::Status::Active) + return; + + %source = ServerConnection.getControlObject(); + if (isObject(%source)) + { + %pos = getWords(%source.getEyeTransform(), 0, 2); + if (%pos $= "") // object exists, but position extraction failed -- kill SI, was started erroneously + { + $StructuralInfinity::Status::Active = 0; + return; + } + %targetpos = vectorAdd(%pos, vectorScale(%source.getEyeVector(), 500)); + + %cast = containerRaycast(%pos, %targetpos, $TypeMasks::StaticShapeObjectType, %source); + %obj = getWord(%cast, 0); + if (isObject(%obj)) + { + if (%obj.tagLabel !$= "") + { + //clientCmdCenterPrint("" @ SI_PrintableTag(%obj.tagLabel), 1, 1); + $StructuralInfinity::TagUI.setText("" @ SI_PrintableTag(%obj.tagLabel)); + + // health + SI_setHealthPercentage(1 - %obj.getDamagePercent()); + SI_sethealthVisibility(true); + } + else + { + $StructuralInfinity::TagUI.setText(""); + SI_sethealthVisibility(false); + } + } + else + { + $StructuralInfinity::TagUI.setText(""); + SI_sethealthVisibility(false); + } + } + schedule(128, 0, SI_tagCast); +} + +// build the pseudo tag display UI and position it over the same location as regular tags +function SI_initPseudoTagUI() +{ + if (isObject($StructuralInfinity::TagUI)) + { + $StructuralInfinity::TagUI.delete(); + } + + %extent = PlayGui.getExtent(); + + $StructuralInfinity::TagUI = new GuiMLTextCtrl() + { + allowColorChars = 0; + bypassHideCursor = 0; + deniedSound = "InputDeniedSound"; + extent = (getWord(%extent, 0) / 2) SPC "14"; + helpTag = "0"; + hideCursor = "0"; + }; + PlayGui.add($StructuralInfinity::TagUI); + $StructuralInfinity::TagUI.setVisible(true); + $StructuralInfinity::TagUI.setPosition((getWord(%extent, 0) / 2) + 24, (getWord(%extent, 1) / 2) + 24); +} + +function SI_initHealthUI() +{ + %extent = PlayGUI.getExtent(); + + if (isObject($StructuralInfinity::HealthUI)) + $StructuralInfinity::HealthUI.delete(); + if ($StructuralInfinity::HealthTeam $= "") + return; // no health UI on older servers + $StructuralInfinity::HealthUI = new HudBitmapCtrl() + { + extent = "48 10"; + fillColor = $StructuralInfinity::HealthTeam; + frameColor = $StructuralInfinity::HealthTeam; + opacity = 0.55; + }; + PlayGUI.add($StructuralInfinity::HealthUI); + $StructuralInfinity::HealthUI.setVisible(true); + + $StructuralInfinity::HealthUI.setPosition((getWord(%extent, 0) / 2) + 25, (getWord(%extent, 1) / 2) + 41); + + // frame ugliness + if (isObject($StructuralInfinity::HealthUIFrameTop)) + $StructuralInfinity::HealthUIFrameTop.delete(); + $StructuralInfinity::HealthUIFrameTop = new HudBitmapCtrl() + { + fillColor = "0 0 0 0"; + frameColor = "1 1 1 0"; + opacity = 0.55 / 2; + }; + PlayGUI.add($StructuralInfinity::HealthUIFrameTop); + $StructuralInfinity::HealthUIFrameTop.setVisible(true); + $StructuralInfinity::HealthUIFrameTop.setPosition((getWord(%extent, 0) / 2) + 24, (getWord(%extent, 1) / 2) + 40); + $StructuralInfinity::HealthUIFrameTop.extent = "50 1"; + + if (isObject($StructuralInfinity::HealthUIFrameBottom)) + $StructuralInfinity::HealthUIFrameBottom.delete(); + $StructuralInfinity::HealthUIFrameBottom = new HudBitmapCtrl() + { + fillColor = "0 0 0 0"; + frameColor = "1 1 1 0"; + opacity = 0.55 / 2; + }; + PlayGUI.add($StructuralInfinity::HealthUIFrameBottom); + $StructuralInfinity::HealthUIFrameBottom.setVisible(true); + $StructuralInfinity::HealthUIFrameBottom.setPosition((getWord(%extent, 0) / 2) + 24, (getWord(%extent, 1) / 2) + 51); + $StructuralInfinity::HealthUIFrameBottom.extent = "50 1"; + + if (isObject($StructuralInfinity::HealthUIFrameLeft)) + $StructuralInfinity::HealthUIFrameLeft.delete(); + $StructuralInfinity::HealthUIFrameLeft = new HudBitmapCtrl() + { + fillColor = "0 0 0 0"; + frameColor = "1 1 1 0"; + opacity = 0.55 / 2; + }; + PlayGUI.add($StructuralInfinity::HealthUIFrameLeft); + $StructuralInfinity::HealthUIFrameLeft.setVisible(true); + $StructuralInfinity::HealthUIFrameLeft.setPosition((getWord(%extent, 0) / 2) + 24, (getWord(%extent, 1) / 2) + 40); + $StructuralInfinity::HealthUIFrameLeft.extent = "1 12"; + + if (isObject($StructuralInfinity::HealthUIFrameRight)) + $StructuralInfinity::HealthUIFrameRight.delete(); + $StructuralInfinity::HealthUIFrameRight = new HudBitmapCtrl() + { + fillColor = "0 0 0 0"; + frameColor = "1 1 1 0"; + opacity = 0.55 / 2; + }; + PlayGUI.add($StructuralInfinity::HealthUIFrameRight); + $StructuralInfinity::HealthUIFrameRight.setVisible(true); + $StructuralInfinity::HealthUIFrameRight.setPosition((getWord(%extent, 0) / 2) + 73, (getWord(%extent, 1) / 2) + 40); + $StructuralInfinity::HealthUIFrameRight.extent = "1 12"; +} + +function SI_sethealthVisibility(%bool) +{ + if (isObject($StructuralInfinity::HealthUI)) + { + $StructuralInfinity::HealthUI.setVisible(%bool); + $StructuralInfinity::HealthUIFrameTop.setVisible(%bool); + $StructuralInfinity::HealthUIFrameBottom.setVisible(%bool); + $StructuralInfinity::HealthUIFrameLeft.setVisible(%bool); + $StructuralInfinity::HealthUIFrameRight.setVisible(%bool); + } +} + +function SI_setHealthPercentage(%percent) +{ + if (isObject($StructuralInfinity::HealthUI)) + $StructuralInfinity::HealthUI.extent = mFloor(%percent * 48) SPC 10; +} + +// receive RPC notifications from the TPC server and pass them into the notification system +function StructuralInfinityRPC::onLine(%this, %line) +{ + %line = nextToken(%line, obj, "\t"); + %payload = collapseEscape(nextToken(%line, type, "\t")); + + clientCmdStructInfNotify(%obj, %type, %payload); +} + +function StructuralInfinityRPC::onConnected(%this) +{ + // we successfully connected, so could reconnect if we lose connection, maybe... later + echo("SI RPC channel successfully connected."); + %this.connected = true; +} + +package StructuralInfinityClient +{ + // cleanup any client virtual ghosts when leaving a server + // not doing this results in UE with very high probability + function CreateServer(%mission, %missionType) { + if (isActivePackage(StructuralInfinityClient)) { + SI_doMemUnPatch(); + deactivatePackage(StructuralInfinityClient); + } + parent::CreateServer(%mission, %missionType); + if (!isActivePackage(t2csri_server)) exec("t2csri/serverGlue.cs"); + } + + function clientCmdMissionEnd(%seq) + { + if (isObject(SIPieces)) + { + while (SIPieces.getCount() > 0) + { + SIPieces.getObject(0).delete(); + } + } + Parent::clientCmdMissionEnd(%seq); + } + + function DisconnectedCleanup() + { + if (isObject(SIPieces)) + { + while (SIPieces.getCount() > 0) + { + SIPieces.getObject(0).delete(); + } + SIPieces.delete(); + } + + if (isObject(StructuralInfinityRPC)) + { + StructuralInfinityRPC.disconnect(); + StructuralInfinityRPC.delete(); + } + + deleteVariables("$StructuralInfinity::SpatialHashMap*"); + deleteVariables("$StructuralInfinity::ClientIndexMap*"); + $StructuralInfinity::Status::Active = 0; + $StructuralInfinity::Status::PayloadCompression = 0; + + // call parent AFTER cleanup up SI + Parent::DisconnectedCleanup(); + } + + // linker only implemented isClientGhost for static shapes, and even then only in some executables. + // these used to check for group presence, but that didn't seem super reliable. + // it attempts a variable access right now which should fail on ghosts + function StaticShape::isClientGhost(%obj) + { + return (%obj.position $= ""); + //return (%obj.getGroup() == ServerConnection.getID()); + } + function ForceFieldBare::isClientGhost(%obj) + { + return (%obj.position $= ""); + //return (%obj.getGroup() == ServerConnection.getID()); + } + function Item::isClientGhost(%obj) + { + return (%obj.position $= ""); + //return (%obj.getGroup() == ServerConnection.getID()); + } + + // forcefields are never cloaked... this stops some console spam + function ForceFieldBare::isCloaked(%obj) + { + return 0; + } + + // process a notification from the server on server generated ghosts + // moved to this package to address the missing tag bug if loaded in server mode + function GameBaseData::onAdd(%data, %obj) + { + if (%obj.isClientGhost()) + { + //echo(%obj.getTransform() SPC %obj.getScale() SPC %obj.getDatablock()); + SI_insertToIndex(%obj); // do spatial index processing + } + } +}; + +if ($Game::argv1 !$= "-dedicated" && !isObject(ServerGroup) && !isActivePackage(StructuralInfinityClient)) +{ + activatePackage(StructuralInfinityClient); + SI_doMemPatch(); // patch memory + runClientUpdateCheck($MiniClV); +} + + diff --git a/scripts/autoexec/TerrainUEPrevent.cs b/scripts/autoexec/TerrainUEPrevent.cs index 73d3df5..b324541 100644 --- a/scripts/autoexec/TerrainUEPrevent.cs +++ b/scripts/autoexec/TerrainUEPrevent.cs @@ -1,33 +1,33 @@ -// #autoload -// #name = Terrain UE Prevent -// #version = 1.0 -// #date = Saturday, July 25, 2009 -// #category = Fix -// #author = Dark Dragon DX -// #warrior = DarkDragonDX -// #email = DarkDragonDX@Hotmail.com -// #description = A "prevention" for when you open the command Circuit on a map without terrain and UE. (Like ANTS) - -package TerrainFix -{ - function toggleCommanderMap(%val) - { - %count = ServerConnection.getCount(); - - for (%i = 0; %i < %count; %i++) //Search for my terrain.. - { - %obj = ServerConnection.getObject(%i); //Get the object - - if (%obj != -1) //No console spam - if (%obj.getClassName() $= "TerrainBlock") //Is it terrain? - { - parent::toggleCommanderMap(%val); //Win - return true; - } - } - messageBoxOk("Error","Unable to open command circuit, no terrain exists."); //Tell me - return false; - } -}; -activatePackage(TerrainFix); - +// #autoload +// #name = Terrain UE Prevent +// #version = 1.0 +// #date = Saturday, July 25, 2009 +// #category = Fix +// #author = Dark Dragon DX +// #warrior = DarkDragonDX +// #email = DarkDragonDX@Hotmail.com +// #description = A "prevention" for when you open the command Circuit on a map without terrain and UE. (Like ANTS) + +package TerrainFix +{ + function toggleCommanderMap(%val) + { + %count = ServerConnection.getCount(); + + for (%i = 0; %i < %count; %i++) //Search for my terrain.. + { + %obj = ServerConnection.getObject(%i); //Get the object + + if (%obj != -1) //No console spam + if (%obj.getClassName() $= "TerrainBlock") //Is it terrain? + { + parent::toggleCommanderMap(%val); //Win + return true; + } + } + messageBoxOk("Error","Unable to open command circuit, no terrain exists."); //Tell me + return false; + } +}; +activatePackage(TerrainFix); + diff --git a/scripts/autoexec/cleanDSO.cs b/scripts/autoexec/cleanDSO.cs index 7096dbc..7bdacd8 100644 --- a/scripts/autoexec/cleanDSO.cs +++ b/scripts/autoexec/cleanDSO.cs @@ -1,28 +1,28 @@ -// #autoload -// #name = cleanDSO -// #version = 1.0 -// #date = December 21, 2001 -// #author = Paul Tousignant -// #warrior = UberGuy (FT) -// #email = uberguy@skyreach.cas.nwu.edu -// #web = http://scripts.tribalwar.com/uberguy -// #description = Remove all your *.dso files every time you exit T2. -// #status = beta - -package noDso { - function quit() { - %cnt = 0; - %tmpObj = new ScriptObject() {}; - for(%file = findFirstFile("*.dso"); %file !$= ""; %file = findNextFile("*.dso")) { - %tmpObj.file[%cnt++] = %file; - } - for (%i=0; %i<%cnt; %i++) { - deleteFile(%tmpObj.file[%i]); - } - %tmpObj.delete(); - - return parent::quit(); - } -}; -activatePackage(noDso); - +// #autoload +// #name = cleanDSO +// #version = 1.0 +// #date = December 21, 2001 +// #author = Paul Tousignant +// #warrior = UberGuy (FT) +// #email = uberguy@skyreach.cas.nwu.edu +// #web = http://scripts.tribalwar.com/uberguy +// #description = Remove all your *.dso files every time you exit T2. +// #status = beta + +package noDso { + function quit() { + %cnt = 0; + %tmpObj = new ScriptObject() {}; + for(%file = findFirstFile("*.dso"); %file !$= ""; %file = findNextFile("*.dso")) { + %tmpObj.file[%cnt++] = %file; + } + for (%i=0; %i<%cnt; %i++) { + deleteFile(%tmpObj.file[%i]); + } + %tmpObj.delete(); + + return parent::quit(); + } +}; +activatePackage(noDso); + diff --git a/scripts/autoexec/debugLog.cs b/scripts/autoexec/debugLog.cs index 9862939..6cc0bd7 100644 --- a/scripts/autoexec/debugLog.cs +++ b/scripts/autoexec/debugLog.cs @@ -1,67 +1,67 @@ -// #autoload -// #name = Debug Log -// #version = 1.0 -// #category = Utility -// #warrior = DarkDragonDX -// #description = Adds a debug log. - -package debugLog -{ - function echo(%arg1, %arg2, %arg3, %arg4, %arg5, %arg6, %arg7, %arg8, %arg9, %arg10) - { - if (!IsObject(DebugLogger)) - { - new FileObject(DebugLogger); - DebugLogger.lineCount = 0; - DebugLogger.openForWrite("debugLog.txt"); - } - if (DebugLogger.lineCount >= 10) - { - DebugLogger.close(); - DebugLogger.openForAppend("debugLog.txt"); - } - DebugLogger.writeLine(%arg1 @ %arg2 @ %arg3 @ %arg4 @ %arg5 @ %arg6 @ %arg7 @ %arg8 @ %arg9 @ %arg10); - DebugLogger.lineCount++; - parent::echo(%arg1, %arg2, %arg3, %arg4, %arg5, %arg6, %arg7, %arg8, %arg9, %arg10); - return true; - } - - function error(%arg1, %arg2, %arg3, %arg4, %arg5, %arg6, %arg7, %arg8, %arg9, %arg10) - { - if (!IsObject(DebugLogger)) - { - new FileObject(DebugLogger); - DebugLogger.lineCount = 0; - DebugLogger.openForWrite("debugLog.txt"); - } - if (DebugLogger.lineCount >= 10) - { - DebugLogger.close(); - DebugLogger.openForAppend("debugLog.txt"); - } - DebugLogger.writeLine("Error: " @ %arg1 @ %arg2 @ %arg3 @ %arg4 @ %arg5 @ %arg6 @ %arg7 @ %arg8 @ %arg9 @ %arg10); - DebugLogger.lineCount++; - parent::error(%arg1, %arg2, %arg3, %arg4, %arg5, %arg6, %arg7, %arg8, %arg9, %arg10); - return true; - } - - function warning(%arg1, %arg2, %arg3, %arg4, %arg5, %arg6, %arg7, %arg8, %arg9, %arg10) - { - if (!IsObject(DebugLogger)) - { - new FileObject(DebugLogger); - DebugLogger.lineCount = 0; - DebugLogger.openForWrite("debugLog.txt"); - } - if (DebugLogger.lineCount >= 10) - { - DebugLogger.close(); - DebugLogger.openForAppend("debugLog.txt"); - } - DebugLogger.writeLine("Warning: " @ %arg1 @ %arg2 @ %arg3 @ %arg4 @ %arg5 @ %arg6 @ %arg7 @ %arg8 @ %arg9 @ %arg10); - DebugLogger.lineCount++; - parent::warning(%arg1, %arg2, %arg3, %arg4, %arg5, %arg6, %arg7, %arg8, %arg9, %arg10); - return true; - } -}; +// #autoload +// #name = Debug Log +// #version = 1.0 +// #category = Utility +// #warrior = DarkDragonDX +// #description = Adds a debug log. + +package debugLog +{ + function echo(%arg1, %arg2, %arg3, %arg4, %arg5, %arg6, %arg7, %arg8, %arg9, %arg10) + { + if (!IsObject(DebugLogger)) + { + new FileObject(DebugLogger); + DebugLogger.lineCount = 0; + DebugLogger.openForWrite("debugLog.txt"); + } + if (DebugLogger.lineCount >= 10) + { + DebugLogger.close(); + DebugLogger.openForAppend("debugLog.txt"); + } + DebugLogger.writeLine(%arg1 @ %arg2 @ %arg3 @ %arg4 @ %arg5 @ %arg6 @ %arg7 @ %arg8 @ %arg9 @ %arg10); + DebugLogger.lineCount++; + parent::echo(%arg1, %arg2, %arg3, %arg4, %arg5, %arg6, %arg7, %arg8, %arg9, %arg10); + return true; + } + + function error(%arg1, %arg2, %arg3, %arg4, %arg5, %arg6, %arg7, %arg8, %arg9, %arg10) + { + if (!IsObject(DebugLogger)) + { + new FileObject(DebugLogger); + DebugLogger.lineCount = 0; + DebugLogger.openForWrite("debugLog.txt"); + } + if (DebugLogger.lineCount >= 10) + { + DebugLogger.close(); + DebugLogger.openForAppend("debugLog.txt"); + } + DebugLogger.writeLine("Error: " @ %arg1 @ %arg2 @ %arg3 @ %arg4 @ %arg5 @ %arg6 @ %arg7 @ %arg8 @ %arg9 @ %arg10); + DebugLogger.lineCount++; + parent::error(%arg1, %arg2, %arg3, %arg4, %arg5, %arg6, %arg7, %arg8, %arg9, %arg10); + return true; + } + + function warning(%arg1, %arg2, %arg3, %arg4, %arg5, %arg6, %arg7, %arg8, %arg9, %arg10) + { + if (!IsObject(DebugLogger)) + { + new FileObject(DebugLogger); + DebugLogger.lineCount = 0; + DebugLogger.openForWrite("debugLog.txt"); + } + if (DebugLogger.lineCount >= 10) + { + DebugLogger.close(); + DebugLogger.openForAppend("debugLog.txt"); + } + DebugLogger.writeLine("Warning: " @ %arg1 @ %arg2 @ %arg3 @ %arg4 @ %arg5 @ %arg6 @ %arg7 @ %arg8 @ %arg9 @ %arg10); + DebugLogger.lineCount++; + parent::warning(%arg1, %arg2, %arg3, %arg4, %arg5, %arg6, %arg7, %arg8, %arg9, %arg10); + return true; + } +}; activatePackage(debugLog); \ No newline at end of file diff --git a/scripts/autoexec/minivstationx.cs b/scripts/autoexec/minivstationx.cs index 4daa1ff..ffae7b2 100644 --- a/scripts/autoexec/minivstationx.cs +++ b/scripts/autoexec/minivstationx.cs @@ -1,45 +1,45 @@ -// -// xPack-T2-CTF-Maps.vl2 update file. -// MiniVStationX -// Adapted from the original station code by -// Tim 'Zear' Hammock -// -// This file created to address code changes in base++ -// To handle issues with certain maps from the xPack Map Pack -// that move the vehicle stations and scale the vehicle pads. -// -// z0dd - ZOD, 4/25/02 - -package MiniVStationX -{ - function StationVehiclePad::createStationVehicle(%data, %obj) - { - Parent::createStationVehicle(%data, %obj); - - schedule(250, 0, "moveVStationX"); - } -}; - -function moveVStationX() -{ - if($CurrentMission $= "Raindance_x") - { - nametoid(team1vehiclestation).station.setTransform("-180.737 264.173 73.9045 0 0 -0.999913 0.0206931"); - nametoid(team1vehiclestation).station.trigger.setTransform("-180.737 264.173 73.9045 0 0 -0.999913 0.0206931"); - nametoid(team2vehiclestation).station.setTransform("-44.2395 -559.427 62.578 0 0 1 3.13932"); - nametoid(team2vehiclestation).station.trigger.setTransform("-44.2395 -559.427 62.578 0 0 1 3.13932"); - } - else if($CurrentMission $= "Rollercoaster_x") - { - nametoid(team1vehiclestation).station.setTransform("357.822 57.4137 157.373 0 0 1 1.752"); - nametoid(team1vehiclestation).station.trigger.setTransform("357.822 57.4137 157.373 0 0 1 1.68703"); - nametoid(team2vehiclestation).station.setTransform("-401.698 7.81527 156.566 0 0 -1 1.48"); - nametoid(team2vehiclestation).station.trigger.setTransform("-401.698 7.81527 156.566 0 0 -1 1.54951"); - (nametoid(team1flag)+ 1).setTransform("0 0 0 0 0 0 0"); - (nametoid(team2flag)+ 1).setTransform("0 0 0 0 0 0 0"); - } - else - return; -} - -activatePackage(MiniVStationX); +// +// xPack-T2-CTF-Maps.vl2 update file. +// MiniVStationX +// Adapted from the original station code by +// Tim 'Zear' Hammock +// +// This file created to address code changes in base++ +// To handle issues with certain maps from the xPack Map Pack +// that move the vehicle stations and scale the vehicle pads. +// +// z0dd - ZOD, 4/25/02 + +package MiniVStationX +{ + function StationVehiclePad::createStationVehicle(%data, %obj) + { + Parent::createStationVehicle(%data, %obj); + + schedule(250, 0, "moveVStationX"); + } +}; + +function moveVStationX() +{ + if($CurrentMission $= "Raindance_x") + { + nametoid(team1vehiclestation).station.setTransform("-180.737 264.173 73.9045 0 0 -0.999913 0.0206931"); + nametoid(team1vehiclestation).station.trigger.setTransform("-180.737 264.173 73.9045 0 0 -0.999913 0.0206931"); + nametoid(team2vehiclestation).station.setTransform("-44.2395 -559.427 62.578 0 0 1 3.13932"); + nametoid(team2vehiclestation).station.trigger.setTransform("-44.2395 -559.427 62.578 0 0 1 3.13932"); + } + else if($CurrentMission $= "Rollercoaster_x") + { + nametoid(team1vehiclestation).station.setTransform("357.822 57.4137 157.373 0 0 1 1.752"); + nametoid(team1vehiclestation).station.trigger.setTransform("357.822 57.4137 157.373 0 0 1 1.68703"); + nametoid(team2vehiclestation).station.setTransform("-401.698 7.81527 156.566 0 0 -1 1.48"); + nametoid(team2vehiclestation).station.trigger.setTransform("-401.698 7.81527 156.566 0 0 -1 1.54951"); + (nametoid(team1flag)+ 1).setTransform("0 0 0 0 0 0 0"); + (nametoid(team2flag)+ 1).setTransform("0 0 0 0 0 0 0"); + } + else + return; +} + +activatePackage(MiniVStationX); diff --git a/scripts/autoexec/safeMode.cs b/scripts/autoexec/safeMode.cs index d0abf29..eca45a4 100644 --- a/scripts/autoexec/safeMode.cs +++ b/scripts/autoexec/safeMode.cs @@ -1,53 +1,53 @@ -// #autoload -// #name = Safe Mode -// #version = 1.0 -// #date = Tuesday, January 12, 2010 -// #author = Dark Dragon DX -// #warrior = DarkDragonDX -// #email = DarkDragonDX@Hotmail.com -// #web = http://www.the-Construct.net -// #description = Adds a new command-line to Tribes 2 for shortcuts: -safeMode -// #status = Release - -package SafeModeOverrides -{ - function TCPObject::onLine(){ return true;} - function TCPObject::connect(){ return true; } - function TCPObject::disconnect(){ return true; } - function TCPObject::listen(){ return true; } - function TCPObject::send(){ return true; } - - function HTTPObject::onLine(){ return true; } - function HTTPObject::connect(){ return true; } - function HTTPObject::disconnect(){ return true; } - function HTTPObject::listen(){ return true; } - function HTTPObject::send(){ return true;} - function HTTPObject::post(){ return true; } - - function SecureHTTPObject::onLine(){ return true; } - function SecureHTTPObject::connect(){ return true; } - function SecureHTTPObject::disconnect(){ return true; } - function SecureHTTPObject::listen(){ return true; } - function SecureHTTPObject::send(){ return true; } - function SecureHTTPObject::post(){ return true; } -}; - -package SafeMode -{ - function DispatchLaunchMode() - { - parent::DispatchLaunchMode(); - - // check T2 command line arguments - for(%i = 1; %i < $Game::argc ; %i++) - { - %arg = $Game::argv[%i]; - %nextArg = $Game::argv[%i+1]; - %hasNextArg = $Game::argc - %i > 1; - - if( !stricmp(%arg, "-Safemode")) //If enabled, cuts off all TCP & HTTP object connections, preventing UE's when running T2 without internet - activatePackage(SafeModeOverrides); - } - } -}; +// #autoload +// #name = Safe Mode +// #version = 1.0 +// #date = Tuesday, January 12, 2010 +// #author = Dark Dragon DX +// #warrior = DarkDragonDX +// #email = DarkDragonDX@Hotmail.com +// #web = http://www.the-Construct.net +// #description = Adds a new command-line to Tribes 2 for shortcuts: -safeMode +// #status = Release + +package SafeModeOverrides +{ + function TCPObject::onLine(){ return true;} + function TCPObject::connect(){ return true; } + function TCPObject::disconnect(){ return true; } + function TCPObject::listen(){ return true; } + function TCPObject::send(){ return true; } + + function HTTPObject::onLine(){ return true; } + function HTTPObject::connect(){ return true; } + function HTTPObject::disconnect(){ return true; } + function HTTPObject::listen(){ return true; } + function HTTPObject::send(){ return true;} + function HTTPObject::post(){ return true; } + + function SecureHTTPObject::onLine(){ return true; } + function SecureHTTPObject::connect(){ return true; } + function SecureHTTPObject::disconnect(){ return true; } + function SecureHTTPObject::listen(){ return true; } + function SecureHTTPObject::send(){ return true; } + function SecureHTTPObject::post(){ return true; } +}; + +package SafeMode +{ + function DispatchLaunchMode() + { + parent::DispatchLaunchMode(); + + // check T2 command line arguments + for(%i = 1; %i < $Game::argc ; %i++) + { + %arg = $Game::argv[%i]; + %nextArg = $Game::argv[%i+1]; + %hasNextArg = $Game::argc - %i > 1; + + if( !stricmp(%arg, "-Safemode")) //If enabled, cuts off all TCP & HTTP object connections, preventing UE's when running T2 without internet + activatePackage(SafeModeOverrides); + } + } +}; activatePackage(SafeMode); \ No newline at end of file diff --git a/scripts/autoexec/staticWaypointFix.cs b/scripts/autoexec/staticWaypointFix.cs index 629e4a7..3540864 100644 --- a/scripts/autoexec/staticWaypointFix.cs +++ b/scripts/autoexec/staticWaypointFix.cs @@ -1,37 +1,37 @@ -// #autoload -// #name = Static Waypoint Fix -// #version = 1.0 -// #category = Fix -// #warrior = Jsut -// #description = Fixes static waypoints in the command circuit. - -package JsutStaticWaypointFix -{ - - function CommanderTree::processCommand(%this, %command, %target, %typeTag) - - { - - parent::processCommand(%this, %command, %target, %typeTag); - - // special case? - - if(%typeTag < 0) - { - switch$(getTaggedString(%command)) - { - // waypoints: tree owns the waypoint targets - case "CreateWayPoint": - %target.settext(%this.currentWaypointID); - return; - } - } - } -}; - -activatePackage(JsutStaticWaypointFix); - - - - - +// #autoload +// #name = Static Waypoint Fix +// #version = 1.0 +// #category = Fix +// #warrior = Jsut +// #description = Fixes static waypoints in the command circuit. + +package JsutStaticWaypointFix +{ + + function CommanderTree::processCommand(%this, %command, %target, %typeTag) + + { + + parent::processCommand(%this, %command, %target, %typeTag); + + // special case? + + if(%typeTag < 0) + { + switch$(getTaggedString(%command)) + { + // waypoints: tree owns the waypoint targets + case "CreateWayPoint": + %target.settext(%this.currentWaypointID); + return; + } + } + } +}; + +activatePackage(JsutStaticWaypointFix); + + + + + diff --git a/scripts/camera.cs b/scripts/camera.cs new file mode 100644 index 0000000..e61c08f --- /dev/null +++ b/scripts/camera.cs @@ -0,0 +1,722 @@ +$Camera::movementSpeed = 40; + +datablock CameraData(Observer) +{ + mode = "observerStatic"; + firstPersonOnly = true; +}; + +datablock CameraData(CommanderCamera) +{ + mode = "observerStatic"; + firstPersonOnly = true; +}; + +function CommanderCamera::onTrigger( %data, %obj, %trigger, %state ) +{ + // no need to do anything here. +} + +function Observer::onTrigger(%data,%obj,%trigger,%state) +{ + // state = 0 means that a trigger key was released + if (%state == 0) + return; + + //first, give the game the opportunity to prevent the observer action + if (!Game.ObserverOnTrigger(%data, %obj, %trigger, %state)) + return; + + //now observer functions if you press the "throw" + if (%trigger >= 4) + return; + + //trigger types: 0:fire 1:altTrigger 2:jump 3:jet 4:throw + %client = %obj.getControllingClient(); + if (%client == 0) + return; + + switch$ (%obj.mode) + { + case "justJoined": + if (isDemo()) + clearCenterPrint(%client); + + //press FIRE + if (%trigger == 0) + { + // clear intro message + clearBottomPrint( %client ); + + //spawn the player + commandToClient(%client, 'setHudMode', 'Standard'); + Game.assignClientTeam(%client); + Game.spawnPlayer( %client, $MatchStarted ); + + if( $MatchStarted ) + { + %client.camera.setFlyMode(); + %client.setControlObject( %client.player ); + } + else + { + %client.camera.getDataBlock().setMode( %client.camera, "pre-game", %client.player ); + %client.setControlObject( %client.camera ); + } + } + + //press JET + else if (%trigger == 3) + { + //cycle throw the static observer spawn points + %markerObj = Game.pickObserverSpawn(%client, true); + %transform = %markerObj.getTransform(); + %obj.setTransform(%transform); + %obj.setFlyMode(); + } + + //press JUMP + else if (%trigger == 2) + { + //switch the observer mode to observing clients + if (isObject(%client.observeFlyClient)) + serverCmdObserveClient(%client, %client.observeFlyClient); + else + serverCmdObserveClient(%client, -1); + + displayObserverHud(%client, %client.observeClient); + messageClient(%client.observeClient, 'Observer', '\c1%1 is now observing you.', %client.name); + } + + case "playerDeath": + // Attached to a dead player - spawn regardless of trigger type + if(!%client.waitRespawn && getSimTime() > %client.suicideRespawnTime) + { + commandToClient(%client, 'setHudMode', 'Standard'); + Game.spawnPlayer( %client, true ); + %client.camera.setFlyMode(); + %client.setControlObject(%client.player); + } + + case "PreviewMode": + if (%trigger == 0) + { + commandToClient(%client, 'setHudMode', 'Standard'); + if( %client.lastTeam ) + Game.clientJoinTeam( %client, %client.lastTeam ); + else + { + Game.assignClientTeam( %client, true ); + + // Spawn the player: + Game.spawnPlayer( %client, false ); + } + + %client.camera.setFlyMode(); + %client.setControlObject( %client.player ); + } + + case "toggleCameraFly": + // this is the default camera mode + + case "observerFly": + // Free-flying observer camera + + if (%trigger == 0) + { + if( !$Host::TournamentMode && $MatchStarted ) + { + // reset observer params + clearBottomPrint(%client); + commandToClient(%client, 'setHudMode', 'Standard'); + + if( %client.lastTeam !$= "" && %client.lastTeam != 0 && Game.numTeams > 1) + { + Game.clientJoinTeam( %client, %client.lastTeam, $MatchStarted ); + %client.camera.setFlyMode(); + %client.setControlObject( %client.player ); + } + else + { + + Game.assignClientTeam( %client ); + + // Spawn the player: + Game.spawnPlayer( %client, true ); + %client.camera.setFlyMode(); + %client.setControlObject( %client.player ); + ClearBottomPrint( %client ); + } + } + else if( !$Host::TournamentMode ) + { + + clearBottomPrint(%client); + Game.assignClientTeam( %client ); + + // Spawn the player: + Game.spawnPlayer( %client, false ); + %client.camera.getDataBlock().setMode( %client.camera, "pre-game", %client.player ); + %client.setControlObject( %client.camera ); + } + } + //press JET + else if (%trigger == 3) + { + %markerObj = Game.pickObserverSpawn(%client, true); + %transform = %markerObj.getTransform(); + %obj.setTransform(%transform); + %obj.setFlyMode(); + } + + //press JUMP + else if (%trigger == 2) + { + //switch the observer mode to observing clients + if (isObject(%client.observeFlyClient)) + serverCmdObserveClient(%client, %client.observeFlyClient); + else + serverCmdObserveClient(%client, -1); + + observerFollowUpdate( %client, %client.observeClient, false ); + displayObserverHud(%client, %client.observeClient); + messageClient(%client.observeClient, 'Observer', '\c1%1 is now observing you.', %client.name); + } + + case "observerStatic": + // Non-moving observer camera + %next = (%trigger == 3 ? true : false); + %markerObj = Game.pickObserverSpawn(%client, %next); + %transform = %markerObj.getTransform(); + %obj.setTransform(%transform); + %obj.setFlyMode(); + + case "observerStaticNoNext": + // Non-moving, non-cycling observer camera + + case "observerTimeout": + // Player didn't respawn quickly enough + if (%trigger == 0) + { + clearBottomPrint(%client); + commandToClient(%client, 'setHudMode', 'Standard'); + if( %client.lastTeam ) + Game.clientJoinTeam( %client, %client.lastTeam, true ); + else + { + Game.assignClientTeam( %client ); + + // Spawn the player: + Game.spawnPlayer( %client, true ); + } + + %client.camera.setFlyMode(); + %client.setControlObject( %client.player ); + } + + //press JET + else if (%trigger == 3) + { + %markerObj = Game.pickObserverSpawn(%client, true); + %transform = %markerObj.getTransform(); + %obj.setTransform(%transform); + %obj.setFlyMode(); + } + + //press JUMP + else if (%trigger == 2) + { + //switch the observer mode to observing clients + if (isObject(%client.observeFlyClient)) + serverCmdObserveClient(%client, %client.observeFlyClient); + else + serverCmdObserveClient(%client, -1); + + // update the observer list for this client + observerFollowUpdate( %client, %client.observeClient, false ); + + displayObserverHud(%client, %client.observeClient); + messageClient(%client.observeClient, 'Observer', '\c1%1 is now observing you.', %client.name); + } + + case "observerFollow": + // Observer attached to a moving object (assume player for now...) + //press FIRE - cycle to next client + if (%trigger == 0) + { + %nextClient = findNextObserveClient(%client); + %prevObsClient = %client.observeClient; + if (%nextClient > 0 && %nextClient != %client.observeClient) + { + // update the observer list for this client + observerFollowUpdate( %client, %nextClient, true ); + + //set the new object + %transform = %nextClient.player.getTransform(); + if( !%nextClient.isMounted() ) + { + %obj.setOrbitMode(%nextClient.player, %transform, 0.5, 4.5, 4.5); + %client.observeClient = %nextClient; + } + else + { + %mount = %nextClient.player.getObjectMount(); + if( %mount.getDataBlock().observeParameters $= "" ) + %params = %transform; + else + %params = %mount.getDataBlock().observeParameters; + + %obj.setOrbitMode(%mount, %mount.getTransform(), getWord( %params, 0 ), getWord( %params, 1 ), getWord( %params, 2 )); + %client.observeClient = %nextClient; + } + + //send the message(s) + displayObserverHud(%client, %nextClient); + messageClient(%nextClient, 'Observer', '\c1%1 is now observing you.', %client.name); + messageClient(%prevObsClient, 'ObserverEnd', '\c1%1 is no longer observing you.', %client.name); + } + } + + //press JET - cycle to prev client + else if (%trigger == 3) + { + %prevClient = findPrevObserveClient(%client); + %prevObsClient = %client.observeClient; + if (%prevClient > 0 && %prevClient != %client.observeClient) + { + // update the observer list for this client + observerFollowUpdate( %client, %prevClient, true ); + + //set the new object + %transform = %prevClient.player.getTransform(); + if( !%prevClient.isMounted() ) + { + %obj.setOrbitMode(%prevClient.player, %transform, 0.5, 4.5, 4.5); + %client.observeClient = %prevClient; + } + else + { + %mount = %prevClient.player.getObjectMount(); + if( %mount.getDataBlock().observeParameters $= "" ) + %params = %transform; + else + %params = %mount.getDataBlock().observeParameters; + + %obj.setOrbitMode(%mount, %mount.getTransform(), getWord( %params, 0 ), getWord( %params, 1 ), getWord( %params, 2 )); + %client.observeClient = %prevClient; + } + + //send the message(s) + displayObserverHud(%client, %prevClient); + messageClient(%prevClient, 'Observer', '\c1%1 is now observing you.', %client.name); + messageClient(%prevObsClient, 'ObserverEnd', '\c1%1 is no longer observing you.', %client.name); + } + } + + //press JUMP + else if (%trigger == 2) + { + // update the observer list for this client + observerFollowUpdate( %client, -1, false ); + + //toggle back to observer fly mode + %obj.mode = "observerFly"; + %obj.setFlyMode(); + updateObserverFlyHud(%client); + messageClient(%client.observeClient, 'ObserverEnd', '\c1%1 is no longer observing you.', %client.name); + } + + case "pre-game": + if(!$Host::TournamentMode || $CountdownStarted) + return; + + if(%client.notReady) + { + %client.notReady = ""; + MessageAll( 0, '\c1%1 is READY.', %client.name ); + if(%client.notReadyCount < 3) + centerprint( %client, "\nWaiting for match start (FIRE if not ready)", 0, 3); + else + centerprint( %client, "\nWaiting for match start", 0, 3); + } + else + { + %client.notReadyCount++; + if(%client.notReadyCount < 4) + { + %client.notReady = true; + MessageAll( 0, '\c1%1 is not READY.', %client.name ); + centerprint( %client, "\nPress FIRE when ready.", 0, 3 ); + } + return; + } + CheckTourneyMatchStart(); + } +} + +function Observer::setMode(%data, %obj, %mode, %targetObj) +{ + if(%mode $= "") + return; + %client = %obj.getControllingClient(); + switch$ (%mode) { + case "justJoined": + commandToClient(%client, 'setHudMode', 'Observer'); + %markerObj = Game.pickObserverSpawn(%client, true); + %transform = %markerObj.getTransform(); + %obj.setTransform(%transform); + %obj.setFlyMode(); + + case "pre-game": + commandToClient(%client, 'setHudMode', 'Observer'); + %obj.setOrbitMode( %targetObj, %targetObj.getTransform(), 0.5, 4.5, 4.5); + + case "observerFly": + // Free-flying observer camera + commandToClient(%client, 'setHudMode', 'Observer'); + %markerObj = Game.pickObserverSpawn(%client, true); + %transform = %markerObj.getTransform(); + %obj.setTransform(%transform); + %obj.setFlyMode(); + + case "observerStatic" or "observerStaticNoNext": + // Non-moving observer camera + %markerObj = Game.pickObserverSpawn(%client, true); + %transform = %markerObj.getTransform(); + %obj.setTransform(%transform); + + case "observerFollow": + // Observer attached to a moving object (assume player for now...) + %transform = %targetObj.getTransform(); + + if( !%targetObj.isMounted() ) + %obj.setOrbitMode(%targetObj, %transform, 0.5, 4.5, 4.5); + else + { + %mount = %targetObj.getObjectMount(); + if( %mount.getDataBlock().observeParameters $= "" ) + %params = %transform; + else + %params = %mount.getDataBlock().observeParameters; + + %obj.setOrbitMode(%mount, %mount.getTransform(), getWord( %params, 0 ), getWord( %params, 1 ), getWord( %params, 2 )); + } + + case "observerTimeout": + commandToClient(%client, 'setHudMode', 'Observer'); + %markerObj = Game.pickObserverSpawn(%client, true); + %transform = %markerObj.getTransform(); + %obj.setTransform(%transform); + %obj.setFlyMode(); + } + %obj.mode = %mode; +} + +function findNextObserveClient(%client) +{ + %index = -1; + %count = ClientGroup.getCount(); + if (%count <= 1) + return -1; + + for (%i = 0; %i < %count; %i++) + { + %cl = ClientGroup.getObject(%i); + if (%cl == %client.observeClient) + { + %index = %i; + break; + } + } + + //now find the next client (note, if not found, %index still == -1) + %index++; + if (%index >= %count) + %index = 0; + + %newClient = -1; + for (%i = %index; %i < %count; %i++) + { + %cl = ClientGroup.getObject(%i); + if (%cl != %client && %cl.player > 0) + { + %newClient = %cl; + break; + } + } + + //if we didn't find anyone, search from the beginning again + if (%newClient < 0) + { + for (%i = 0; %i < %count; %i++) + { + %cl = ClientGroup.getObject(%i); + if (%cl != %client && %cl.player > 0) + { + %newClient = %cl; + break; + } + } + } + + //if we still haven't found anyone (new), give up.. + if (%newClient < 0 || %newClient.player == %player) + return -1; +} + +function findPrevObserveClient(%client) +{ + %index = -1; + %count = ClientGroup.getCount(); + if (%count <= 1) + return -1; + + for (%i = 0; %i < %count; %i++) + { + %cl = ClientGroup.getObject(%i); + if (%cl == %client.observeClient) + { + %index = %i; + break; + } + } + + //now find the prev client + %index--; + if (%index < 0) + %index = %count - 1; + + %newClient = -1; + for (%i = %index; %i >= 0; %i--) + { + %cl = ClientGroup.getObject(%i); + if (%cl != %client && %cl.player > 0) + { + %newClient = %cl; + break; + } + } + + //if we didn't find anyone, search from the end again + if (%newClient < 0) + { + for (%i = %count - 1; %i >= 0; %i--) + { + %cl = ClientGroup.getObject(%i); + if (%cl != %client && %cl.player > 0) + { + %newClient = %cl; + break; + } + } + } + + //if we still haven't found anyone (new), give up.. + if (%newClient < 0 || %newClient.player == %player) + return -1; +} + +function observeClient(%client) +{ + if( $testcheats ) + { + //pass in -1 to choose any client... + commandToServer('observeClient', %client); + } +} + +function serverCmdObserveClient(%client, %target) +{ + //clear the observer fly mode var... + %client.observeFlyClient = -1; + + //cancel any scheduled update + cancel(%client.obsHudSchedule); + + // must be an observer when observing other clients + if( %client.getControlObject() != %client.camera) + return; + + //can't observer yourself + if (%client == %target) + return; + + %count = ClientGroup.getCount(); + + //can't go into observer mode if you're the only client + if (%count <= 1) + return; + + //make sure the target actually exists + if (%target > 0) + { + %found = false; + for (%i = 0; %i < %count; %i++) + { + %cl = ClientGroup.getObject(%i); + if (%cl == %target) + { + %found = true; + break; + } + } + + if (!%found) + return; + } + + else + { + %client.observeClient = -1; + %target = findNextObserveClient(%client); + if (%target <= 0) + return; + } + + //send the message + if (%client.camera.mode !$= "observerFollow") + { + if (isObject(%client.player)) + %client.player.scriptKill(0); + + //messageAllExcept(%client, -1, 'ClientNowObserver', '\c1%1 is now an observer.', %client.name); + //messageClient(%client, 'YouNowObserver', '\c1You are now observing %1.', %target.name); + } + + %client.camera.getDataBlock().setMode(%client.camera, "observerFollow", %target.player); + %client.setControlObject(%client.camera); + + //tag is used if a client who is being observed dies... + %client.observeClient = %target; +} + +function observerFollowUpdate( %client, %nextClient, %cycle ) +{ + %Oclient = %client.observeClient; + if( %Oclient $= "" ) + return; + + // changed to observer fly... + if( %nextClient == -1 ) + { + // find us in their observer list and remove, then reshuffle the list... + for( %i = 0; %i < %Oclient.observeCount; %i++ ) + { + if( %Oclient.observers[%i] == %client ) + { + %Oclient.observeCount--; + %Oclient.observers[%i] = %Oclient.observers[%Oclient.observeCount]; + %Oclient.observers[%Oclient.observeCount] = ""; + break; + } + } + return; // were done.. + } + + // changed from observer fly to observer follow... + if( !%cycle && %nextClient != -1 ) + { + // if nobody is observing this guy, initialize their observer count... + if( %nextClient.observeCount $= "" ) + %nextClient.observeCount = 0; + + // add us to their list of observers... + %nextClient.observers[%nextClient.observeCount] = %client; + %nextClient.observeCount++; + return; // were done. + } + + if( %nextClient != -1 ) + { + // cycling to the next client... + for( %i = 0; %i < %Oclient.observeCount; %i++ ) + { + // first remove us from our prev client's list... + if( %Oclient.observers[%i] == %client ) + { + %Oclient.observeCount--; + %Oclient.observers[%i] = %Oclient.observers[%Oclient.observeCount]; + %Oclient.observers[%Oclient.observeCount] = ""; + break; // screw you guys, i'm goin home! + } + } + + // if nobody is observing this guy, initialize their observer count... + if( %nextClient.observeCount $= "" ) + %nextClient.observeCount = 0; + + // now add us to the new clients list... + %nextClient.observeCount++; + %nextClient.observers[%nextClient.observeCount - 1] = %client; + } +} + +function updateObserverFlyHud(%client) +{ + if (!isObject(%client)) + return; + //just in case there are two threads going... + cancel(%client.obsHudSchedule); + %client.observeFlyClient = -1; + + //make sure the client is supposed to be in observer fly mode... + if (!isObject(%client) || %client.team != 0 || %client.getControlObject() != %client.camera || %client.camera.mode $= "observerFollow") + return; + + //get various info about the player's eye + %srcEyeTransform = %client.camera.getTransform(); + %srcEyePoint = firstWord(%srcEyeTransform) @ " " @ getWord(%srcEyeTransform, 1) @ " " @ getWord(%srcEyeTransform, 2); + + %srcEyeVector = MatrixMulVector("0 0 0 " @ getWords(%srcEyeTransform, 3, 6), "0 1 0"); + %srcEyeVector = VectorNormalize(%srcEyeVector); + + //see if there's an enemy near our defense location... + %clientCount = 0; + %count = ClientGroup.getCount(); + %viewedClient = -1; + %clientDot = -1; + for(%i = 0; %i < %count; %i++) + { + %cl = ClientGroup.getObject(%i); + + //make sure we find an AI who's alive and not the client + if (%cl != %client && isObject(%cl.player)) + { + //make sure the player is within range + %clPos = %cl.player.getWorldBoxCenter(); + %distance = VectorDist(%clPos, %srcEyePoint); + if (%distance <= 30) + { + //create the vector from the client to the client + %clVector = VectorNormalize(VectorSub(%clPos, %srcEyePoint)); + + //see if the dot product is greater than our current, and greater than 0.6 + %dot = VectorDot(%clVector, %srcEyeVector); + + if (%dot > 0.6 && %dot > %clientDot) + { + //make sure we're not looking through walls... + %mask = $TypeMasks::TerrainObjectType | $TypeMasks::InteriorObjectType | $TypeMasks::StaticShapeObjectType; + %losResult = containerRayCast(%srcEyePoint, %clPos, %mask); + %losObject = GetWord(%losResult, 0); + if (!isObject(%losObject)) + { + %viewedClient = %cl; + %clientDot = %dot; + } + } + } + } + } + + if (isObject(%viewedClient)) + displayObserverHud(%client, 0, %viewedClient); + else + displayObserverHud(%client, 0); + + %client.observeFlyClient = %viewedClient; + + //schedule the next... + %client.obsHudSchedule = schedule(500, %client, updateObserverFlyHud, %client); +} + diff --git a/scripts/chatMenuHud.cs b/scripts/chatMenuHud.cs index fde11c9..c76f05e 100644 --- a/scripts/chatMenuHud.cs +++ b/scripts/chatMenuHud.cs @@ -1,233 +1,233 @@ -//------------------------------------------------------------------------------ -// -// chatMenuHud.cs -// -//------------------------------------------------------------------------------ - -if ( isFile( "prefs/customVoiceBinds.cs" ) ) - $defaultVoiceBinds = false; -else - $defaultVoiceBinds = true; - -// Load in all of the installed chat items: -exec( "scripts/cannedChatItems.cs" ); - - -//------------------------------------------------------------------------------ -// Chat menu loading function: -new SimSet( ChatMenuList ); // Store all of the chat menu maps here so that we can delete them later: -function activateChatMenu( %filename ) -{ - if ( isFile( %filename ) || isFile( %filename @ ".dso" ) ) - { - // Clear the old chat menu: - ChatMenuList.clear(); - - // Create the root of the new menu: - $RootChatMenu = new ActionMap(); - ChatMenuList.add( $RootChatMenu ); - $CurrentChatMenu = $RootChatMenu; - $CurrentChatMenu.optionCount = 0; - $CurrentChatMenu.bindCmd(keyboard, escape, "cancelChatMenu();", ""); - - // Build the new chat menu: - exec( %filename ); - } - else - error( "Chat menu file \"" @ %filename @ "\" not found!" ); -} - -//------------------------------------------------------------------------------ -// Chat menu building functions: -function startChatMenu(%heading) -{ - %key = firstWord(%heading); - %text = restWords(%heading); - %menu = new ActionMap(); - ChatMenuList.add( %menu ); - %cm = $CurrentChatMenu; - %cm.bindCmd(keyboard, %key, "setChatMenu(\"" @ %text @ "\", " @ %menu @ ");", ""); - %cm.option[%cm.optionCount] = %key @ ": " @ %text; - %cm.command[%cm.optionCount] = %menu; // Save this off here for later... - %cm.isMenu[%cm.optionCount] = 1; - %cm.optionCount++; - %menu.parent = %cm; - %menu.bindCmd(keyboard, escape, "cancelChatMenu();", ""); - %menu.optionCount = 0; - $CurrentChatMenu = %menu; -} - -function endChatMenu() -{ - $CurrentChatMenu = $CurrentChatMenu.parent; -} - -function addChat(%keyDesc, %command) -{ - %key = firstWord(%keyDesc); - %text = restWords(%keyDesc); - %cm = $CurrentChatMenu; - %cm.bindCmd(keyboard, %key, "issueChatCmd(" @ %cm @ "," @ %cm.optionCount @ ");", ""); - %cm.option[%cm.optionCount] = %key @ ": " @ %text; - %cm.command[%cm.optionCount] = %command; - %cm.isMenu[%cm.optionCount] = 0; - %cm.optionCount++; -} - - -//------------------------------------------------------------------------------ -// Chat menu hud functions: -$ChatMenuHudLineCount = 0; -function activateChatMenuHud( %make ) -{ - if(%make && !TaskHudDlg.isVisible()) - showChatMenuHud(); -} - -function showChatMenuHud() -{ - Canvas.pushDialog(ChatMenuHudDlg); - ChatMenuHudDlg.setVisible(true); - setChatMenu(Root, $RootChatMenu); -} - -function cancelChatMenu() -{ - $CurrentChatMenu.pop(); - $CurrentChatMenu = $RootChatMenu; - Canvas.popDialog(ChatMenuHudDlg); - ChatMenuHudDlg.setVisible(false); -} - -function setChatMenu( %name, %menu ) -{ - for ( %i = 0; %i < $ChatMenuHudLineCount; %i++ ) - chatMenuHud.remove( $ChatMenuHudText[%i] ); - - $ChatMenuHudLineCount = %menu.optionCount + 1; - chatMenuHud.extent = "170" SPC ( $ChatMenuHudLineCount * 15 ) + 8; - - // First add the menu title line: - $ChatMenuHudText[0] = new GuiTextCtrl() - { - profile = "GuiHudVoiceMenuProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "5 3"; - extent = "165 20"; - minExtent = "8 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - helpTag = "0"; - text = "\c2" @ %name @ " Menu:"; - }; - chatMenuHud.add( $ChatMenuHudText[0] ); - - // Now add all of the menu options: - for ( %option = 0; %option < %menu.optionCount; %option++ ) - { - %yOffset = ( %option * 15 ) + 18; - - if ( %menu.isMenu[%option] == 1 ) - { - $ChatMenuHudText[%option + 1] = new GuiTextCtrl() - { - profile = "GuiHudVoiceMenuProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "5 " @ %yOffset; - extent = "165 20"; - minExtent = "8 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - helpTag = "0"; - text = " " @ %menu.option[%option]; - }; - } - else - { - $ChatMenuHudText[%option + 1] = new GuiTextCtrl() - { - profile = "GuiHudVoiceCommandProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "5 " @ %yOffset; - extent = "165 20"; - minExtent = "8 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - helpTag = "0"; - text = " " @ %menu.option[%option]; - }; - } - - chatMenuHud.add( $ChatMenuHudText[%option + 1] ); - } - - //bind "anykey" to closing the chat menu, so if you press an invalid entry, you don't accidently - //open the commander map or something... - %menu.bindCmd(keyboard, "anykey", "cancelChatMenu();", ""); - - // Pop the old menu map and push the new menu's map: - $CurrentChatMenu.pop(); - $CurrentChatMenu = %menu; - %menu.push(); -} - -function issueChatCmd( %menu, %index ) -{ - processChatItemCallbacks( %menu.command[%index] ); - commandToServer( 'CannedChat', %menu.command[%index], false ); - cancelChatMenu(); -} - - -//------------------------------------------------------------------------------ -// Canned chat handler: -function serverCmdCannedChat( %client, %command, %fromAI ) -{ - %cmdCode = getWord( %command, 0 ); - %cmdId = getSubStr( %cmdCode, 1, strlen( %command ) - 1 ); - %cmdString = getWord( %command, 1 ); - if ( %cmdString $= "" ) - %cmdString = getTaggedString( %cmdCode ); - - if ( !isObject( $ChatTable[%cmdId] ) ) - { - error( %cmdString @ " is not a recognized canned chat command." ); - return; - } - - %chatItem = $ChatTable[%cmdId]; - - //if there is text - if (%chatItem.text !$= "" || !%chatItem.play3D) - { - %message = %chatItem.text @ "~w" @ %chatItem.audioFile; - - if ( %chatItem.teamOnly ) - cannedChatMessageTeam( %client, %client.team, '\c3%1: %2', %client.name, %message, %chatItem.defaultKeys ); - else - cannedChatMessageAll( %client, '\c4%1: %2', %client.name, %message, %chatItem.defaultKeys ); - } - - //if no text, see if the audio is to be played in 3D... - else if ( %chatItem.play3D && %client.player ) - playTargetAudio(%client.target, addTaggedString(%chatItem.audioFile), AudioClosest3d, true); - - if ( %chatItem.animation !$= "" ) - PlayAnim(%client, %chatItem.animation); // z0dd - ZOD, 8/15/02. Remove client direct requests to start animations. Was: serverCmdPlayAnim - - // Let the AI respond to the canned chat messages (from humans only) - if (!%fromAI) - CreateVoiceServerTask(%client, %cmdCode); -} - -if ( $defaultVoiceBinds ) - activateChatMenu( "scripts/voiceBinds.cs" ); -else - activateChatMenu( "prefs/customVoiceBinds.cs" ); - +//------------------------------------------------------------------------------ +// +// chatMenuHud.cs +// +//------------------------------------------------------------------------------ + +if ( isFile( "prefs/customVoiceBinds.cs" ) ) + $defaultVoiceBinds = false; +else + $defaultVoiceBinds = true; + +// Load in all of the installed chat items: +exec( "scripts/cannedChatItems.cs" ); + + +//------------------------------------------------------------------------------ +// Chat menu loading function: +new SimSet( ChatMenuList ); // Store all of the chat menu maps here so that we can delete them later: +function activateChatMenu( %filename ) +{ + if ( isFile( %filename ) || isFile( %filename @ ".dso" ) ) + { + // Clear the old chat menu: + ChatMenuList.clear(); + + // Create the root of the new menu: + $RootChatMenu = new ActionMap(); + ChatMenuList.add( $RootChatMenu ); + $CurrentChatMenu = $RootChatMenu; + $CurrentChatMenu.optionCount = 0; + $CurrentChatMenu.bindCmd(keyboard, escape, "cancelChatMenu();", ""); + + // Build the new chat menu: + exec( %filename ); + } + else + error( "Chat menu file \"" @ %filename @ "\" not found!" ); +} + +//------------------------------------------------------------------------------ +// Chat menu building functions: +function startChatMenu(%heading) +{ + %key = firstWord(%heading); + %text = restWords(%heading); + %menu = new ActionMap(); + ChatMenuList.add( %menu ); + %cm = $CurrentChatMenu; + %cm.bindCmd(keyboard, %key, "setChatMenu(\"" @ %text @ "\", " @ %menu @ ");", ""); + %cm.option[%cm.optionCount] = %key @ ": " @ %text; + %cm.command[%cm.optionCount] = %menu; // Save this off here for later... + %cm.isMenu[%cm.optionCount] = 1; + %cm.optionCount++; + %menu.parent = %cm; + %menu.bindCmd(keyboard, escape, "cancelChatMenu();", ""); + %menu.optionCount = 0; + $CurrentChatMenu = %menu; +} + +function endChatMenu() +{ + $CurrentChatMenu = $CurrentChatMenu.parent; +} + +function addChat(%keyDesc, %command) +{ + %key = firstWord(%keyDesc); + %text = restWords(%keyDesc); + %cm = $CurrentChatMenu; + %cm.bindCmd(keyboard, %key, "issueChatCmd(" @ %cm @ "," @ %cm.optionCount @ ");", ""); + %cm.option[%cm.optionCount] = %key @ ": " @ %text; + %cm.command[%cm.optionCount] = %command; + %cm.isMenu[%cm.optionCount] = 0; + %cm.optionCount++; +} + + +//------------------------------------------------------------------------------ +// Chat menu hud functions: +$ChatMenuHudLineCount = 0; +function activateChatMenuHud( %make ) +{ + if(%make && !TaskHudDlg.isVisible()) + showChatMenuHud(); +} + +function showChatMenuHud() +{ + Canvas.pushDialog(ChatMenuHudDlg); + ChatMenuHudDlg.setVisible(true); + setChatMenu(Root, $RootChatMenu); +} + +function cancelChatMenu() +{ + $CurrentChatMenu.pop(); + $CurrentChatMenu = $RootChatMenu; + Canvas.popDialog(ChatMenuHudDlg); + ChatMenuHudDlg.setVisible(false); +} + +function setChatMenu( %name, %menu ) +{ + for ( %i = 0; %i < $ChatMenuHudLineCount; %i++ ) + chatMenuHud.remove( $ChatMenuHudText[%i] ); + + $ChatMenuHudLineCount = %menu.optionCount + 1; + chatMenuHud.extent = "170" SPC ( $ChatMenuHudLineCount * 15 ) + 8; + + // First add the menu title line: + $ChatMenuHudText[0] = new GuiTextCtrl() + { + profile = "GuiHudVoiceMenuProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 3"; + extent = "165 20"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + helpTag = "0"; + text = "\c2" @ %name @ " Menu:"; + }; + chatMenuHud.add( $ChatMenuHudText[0] ); + + // Now add all of the menu options: + for ( %option = 0; %option < %menu.optionCount; %option++ ) + { + %yOffset = ( %option * 15 ) + 18; + + if ( %menu.isMenu[%option] == 1 ) + { + $ChatMenuHudText[%option + 1] = new GuiTextCtrl() + { + profile = "GuiHudVoiceMenuProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 " @ %yOffset; + extent = "165 20"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + helpTag = "0"; + text = " " @ %menu.option[%option]; + }; + } + else + { + $ChatMenuHudText[%option + 1] = new GuiTextCtrl() + { + profile = "GuiHudVoiceCommandProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 " @ %yOffset; + extent = "165 20"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + helpTag = "0"; + text = " " @ %menu.option[%option]; + }; + } + + chatMenuHud.add( $ChatMenuHudText[%option + 1] ); + } + + //bind "anykey" to closing the chat menu, so if you press an invalid entry, you don't accidently + //open the commander map or something... + %menu.bindCmd(keyboard, "anykey", "cancelChatMenu();", ""); + + // Pop the old menu map and push the new menu's map: + $CurrentChatMenu.pop(); + $CurrentChatMenu = %menu; + %menu.push(); +} + +function issueChatCmd( %menu, %index ) +{ + processChatItemCallbacks( %menu.command[%index] ); + commandToServer( 'CannedChat', %menu.command[%index], false ); + cancelChatMenu(); +} + + +//------------------------------------------------------------------------------ +// Canned chat handler: +function serverCmdCannedChat( %client, %command, %fromAI ) +{ + %cmdCode = getWord( %command, 0 ); + %cmdId = getSubStr( %cmdCode, 1, strlen( %command ) - 1 ); + %cmdString = getWord( %command, 1 ); + if ( %cmdString $= "" ) + %cmdString = getTaggedString( %cmdCode ); + + if ( !isObject( $ChatTable[%cmdId] ) ) + { + error( %cmdString @ " is not a recognized canned chat command." ); + return; + } + + %chatItem = $ChatTable[%cmdId]; + + //if there is text + if (%chatItem.text !$= "" || !%chatItem.play3D) + { + %message = %chatItem.text @ "~w" @ %chatItem.audioFile; + + if ( %chatItem.teamOnly ) + cannedChatMessageTeam( %client, %client.team, '\c3%1: %2', %client.name, %message, %chatItem.defaultKeys ); + else + cannedChatMessageAll( %client, '\c4%1: %2', %client.name, %message, %chatItem.defaultKeys ); + } + + //if no text, see if the audio is to be played in 3D... + else if ( %chatItem.play3D && %client.player ) + playTargetAudio(%client.target, addTaggedString(%chatItem.audioFile), AudioClosest3d, true); + + if ( %chatItem.animation !$= "" ) + PlayAnim(%client, %chatItem.animation); // z0dd - ZOD, 8/15/02. Remove client direct requests to start animations. Was: serverCmdPlayAnim + + // Let the AI respond to the canned chat messages (from humans only) + if (!%fromAI) + CreateVoiceServerTask(%client, %cmdCode); +} + +if ( $defaultVoiceBinds ) + activateChatMenu( "scripts/voiceBinds.cs" ); +else + activateChatMenu( "prefs/customVoiceBinds.cs" ); + diff --git a/scripts/client.cs b/scripts/client.cs index 43ec6f6..033f5ba 100644 --- a/scripts/client.cs +++ b/scripts/client.cs @@ -1,2182 +1,2182 @@ -//---------------------------------------------------------------------------- - -//---------------------------------------------------------------------------- -function SAD(%password) -{ - if(%password !$= "") - commandToServer('SAD', %password); -} - -function SADSetPassword(%password) -{ - commandToServer('SADSetPassword', %password); -} - -function use(%data) -{ - // %data is currently the datablock name of the item - commandToServer('use',%data); -} - -function throw(%data) -{ - // %data is currently the datablock name of the item - commandToServer('throw',%data); -} - -function giveAll() -{ - commandToServer('giveAll'); -} - -function clientCmdSetPlayContent() -{ - if ( $LaunchMode $= "InteriorView" ) - Canvas.setContent( interiorPreviewGui ); - else if ( $LaunchMode $= "TSShow" ) - Canvas.setContent( TSShowGui ); - else - Canvas.setContent( Playgui ); -} - -function clientCmdPickTeamMenu( %teamA, %teamB ) -{ - ClientCmdSetHudMode("PickTeam"); - PickTeamAButton.text = getTaggedString( %teamA ); - PickTeamBButton.text = getTaggedString( %teamB ); - PickTeamFrame.setTitle( "Pick Team" ); - - Canvas.pushDialog( PickTeamDlg ); -} - -function clientCmdProcessPickTeam( %option ) -{ - if( %option !$= "" && %option <= 4 ) - CommandToServer( 'clientPickedTeam', %option ); - else if( %option !$= "" && %option == 5 ) - disconnect(); - - Canvas.popDialog( PickTeamDlg ); -} - -new MessageVector(HudMessageVector); - -$LastHudTarget = 0; - -function addMessageHudLine(%text) -{ - %adjustPos = false; - if( chatPageDown.isVisible() ) - { - %adjustPos = true; - %origPosition = chatHud.position; - } - - //add the message... - while( !chatPageDown.isVisible() && HudMessageVector.getNumLines() && (HudMessageVector.getNumLines() >= $pref::HudMessageLogSize)) - { - %tag = HudMessageVector.getLineTag(0); - if(%tag != 0) - %tag.delete(); - HudMessageVector.popFrontLine(); - } - HudMessageVector.pushBackLine(%text, $LastHudTarget); - $LastHudTarget = 0; - - //now that we've added the message, see if we need to reset the position - if ( %adjustPos ) - { - chatPageDown.setVisible(true); - ChatPageDown.position = ( firstWord( outerChatHud.extent ) - 20 ) @ " " @ ( $chatScrollLenY[$Pref::chatHudLength] - 6 ); - chatHud.position = %origPosition; - } - else - chatPageDown.setVisible(false); - -} - -function pageUpMessageHud() -{ - //find out the text line height - %textHeight = chatHud.profile.fontSize; - if (%textHeight <= 0) - %textHeight = 12; - - //find out how many lines per page are visible - %chatScrollHeight = getWord(chatHud.getGroup().getGroup().extent, 1); - if (%chatScrollHeight <= 0) - return; - - %pageLines = mFloor(%chatScrollHeight / %textHeight) - 1; - if (%pageLines <= 0) - %pageLines = 1; - - //see how many lines we actually can scroll up: - %chatPosition = -1 * getWord(chatHud.position, 1); - %linesToScroll = mFloor((%chatPosition / %textHeight) + 0.5); - if (%linesToScroll <= 0) - return; - - if (%linesToScroll > %pageLines) - %scrollLines = %pageLines; - else - %scrollLines = %linesToScroll; - - //now set the position - chatHud.position = firstWord(chatHud.position) SPC (getWord(chatHud.position, 1) + (%scrollLines * %textHeight)); - - //display the pageup icon - ChatPageDown.position = ( firstWord( outerChatHud.extent ) - 20 ) @ " " @ ( $chatScrollLenY[$pref::chatHudLength] - 6 ); - chatPageDown.setVisible(true); -} - -function pageDownMessageHud() -{ - //find out the text line height - %textHeight = chatHud.profile.fontSize; - if (%textHeight <= 0) - %textHeight = 12; - - //find out how many lines per page are visible - %chatScrollHeight = getWord(chatHud.getGroup().getGroup().extent, 1); - 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(chatHud.extent, 1) - %chatScrollHeight + getWord(chatHud.position, 1); - %linesToScroll = mFloor((%chatPosition / %textHeight) + 0.5); - if (%linesToScroll <= 0) - return; - - if (%linesToScroll > %pageLines) - %scrollLines = %pageLines; - else - %scrollLines = %linesToScroll; - - //now set the position - chatHud.position = firstWord(chatHud.position) SPC (getWord(chatHud.position, 1) - (%scrollLines * %textHeight)); - - //see if we have should (still) display the pagedown icon - if (%scrollLines < %linesToScroll) - { - chatPageDown.setVisible(true); - ChatPageDown.position = ( firstWord( outerChatHud.extent ) - 20 ) @ " " @ ( $chatScrollLenY[$Pref::chatHudLength] - 6 ); - } - else - chatPageDown.setVisible(false); -} - - -function RTS_RightButton(%val) -{ - if(%val) - { - CommanderTVControl.push(); - RTS_LeftButton(0); - CursorOff(); - } - else - { - CommanderTVControl.pop(); - Canvas.cursorOn(); //Show the cursor - } -} - -function clientCmdAlxPlayMusic(%file) -{ -alxPlayMusic(%file); -return %file; -} - -function RTS_LeftButton(%val) -{ - if (%val) //We clicked -- we must make our little selection box o' doom - { - %pos = Canvas.getCursorPos(); - PlayGui.selectBox = new HudZoom() { - profile = "ZoomHudProfile"; - position = %pos; - extent = "5 5"; //Any smaller and you don't know it exists. - visible = "1"; - fillColor = "0.250000 0.250000 0.250000 0.250000"; - frameColor = "0.000000 1.000000 0.000000 1.000000"; - opacity = "1"; - }; - PlayGui.add(Playgui.selectBox); - RTS_RightButton(0); - Canvas.setCursor(GrabCursor); - $RTSSelect = true; - RTS_SelectLoop(); - } - else - { - if (IsObject(Playgui.selectBox)) - Playgui.selectBox.delete(); - Canvas.setCursor(DefaultCursor); - $RTSSelect = false; - } -} - -//I should get Emp to handle this.. he knows his vect0r math -function RTS_SelectLoop() //For now, unless there's a function on the Canvas that is called when le' cursor is moved -{ -if (!$RTSSelect) -return; - -%pos = Canvas.getCursorPos(); -%x = getWord(%pos, 0); -%y = getWord(%pos, 1); - -PlayGui.selectBox.setExtent(%x * 0.5, %y * 0.5); -schedule(1,0,"RTS_SelectLoop"); -} - -function clientCmdIsRTSGame() -{ -hudClusterBack.opacity = 0; //Make it invisible -clientCmdShowCursor(1); //Show our cursor -} - -$cursorControlled = true; - -function CursorOff() -{ - if ( $cursorControlled ) - lockMouse(true); - Canvas.cursorOff(); -} - -function CursorOn() -{ - if ( $cursorControlled ) - lockMouse(false); - Canvas.cursorOn(); - Canvas.setCursor(DefaultCursor); -} - -function toggleCursorControl() -{ - // If the user manually toggles the mouse control, lock or unlock for them - if ( $cursorControlled ) - $cursorControlled = false; - else - $cursorControlled = true; - lockMouse($cursorControlled); -} - -if ( $platform $= "linux" ) - GlobalActionMap.bindCmd(keyboard, "ctrl g", "", "toggleCursorControl();"); - -function toggleNetDisplayHud(%val) -{ - if(%val) - { - if(NetGraphHudFrame.isVisible()) - { - NetGraphHudFrame.setVisible(false); - NetBarHudFrame.setVisible(true); - } - else if(NetBarHudFrame.isVisible()) - { - NetBarHudFrame.setVisible(false); - } - else - NetGraphHudFrame.setVisible(true); - } -} - -function PlayGui::onWake(%this) -{ - // Make sure the shell hum is off: - if ( $HudHandle[shellScreen] !$= "" ) - { - alxStop( $HudHandle[shellScreen] ); - $HudHandle[shellScreen] = ""; - } - - $enableDirectInput = "1"; - activateDirectInput(); - - // chat hud dialog - Canvas.pushDialog( MainChatHud ); - chatHud.attach(HudMessageVector); - - // just update the action map here, the huds should be properly setup - updateActionMaps(); - - // hack city - these controls are floating around and need to be clamped - schedule(0, 0, "refreshCenterTextCtrl"); - schedule(0, 0, "refreshBottomTextCtrl"); - - // update the network graph prefs - NetGraphHud.getPrefs(); -} - -function refreshBottomTextCtrl() -{ - BottomPrintText.position = "0 0"; -} - -function refreshCenterTextCtrl() -{ - CenterPrintText.position = "0 0"; -} - -function PlayGui::onSleep(%this) -{ - Canvas.popDialog( MainChatHud ); - - //pop all possible keymaps - moveMap.pop(); - if ( isObject( passengerKeys ) ) - passengerKeys.pop(); - if ( isObject( observerBlockMap ) ) - observerBlockMap.pop(); - if ( isObject( observerMap ) ) - observerMap.pop(); - //flyingCameraMove.pop(); -} - -function onConnectRequestRejected( %msg ) -{ - switch$(%msg) - { - case "CR_INVALID_CONNECT_PACKET": - %error = "Network error - badly formed network packet - this should not happen!"; - case "CR_AUTHENTICATION_FAILED": - %error = "Failed to authenticate with server. Please restart TRIBES 2 and try again."; - case "CR_YOUAREBANNED": - %error = "You are not allowed to play on this server."; - case "CR_SERVERFULL": - %error = "This server is full."; - default: - %error = "Connection error. Please try another server. Error code: (" @ %msg @ ")"; - } - DisconnectedCleanup(); - MessageBoxOK( "REJECTED", %error); -} - -function onChallengeRequestRejected( %msg ) -{ - CloseMessagePopup(); - DisconnectedCleanup(); - switch$(%msg) - { - case "PASSWORD": - if ( $JoinGamePassword $= "" ) - Canvas.pushDialog( PasswordDlg ); - else - { - $JoinGamePassword = ""; - MessageBoxOK( "REJECTED", "That password is incorrect."); - } - return; - case "CHR_PROTOCOL_SERVER": - %error = "Incompatible protocol version: The server is running an older, incompatible version of Tribes 2."; - case "CHR_PROTOCOL": - %error = "Incompatible protocol version: You must upgrade your game version to play on this server."; - case "CHR_NOT_AUTHENTICATED": - %error = "This is an online server - you must be logged in to play on it."; - case "CHR_INVALID_SERVER_PACKET": - %error = "Invalid server response packet. This should not happen."; - case "WS_PeerAuthServer_ExpiredClientCertificate": - %error = "Authentication error - please restart TRIBES 2 and try again."; - default: - %error = "Connection challenge error. Please try another server. Error code: (" @ %msg @ ")"; - } - MessageBoxOK( "REJECTED", %error ); -} - -function onConnectRequestTimedOut() -{ - DisconnectedCleanup(); - MessageBoxOK( "TIMED OUT", "Your connection to the server timed out." ); -} - -function onConnectionToServerTimedOut() -{ - DisconnectedCleanup(); - MessageBoxOK( "TIMED OUT", "Your connection to the server timed out."); -} - -function onConnectionToServerLost( %msg ) -{ - DisconnectedCleanup(); - if ( %msg $= "" ) - %msg = "Your connection to the server was lost."; - MessageBoxOK( "DISCONNECTED", %msg ); -} - -// Client voting functions: -function startNewVote(%name, %arg1, %arg2, %arg3, %arg4, %playerVote) -{ - if ( %arg1 $= "" ) - %arg1 = 0; - if ( %arg2 $= "" ) - %arg2 = 0; - if ( %arg3 $= "" ) - %arg3 = 0; - if ( %arg4 $= "" ) - %arg4 = 0; - if ( %playerVote $= "" ) - %playerVote = 0; - - commandToServer('startNewVote', %name, %arg1, %arg2, %arg3, %arg4, %playerVote); -} - -function setPlayerVote(%vote) -{ - commandToServer('setPlayerVote', %vote); -} - -function ClientCmdVoteSubmitted(%type) -{ - clientCmdClearBottomPrint(); - - if(%type) - alxPlay(VoteAgainstSound, 0, 0, 0); - else - alxPlay(VoteForSound, 0, 0, 0); -} -// End client voting functions. - -//-------------------------------------------------------------------------- -// Player pref functions: -function getPlayerPrefs( %player ) -{ - %voiceMuted = false; - if ( $PlayingOnline ) - { - if ( !%player.isSmurf ) - { - %record = queryPlayerDatabase( %player.guid ); - if ( %record !$= "" ) - { - if ( firstWord( %record ) == 1 ) - { - %player.chatMuted = true; - commandToServer( 'TogglePlayerMute', %player.clientId ); - } - - %voiceMuted = getWord( %record, 1 ) == 1; - } - } - else - %voiceMuted = true; // For now, automatically mute smurfs - } - - commandToServer( 'ListenTo', %player.clientId, !%voiceMuted, false ); -} - -//-------------------------------------------------------------------------- -function handlePlayerMuted( %msgType, %msgString, %name, %client, %mute ) -{ - if ( isObject( $PlayerList[%client] ) ) - { - $PlayerList[%client].chatMuted = %mute; - if ( $PlayingOnline && !$PlayerList[%client].isSmurf && $PlayerList[%client].guid > 0 ) - setPlayerTextMuted( $PlayerList[%client].guid, %mute ); - } -} - -//-------------------------------------------------------------------------- -function clientCmdEndBomberSight() -{ - PlayGui.remove($bombSightHud); -} - -function clientCmdRemoveReticle() -{ - reticleHud.setBitmap(""); - reticleFrameHud.setVisible(false); -} - -function clientCmdSetBeaconNames(%target, %marker, %vehicle) -{ - setBeaconNames(%target, %marker, %vehicle); -} - -function clientCmdStartBomberSight() -{ - $bombSightHud = new HudBombSight(bombSightName) { - profile = "GuiDefaultProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "286 206"; - extent = "67 67"; - minExtent = "8 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - helpTag = "0"; - minDisplayHeight = "20"; - }; - PlayGui.add($bombSightHud); -} - -function tempShowSpeed(%client) -{ - if(!$tmpSpeedShow) - $tmpSpeedShow = true; - else - $tmpSpeedShow = false; - commandToClient(%client, 'toggleSpeed', %client, $tmpSpeedShow); -} - -function clientCmdToggleSpeed(%client, %toggle) -{ - if(%toggle) { - %tempSpeedHud = new GuiTextCtrl(tmpSpeed) { - profile = "GuiTempSpeedProfile"; - horizSizing = "center"; - vertSizing = "top"; - position = "175 200"; - extent = "120 50"; - minExtent = "8 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - }; - PlayGui.add(%tempSpeedHud); - %client.updateTempSpeed(%client); - } - else { - cancel(%client.tmpSpeedCheck); - tmpSpeed.delete(); - } -} - -function GameConnection::updateTempSpeed(%client) -{ - commandToClient(%client, 'getTempSpeed'); - %client.tmpSpeedCheck = %client.schedule(100, "updateTempSpeed", %client); -} - -function clientCmdGetTempSpeed() -{ - %vel = getControlObjectSpeed(); - tmpSpeed.setValue(%vel); -} - -function clientCmdInitLoadClientFavorites() -{ - loadFavorite($pref::FavCurrentSelect); -} - -function clientCmdToggleDashHud(%val) -{ - if(!%val) { - if(isObject(vDiagramHud)) - { - vDiagramHud.delete(); - cancel(dashboardHud.speedCheck); - vSpeedBox.delete(); - } - if(isObject(vOverheadHud)) - vOverheadHud.delete(); - if(isObject(vEnergyFrame)) - vEnergyFrame.delete(); - if(isObject(vDamageFrame)) - vDamageFrame.delete(); - if(isObject(vAltitudeBox)) - { - cancel(dashboardHud.altitudeCheck); - vAltitudeBox.delete(); - } - if(isObject(vWeaponOne)) - vWeaponOne.delete(); - if(isObject(vWeaponTwo)) - vWeaponTwo.delete(); - if(isObject(vWeaponThree)) - vWeaponThree.delete(); - if(isObject(vWeapHiliteOne)) - vWeapHiliteOne.delete(); - if(isObject(vWeapHiliteTwo)) - vWeapHiliteTwo.delete(); - if(isObject(vWeapHiliteThree)) - vWeapHiliteThree.delete(); - if(isObject(vPassengerHud)) - vPassengerHud.delete(); - if(isObject(bombardierHud)) - bombardierHud.delete(); - if(isObject(turreteerHud)) - turreteerHud.delete(); - // reset in case of vehicle-specific reticle - //reticleHud.setBitmap(""); - //reticleFrameHud.setVisible(false); - } - dashboardHud.setVisible(%val); -} - -function addEnergyGauge( %vehType ) -{ - switch$ (%vehType) - { - case "Assault" or "Bomber": - dashboardHud.nrgBar = new HudBitmapCtrl(vEnergyFrame) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "160 80"; - extent = "118 19"; - minExtent = "8 8"; - visible = "1"; - bitmap = "gui/hud_veh_new_dashpiece_5"; - opacity = "0.8"; - - new HudEnergy(vEnergyBar) { - profile = "GuiDefaultProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "0 0"; - extent = "118 19"; - minExtent = "8 8"; - visible = "1"; - fillColor = "0.353000 0.373000 0.933000 0.800000"; - frameColor = "0.000000 1.000000 0.000000 1.000000"; - autoCenter = "0"; - autoResize = "0"; - displayMounted = true; - bitmap = "gui/hud_veh_new_dashpiece_5"; - verticalFill = false; - subRegion = "4 5 98 5"; - pulseRate = "500"; - pulseThreshold = "0.3"; - //modColor = "1.000000 0.500000 0.000000 1.000000"; - }; - - new HudCapacitor(vCapBar) { - profile = "GuiDefaultProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "0 8"; - extent = "118 8"; - minExtent = "8 8"; - visible = "1"; - fillColor = "1.000 0.729 0.301 0.800000"; - frameColor = "0.000000 1.000000 0.000000 1.000000"; - autoCenter = "0"; - autoResize = "0"; - displayMounted = true; - bitmap = "gui/hud_veh_new_dashpiece_5"; - verticalFill = false; - subRegion = "4 5 98 5"; - pulseRate = "500"; - pulseThreshold = "0.3"; - //modColor = "1.000000 0.500000 0.000000 1.000000"; - }; - }; - dashboardHud.add(dashboardHud.nrgBar); - - default: - dashboardHud.nrgBar = new HudBitmapCtrl(vEnergyFrame) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "160 80"; - extent = "118 19"; - minExtent = "8 8"; - visible = "1"; - bitmap = "gui/hud_veh_new_dashpiece_5"; - opacity = "0.8"; - - new HudEnergy(vEnergyBar) { - profile = "GuiDefaultProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "0 0"; - extent = "118 19"; - minExtent = "8 8"; - visible = "1"; - fillColor = "0.353000 0.373000 0.933000 0.800000"; - frameColor = "0.000000 1.000000 0.000000 1.000000"; - autoCenter = "0"; - autoResize = "0"; - displayMounted = true; - bitmap = "gui/hud_veh_new_dashpiece_5"; - verticalFill = false; - subRegion = "4 5 98 10"; - pulseRate = "500"; - pulseThreshold = "0.3"; - //modColor = "1.000000 0.500000 0.000000 1.000000"; - }; - }; - dashboardHud.add(dashboardHud.nrgBar); - } -} - -function clientCmdShowVehicleGauges(%vehType, %node) -{ - //if(!((%vehType $= "Bomber" || %vehType $= "Assault") && %node > 0)) - if(%node == 0) - { - // common elements that show up on all vehicle pilot HUDs - dashboardHud.diagram = new HudBitmapCtrl(vDiagramHud) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "200 10"; - extent = "176 108"; - minExtent = "8 8"; - visible = "1"; - bitmap = "gui/hud_veh_new_dash"; - opacity = "0.8"; - }; - dashboardHud.add(dashboardHud.diagram); - - dashboardHud.vehDiagram = new HudBitmapCtrl(vOverheadHud) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "256 0"; - extent = "128 128"; - minExtent = "8 8"; - visible = "1"; - bitmap = ""; - opacity = "1.0"; - }; - dashboardHud.add(dashboardHud.vehDiagram); - - addEnergyGauge( %vehType ); - - dashboardHud.dmgBar = new HudBitmapCtrl(vDamageFrame) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "361 80"; - extent = "118 19"; - minExtent = "8 8"; - visible = "1"; - bitmap = "gui/hud_veh_new_dashpiece_4"; - opacity = "0.8"; - - new HudDamage(vDamageBar) { - profile = "GuiDefaultProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "0 0"; - extent = "118 19"; - minExtent = "8 8"; - visible = "1"; - fillColor = "0.000000 1.0000 0.000000 0.800000"; - frameColor = "0.000000 1.000000 0.000000 0.000000"; - bitmap = "gui/hud_veh_new_dashpiece_4"; - verticalFill = false; - displayMounted = true; - opacity = "0.8"; - subRegion = "18 5 97 10"; - pulseRate = "500"; - pulseThreshold = "0.3"; - //modColor = "1.000000 0.500000 0.000000 1.000000"; - }; - }; - dashboardHud.add(dashboardHud.dmgBar); - - dashboardHud.speedBox = new GuiControl(vSpeedBox) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "210 47"; - extent = "40 40"; - minExtent = "8 8"; - visible = "1"; - - new GuiTextCtrl(vSpeedText) { - profile = "GuiDashTextProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "3 15"; - extent = "18 15"; - minExtent = "8 8"; - visible = "1"; - text = "test"; - }; - new GuiTextCtrl(vSpeedTxtLbl) { - profile = "GuiDashTextProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "18 15"; - extent = "27 15"; - minExtent = "8 8"; - visible = "1"; - text = "KPH"; - }; - }; - dashboardHud.add(dashboardHud.speedBox); - - dashboardHud.updateSpeed(); - } - - switch$ (%vehType) { - case "Shrike" : - vOverheadHud.setBitmap("gui/hud_veh_icon_shrike"); - // add altitude box for flying vehicles - dashboardHud.altBox = new HudBitmapCtrl(vAltitudeBox) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "371 56"; - extent = "68 22"; - minExtent = "8 8"; - bitmap = "gui/hud_veh_new_dashpiece_1"; - visible = "1"; - opacity = "0.8"; - - new GuiTextCtrl(vAltitudeText) { - profile = "GuiDashTextProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "19 5"; - extent = "18 15"; - minExtent = "8 8"; - visible = "1"; - text = "test"; - }; - new GuiTextCtrl(vAltitudeTxtLbl) { - profile = "GuiDashTextProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "40 5"; - extent = "12 15"; - minExtent = "8 8"; - visible = "1"; - text = "M"; - }; - }; - dashboardHud.add(dashboardHud.altBox); - dashboardHud.updateAltitude(); - // add right-hand weapons box and highlight - dashboardHud.weapon = new GuiControl(vWeapHiliteOne) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "358 22"; - extent = "80 33"; - minExtent = "8 8"; - visible = "1"; - - new HudBitmapCtrl(vWeapBkgdOne) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "0 0"; - extent = "82 40"; - minExtent = "8 8"; - bitmap = "gui/hud_veh_new_dashpiece_2"; - visible = "1"; - opacity = "0.8"; - - new HudBitmapCtrl(vWeapIconOne) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "28 6"; - extent = "25 25"; - minExtent = "8 8"; - bitmap = "gui/hud_blaster"; - visible = "1"; - opacity = "0.8"; - }; - }; - }; - dashboardHud.add(dashboardHud.weapon); - // change to shrike reticle - reticleHud.setBitmap("gui/hud_ret_shrike"); - reticleFrameHud.setVisible(false); - - case "Bomber" : - if(%node == 1) - { - // bombardier hud - dashboardHud.bHud = new GuiControl(bombardierHud) { - profile = "GuiDefaultProfile"; - horizSizing = "center"; - vertSizing = "top"; - position = "200 75"; - extent = "240 50"; - minExtent = "8 8"; - visible = "1"; - - new HudBitmapCtrl(vWeap1Hilite) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "18 9"; - extent = "80 44"; - minExtent = "8 8"; - visible = "1"; - bitmap = "gui/hud_veh_new_hilite_left"; - opacity = "0.3"; - }; - new HudBitmapCtrl(vWeap2Hilite) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "141 9"; - extent = "80 44"; - minExtent = "8 8"; - visible = "0"; - bitmap = "gui/hud_veh_new_hilite_right"; - opacity = "0.3"; - }; - new HudBitmapCtrl(vWeap3Hilite) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "99 9"; - extent = "40 44"; - minExtent = "8 8"; - visible = "0"; - bitmap = "gui/hud_veh_new_hilite_middle"; - opacity = "0.3"; - }; - - new HudBitmapCtrl(bombardierFrame) { - profile = "GuiDashBoxProfile"; - horizSizing = "center"; - vertSizing = "bottom"; - position = "20 8"; - extent = "200 40"; - minExtent = "8 8"; - visible = "1"; - bitmap = "gui/hud_veh_new_bombardier_dash"; - opacity = "1.0"; - - new HudBitmapCtrl(vWeaponOne) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "28 5"; - extent = "25 25"; - minExtent = "8 8"; - visible = "1"; - bitmap = "gui/hud_blaster"; - }; - - new HudBitmapCtrl(vWeaponTwo) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "87 6"; - extent = "25 25"; - minExtent = "8 8"; - visible = "1"; - bitmap = "gui/hud_targetlaser"; - }; - - new HudBitmapCtrl(vWeaponThree) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "147 6"; - extent = "25 25"; - minExtent = "8 8"; - visible = "1"; - bitmap = "gui/hud_veh_bomb"; - }; - }; - }; - dashboardHud.add(dashboardHud.bHud); - - dashboardHud.nrgBar = new HudBitmapCtrl(vEnergyFrame) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "110 95"; - extent = "118 19"; - minExtent = "8 8"; - visible = "1"; - flipVertical = true; - bitmap = "gui/hud_veh_new_dashpiece_5"; - opacity = "0.8"; - - new HudEnergy(vEnergyBar) { - profile = "GuiDefaultProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "0 0"; - extent = "118 19"; - minExtent = "8 8"; - visible = "1"; - fillColor = "0.353000 0.373000 0.933000 0.800000"; - frameColor = "0.000000 1.000000 0.000000 1.000000"; - autoCenter = "0"; - autoResize = "0"; - displayMounted = true; - bitmap = "gui/hud_veh_new_dashpiece_5"; - verticalFill = false; - subRegion = "4 5 98 5"; - pulseRate = "500"; - pulseThreshold = "0.3"; - //modColor = "1.000000 0.500000 0.000000 1.000000"; - }; - new HudCapacitor(vCapBar) { - profile = "GuiDefaultProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "0 8"; - extent = "118 8"; - minExtent = "8 8"; - visible = "1"; - fillColor = "1.000 0.729 0.301 0.800000"; - frameColor = "0.000000 1.000000 0.000000 1.000000"; - autoCenter = "0"; - autoResize = "0"; - displayMounted = true; - bitmap = "gui/hud_veh_new_dashpiece_5"; - verticalFill = false; - subRegion = "4 5 98 5"; - pulseRate = "500"; - pulseThreshold = "0.3"; - //modColor = "1.000000 0.500000 0.000000 1.000000"; - }; - }; - dashboardHud.add(dashboardHud.nrgBar); - - dashboardHud.dmgBar = new HudBitmapCtrl(vDamageFrame) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "410 95"; - extent = "118 19"; - minExtent = "8 8"; - visible = "1"; - flipVertical = true; - bitmap = "gui/hud_veh_new_dashpiece_4"; - opacity = "0.8"; - - new HudDamage(vDamageBar) { - profile = "GuiDefaultProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "0 0"; - extent = "118 19"; - minExtent = "8 8"; - visible = "1"; - fillColor = "0.000000 1.0000 0.000000 0.800000"; - frameColor = "0.000000 1.000000 0.000000 0.000000"; - bitmap = "gui/hud_veh_new_dashpiece_4"; - verticalFill = false; - displayMounted = true; - opacity = "0.8"; - subRegion = "18 5 97 10"; - pulseRate = "500"; - pulseThreshold = "0.3"; - //modColor = "1.000000 0.500000 0.000000 1.000000"; - }; - }; - dashboardHud.add(dashboardHud.dmgBar); - $numVWeapons = 3; - reticleHud.setBitmap("gui/hud_ret_shrike"); - reticleFrameHud.setVisible(false); - } - else if(%node == 0) - { - // pilot dashboard hud - vOverheadHud.setBitmap("gui/hud_veh_icon_bomber"); - // add altitude box for flying vehicles - dashboardHud.altBox = new HudBitmapCtrl(vAltitudeBox) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "371 56"; - extent = "68 22"; - minExtent = "8 8"; - bitmap = "gui/hud_veh_new_dashpiece_1"; - visible = "1"; - opacity = "0.8"; - - new GuiTextCtrl(vAltitudeText) { - profile = "GuiDashTextProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "19 5"; - extent = "18 15"; - minExtent = "8 8"; - visible = "1"; - text = "test"; - }; - new GuiTextCtrl(vAltitudeTxtLbl) { - profile = "GuiDashTextProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "40 5"; - extent = "12 15"; - minExtent = "8 8"; - visible = "1"; - text = "M"; - }; - }; - dashboardHud.add(dashboardHud.altBox); - dashboardHud.updateAltitude(); - } - else - { - // tailgunner hud - dashboardHud.vehDiagram = new HudBitmapCtrl(vOverheadHud) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "256 0"; - extent = "128 128"; - minExtent = "8 8"; - visible = "1"; - bitmap = "gui/hud_veh_icon_bomber"; - opacity = "1.0"; - }; - dashboardHud.add(dashboardHud.vehDiagram); - - dashboardHud.nrgBar = new HudBitmapCtrl(vEnergyFrame) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "177 50"; - extent = "118 19"; - minExtent = "8 8"; - visible = "1"; - bitmap = "gui/hud_veh_new_dashpiece_5"; - flipVertical = true; - opacity = "0.8"; - - new HudEnergy(vEnergyBar) { - profile = "GuiDefaultProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "0 0"; - extent = "118 19"; - minExtent = "8 8"; - visible = "1"; - fillColor = "0.353000 0.373000 0.933000 0.800000"; - frameColor = "0.000000 1.000000 0.000000 1.000000"; - autoCenter = "0"; - autoResize = "0"; - displayMounted = true; - bitmap = "gui/hud_veh_new_dashpiece_5"; - verticalFill = false; - subRegion = "4 5 98 10"; - pulseRate = "500"; - pulseThreshold = "0.3"; - }; - }; - dashboardHud.add(dashboardHud.nrgBar); - - dashboardHud.dmgBar = new HudBitmapCtrl(vDamageFrame) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "345 50"; - extent = "118 19"; - minExtent = "8 8"; - visible = "1"; - bitmap = "gui/hud_veh_new_dashpiece_4"; - flipVertical = true; - opacity = "0.8"; - - new HudDamage(vDamageBar) { - profile = "GuiDefaultProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "0 0"; - extent = "118 19"; - minExtent = "8 8"; - visible = "1"; - fillColor = "0.000000 1.0000 0.000000 0.800000"; - frameColor = "0.000000 1.000000 0.000000 0.000000"; - bitmap = "gui/hud_veh_new_dashpiece_4"; - verticalFill = false; - displayMounted = true; - opacity = "0.8"; - subRegion = "18 5 97 10"; - pulseRate = "500"; - pulseThreshold = "0.3"; - }; - }; - dashboardHud.add(dashboardHud.dmgBar); - } - if(%node != 1) - { - // passenger slot "dots" - vOverheadHud.passengerHud = new GuiControl(vPassengerHud) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "0 0"; - extent = "101 101"; - minExtent = "8 8"; - visible = "1"; - - new GuiBitmapCtrl(vPassenger0Slot) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "59 24"; - extent = "10 10"; - minExtent = "3 3"; - visible = "0"; - bitmap = "gui/hud_veh_seatdot"; - }; - new GuiBitmapCtrl(vPassenger1Slot) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "59 39"; - extent = "10 10"; - minExtent = "3 3"; - visible = "0"; - bitmap = "gui/hud_veh_seatdot"; - }; - new GuiBitmapCtrl(vPassenger2Slot) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "59 84"; - extent = "10 10"; - minExtent = "3 3"; - visible = "0"; - bitmap = "gui/hud_veh_seatdot"; - }; - }; - vOverheadHud.add(vOverheadHud.passengerHud); - } - case "HAPC" : - if(%node == 0) - { - vOverheadHud.setBitmap("gui/hud_veh_icon_hapc"); - // add altitude box for flying vehicles - dashboardHud.altBox = new HudBitmapCtrl(vAltitudeBox) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "371 56"; - extent = "68 22"; - minExtent = "8 8"; - bitmap = "gui/hud_veh_new_dashpiece_1"; - visible = "1"; - opacity = "0.8"; - - new GuiTextCtrl(vAltitudeText) { - profile = "GuiDashTextProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "19 5"; - extent = "18 15"; - minExtent = "8 8"; - visible = "1"; - text = "test"; - }; - new GuiTextCtrl(vAltitudeTxtLbl) { - profile = "GuiDashTextProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "40 5"; - extent = "12 15"; - minExtent = "8 8"; - visible = "1"; - text = "M"; - }; - }; - dashboardHud.add(dashboardHud.altBox); - updateVehicleAltitude(); - dashboardHud.updateAltitude(); - - } - else - { - // passenger hud - dashboardHud.vehDiagram = new HudBitmapCtrl(vOverheadHud) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "256 0"; - extent = "128 128"; - minExtent = "8 8"; - visible = "1"; - bitmap = "gui/hud_veh_icon_hapc"; - opacity = "1.0"; - }; - dashboardHud.add(dashboardHud.vehDiagram); - - dashboardHud.nrgBar = new HudBitmapCtrl(vEnergyFrame) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "180 30"; - extent = "118 19"; - minExtent = "8 8"; - visible = "1"; - bitmap = "gui/hud_veh_new_dashpiece_5"; - flipVertical = true; - opacity = "0.8"; - - new HudEnergy(vEnergyBar) { - profile = "GuiDefaultProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "0 0"; - extent = "118 19"; - minExtent = "8 8"; - visible = "1"; - fillColor = "0.353000 0.373000 0.933000 0.800000"; - frameColor = "0.000000 1.000000 0.000000 1.000000"; - autoCenter = "0"; - autoResize = "0"; - displayMounted = true; - bitmap = "gui/hud_veh_new_dashpiece_5"; - verticalFill = false; - subRegion = "4 5 98 10"; - pulseRate = "500"; - pulseThreshold = "0.3"; - }; - }; - dashboardHud.add(dashboardHud.nrgBar); - - dashboardHud.dmgBar = new HudBitmapCtrl(vDamageFrame) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "342 30"; - extent = "118 19"; - minExtent = "8 8"; - visible = "1"; - bitmap = "gui/hud_veh_new_dashpiece_4"; - flipVertical = true; - opacity = "0.8"; - - new HudDamage(vDamageBar) { - profile = "GuiDefaultProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "0 0"; - extent = "118 19"; - minExtent = "8 8"; - visible = "1"; - fillColor = "0.000000 1.0000 0.000000 0.800000"; - frameColor = "0.000000 1.000000 0.000000 0.000000"; - bitmap = "gui/hud_veh_new_dashpiece_4"; - verticalFill = false; - displayMounted = true; - opacity = "0.8"; - subRegion = "18 5 97 10"; - pulseRate = "500"; - pulseThreshold = "0.3"; - }; - }; - dashboardHud.add(dashboardHud.dmgBar); - } - // passenger slot "dots" - vOverheadHud.passengerHud = new GuiControl(vPassengerHud) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "0 0"; - extent = "101 101"; - minExtent = "8 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - helpTag = "0"; - - new GuiBitmapCtrl(vPassenger0Slot) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "59 65"; - extent = "10 10"; - minExtent = "3 3"; - visible = "0"; - setFirstResponder = "0"; - modal = "1"; - bitmap = "gui/hud_veh_seatdot"; - wrap = "0"; - }; - new GuiBitmapCtrl(vPassenger1Slot) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "59 84"; - extent = "10 10"; - minExtent = "3 3"; - visible = "0"; - setFirstResponder = "0"; - modal = "1"; - bitmap = "gui/hud_veh_seatdot"; - wrap = "0"; - }; - new GuiBitmapCtrl(vPassenger2Slot) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "38 29"; - extent = "10 10"; - minExtent = "3 3"; - visible = "0"; - setFirstResponder = "0"; - modal = "1"; - bitmap = "gui/hud_veh_seatdot"; - wrap = "0"; - }; - new GuiBitmapCtrl(vPassenger3Slot) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "38 50"; - extent = "10 10"; - minExtent = "3 3"; - visible = "0"; - setFirstResponder = "0"; - modal = "1"; - bitmap = "gui/hud_veh_seatdot"; - wrap = "0"; - }; - new GuiBitmapCtrl(vPassenger4Slot) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "80 50"; - extent = "10 10"; - minExtent = "3 3"; - visible = "0"; - setFirstResponder = "0"; - modal = "1"; - bitmap = "gui/hud_veh_seatdot"; - wrap = "0"; - }; - new GuiBitmapCtrl(vPassenger5Slot) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "80 29"; - extent = "10 10"; - minExtent = "3 3"; - visible = "0"; - setFirstResponder = "0"; - modal = "1"; - bitmap = "gui/hud_veh_seatdot"; - wrap = "0"; - }; - }; - vOverheadHud.add(vOverheadHud.passengerHud); - - case "Assault" : - if(%node == 1) - { - // turreteer hud - dashboardHud.tHud = new GuiControl(turreteerHud) { - profile = "GuiDefaultProfile"; - horizSizing = "center"; - vertSizing = "top"; - position = "225 70"; - extent = "240 50"; - minExtent = "8 8"; - visible = "1"; - - new HudBitmapCtrl(vWeap1Hilite) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "40 11"; - extent = "80 44"; - minExtent = "8 8"; - visible = "1"; - bitmap = "gui/hud_veh_new_hilite_left"; - opacity = "0.4"; - }; - new HudBitmapCtrl(vWeap2Hilite) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "118 11"; - extent = "80 44"; - minExtent = "8 8"; - visible = "0"; - bitmap = "gui/hud_veh_new_hilite_right"; - opacity = "0.4"; - }; - - new HudBitmapCtrl(turreteerFrame) { - profile = "GuiDashBoxProfile"; - horizSizing = "center"; - vertSizing = "bottom"; - position = "20 8"; - extent = "152 36"; - minExtent = "8 8"; - visible = "1"; - bitmap = "gui/hud_veh_new_tankgunner_dash"; - opacity = "0.8"; - - new HudBitmapCtrl(vWeaponOne) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "25 8"; - extent = "25 25"; - minExtent = "8 8"; - visible = "1"; - bitmap = "gui/hud_chaingun"; - }; - - new HudBitmapCtrl(vWeaponTwo) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "99 8"; - extent = "25 25"; - minExtent = "8 8"; - visible = "1"; - bitmap = "gui/hud_mortor"; - }; - }; - }; - dashboardHud.add(dashboardHud.tHud); - - dashboardHud.nrgBar = new HudBitmapCtrl(vEnergyFrame) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "134 95"; - extent = "118 19"; - minExtent = "8 8"; - visible = "1"; - flipVertical = true; - bitmap = "gui/hud_veh_new_dashpiece_5"; - opacity = "0.8"; - - new HudEnergy(vEnergyBar) { - profile = "GuiDefaultProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "0 0"; - extent = "118 19"; - minExtent = "8 8"; - visible = "1"; - fillColor = "0.353000 0.373000 0.933000 0.800000"; - frameColor = "0.000000 1.000000 0.000000 1.000000"; - autoCenter = "0"; - autoResize = "0"; - displayMounted = true; - bitmap = "gui/hud_veh_new_dashpiece_5"; - verticalFill = false; - subRegion = "4 5 98 5"; - pulseRate = "500"; - pulseThreshold = "0.3"; - //modColor = "1.000000 0.500000 0.000000 1.000000"; - }; - new HudCapacitor(vCapBar) { - profile = "GuiDefaultProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "0 8"; - extent = "118 8"; - minExtent = "8 8"; - visible = "1"; - fillColor = "1.000 0.729 0.301 0.800000"; - frameColor = "0.000000 1.000000 0.000000 1.000000"; - autoCenter = "0"; - autoResize = "0"; - displayMounted = true; - bitmap = "gui/hud_veh_new_dashpiece_5"; - verticalFill = false; - subRegion = "4 5 98 5"; - pulseRate = "500"; - pulseThreshold = "0.3"; - //modColor = "1.000000 0.500000 0.000000 1.000000"; - }; - }; - dashboardHud.add(dashboardHud.nrgBar); - - dashboardHud.dmgBar = new HudBitmapCtrl(vDamageFrame) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "390 95"; - extent = "118 19"; - minExtent = "8 8"; - visible = "1"; - flipVertical = true; - bitmap = "gui/hud_veh_new_dashpiece_4"; - opacity = "0.8"; - - new HudDamage(vDamageBar) { - profile = "GuiDefaultProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "0 0"; - extent = "118 19"; - minExtent = "8 8"; - visible = "1"; - fillColor = "0.000000 1.0000 0.000000 0.800000"; - frameColor = "0.000000 1.000000 0.000000 0.000000"; - bitmap = "gui/hud_veh_new_dashpiece_4"; - verticalFill = false; - displayMounted = true; - opacity = "0.8"; - subRegion = "18 5 97 10"; - pulseRate = "500"; - pulseThreshold = "0.3"; - //modColor = "1.000000 0.500000 0.000000 1.000000"; - }; - }; - dashboardHud.add(dashboardHud.dmgBar); - - $numVWeapons = 2; - // add tank chaingun reticle - reticleHud.setBitmap("gui/hud_ret_tankchaingun"); - reticleFrameHud.setVisible(false); - } - else - { - // node 0 == driver - vOverheadHud.setBitmap("gui/hud_veh_icon_assault"); - // passenger slot "dots" - vOverheadHud.passengerHud = new GuiControl(vPassengerHud) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "0 0"; - extent = "101 101"; - minExtent = "8 8"; - visible = "1"; - - new GuiBitmapCtrl(vPassenger0Slot) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "64 30"; - extent = "10 10"; - minExtent = "3 3"; - visible = "0"; - bitmap = "gui/hud_veh_seatdot"; - }; - new GuiBitmapCtrl(vPassenger1Slot) { - profile = "GuiDashBoxProfile"; - horizSizing = "right"; - vertSizing = "top"; - position = "53 53"; - extent = "10 10"; - minExtent = "3 3"; - visible = "0"; - bitmap = "gui/hud_veh_seatdot"; - }; - }; - vOverheadHud.add(vOverheadHud.passengerHud); - } - - case "Hoverbike" : - vOverheadHud.setBitmap("gui/hud_veh_icon_hoverbike"); - - case "MPB" : - vOverheadHud.setBitmap("gui/hud_veh_icon_mpb"); - - } - if(%node == 0) - vDiagramHud.setVisible(true); - else - if(isObject(vDiagramHud)) - vDiagramHud.setVisible(false); -} - -function GuiControl::updateAltitude(%this) -{ - %alt = getControlObjectAltitude(); - vAltitudeText.setValue(%alt); - %this.altitudeCheck = %this.schedule(500, "updateAltitude"); -} - -function GuiControl::updateSpeed(%this) -{ - %vel = getControlObjectSpeed(); - // convert from m/s to km/h - %cVel = mFloor(%vel * 3.6); // m/s * (3600/1000) = km/h - vSpeedText.setValue(%cVel); - %this.speedCheck = %this.schedule(500, "updateSpeed"); -} - -//function clientCmdShowVehicleWeapons(%vehicleType) -//{ - // all vehicle weapons are energy based; a -1 displays an infinity symbol - // for that weapon's ammo amount - //switch$ (%vehicleType) - //{ - // case "ScoutFlyer": - // // blaster - // vWeaponsBox.addWeapon(0, -1); - // case "BomberFlyer": - // // plasma, bomb and targeting laser - // vWeaponsBox.addWeapon(1, -1); - // vWeaponsBox.addWeapon(3, -1); - // vWeaponsBox.addWeapon(4, -1); - // case "AssaultVehicle": - // vWeaponsBox.addWeapon(1, -1); - // vWeaponsBox.addWeapon(3, -1); - //} - //vWeaponsBox.setVisible(true); -//} - -// if set, then static shapes with data member 'noIndividualDamage' set will -// not display their damage bars -function clientCmdProtectingStaticObjects(%val) -{ - NavHud.protectedStatics = %val; -} - -function clientCmdCheckPassengers(%pString) -{ - // since each slot is represented by a "1" or a "0" followed by a space, the length - // of the string divided by 2 is equal to the number of slots in the vehicle - %numSlots = strlen(%pString) / 2; - for(%i = 0; %i < %numSlots; %i++) - { - %pass = "vPassenger" @ %i @ "Slot"; - if(isObject(%pass)) - if(getWord(%pString, %i) $= "1") - %pass.setVisible(true); - else - %pass.setVisible(false); - } -} - -function clientCmdShowPassenger(%slot, %full) -{ - %dotNum = "vPassenger" @ %slot @ "Slot"; - if(isObject(%dotNum)) - %dotNum.setVisible(%full); -} - -function clientCmdClearPassengers() -{ - for(%i = 1; %i < 6; %i++) - { - %pass = "vPassenger" @ %i @ "Slot"; - %pass.setVisible(false); - } -} - -addMessageCallback( 'MsgMissionDropInfo', handleDropInfoMessage ); -addMessageCallback( 'MsgTeamList', handleTeamListMessage ); -addMessageCallback( 'LeaveMissionArea', HandleLeaveMissionAreaAlarmMessage ); -addMessageCallback( 'EnterMissionArea', HandleEnterMissionAreaAlarmMessage ); -addMessageCallback( 'msgBountyStreakBonus', HandleBountyStreakMessage ); -addMessageCallback( 'onClientKicked', handleIveBeenKicked ); -addMessageCallback( 'onClientBanned', handleIveBeenBanned ); -addMessageCallback( 'msgDeploySensorRed', clientDeploySensorRed ); -addMessageCallback( 'msgDeploySensorGrn', clientDeploySensorGrn ); -addMessageCallback( 'msgDeploySensorOff', clientDeploySensorOff ); -addMessageCallback( 'msgPackIconOff', clientPackIconOff ); -addMessageCallback( 'MsgForceObserver', HandleForceObserver ); -addMessageCallback( 'MsgPlayerMuted', handlePlayerMuted ); - -//------------------------------------------------------------------------------ -// Siege-specific callbacks: -addMessageCallback( 'MsgSiegeHalftime', handleSiegeHalftimeMessage ); -addMessageCallback( 'MsgSiegeResult', handleSiegeResultMessage ); -addMessageCallback( 'MsgSiegeAddLine', handleSiegeLineMessage ); -//------------------------------------------------------------------------------ - -function HandleForceObserver( %msgType, %msgString ) -{ - -} - -function handleIveBeenBanned(%msgType, %msgString) -{ - DisconnectedCleanup(); -} - -function handleIveBeenKicked(%msgType, %msgString) -{ - DisconnectedCleanup(); -} - -function clientDeploySensorRed() -{ - deploySensor.color = "255 0 0"; - deploySensor.setVisible(true); -} - -function clientDeploySensorGrn() -{ - deploySensor.color = "0 255 0"; - deploySensor.setVisible(true); -} - -function clientDeploySensorOff() -{ - deploySensor.setVisible(false); -} - -function clientPackIconOff() -{ - backpackIcon.setBitmap(""); - backpackFrame.setVisible(false); - backpackText.setValue(""); - backpackText.setVisible(false); - backpackFrame.pack = false; -} - -function HandleBountyStreakMessage(%msgType, %msgString, %client, %streak, %award) -{ - %delay = alxGetWaveLen("fx/misc/bounty_bonus.wav"); - %overlap = 0.50; - - alxPlay(BountyBellSound, 0, 0, 0); //first bell - for (%loop = 1; %loop < %award; %loop++) //any repetitions, overlapped. - schedule((%delay * %loop) * %overlap, 0, "alxPlay", BountyBellSound, 0, 0, 0); -} - -function HandleLeaveMissionAreaAlarmMessage(%msgType, %msgString) -{ - //Tinman - sounds are now sent by the individual game script - //if(ServerConnection.OutOfBoundsHandle $= "") - // ServerConnection.OutOfBoundsHandle = alxPlay(OutOfBoundsSound, 0, 0, 0); -} - -function HandleEnterMissionAreaAlarmMessage(%msgType, %msgString) -{ - //Tinman - sounds are now sent by the individual game script - //if(ServerConnection.OutOfBoundsHandle !$= "") - // alxStop(ServerConnection.OutOfBoundsHandle); - // - //ServerConnection.OutOfBoundsHandle = ""; -} - -function handleDropInfoMessage( %msgType, %msgString, %map, %gameType, %serverName ) -{ - $clServerName = %serverName; - $clMissionName = %map; - $clMissionType = %gameType; -} - -function handleTeamListMessage( %msgType, %msgString, %teamCount, %teamList ) -{ - // Save off the team names: - $clTeamCount = %teamCount; - for ( %i = 0; %i < %teamCount; %i++ ) - $clTeamScore[%i + 1, 0] = getRecord( %teamList, %i ); - - // Initialize the lobby: - LobbyPlayerList.initColumns(); -} - -//---------------------------------------------------------------------------- - -function clientCmdStartEffect( %effect ) -{ - // Put in iterations - StartEffect( %effect ); -} - -function clientCmdStopEffect( %effect ) -{ - StopEffect( %effect ); -} - -function clientCmdPickTeam() -{ - -} - -function clientCmdMissionStartPhase1(%seq, %missionName, %musicTrack) -{ - echo( "got client StartPhase1..." ); - - // Reset the loading progress controls: - LoadingProgress.setValue( 0 ); - DB_LoadingProgress.setValue( 0 ); - LoadingProgressTxt.setValue( "LOADING MISSION" ); - DB_LoadingProgressTxt.setValue( "LOADING MISSION" ); - - clientCmdPlayMusic(%musicTrack); - commandToServer('MissionStartPhase1Done', %seq); - clientCmdResetCommandMap(); -} - -function clientCmdMissionStartPhase2(%seq) -{ - // clean some stuff up. - MessageHud.close(); - purgeResources(); - if (!$pref::NoClearConsole) - cls(); - commandToServer('MissionStartPhase2Done', %seq); -} - -function clientCmdMissionStartPhase3(%seq, %missionName) -{ - $MSeq = %seq; - - //Reset Inventory Hud... - if($Hud['inventoryScreen'] !$= "") - { - %favList = $Hud['inventoryScreen'].data[0, 1].type TAB $Hud['inventoryScreen'].data[0, 1].getValue(); - for ( %i = 1; %i < $Hud['inventoryScreen'].count; %i++ ) - if($Hud['inventoryScreen'].data[%i, 1].getValue() $= invalid) - %favList = %favList TAB $Hud['inventoryScreen'].data[%i, 1].type TAB "EMPTY"; - else - %favList = %favList TAB $Hud['inventoryScreen'].data[%i, 1].type TAB $Hud['inventoryScreen'].data[%i, 1].getValue(); - commandToServer( 'setClientFav', %favList ); - } - else - commandToServer( 'setClientFav', $pref::Favorite[$pref::FavCurrentSelect]); - - // needed? - $MissionName = %missionName; - //commandToServer( 'getScores' ); - - // only show dialog if actually lights - if(lightScene("sceneLightingComplete", $LaunchMode $= "SceneLight" ? "forceWritable" : "")) - { - error("beginning SceneLighting...."); - schedule(1, 0, "updateLightingProgress"); - $lightingMission = true; - LoadingProgress.setValue( 0 ); - DB_LoadingProgress.setValue( 0 ); - LoadingProgressTxt.setValue( "LIGHTING MISSION" ); - DB_LoadingProgressTxt.setValue( "LIGHTING MISSION" ); - $missionLightStarted = true; - Canvas.repaint(); - } -} - -function clientCmdMissionEnd(%seq) -{ - alxStopAll(); - // disable mission lighting if it's going (since the interiors will be gone in a sec) - $lightingMission = false; - $sceneLighting::terminateLighting = true; -} - -function clientCmdSetPowerAudioProfiles(%up, %down) -{ - setPowerAudioProfiles(%up, %down); -} - -function ghostAlwaysStarted(%ghostCount) -{ - echo( "starting to ghost " @ %ghostCount @ " server objects...."); - - LoadingProgress.setValue( 0 ); - DB_LoadingProgress.setValue( 0 ); - LoadingProgressTxt.setValue( "LOADING OBJECTS" ); - DB_LoadingProgressTxt.setValue( "LOADING OBJECTS" ); - Canvas.repaint(); - $ghostCount = %ghostCount; - $ghostsRecvd = 0; -} - -function ghostAlwaysObjectReceived() -{ - $ghostsRecvd++; - %pct = $ghostsRecvd / $ghostCount; - LoadingProgress.setValue( %pct ); - DB_LoadingProgress.setValue( %pct ); - Canvas.repaint(); -} - -function updateLightingProgress() -{ - if( $SceneLighting::lightingProgress == 0) - { - if($sceneLightStarted) - { - $sceneLightStarted = false; - } - else - $SceneLighting::lightingProgress = 1; - } - - LoadingProgress.setValue( $SceneLighting::lightingProgress ); - DB_LoadingProgress.setValue( $SceneLighting::lightingProgress ); - if($lightingMission) - $lightingProgressThread = schedule(1, 0, "updateLightingProgress"); -} - -function sceneLightingComplete() -{ - LoadingProgress.setValue( 1 ); - DB_LoadingProgress.setValue( 1 ); - - echo("Scenelighting done..."); - $lightingMission = false; - - cleanUpHuds(); - - if($LaunchMode $= "SceneLight") - { - quit(); - return; - } - - clientCmdResetHud(); - commandToServer('SetVoiceInfo', $pref::Audio::voiceChannels, $pref::Audio::decodingMask, $pref::Audio::encodingLevel); - commandToServer('EnableVehicleTeleport', $pref::Vehicle::pilotTeleport ); - commandToServer('MissionStartPhase3Done', $MSeq); -} - -function clientCmdSetVoiceInfo(%channels, %decodingMask, %encodingLevel) -{ - $Audio::serverChannels = %channels; - $Audio::serverDecodingMask = %decodingMask; - $Audio::serverEncodingLevel = %encodingLevel; -} - -function ClientReceivedDataBlock(%index, %total) -{ - %pct = %index / %total; - LoadingProgress.setValue( %pct ); - LoadingProgress.setValue( %pct ); - Canvas.repaint(); -} - -function GameConnection::onTargetLocked( %con, %state ) -{ - if( %state $= "true" ) - { - if( !%con.targetTone ) - %con.targetTone = alxPlay( "sLockedTone", 0, 0, 0 ); - } - else - { - if( %con.targetTone $= "" ) - return; - - if( %con.targetTone ) - alxStop( %con.targetTone ); - - %con.targetTone = ""; - } -} - -function GameConnection::onTrackingTarget( %con, %state ) -{ - if( %state $= "true" ) - { - if( !%con.trackingTargetTone ) - %con.trackingTargetTone = alxPlay( "sSearchingTone", 0, 0, 0 ); - } - else - { - if( %con.trackingTargetTone $= "" ) - return; - - if( %con.trackingTargetTone ) - alxStop( %con.trackingTargetTone ); - - %con.TrackingTargetTone = ""; - } -} - -function GameConnection::onLockWarning( %con, %state ) -{ - if( %state $= "true" ) - { - if( !%con.lockWarningTone ) - %con.lockWarningTone = alxPlay( "sMissileLockWarningTone", 0, 0, 0 ); - - } - else - { - if( %con.lockWarningTone $= "" ) - return; - - if( %con.lockWarningTone ) - alxStop( %con.lockWarningTone ); - - %con.lockWarningTone = ""; - } -} - -function GameConnection::onHomeWarning( %con, %state ) -{ - if( %state $= "true" ) - { - if( !%con.homeWarningTone ) - %con.homeWarningTone = alxPlay( "sMissileHomingWarningTone", 0, 0, 0 ); - } - else - { - if( %con.homeWarningTone $= "" ) - return; - - if( %con.homeWarningTone ) - alxStop( %con.homeWarningTone ); - - %con.homeWarningTone = ""; - } -} - -function GameConnection::initialControlSet(%this) -{ - if ( $LaunchMode $= "InteriorView" ) - { - Canvas.setContent( InteriorPreviewGui ); - return; - } - - if( $LaunchMode $= "TSShow" ) - { - Canvas.setContent( TSShowGui ); - return; - } - - if( Canvas.getContent() != PlayGui.getId() ) - { - Canvas.setContent( PlayGui ); - Canvas.pushDialog( MainChatHud ); - CommandToServer('PlayContentSet'); - } -} - -//------------------------------------------------------------------------------ -// Siege-specific client functions: -//------------------------------------------------------------------------------ -function handleSiegeHalftimeMessage( %msgType, %msgString ) -{ - alxPlay( SiegeSwitchSides, 0, 0, 0 ); - showTaskHudDlg( false ); - SiegeHalftimeText.setText( "" ); -} - -//------------------------------------------------------------------------------ -function handleSiegeResultMessage( %msgType, %msgString, %result ) -{ - SiegeHalftimeHeaderText.setText( "" @ detag( %result ) ); -} - -//------------------------------------------------------------------------------ -function handleSiegeLineMessage( %msgType, %msgString, %line ) -{ - %text = SiegeHalftimeText.getText(); - if ( %text $= "" ) - %newText = detag( %line ); - else - %newText = %text NL detag( %line ); - SiegeHalftimeText.setText( %newText ); -} - -//------------------------------------------------------------------------------ -function clientCmdSetHalftimeClock( %time ) -{ - SiegeHalftimeClock.setTime( %time ); -} - -//------------------------------------------------------------------------------ -function SiegeHalftimeHeaderText::onResize( %this, %width, %height ) -{ - %w = firstWord( SiegeHalftimeHeader.getExtent() ); - SiegeHalftimeHeader.setExtent( %w, %height + 6 ); - %paneHeight = getWord( siegeHalftimeHud.getExtent(), 1 ); - %x = firstWord( SiegeHalftimeScroll.getPosition() ); - %y = %height + 40; - %w = firstWord( SiegeHalftimeScroll.getExtent() ); - %h = %paneHeight - %height - 59; - SiegeHalftimeScroll.resize( %x, %y, %w, %h ); -} - -//Was moved to client.cs from console_end.cs because alxPlayMusic didn't want to work from console_end.cs for some odd reason ... -if ($pref::Audio::musicEnabled) - alxPlayMusic("T2BOL/Music/Menu.mp3"); - +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +function SAD(%password) +{ + if(%password !$= "") + commandToServer('SAD', %password); +} + +function SADSetPassword(%password) +{ + commandToServer('SADSetPassword', %password); +} + +function use(%data) +{ + // %data is currently the datablock name of the item + commandToServer('use',%data); +} + +function throw(%data) +{ + // %data is currently the datablock name of the item + commandToServer('throw',%data); +} + +function giveAll() +{ + commandToServer('giveAll'); +} + +function clientCmdSetPlayContent() +{ + if ( $LaunchMode $= "InteriorView" ) + Canvas.setContent( interiorPreviewGui ); + else if ( $LaunchMode $= "TSShow" ) + Canvas.setContent( TSShowGui ); + else + Canvas.setContent( Playgui ); +} + +function clientCmdPickTeamMenu( %teamA, %teamB ) +{ + ClientCmdSetHudMode("PickTeam"); + PickTeamAButton.text = getTaggedString( %teamA ); + PickTeamBButton.text = getTaggedString( %teamB ); + PickTeamFrame.setTitle( "Pick Team" ); + + Canvas.pushDialog( PickTeamDlg ); +} + +function clientCmdProcessPickTeam( %option ) +{ + if( %option !$= "" && %option <= 4 ) + CommandToServer( 'clientPickedTeam', %option ); + else if( %option !$= "" && %option == 5 ) + disconnect(); + + Canvas.popDialog( PickTeamDlg ); +} + +new MessageVector(HudMessageVector); + +$LastHudTarget = 0; + +function addMessageHudLine(%text) +{ + %adjustPos = false; + if( chatPageDown.isVisible() ) + { + %adjustPos = true; + %origPosition = chatHud.position; + } + + //add the message... + while( !chatPageDown.isVisible() && HudMessageVector.getNumLines() && (HudMessageVector.getNumLines() >= $pref::HudMessageLogSize)) + { + %tag = HudMessageVector.getLineTag(0); + if(%tag != 0) + %tag.delete(); + HudMessageVector.popFrontLine(); + } + HudMessageVector.pushBackLine(%text, $LastHudTarget); + $LastHudTarget = 0; + + //now that we've added the message, see if we need to reset the position + if ( %adjustPos ) + { + chatPageDown.setVisible(true); + ChatPageDown.position = ( firstWord( outerChatHud.extent ) - 20 ) @ " " @ ( $chatScrollLenY[$Pref::chatHudLength] - 6 ); + chatHud.position = %origPosition; + } + else + chatPageDown.setVisible(false); + +} + +function pageUpMessageHud() +{ + //find out the text line height + %textHeight = chatHud.profile.fontSize; + if (%textHeight <= 0) + %textHeight = 12; + + //find out how many lines per page are visible + %chatScrollHeight = getWord(chatHud.getGroup().getGroup().extent, 1); + if (%chatScrollHeight <= 0) + return; + + %pageLines = mFloor(%chatScrollHeight / %textHeight) - 1; + if (%pageLines <= 0) + %pageLines = 1; + + //see how many lines we actually can scroll up: + %chatPosition = -1 * getWord(chatHud.position, 1); + %linesToScroll = mFloor((%chatPosition / %textHeight) + 0.5); + if (%linesToScroll <= 0) + return; + + if (%linesToScroll > %pageLines) + %scrollLines = %pageLines; + else + %scrollLines = %linesToScroll; + + //now set the position + chatHud.position = firstWord(chatHud.position) SPC (getWord(chatHud.position, 1) + (%scrollLines * %textHeight)); + + //display the pageup icon + ChatPageDown.position = ( firstWord( outerChatHud.extent ) - 20 ) @ " " @ ( $chatScrollLenY[$pref::chatHudLength] - 6 ); + chatPageDown.setVisible(true); +} + +function pageDownMessageHud() +{ + //find out the text line height + %textHeight = chatHud.profile.fontSize; + if (%textHeight <= 0) + %textHeight = 12; + + //find out how many lines per page are visible + %chatScrollHeight = getWord(chatHud.getGroup().getGroup().extent, 1); + 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(chatHud.extent, 1) - %chatScrollHeight + getWord(chatHud.position, 1); + %linesToScroll = mFloor((%chatPosition / %textHeight) + 0.5); + if (%linesToScroll <= 0) + return; + + if (%linesToScroll > %pageLines) + %scrollLines = %pageLines; + else + %scrollLines = %linesToScroll; + + //now set the position + chatHud.position = firstWord(chatHud.position) SPC (getWord(chatHud.position, 1) - (%scrollLines * %textHeight)); + + //see if we have should (still) display the pagedown icon + if (%scrollLines < %linesToScroll) + { + chatPageDown.setVisible(true); + ChatPageDown.position = ( firstWord( outerChatHud.extent ) - 20 ) @ " " @ ( $chatScrollLenY[$Pref::chatHudLength] - 6 ); + } + else + chatPageDown.setVisible(false); +} + + +function RTS_RightButton(%val) +{ + if(%val) + { + CommanderTVControl.push(); + RTS_LeftButton(0); + CursorOff(); + } + else + { + CommanderTVControl.pop(); + Canvas.cursorOn(); //Show the cursor + } +} + +function clientCmdAlxPlayMusic(%file) +{ +alxPlayMusic(%file); +return %file; +} + +function RTS_LeftButton(%val) +{ + if (%val) //We clicked -- we must make our little selection box o' doom + { + %pos = Canvas.getCursorPos(); + PlayGui.selectBox = new HudZoom() { + profile = "ZoomHudProfile"; + position = %pos; + extent = "5 5"; //Any smaller and you don't know it exists. + visible = "1"; + fillColor = "0.250000 0.250000 0.250000 0.250000"; + frameColor = "0.000000 1.000000 0.000000 1.000000"; + opacity = "1"; + }; + PlayGui.add(Playgui.selectBox); + RTS_RightButton(0); + Canvas.setCursor(GrabCursor); + $RTSSelect = true; + RTS_SelectLoop(); + } + else + { + if (IsObject(Playgui.selectBox)) + Playgui.selectBox.delete(); + Canvas.setCursor(DefaultCursor); + $RTSSelect = false; + } +} + +//I should get Emp to handle this.. he knows his vect0r math +function RTS_SelectLoop() //For now, unless there's a function on the Canvas that is called when le' cursor is moved +{ +if (!$RTSSelect) +return; + +%pos = Canvas.getCursorPos(); +%x = getWord(%pos, 0); +%y = getWord(%pos, 1); + +PlayGui.selectBox.setExtent(%x * 0.5, %y * 0.5); +schedule(1,0,"RTS_SelectLoop"); +} + +function clientCmdIsRTSGame() +{ +hudClusterBack.opacity = 0; //Make it invisible +clientCmdShowCursor(1); //Show our cursor +} + +$cursorControlled = true; + +function CursorOff() +{ + if ( $cursorControlled ) + lockMouse(true); + Canvas.cursorOff(); +} + +function CursorOn() +{ + if ( $cursorControlled ) + lockMouse(false); + Canvas.cursorOn(); + Canvas.setCursor(DefaultCursor); +} + +function toggleCursorControl() +{ + // If the user manually toggles the mouse control, lock or unlock for them + if ( $cursorControlled ) + $cursorControlled = false; + else + $cursorControlled = true; + lockMouse($cursorControlled); +} + +if ( $platform $= "linux" ) + GlobalActionMap.bindCmd(keyboard, "ctrl g", "", "toggleCursorControl();"); + +function toggleNetDisplayHud(%val) +{ + if(%val) + { + if(NetGraphHudFrame.isVisible()) + { + NetGraphHudFrame.setVisible(false); + NetBarHudFrame.setVisible(true); + } + else if(NetBarHudFrame.isVisible()) + { + NetBarHudFrame.setVisible(false); + } + else + NetGraphHudFrame.setVisible(true); + } +} + +function PlayGui::onWake(%this) +{ + // Make sure the shell hum is off: + if ( $HudHandle[shellScreen] !$= "" ) + { + alxStop( $HudHandle[shellScreen] ); + $HudHandle[shellScreen] = ""; + } + + $enableDirectInput = "1"; + activateDirectInput(); + + // chat hud dialog + Canvas.pushDialog( MainChatHud ); + chatHud.attach(HudMessageVector); + + // just update the action map here, the huds should be properly setup + updateActionMaps(); + + // hack city - these controls are floating around and need to be clamped + schedule(0, 0, "refreshCenterTextCtrl"); + schedule(0, 0, "refreshBottomTextCtrl"); + + // update the network graph prefs + NetGraphHud.getPrefs(); +} + +function refreshBottomTextCtrl() +{ + BottomPrintText.position = "0 0"; +} + +function refreshCenterTextCtrl() +{ + CenterPrintText.position = "0 0"; +} + +function PlayGui::onSleep(%this) +{ + Canvas.popDialog( MainChatHud ); + + //pop all possible keymaps + moveMap.pop(); + if ( isObject( passengerKeys ) ) + passengerKeys.pop(); + if ( isObject( observerBlockMap ) ) + observerBlockMap.pop(); + if ( isObject( observerMap ) ) + observerMap.pop(); + //flyingCameraMove.pop(); +} + +function onConnectRequestRejected( %msg ) +{ + switch$(%msg) + { + case "CR_INVALID_CONNECT_PACKET": + %error = "Network error - badly formed network packet - this should not happen!"; + case "CR_AUTHENTICATION_FAILED": + %error = "Failed to authenticate with server. Please restart TRIBES 2 and try again."; + case "CR_YOUAREBANNED": + %error = "You are not allowed to play on this server."; + case "CR_SERVERFULL": + %error = "This server is full."; + default: + %error = "Connection error. Please try another server. Error code: (" @ %msg @ ")"; + } + DisconnectedCleanup(); + MessageBoxOK( "REJECTED", %error); +} + +function onChallengeRequestRejected( %msg ) +{ + CloseMessagePopup(); + DisconnectedCleanup(); + switch$(%msg) + { + case "PASSWORD": + if ( $JoinGamePassword $= "" ) + Canvas.pushDialog( PasswordDlg ); + else + { + $JoinGamePassword = ""; + MessageBoxOK( "REJECTED", "That password is incorrect."); + } + return; + case "CHR_PROTOCOL_SERVER": + %error = "Incompatible protocol version: The server is running an older, incompatible version of Tribes 2."; + case "CHR_PROTOCOL": + %error = "Incompatible protocol version: You must upgrade your game version to play on this server."; + case "CHR_NOT_AUTHENTICATED": + %error = "This is an online server - you must be logged in to play on it."; + case "CHR_INVALID_SERVER_PACKET": + %error = "Invalid server response packet. This should not happen."; + case "WS_PeerAuthServer_ExpiredClientCertificate": + %error = "Authentication error - please restart TRIBES 2 and try again."; + default: + %error = "Connection challenge error. Please try another server. Error code: (" @ %msg @ ")"; + } + MessageBoxOK( "REJECTED", %error ); +} + +function onConnectRequestTimedOut() +{ + DisconnectedCleanup(); + MessageBoxOK( "TIMED OUT", "Your connection to the server timed out." ); +} + +function onConnectionToServerTimedOut() +{ + DisconnectedCleanup(); + MessageBoxOK( "TIMED OUT", "Your connection to the server timed out."); +} + +function onConnectionToServerLost( %msg ) +{ + DisconnectedCleanup(); + if ( %msg $= "" ) + %msg = "Your connection to the server was lost."; + MessageBoxOK( "DISCONNECTED", %msg ); +} + +// Client voting functions: +function startNewVote(%name, %arg1, %arg2, %arg3, %arg4, %playerVote) +{ + if ( %arg1 $= "" ) + %arg1 = 0; + if ( %arg2 $= "" ) + %arg2 = 0; + if ( %arg3 $= "" ) + %arg3 = 0; + if ( %arg4 $= "" ) + %arg4 = 0; + if ( %playerVote $= "" ) + %playerVote = 0; + + commandToServer('startNewVote', %name, %arg1, %arg2, %arg3, %arg4, %playerVote); +} + +function setPlayerVote(%vote) +{ + commandToServer('setPlayerVote', %vote); +} + +function ClientCmdVoteSubmitted(%type) +{ + clientCmdClearBottomPrint(); + + if(%type) + alxPlay(VoteAgainstSound, 0, 0, 0); + else + alxPlay(VoteForSound, 0, 0, 0); +} +// End client voting functions. + +//-------------------------------------------------------------------------- +// Player pref functions: +function getPlayerPrefs( %player ) +{ + %voiceMuted = false; + if ( $PlayingOnline ) + { + if ( !%player.isSmurf ) + { + %record = queryPlayerDatabase( %player.guid ); + if ( %record !$= "" ) + { + if ( firstWord( %record ) == 1 ) + { + %player.chatMuted = true; + commandToServer( 'TogglePlayerMute', %player.clientId ); + } + + %voiceMuted = getWord( %record, 1 ) == 1; + } + } + else + %voiceMuted = true; // For now, automatically mute smurfs + } + + commandToServer( 'ListenTo', %player.clientId, !%voiceMuted, false ); +} + +//-------------------------------------------------------------------------- +function handlePlayerMuted( %msgType, %msgString, %name, %client, %mute ) +{ + if ( isObject( $PlayerList[%client] ) ) + { + $PlayerList[%client].chatMuted = %mute; + if ( $PlayingOnline && !$PlayerList[%client].isSmurf && $PlayerList[%client].guid > 0 ) + setPlayerTextMuted( $PlayerList[%client].guid, %mute ); + } +} + +//-------------------------------------------------------------------------- +function clientCmdEndBomberSight() +{ + PlayGui.remove($bombSightHud); +} + +function clientCmdRemoveReticle() +{ + reticleHud.setBitmap(""); + reticleFrameHud.setVisible(false); +} + +function clientCmdSetBeaconNames(%target, %marker, %vehicle) +{ + setBeaconNames(%target, %marker, %vehicle); +} + +function clientCmdStartBomberSight() +{ + $bombSightHud = new HudBombSight(bombSightName) { + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "286 206"; + extent = "67 67"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + helpTag = "0"; + minDisplayHeight = "20"; + }; + PlayGui.add($bombSightHud); +} + +function tempShowSpeed(%client) +{ + if(!$tmpSpeedShow) + $tmpSpeedShow = true; + else + $tmpSpeedShow = false; + commandToClient(%client, 'toggleSpeed', %client, $tmpSpeedShow); +} + +function clientCmdToggleSpeed(%client, %toggle) +{ + if(%toggle) { + %tempSpeedHud = new GuiTextCtrl(tmpSpeed) { + profile = "GuiTempSpeedProfile"; + horizSizing = "center"; + vertSizing = "top"; + position = "175 200"; + extent = "120 50"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + }; + PlayGui.add(%tempSpeedHud); + %client.updateTempSpeed(%client); + } + else { + cancel(%client.tmpSpeedCheck); + tmpSpeed.delete(); + } +} + +function GameConnection::updateTempSpeed(%client) +{ + commandToClient(%client, 'getTempSpeed'); + %client.tmpSpeedCheck = %client.schedule(100, "updateTempSpeed", %client); +} + +function clientCmdGetTempSpeed() +{ + %vel = getControlObjectSpeed(); + tmpSpeed.setValue(%vel); +} + +function clientCmdInitLoadClientFavorites() +{ + loadFavorite($pref::FavCurrentSelect); +} + +function clientCmdToggleDashHud(%val) +{ + if(!%val) { + if(isObject(vDiagramHud)) + { + vDiagramHud.delete(); + cancel(dashboardHud.speedCheck); + vSpeedBox.delete(); + } + if(isObject(vOverheadHud)) + vOverheadHud.delete(); + if(isObject(vEnergyFrame)) + vEnergyFrame.delete(); + if(isObject(vDamageFrame)) + vDamageFrame.delete(); + if(isObject(vAltitudeBox)) + { + cancel(dashboardHud.altitudeCheck); + vAltitudeBox.delete(); + } + if(isObject(vWeaponOne)) + vWeaponOne.delete(); + if(isObject(vWeaponTwo)) + vWeaponTwo.delete(); + if(isObject(vWeaponThree)) + vWeaponThree.delete(); + if(isObject(vWeapHiliteOne)) + vWeapHiliteOne.delete(); + if(isObject(vWeapHiliteTwo)) + vWeapHiliteTwo.delete(); + if(isObject(vWeapHiliteThree)) + vWeapHiliteThree.delete(); + if(isObject(vPassengerHud)) + vPassengerHud.delete(); + if(isObject(bombardierHud)) + bombardierHud.delete(); + if(isObject(turreteerHud)) + turreteerHud.delete(); + // reset in case of vehicle-specific reticle + //reticleHud.setBitmap(""); + //reticleFrameHud.setVisible(false); + } + dashboardHud.setVisible(%val); +} + +function addEnergyGauge( %vehType ) +{ + switch$ (%vehType) + { + case "Assault" or "Bomber": + dashboardHud.nrgBar = new HudBitmapCtrl(vEnergyFrame) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "160 80"; + extent = "118 19"; + minExtent = "8 8"; + visible = "1"; + bitmap = "gui/hud_veh_new_dashpiece_5"; + opacity = "0.8"; + + new HudEnergy(vEnergyBar) { + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "0 0"; + extent = "118 19"; + minExtent = "8 8"; + visible = "1"; + fillColor = "0.353000 0.373000 0.933000 0.800000"; + frameColor = "0.000000 1.000000 0.000000 1.000000"; + autoCenter = "0"; + autoResize = "0"; + displayMounted = true; + bitmap = "gui/hud_veh_new_dashpiece_5"; + verticalFill = false; + subRegion = "4 5 98 5"; + pulseRate = "500"; + pulseThreshold = "0.3"; + //modColor = "1.000000 0.500000 0.000000 1.000000"; + }; + + new HudCapacitor(vCapBar) { + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "0 8"; + extent = "118 8"; + minExtent = "8 8"; + visible = "1"; + fillColor = "1.000 0.729 0.301 0.800000"; + frameColor = "0.000000 1.000000 0.000000 1.000000"; + autoCenter = "0"; + autoResize = "0"; + displayMounted = true; + bitmap = "gui/hud_veh_new_dashpiece_5"; + verticalFill = false; + subRegion = "4 5 98 5"; + pulseRate = "500"; + pulseThreshold = "0.3"; + //modColor = "1.000000 0.500000 0.000000 1.000000"; + }; + }; + dashboardHud.add(dashboardHud.nrgBar); + + default: + dashboardHud.nrgBar = new HudBitmapCtrl(vEnergyFrame) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "160 80"; + extent = "118 19"; + minExtent = "8 8"; + visible = "1"; + bitmap = "gui/hud_veh_new_dashpiece_5"; + opacity = "0.8"; + + new HudEnergy(vEnergyBar) { + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "0 0"; + extent = "118 19"; + minExtent = "8 8"; + visible = "1"; + fillColor = "0.353000 0.373000 0.933000 0.800000"; + frameColor = "0.000000 1.000000 0.000000 1.000000"; + autoCenter = "0"; + autoResize = "0"; + displayMounted = true; + bitmap = "gui/hud_veh_new_dashpiece_5"; + verticalFill = false; + subRegion = "4 5 98 10"; + pulseRate = "500"; + pulseThreshold = "0.3"; + //modColor = "1.000000 0.500000 0.000000 1.000000"; + }; + }; + dashboardHud.add(dashboardHud.nrgBar); + } +} + +function clientCmdShowVehicleGauges(%vehType, %node) +{ + //if(!((%vehType $= "Bomber" || %vehType $= "Assault") && %node > 0)) + if(%node == 0) + { + // common elements that show up on all vehicle pilot HUDs + dashboardHud.diagram = new HudBitmapCtrl(vDiagramHud) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "200 10"; + extent = "176 108"; + minExtent = "8 8"; + visible = "1"; + bitmap = "gui/hud_veh_new_dash"; + opacity = "0.8"; + }; + dashboardHud.add(dashboardHud.diagram); + + dashboardHud.vehDiagram = new HudBitmapCtrl(vOverheadHud) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "256 0"; + extent = "128 128"; + minExtent = "8 8"; + visible = "1"; + bitmap = ""; + opacity = "1.0"; + }; + dashboardHud.add(dashboardHud.vehDiagram); + + addEnergyGauge( %vehType ); + + dashboardHud.dmgBar = new HudBitmapCtrl(vDamageFrame) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "361 80"; + extent = "118 19"; + minExtent = "8 8"; + visible = "1"; + bitmap = "gui/hud_veh_new_dashpiece_4"; + opacity = "0.8"; + + new HudDamage(vDamageBar) { + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "0 0"; + extent = "118 19"; + minExtent = "8 8"; + visible = "1"; + fillColor = "0.000000 1.0000 0.000000 0.800000"; + frameColor = "0.000000 1.000000 0.000000 0.000000"; + bitmap = "gui/hud_veh_new_dashpiece_4"; + verticalFill = false; + displayMounted = true; + opacity = "0.8"; + subRegion = "18 5 97 10"; + pulseRate = "500"; + pulseThreshold = "0.3"; + //modColor = "1.000000 0.500000 0.000000 1.000000"; + }; + }; + dashboardHud.add(dashboardHud.dmgBar); + + dashboardHud.speedBox = new GuiControl(vSpeedBox) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "210 47"; + extent = "40 40"; + minExtent = "8 8"; + visible = "1"; + + new GuiTextCtrl(vSpeedText) { + profile = "GuiDashTextProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "3 15"; + extent = "18 15"; + minExtent = "8 8"; + visible = "1"; + text = "test"; + }; + new GuiTextCtrl(vSpeedTxtLbl) { + profile = "GuiDashTextProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "18 15"; + extent = "27 15"; + minExtent = "8 8"; + visible = "1"; + text = "KPH"; + }; + }; + dashboardHud.add(dashboardHud.speedBox); + + dashboardHud.updateSpeed(); + } + + switch$ (%vehType) { + case "Shrike" : + vOverheadHud.setBitmap("gui/hud_veh_icon_shrike"); + // add altitude box for flying vehicles + dashboardHud.altBox = new HudBitmapCtrl(vAltitudeBox) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "371 56"; + extent = "68 22"; + minExtent = "8 8"; + bitmap = "gui/hud_veh_new_dashpiece_1"; + visible = "1"; + opacity = "0.8"; + + new GuiTextCtrl(vAltitudeText) { + profile = "GuiDashTextProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "19 5"; + extent = "18 15"; + minExtent = "8 8"; + visible = "1"; + text = "test"; + }; + new GuiTextCtrl(vAltitudeTxtLbl) { + profile = "GuiDashTextProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "40 5"; + extent = "12 15"; + minExtent = "8 8"; + visible = "1"; + text = "M"; + }; + }; + dashboardHud.add(dashboardHud.altBox); + dashboardHud.updateAltitude(); + // add right-hand weapons box and highlight + dashboardHud.weapon = new GuiControl(vWeapHiliteOne) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "358 22"; + extent = "80 33"; + minExtent = "8 8"; + visible = "1"; + + new HudBitmapCtrl(vWeapBkgdOne) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "0 0"; + extent = "82 40"; + minExtent = "8 8"; + bitmap = "gui/hud_veh_new_dashpiece_2"; + visible = "1"; + opacity = "0.8"; + + new HudBitmapCtrl(vWeapIconOne) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "28 6"; + extent = "25 25"; + minExtent = "8 8"; + bitmap = "gui/hud_blaster"; + visible = "1"; + opacity = "0.8"; + }; + }; + }; + dashboardHud.add(dashboardHud.weapon); + // change to shrike reticle + reticleHud.setBitmap("gui/hud_ret_shrike"); + reticleFrameHud.setVisible(false); + + case "Bomber" : + if(%node == 1) + { + // bombardier hud + dashboardHud.bHud = new GuiControl(bombardierHud) { + profile = "GuiDefaultProfile"; + horizSizing = "center"; + vertSizing = "top"; + position = "200 75"; + extent = "240 50"; + minExtent = "8 8"; + visible = "1"; + + new HudBitmapCtrl(vWeap1Hilite) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "18 9"; + extent = "80 44"; + minExtent = "8 8"; + visible = "1"; + bitmap = "gui/hud_veh_new_hilite_left"; + opacity = "0.3"; + }; + new HudBitmapCtrl(vWeap2Hilite) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "141 9"; + extent = "80 44"; + minExtent = "8 8"; + visible = "0"; + bitmap = "gui/hud_veh_new_hilite_right"; + opacity = "0.3"; + }; + new HudBitmapCtrl(vWeap3Hilite) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "99 9"; + extent = "40 44"; + minExtent = "8 8"; + visible = "0"; + bitmap = "gui/hud_veh_new_hilite_middle"; + opacity = "0.3"; + }; + + new HudBitmapCtrl(bombardierFrame) { + profile = "GuiDashBoxProfile"; + horizSizing = "center"; + vertSizing = "bottom"; + position = "20 8"; + extent = "200 40"; + minExtent = "8 8"; + visible = "1"; + bitmap = "gui/hud_veh_new_bombardier_dash"; + opacity = "1.0"; + + new HudBitmapCtrl(vWeaponOne) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "28 5"; + extent = "25 25"; + minExtent = "8 8"; + visible = "1"; + bitmap = "gui/hud_blaster"; + }; + + new HudBitmapCtrl(vWeaponTwo) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "87 6"; + extent = "25 25"; + minExtent = "8 8"; + visible = "1"; + bitmap = "gui/hud_targetlaser"; + }; + + new HudBitmapCtrl(vWeaponThree) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "147 6"; + extent = "25 25"; + minExtent = "8 8"; + visible = "1"; + bitmap = "gui/hud_veh_bomb"; + }; + }; + }; + dashboardHud.add(dashboardHud.bHud); + + dashboardHud.nrgBar = new HudBitmapCtrl(vEnergyFrame) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "110 95"; + extent = "118 19"; + minExtent = "8 8"; + visible = "1"; + flipVertical = true; + bitmap = "gui/hud_veh_new_dashpiece_5"; + opacity = "0.8"; + + new HudEnergy(vEnergyBar) { + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "0 0"; + extent = "118 19"; + minExtent = "8 8"; + visible = "1"; + fillColor = "0.353000 0.373000 0.933000 0.800000"; + frameColor = "0.000000 1.000000 0.000000 1.000000"; + autoCenter = "0"; + autoResize = "0"; + displayMounted = true; + bitmap = "gui/hud_veh_new_dashpiece_5"; + verticalFill = false; + subRegion = "4 5 98 5"; + pulseRate = "500"; + pulseThreshold = "0.3"; + //modColor = "1.000000 0.500000 0.000000 1.000000"; + }; + new HudCapacitor(vCapBar) { + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "0 8"; + extent = "118 8"; + minExtent = "8 8"; + visible = "1"; + fillColor = "1.000 0.729 0.301 0.800000"; + frameColor = "0.000000 1.000000 0.000000 1.000000"; + autoCenter = "0"; + autoResize = "0"; + displayMounted = true; + bitmap = "gui/hud_veh_new_dashpiece_5"; + verticalFill = false; + subRegion = "4 5 98 5"; + pulseRate = "500"; + pulseThreshold = "0.3"; + //modColor = "1.000000 0.500000 0.000000 1.000000"; + }; + }; + dashboardHud.add(dashboardHud.nrgBar); + + dashboardHud.dmgBar = new HudBitmapCtrl(vDamageFrame) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "410 95"; + extent = "118 19"; + minExtent = "8 8"; + visible = "1"; + flipVertical = true; + bitmap = "gui/hud_veh_new_dashpiece_4"; + opacity = "0.8"; + + new HudDamage(vDamageBar) { + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "0 0"; + extent = "118 19"; + minExtent = "8 8"; + visible = "1"; + fillColor = "0.000000 1.0000 0.000000 0.800000"; + frameColor = "0.000000 1.000000 0.000000 0.000000"; + bitmap = "gui/hud_veh_new_dashpiece_4"; + verticalFill = false; + displayMounted = true; + opacity = "0.8"; + subRegion = "18 5 97 10"; + pulseRate = "500"; + pulseThreshold = "0.3"; + //modColor = "1.000000 0.500000 0.000000 1.000000"; + }; + }; + dashboardHud.add(dashboardHud.dmgBar); + $numVWeapons = 3; + reticleHud.setBitmap("gui/hud_ret_shrike"); + reticleFrameHud.setVisible(false); + } + else if(%node == 0) + { + // pilot dashboard hud + vOverheadHud.setBitmap("gui/hud_veh_icon_bomber"); + // add altitude box for flying vehicles + dashboardHud.altBox = new HudBitmapCtrl(vAltitudeBox) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "371 56"; + extent = "68 22"; + minExtent = "8 8"; + bitmap = "gui/hud_veh_new_dashpiece_1"; + visible = "1"; + opacity = "0.8"; + + new GuiTextCtrl(vAltitudeText) { + profile = "GuiDashTextProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "19 5"; + extent = "18 15"; + minExtent = "8 8"; + visible = "1"; + text = "test"; + }; + new GuiTextCtrl(vAltitudeTxtLbl) { + profile = "GuiDashTextProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "40 5"; + extent = "12 15"; + minExtent = "8 8"; + visible = "1"; + text = "M"; + }; + }; + dashboardHud.add(dashboardHud.altBox); + dashboardHud.updateAltitude(); + } + else + { + // tailgunner hud + dashboardHud.vehDiagram = new HudBitmapCtrl(vOverheadHud) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "256 0"; + extent = "128 128"; + minExtent = "8 8"; + visible = "1"; + bitmap = "gui/hud_veh_icon_bomber"; + opacity = "1.0"; + }; + dashboardHud.add(dashboardHud.vehDiagram); + + dashboardHud.nrgBar = new HudBitmapCtrl(vEnergyFrame) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "177 50"; + extent = "118 19"; + minExtent = "8 8"; + visible = "1"; + bitmap = "gui/hud_veh_new_dashpiece_5"; + flipVertical = true; + opacity = "0.8"; + + new HudEnergy(vEnergyBar) { + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "0 0"; + extent = "118 19"; + minExtent = "8 8"; + visible = "1"; + fillColor = "0.353000 0.373000 0.933000 0.800000"; + frameColor = "0.000000 1.000000 0.000000 1.000000"; + autoCenter = "0"; + autoResize = "0"; + displayMounted = true; + bitmap = "gui/hud_veh_new_dashpiece_5"; + verticalFill = false; + subRegion = "4 5 98 10"; + pulseRate = "500"; + pulseThreshold = "0.3"; + }; + }; + dashboardHud.add(dashboardHud.nrgBar); + + dashboardHud.dmgBar = new HudBitmapCtrl(vDamageFrame) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "345 50"; + extent = "118 19"; + minExtent = "8 8"; + visible = "1"; + bitmap = "gui/hud_veh_new_dashpiece_4"; + flipVertical = true; + opacity = "0.8"; + + new HudDamage(vDamageBar) { + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "0 0"; + extent = "118 19"; + minExtent = "8 8"; + visible = "1"; + fillColor = "0.000000 1.0000 0.000000 0.800000"; + frameColor = "0.000000 1.000000 0.000000 0.000000"; + bitmap = "gui/hud_veh_new_dashpiece_4"; + verticalFill = false; + displayMounted = true; + opacity = "0.8"; + subRegion = "18 5 97 10"; + pulseRate = "500"; + pulseThreshold = "0.3"; + }; + }; + dashboardHud.add(dashboardHud.dmgBar); + } + if(%node != 1) + { + // passenger slot "dots" + vOverheadHud.passengerHud = new GuiControl(vPassengerHud) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "0 0"; + extent = "101 101"; + minExtent = "8 8"; + visible = "1"; + + new GuiBitmapCtrl(vPassenger0Slot) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "59 24"; + extent = "10 10"; + minExtent = "3 3"; + visible = "0"; + bitmap = "gui/hud_veh_seatdot"; + }; + new GuiBitmapCtrl(vPassenger1Slot) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "59 39"; + extent = "10 10"; + minExtent = "3 3"; + visible = "0"; + bitmap = "gui/hud_veh_seatdot"; + }; + new GuiBitmapCtrl(vPassenger2Slot) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "59 84"; + extent = "10 10"; + minExtent = "3 3"; + visible = "0"; + bitmap = "gui/hud_veh_seatdot"; + }; + }; + vOverheadHud.add(vOverheadHud.passengerHud); + } + case "HAPC" : + if(%node == 0) + { + vOverheadHud.setBitmap("gui/hud_veh_icon_hapc"); + // add altitude box for flying vehicles + dashboardHud.altBox = new HudBitmapCtrl(vAltitudeBox) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "371 56"; + extent = "68 22"; + minExtent = "8 8"; + bitmap = "gui/hud_veh_new_dashpiece_1"; + visible = "1"; + opacity = "0.8"; + + new GuiTextCtrl(vAltitudeText) { + profile = "GuiDashTextProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "19 5"; + extent = "18 15"; + minExtent = "8 8"; + visible = "1"; + text = "test"; + }; + new GuiTextCtrl(vAltitudeTxtLbl) { + profile = "GuiDashTextProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "40 5"; + extent = "12 15"; + minExtent = "8 8"; + visible = "1"; + text = "M"; + }; + }; + dashboardHud.add(dashboardHud.altBox); + updateVehicleAltitude(); + dashboardHud.updateAltitude(); + + } + else + { + // passenger hud + dashboardHud.vehDiagram = new HudBitmapCtrl(vOverheadHud) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "256 0"; + extent = "128 128"; + minExtent = "8 8"; + visible = "1"; + bitmap = "gui/hud_veh_icon_hapc"; + opacity = "1.0"; + }; + dashboardHud.add(dashboardHud.vehDiagram); + + dashboardHud.nrgBar = new HudBitmapCtrl(vEnergyFrame) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "180 30"; + extent = "118 19"; + minExtent = "8 8"; + visible = "1"; + bitmap = "gui/hud_veh_new_dashpiece_5"; + flipVertical = true; + opacity = "0.8"; + + new HudEnergy(vEnergyBar) { + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "0 0"; + extent = "118 19"; + minExtent = "8 8"; + visible = "1"; + fillColor = "0.353000 0.373000 0.933000 0.800000"; + frameColor = "0.000000 1.000000 0.000000 1.000000"; + autoCenter = "0"; + autoResize = "0"; + displayMounted = true; + bitmap = "gui/hud_veh_new_dashpiece_5"; + verticalFill = false; + subRegion = "4 5 98 10"; + pulseRate = "500"; + pulseThreshold = "0.3"; + }; + }; + dashboardHud.add(dashboardHud.nrgBar); + + dashboardHud.dmgBar = new HudBitmapCtrl(vDamageFrame) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "342 30"; + extent = "118 19"; + minExtent = "8 8"; + visible = "1"; + bitmap = "gui/hud_veh_new_dashpiece_4"; + flipVertical = true; + opacity = "0.8"; + + new HudDamage(vDamageBar) { + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "0 0"; + extent = "118 19"; + minExtent = "8 8"; + visible = "1"; + fillColor = "0.000000 1.0000 0.000000 0.800000"; + frameColor = "0.000000 1.000000 0.000000 0.000000"; + bitmap = "gui/hud_veh_new_dashpiece_4"; + verticalFill = false; + displayMounted = true; + opacity = "0.8"; + subRegion = "18 5 97 10"; + pulseRate = "500"; + pulseThreshold = "0.3"; + }; + }; + dashboardHud.add(dashboardHud.dmgBar); + } + // passenger slot "dots" + vOverheadHud.passengerHud = new GuiControl(vPassengerHud) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "0 0"; + extent = "101 101"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + helpTag = "0"; + + new GuiBitmapCtrl(vPassenger0Slot) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "59 65"; + extent = "10 10"; + minExtent = "3 3"; + visible = "0"; + setFirstResponder = "0"; + modal = "1"; + bitmap = "gui/hud_veh_seatdot"; + wrap = "0"; + }; + new GuiBitmapCtrl(vPassenger1Slot) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "59 84"; + extent = "10 10"; + minExtent = "3 3"; + visible = "0"; + setFirstResponder = "0"; + modal = "1"; + bitmap = "gui/hud_veh_seatdot"; + wrap = "0"; + }; + new GuiBitmapCtrl(vPassenger2Slot) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "38 29"; + extent = "10 10"; + minExtent = "3 3"; + visible = "0"; + setFirstResponder = "0"; + modal = "1"; + bitmap = "gui/hud_veh_seatdot"; + wrap = "0"; + }; + new GuiBitmapCtrl(vPassenger3Slot) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "38 50"; + extent = "10 10"; + minExtent = "3 3"; + visible = "0"; + setFirstResponder = "0"; + modal = "1"; + bitmap = "gui/hud_veh_seatdot"; + wrap = "0"; + }; + new GuiBitmapCtrl(vPassenger4Slot) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "80 50"; + extent = "10 10"; + minExtent = "3 3"; + visible = "0"; + setFirstResponder = "0"; + modal = "1"; + bitmap = "gui/hud_veh_seatdot"; + wrap = "0"; + }; + new GuiBitmapCtrl(vPassenger5Slot) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "80 29"; + extent = "10 10"; + minExtent = "3 3"; + visible = "0"; + setFirstResponder = "0"; + modal = "1"; + bitmap = "gui/hud_veh_seatdot"; + wrap = "0"; + }; + }; + vOverheadHud.add(vOverheadHud.passengerHud); + + case "Assault" : + if(%node == 1) + { + // turreteer hud + dashboardHud.tHud = new GuiControl(turreteerHud) { + profile = "GuiDefaultProfile"; + horizSizing = "center"; + vertSizing = "top"; + position = "225 70"; + extent = "240 50"; + minExtent = "8 8"; + visible = "1"; + + new HudBitmapCtrl(vWeap1Hilite) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "40 11"; + extent = "80 44"; + minExtent = "8 8"; + visible = "1"; + bitmap = "gui/hud_veh_new_hilite_left"; + opacity = "0.4"; + }; + new HudBitmapCtrl(vWeap2Hilite) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "118 11"; + extent = "80 44"; + minExtent = "8 8"; + visible = "0"; + bitmap = "gui/hud_veh_new_hilite_right"; + opacity = "0.4"; + }; + + new HudBitmapCtrl(turreteerFrame) { + profile = "GuiDashBoxProfile"; + horizSizing = "center"; + vertSizing = "bottom"; + position = "20 8"; + extent = "152 36"; + minExtent = "8 8"; + visible = "1"; + bitmap = "gui/hud_veh_new_tankgunner_dash"; + opacity = "0.8"; + + new HudBitmapCtrl(vWeaponOne) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "25 8"; + extent = "25 25"; + minExtent = "8 8"; + visible = "1"; + bitmap = "gui/hud_chaingun"; + }; + + new HudBitmapCtrl(vWeaponTwo) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "99 8"; + extent = "25 25"; + minExtent = "8 8"; + visible = "1"; + bitmap = "gui/hud_mortor"; + }; + }; + }; + dashboardHud.add(dashboardHud.tHud); + + dashboardHud.nrgBar = new HudBitmapCtrl(vEnergyFrame) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "134 95"; + extent = "118 19"; + minExtent = "8 8"; + visible = "1"; + flipVertical = true; + bitmap = "gui/hud_veh_new_dashpiece_5"; + opacity = "0.8"; + + new HudEnergy(vEnergyBar) { + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "0 0"; + extent = "118 19"; + minExtent = "8 8"; + visible = "1"; + fillColor = "0.353000 0.373000 0.933000 0.800000"; + frameColor = "0.000000 1.000000 0.000000 1.000000"; + autoCenter = "0"; + autoResize = "0"; + displayMounted = true; + bitmap = "gui/hud_veh_new_dashpiece_5"; + verticalFill = false; + subRegion = "4 5 98 5"; + pulseRate = "500"; + pulseThreshold = "0.3"; + //modColor = "1.000000 0.500000 0.000000 1.000000"; + }; + new HudCapacitor(vCapBar) { + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "0 8"; + extent = "118 8"; + minExtent = "8 8"; + visible = "1"; + fillColor = "1.000 0.729 0.301 0.800000"; + frameColor = "0.000000 1.000000 0.000000 1.000000"; + autoCenter = "0"; + autoResize = "0"; + displayMounted = true; + bitmap = "gui/hud_veh_new_dashpiece_5"; + verticalFill = false; + subRegion = "4 5 98 5"; + pulseRate = "500"; + pulseThreshold = "0.3"; + //modColor = "1.000000 0.500000 0.000000 1.000000"; + }; + }; + dashboardHud.add(dashboardHud.nrgBar); + + dashboardHud.dmgBar = new HudBitmapCtrl(vDamageFrame) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "390 95"; + extent = "118 19"; + minExtent = "8 8"; + visible = "1"; + flipVertical = true; + bitmap = "gui/hud_veh_new_dashpiece_4"; + opacity = "0.8"; + + new HudDamage(vDamageBar) { + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "0 0"; + extent = "118 19"; + minExtent = "8 8"; + visible = "1"; + fillColor = "0.000000 1.0000 0.000000 0.800000"; + frameColor = "0.000000 1.000000 0.000000 0.000000"; + bitmap = "gui/hud_veh_new_dashpiece_4"; + verticalFill = false; + displayMounted = true; + opacity = "0.8"; + subRegion = "18 5 97 10"; + pulseRate = "500"; + pulseThreshold = "0.3"; + //modColor = "1.000000 0.500000 0.000000 1.000000"; + }; + }; + dashboardHud.add(dashboardHud.dmgBar); + + $numVWeapons = 2; + // add tank chaingun reticle + reticleHud.setBitmap("gui/hud_ret_tankchaingun"); + reticleFrameHud.setVisible(false); + } + else + { + // node 0 == driver + vOverheadHud.setBitmap("gui/hud_veh_icon_assault"); + // passenger slot "dots" + vOverheadHud.passengerHud = new GuiControl(vPassengerHud) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "0 0"; + extent = "101 101"; + minExtent = "8 8"; + visible = "1"; + + new GuiBitmapCtrl(vPassenger0Slot) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "64 30"; + extent = "10 10"; + minExtent = "3 3"; + visible = "0"; + bitmap = "gui/hud_veh_seatdot"; + }; + new GuiBitmapCtrl(vPassenger1Slot) { + profile = "GuiDashBoxProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "53 53"; + extent = "10 10"; + minExtent = "3 3"; + visible = "0"; + bitmap = "gui/hud_veh_seatdot"; + }; + }; + vOverheadHud.add(vOverheadHud.passengerHud); + } + + case "Hoverbike" : + vOverheadHud.setBitmap("gui/hud_veh_icon_hoverbike"); + + case "MPB" : + vOverheadHud.setBitmap("gui/hud_veh_icon_mpb"); + + } + if(%node == 0) + vDiagramHud.setVisible(true); + else + if(isObject(vDiagramHud)) + vDiagramHud.setVisible(false); +} + +function GuiControl::updateAltitude(%this) +{ + %alt = getControlObjectAltitude(); + vAltitudeText.setValue(%alt); + %this.altitudeCheck = %this.schedule(500, "updateAltitude"); +} + +function GuiControl::updateSpeed(%this) +{ + %vel = getControlObjectSpeed(); + // convert from m/s to km/h + %cVel = mFloor(%vel * 3.6); // m/s * (3600/1000) = km/h + vSpeedText.setValue(%cVel); + %this.speedCheck = %this.schedule(500, "updateSpeed"); +} + +//function clientCmdShowVehicleWeapons(%vehicleType) +//{ + // all vehicle weapons are energy based; a -1 displays an infinity symbol + // for that weapon's ammo amount + //switch$ (%vehicleType) + //{ + // case "ScoutFlyer": + // // blaster + // vWeaponsBox.addWeapon(0, -1); + // case "BomberFlyer": + // // plasma, bomb and targeting laser + // vWeaponsBox.addWeapon(1, -1); + // vWeaponsBox.addWeapon(3, -1); + // vWeaponsBox.addWeapon(4, -1); + // case "AssaultVehicle": + // vWeaponsBox.addWeapon(1, -1); + // vWeaponsBox.addWeapon(3, -1); + //} + //vWeaponsBox.setVisible(true); +//} + +// if set, then static shapes with data member 'noIndividualDamage' set will +// not display their damage bars +function clientCmdProtectingStaticObjects(%val) +{ + NavHud.protectedStatics = %val; +} + +function clientCmdCheckPassengers(%pString) +{ + // since each slot is represented by a "1" or a "0" followed by a space, the length + // of the string divided by 2 is equal to the number of slots in the vehicle + %numSlots = strlen(%pString) / 2; + for(%i = 0; %i < %numSlots; %i++) + { + %pass = "vPassenger" @ %i @ "Slot"; + if(isObject(%pass)) + if(getWord(%pString, %i) $= "1") + %pass.setVisible(true); + else + %pass.setVisible(false); + } +} + +function clientCmdShowPassenger(%slot, %full) +{ + %dotNum = "vPassenger" @ %slot @ "Slot"; + if(isObject(%dotNum)) + %dotNum.setVisible(%full); +} + +function clientCmdClearPassengers() +{ + for(%i = 1; %i < 6; %i++) + { + %pass = "vPassenger" @ %i @ "Slot"; + %pass.setVisible(false); + } +} + +addMessageCallback( 'MsgMissionDropInfo', handleDropInfoMessage ); +addMessageCallback( 'MsgTeamList', handleTeamListMessage ); +addMessageCallback( 'LeaveMissionArea', HandleLeaveMissionAreaAlarmMessage ); +addMessageCallback( 'EnterMissionArea', HandleEnterMissionAreaAlarmMessage ); +addMessageCallback( 'msgBountyStreakBonus', HandleBountyStreakMessage ); +addMessageCallback( 'onClientKicked', handleIveBeenKicked ); +addMessageCallback( 'onClientBanned', handleIveBeenBanned ); +addMessageCallback( 'msgDeploySensorRed', clientDeploySensorRed ); +addMessageCallback( 'msgDeploySensorGrn', clientDeploySensorGrn ); +addMessageCallback( 'msgDeploySensorOff', clientDeploySensorOff ); +addMessageCallback( 'msgPackIconOff', clientPackIconOff ); +addMessageCallback( 'MsgForceObserver', HandleForceObserver ); +addMessageCallback( 'MsgPlayerMuted', handlePlayerMuted ); + +//------------------------------------------------------------------------------ +// Siege-specific callbacks: +addMessageCallback( 'MsgSiegeHalftime', handleSiegeHalftimeMessage ); +addMessageCallback( 'MsgSiegeResult', handleSiegeResultMessage ); +addMessageCallback( 'MsgSiegeAddLine', handleSiegeLineMessage ); +//------------------------------------------------------------------------------ + +function HandleForceObserver( %msgType, %msgString ) +{ + +} + +function handleIveBeenBanned(%msgType, %msgString) +{ + DisconnectedCleanup(); +} + +function handleIveBeenKicked(%msgType, %msgString) +{ + DisconnectedCleanup(); +} + +function clientDeploySensorRed() +{ + deploySensor.color = "255 0 0"; + deploySensor.setVisible(true); +} + +function clientDeploySensorGrn() +{ + deploySensor.color = "0 255 0"; + deploySensor.setVisible(true); +} + +function clientDeploySensorOff() +{ + deploySensor.setVisible(false); +} + +function clientPackIconOff() +{ + backpackIcon.setBitmap(""); + backpackFrame.setVisible(false); + backpackText.setValue(""); + backpackText.setVisible(false); + backpackFrame.pack = false; +} + +function HandleBountyStreakMessage(%msgType, %msgString, %client, %streak, %award) +{ + %delay = alxGetWaveLen("fx/misc/bounty_bonus.wav"); + %overlap = 0.50; + + alxPlay(BountyBellSound, 0, 0, 0); //first bell + for (%loop = 1; %loop < %award; %loop++) //any repetitions, overlapped. + schedule((%delay * %loop) * %overlap, 0, "alxPlay", BountyBellSound, 0, 0, 0); +} + +function HandleLeaveMissionAreaAlarmMessage(%msgType, %msgString) +{ + //Tinman - sounds are now sent by the individual game script + //if(ServerConnection.OutOfBoundsHandle $= "") + // ServerConnection.OutOfBoundsHandle = alxPlay(OutOfBoundsSound, 0, 0, 0); +} + +function HandleEnterMissionAreaAlarmMessage(%msgType, %msgString) +{ + //Tinman - sounds are now sent by the individual game script + //if(ServerConnection.OutOfBoundsHandle !$= "") + // alxStop(ServerConnection.OutOfBoundsHandle); + // + //ServerConnection.OutOfBoundsHandle = ""; +} + +function handleDropInfoMessage( %msgType, %msgString, %map, %gameType, %serverName ) +{ + $clServerName = %serverName; + $clMissionName = %map; + $clMissionType = %gameType; +} + +function handleTeamListMessage( %msgType, %msgString, %teamCount, %teamList ) +{ + // Save off the team names: + $clTeamCount = %teamCount; + for ( %i = 0; %i < %teamCount; %i++ ) + $clTeamScore[%i + 1, 0] = getRecord( %teamList, %i ); + + // Initialize the lobby: + LobbyPlayerList.initColumns(); +} + +//---------------------------------------------------------------------------- + +function clientCmdStartEffect( %effect ) +{ + // Put in iterations + StartEffect( %effect ); +} + +function clientCmdStopEffect( %effect ) +{ + StopEffect( %effect ); +} + +function clientCmdPickTeam() +{ + +} + +function clientCmdMissionStartPhase1(%seq, %missionName, %musicTrack) +{ + echo( "got client StartPhase1..." ); + + // Reset the loading progress controls: + LoadingProgress.setValue( 0 ); + DB_LoadingProgress.setValue( 0 ); + LoadingProgressTxt.setValue( "LOADING MISSION" ); + DB_LoadingProgressTxt.setValue( "LOADING MISSION" ); + + clientCmdPlayMusic(%musicTrack); + commandToServer('MissionStartPhase1Done', %seq); + clientCmdResetCommandMap(); +} + +function clientCmdMissionStartPhase2(%seq) +{ + // clean some stuff up. + MessageHud.close(); + purgeResources(); + if (!$pref::NoClearConsole) + cls(); + commandToServer('MissionStartPhase2Done', %seq); +} + +function clientCmdMissionStartPhase3(%seq, %missionName) +{ + $MSeq = %seq; + + //Reset Inventory Hud... + if($Hud['inventoryScreen'] !$= "") + { + %favList = $Hud['inventoryScreen'].data[0, 1].type TAB $Hud['inventoryScreen'].data[0, 1].getValue(); + for ( %i = 1; %i < $Hud['inventoryScreen'].count; %i++ ) + if($Hud['inventoryScreen'].data[%i, 1].getValue() $= invalid) + %favList = %favList TAB $Hud['inventoryScreen'].data[%i, 1].type TAB "EMPTY"; + else + %favList = %favList TAB $Hud['inventoryScreen'].data[%i, 1].type TAB $Hud['inventoryScreen'].data[%i, 1].getValue(); + commandToServer( 'setClientFav', %favList ); + } + else + commandToServer( 'setClientFav', $pref::Favorite[$pref::FavCurrentSelect]); + + // needed? + $MissionName = %missionName; + //commandToServer( 'getScores' ); + + // only show dialog if actually lights + if(lightScene("sceneLightingComplete", $LaunchMode $= "SceneLight" ? "forceWritable" : "")) + { + error("beginning SceneLighting...."); + schedule(1, 0, "updateLightingProgress"); + $lightingMission = true; + LoadingProgress.setValue( 0 ); + DB_LoadingProgress.setValue( 0 ); + LoadingProgressTxt.setValue( "LIGHTING MISSION" ); + DB_LoadingProgressTxt.setValue( "LIGHTING MISSION" ); + $missionLightStarted = true; + Canvas.repaint(); + } +} + +function clientCmdMissionEnd(%seq) +{ + alxStopAll(); + // disable mission lighting if it's going (since the interiors will be gone in a sec) + $lightingMission = false; + $sceneLighting::terminateLighting = true; +} + +function clientCmdSetPowerAudioProfiles(%up, %down) +{ + setPowerAudioProfiles(%up, %down); +} + +function ghostAlwaysStarted(%ghostCount) +{ + echo( "starting to ghost " @ %ghostCount @ " server objects...."); + + LoadingProgress.setValue( 0 ); + DB_LoadingProgress.setValue( 0 ); + LoadingProgressTxt.setValue( "LOADING OBJECTS" ); + DB_LoadingProgressTxt.setValue( "LOADING OBJECTS" ); + Canvas.repaint(); + $ghostCount = %ghostCount; + $ghostsRecvd = 0; +} + +function ghostAlwaysObjectReceived() +{ + $ghostsRecvd++; + %pct = $ghostsRecvd / $ghostCount; + LoadingProgress.setValue( %pct ); + DB_LoadingProgress.setValue( %pct ); + Canvas.repaint(); +} + +function updateLightingProgress() +{ + if( $SceneLighting::lightingProgress == 0) + { + if($sceneLightStarted) + { + $sceneLightStarted = false; + } + else + $SceneLighting::lightingProgress = 1; + } + + LoadingProgress.setValue( $SceneLighting::lightingProgress ); + DB_LoadingProgress.setValue( $SceneLighting::lightingProgress ); + if($lightingMission) + $lightingProgressThread = schedule(1, 0, "updateLightingProgress"); +} + +function sceneLightingComplete() +{ + LoadingProgress.setValue( 1 ); + DB_LoadingProgress.setValue( 1 ); + + echo("Scenelighting done..."); + $lightingMission = false; + + cleanUpHuds(); + + if($LaunchMode $= "SceneLight") + { + quit(); + return; + } + + clientCmdResetHud(); + commandToServer('SetVoiceInfo', $pref::Audio::voiceChannels, $pref::Audio::decodingMask, $pref::Audio::encodingLevel); + commandToServer('EnableVehicleTeleport', $pref::Vehicle::pilotTeleport ); + commandToServer('MissionStartPhase3Done', $MSeq); +} + +function clientCmdSetVoiceInfo(%channels, %decodingMask, %encodingLevel) +{ + $Audio::serverChannels = %channels; + $Audio::serverDecodingMask = %decodingMask; + $Audio::serverEncodingLevel = %encodingLevel; +} + +function ClientReceivedDataBlock(%index, %total) +{ + %pct = %index / %total; + LoadingProgress.setValue( %pct ); + LoadingProgress.setValue( %pct ); + Canvas.repaint(); +} + +function GameConnection::onTargetLocked( %con, %state ) +{ + if( %state $= "true" ) + { + if( !%con.targetTone ) + %con.targetTone = alxPlay( "sLockedTone", 0, 0, 0 ); + } + else + { + if( %con.targetTone $= "" ) + return; + + if( %con.targetTone ) + alxStop( %con.targetTone ); + + %con.targetTone = ""; + } +} + +function GameConnection::onTrackingTarget( %con, %state ) +{ + if( %state $= "true" ) + { + if( !%con.trackingTargetTone ) + %con.trackingTargetTone = alxPlay( "sSearchingTone", 0, 0, 0 ); + } + else + { + if( %con.trackingTargetTone $= "" ) + return; + + if( %con.trackingTargetTone ) + alxStop( %con.trackingTargetTone ); + + %con.TrackingTargetTone = ""; + } +} + +function GameConnection::onLockWarning( %con, %state ) +{ + if( %state $= "true" ) + { + if( !%con.lockWarningTone ) + %con.lockWarningTone = alxPlay( "sMissileLockWarningTone", 0, 0, 0 ); + + } + else + { + if( %con.lockWarningTone $= "" ) + return; + + if( %con.lockWarningTone ) + alxStop( %con.lockWarningTone ); + + %con.lockWarningTone = ""; + } +} + +function GameConnection::onHomeWarning( %con, %state ) +{ + if( %state $= "true" ) + { + if( !%con.homeWarningTone ) + %con.homeWarningTone = alxPlay( "sMissileHomingWarningTone", 0, 0, 0 ); + } + else + { + if( %con.homeWarningTone $= "" ) + return; + + if( %con.homeWarningTone ) + alxStop( %con.homeWarningTone ); + + %con.homeWarningTone = ""; + } +} + +function GameConnection::initialControlSet(%this) +{ + if ( $LaunchMode $= "InteriorView" ) + { + Canvas.setContent( InteriorPreviewGui ); + return; + } + + if( $LaunchMode $= "TSShow" ) + { + Canvas.setContent( TSShowGui ); + return; + } + + if( Canvas.getContent() != PlayGui.getId() ) + { + Canvas.setContent( PlayGui ); + Canvas.pushDialog( MainChatHud ); + CommandToServer('PlayContentSet'); + } +} + +//------------------------------------------------------------------------------ +// Siege-specific client functions: +//------------------------------------------------------------------------------ +function handleSiegeHalftimeMessage( %msgType, %msgString ) +{ + alxPlay( SiegeSwitchSides, 0, 0, 0 ); + showTaskHudDlg( false ); + SiegeHalftimeText.setText( "" ); +} + +//------------------------------------------------------------------------------ +function handleSiegeResultMessage( %msgType, %msgString, %result ) +{ + SiegeHalftimeHeaderText.setText( "" @ detag( %result ) ); +} + +//------------------------------------------------------------------------------ +function handleSiegeLineMessage( %msgType, %msgString, %line ) +{ + %text = SiegeHalftimeText.getText(); + if ( %text $= "" ) + %newText = detag( %line ); + else + %newText = %text NL detag( %line ); + SiegeHalftimeText.setText( %newText ); +} + +//------------------------------------------------------------------------------ +function clientCmdSetHalftimeClock( %time ) +{ + SiegeHalftimeClock.setTime( %time ); +} + +//------------------------------------------------------------------------------ +function SiegeHalftimeHeaderText::onResize( %this, %width, %height ) +{ + %w = firstWord( SiegeHalftimeHeader.getExtent() ); + SiegeHalftimeHeader.setExtent( %w, %height + 6 ); + %paneHeight = getWord( siegeHalftimeHud.getExtent(), 1 ); + %x = firstWord( SiegeHalftimeScroll.getPosition() ); + %y = %height + 40; + %w = firstWord( SiegeHalftimeScroll.getExtent() ); + %h = %paneHeight - %height - 59; + SiegeHalftimeScroll.resize( %x, %y, %w, %h ); +} + +//Was moved to client.cs from console_end.cs because alxPlayMusic didn't want to work from console_end.cs for some odd reason ... +if ($pref::Audio::musicEnabled) + alxPlayMusic("T2BOL/Music/Menu.mp3"); + diff --git a/scripts/commanderMap.cs b/scripts/commanderMap.cs index 2fa5a00..220eda2 100644 --- a/scripts/commanderMap.cs +++ b/scripts/commanderMap.cs @@ -1,995 +1,995 @@ -//-------------------------------------------------------------------------- -// ActionMap: -//-------------------------------------------------------------------------- -$CommanderMap::useMovementKeys = false; - -// help overlay toggle -function toggleCmdMapHelpGui( %val ) -{ - if ( %val) - toggleCmdMapHelpText(); -} - -// shortcuts to buttons: top buttons -function toggleAction(%control) -{ - %control.setValue(!%control.getValue()); - %control.onAction(); -} - -function bindAction(%fromMap, %command, %bindCmd, %bind1, %bind2 ) -{ - if(!isObject(%fromMap)) - return(false); - - %bind = %fromMap.getBinding(%command); - if(%bind $= "") - return(false); - - // only allow keyboard - %device = getField(%bind, 0); - if(%device !$= "keyboard") - return(false); - - %action = getField(%bind, 1); - - // bind or bindcmd? - if(%bindCmd) - CommanderKeyMap.bindCmd( %device, %action, %bind1, %bind2 ); - else - CommanderKeyMap.bind( %device, %action, %bind1 ); - - return(true); -} - -function createCommanderKeyMap() -{ - if(isObject(CommanderKeyMap)) - CommanderKeyMap.delete(); - - new ActionMap(CommanderKeyMap); - - // copy in all the binds we want from the moveMap - CommanderKeyMap.copyBind( moveMap, ToggleMessageHud ); - CommanderKeyMap.copyBind( moveMap, TeamMessageHud ); - CommanderKeyMap.copyBind( moveMap, resizeChatHud ); - CommanderKeyMap.copyBind( moveMap, pageMessageHudUp ); - CommanderKeyMap.copyBind( moveMap, pageMessageHudDown ); - CommanderKeyMap.copyBind( moveMap, activateChatMenuHud ); - - // Miscellaneous other binds: - CommanderKeyMap.copyBind( moveMap, voteYes ); - CommanderKeyMap.copyBind( moveMap, voteNo ); - CommanderKeyMap.copyBind( moveMap, toggleCommanderMap ); - CommanderKeyMap.copyBind( moveMap, toggleHelpGui ); - CommanderKeyMap.copyBind( moveMap, toggleScoreScreen); - CommanderKeyMap.copyBind( moveMap, startRecordingDemo ); - CommanderKeyMap.copyBind( moveMap, stopRecordingDemo ); - CommanderKeyMap.copyBind( moveMap, voiceCapture ); - CommanderKeyMap.bindCmd( keyboard, escape, "", "toggleCommanderMap( true );" ); - - // grab help key from movemap - if(!bindAction( moveMap, toggleHelpGui, false, toggleCmdMapHelpGui )) - CommanderKeyMap.bind( keyboard, F1, toggleCmdMapHelpGui ); - - // Bind the command assignment/response keys as well: - CommanderKeyMap.copyBind( moveMap, toggleTaskListDlg ); - CommanderKeyMap.copyBind( moveMap, fnAcceptTask ); - CommanderKeyMap.copyBind( moveMap, fnDeclineTask ); - CommanderKeyMap.copyBind( moveMap, fnTaskCompleted ); - CommanderKeyMap.copyBind( moveMap, fnResetTaskList ); - - // button shortcuts - CommanderKeyMap.bindCmd( keyboard, 1, "toggleAction(CMDPlayersButton);", "" ); - CommanderKeyMap.bindCmd( keyboard, 2, "toggleAction(CMDTacticalButton);", "" ); - CommanderKeyMap.bindCmd( keyboard, 3, "toggleAction(CMDDeployedTacticalButton);", "" ); - CommanderKeyMap.bindCmd( keyboard, 4, "toggleAction(CMDMiscButton);", "" ); - CommanderKeyMap.bindCmd( keyboard, 5, "toggleAction(CMDDeployedMiscButton);", "" ); - CommanderKeyMap.bindCmd( keyboard, 6, "toggleAction(CMDWaypointsButton);", "" ); - CommanderKeyMap.bindCmd( keyboard, 7, "toggleAction(CMDObjectivesButton);", "" ); - - // bottom buttons - CommanderKeyMap.bindCmd( keyboard, w, "toggleAction(CMDShowSensorsButton);", "" ); - CommanderKeyMap.bindCmd( keyboard, space, "cycleMouseMode();", "" ); - CommanderKeyMap.bindCmd( keyboard, q, "toggleAction(CMDCenterButton);", "" ); - CommanderKeyMap.bindCmd( keyboard, t, "toggleAction(CMDTextButton);", "" ); - CommanderKeyMap.bindCmd( keyboard, b, "toggleAction(CMDCameraButton);", "" ); - - // camera control (always arrows) - CommanderKeyMap.bindCmd( keyboard, left, "CommanderMap.cameraMove(left, true);", "commanderMap.cameraMove(left, false);" ); - CommanderKeyMap.bindCmd( keyboard, right, "CommanderMap.cameraMove(right, true);", "commanderMap.cameraMove(right, false);" ); - CommanderKeyMap.bindCmd( keyboard, up, "CommanderMap.cameraMove(up, true);", "commanderMap.cameraMove(up, false);" ); - CommanderKeyMap.bindCmd( keyboard, down, "CommanderMap.cameraMove(down, true);", "commanderMap.cameraMove(down, false);" ); - CommanderKeyMap.bindCmd( keyboard, numpadadd, "CommanderMap.cameraMove(in, true);", "commanderMap.cameraMove(in, false);" ); - CommanderKeyMap.bindCmd( keyboard, numpadminus, "CommanderMap.cameraMove(out, true);", "commanderMap.cameraMove(out, false);" ); - - CommanderKeyMap.bindCmd( keyboard, a, "CommanderMap.cameraMove(in, true);", "commanderMap.cameraMove(in, false);" ); - CommanderKeyMap.bindCmd( keyboard, z, "CommanderMap.cameraMove(out, true);", "commanderMap.cameraMove(out, false);" ); - - // steal the movement keys? (more likely than others to be a duplicate binding) - if($CommanderMap::useMovementKeys) - { - bindAction( moveMap, moveleft, true, "CommanderMap.cameraMove(left, true);", "commanderMap.cameraMove(left, false);" ); - bindAction( moveMap, moveright, true, "CommanderMap.cameraMove(right, true);", "commanderMap.cameraMove(right, false);" ); - bindAction( moveMap, moveforward, true, "CommanderMap.cameraMove(up, true);", "commanderMap.cameraMove(up, false);" ); - bindAction( moveMap, movebackward, true, "CommanderMap.cameraMove(down, true);", "commanderMap.cameraMove(down, false);" ); - } - else - { - CommanderKeyMap.bindCmd( keyboard, s, "CommanderMap.cameraMove(left, true);", "commanderMap.cameraMove(left, false);" ); - CommanderKeyMap.bindCmd( keyboard, f, "CommanderMap.cameraMove(right, true);", "commanderMap.cameraMove(right, false);" ); - CommanderKeyMap.bindCmd( keyboard, e, "CommanderMap.cameraMove(up, true);", "commanderMap.cameraMove(up, false);" ); - CommanderKeyMap.bindCmd( keyboard, d, "CommanderMap.cameraMove(down, true);", "commanderMap.cameraMove(down, false);" ); - } -} - -//-------------------------------------------------------------------------- -// Default Icons: -new CommanderIconData(CMDDefaultIcon) -{ - selectImage = "animation base_select true true looping 100"; - hilightImage = "animation base_select true true flipflop 100"; -}; - -new CommanderIconData(CMDAssignedTaskIcon) -{ - baseImage = "static diamond_not_selected true true"; - selectImage = "animation assigned_task_anim false true looping 100"; - hilightImage = "animation assigned_task_anim false true looping 100"; -}; - -new CommanderIconData(CMDPotentialTaskIcon) -{ - baseImage = "static diamond_not_selected true true"; - selectImage = "animation assigned_task_anim false true looping 100"; - hilightImage = "animation assigned_task_anim false true looping 100"; -}; - -new CommanderIconData(CMDWaypointIcon) -{ - baseImage = "animation waypoint_anim false false looping 100"; -}; - -//-------------------------------------------------------------------------- -// CommanderMapGui: -//-------------------------------------------------------------------------- -function clientCmdResetCommandMap() -{ - CommanderMapGui.reset(); -} - -function clientCmdScopeCommanderMap(%scope) -{ - if(!isPlayingDemo()) - return; - - if(%scope) - { - CommanderMap.openAllCategories(); - CommanderMapGui.open(); - } - else - CommanderMapGui.close(); -} - -function CommanderMapGui::onWake(%this) -{ - clientCmdControlObjectReset(); - - commandToServer('ScopeCommanderMap', true); - - createCommanderKeyMap(); - CommanderKeyMap.push(); - - if ( $HudHandle[CommandScreen] ) - alxStop( $HudHandle[CommandScreen] ); - alxPlay(CommandMapActivateSound, 0, 0, 0); - $HudHandle[CommandScreen] = alxPlay(CommandMapHumSound, 0, 0, 0); - - CMDTextButton.setValue(CommanderMap.renderText); - - // follow the player the first time - if(%this.firstWake) - { - CommanderMap.selectControlObject(); - CommanderMap.followLastSelected(); - %this.firstWake = false; - } - - if(CommanderTV.open) - CommanderTV.watchTarget(CommanderTV.target); - - // chat hud dialog - Canvas.pushDialog(MainChatHud); - chatHud.attach(HudMessageVector); - - %this.open = true; -} - -function CommanderMapGui::onSleep(%this) -{ - %this.open = false; - - commandToServer('ScopeCommanderMap', false); - - if(CMContextPopup.visible == true) - CMContextPopup.reset(); - - CommanderKeyMap.pop(); - Canvas.popDialog(MainChatHud); - - alxStop($HudHandle[CommandScreen]); - alxPlay(CommandMapDeactivateSound, 0, 0, 0); - $HudHandle[CommandScreen] = ""; - - // will reset the control object on this client.. should only be sent - // if this gui is being removed outside of CommanderMapGui::close() - if(CommanderTV.open && CommanderTV.attached) - commandToServer('AttachCommanderCamera', -1); - - //always set the cursor back to an arrow when you leave... - Canvas.setCursor(CMDCursorArrow); -} - -function CommanderMapGui::open(%this) -{ - if(%this.open) - return; - - commandToServer('SetPDAPose', true); - Canvas.setContent(%this); -} - -function CommanderMapGui::close(%this) -{ - if(!%this.open) - return; - - // only need to have control object reset if still attached to an object -// if(CommanderTV.open && CommanderTV.attached) -// { - commandToServer('ResetControlObject'); - - // reset the attached state since we will not be getting an attached response - CommanderTV.attached = false; -// } -// else -// clientCmdControlObjectReset(); - - commandToServer('SetPDAPose', false); -} - -function CommanderMapGui::toggle(%this) -{ - if(%this.open) - %this.close(); - else - %this.open(); -} - -function CommanderMapGui::onAdd(%this) -{ - %this.open = false; - - new GuiControl(CMContextPopupDlg) - { - profile = "GuiModelessDialogProfile"; - horizSizing = "width"; - vertSizing = "height"; - position = "0 0"; - extent = "640 480"; - minExtent = "8 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - - new GuiCommanderMapPopupMenu(CMContextPopup) - { - profile = "CommanderPopupProfile"; - position = "0 0"; - extent = "0 0"; - minExtent = "0 0"; - maxPopupHeight = "200"; - }; - }; - - CMContextPopup.numEntries = 0; - CMContextPopup.actionMap = -1; - CMContextPopup.focusedEntry = -1; - CMContextPopup.visible = false; - CMContextPopup.target = -1; -} - -function CommanderMapGui::reset(%this) -{ - clientCmdControlObjectReset(); - CommanderMap.openAllCategories(); - CommanderMap.resetCamera(); - CommanderTV.watchTarget(-1); - - // remove all tasks and clean task list - clientCmdResetTaskList(); - - // reset waypoints - if(isObject($ClientWaypoints)) - $ClientWaypoints.delete(); - - // this can be called when not connected to a server - if(isObject(ServerConnection)) - { - $ClientWaypoints = new SimGroup(); - ServerConnection.add($ClientWaypoints); - } - - %this.firstWake = true; - CommanderTree.currentWaypointID = 0; -} - -function CommanderMapGui::openCameraControl(%this, %open) -{ - %step = getWord(CommanderTV.extent, 1); - %x = getWord(CommanderTreeContainer.position, 0); - %y = getWord(CommanderTreeContainer.position, 1); - %w = getWord(CommanderTreeContainer.extent, 0); - %h = getWord(CommanderTreeContainer.extent, 1); - - if(%open) - %h = %h - %step; - else - %h = %h + %step; - - CommanderTreeContainer.resize(%x, %y, %w, %h); - CommanderTV.setVisible(%open); - - CommanderTV.open = %open; - CommanderTV.watchTarget(CommanderTV.target); - - if(!CommanderTV.open) - commandToServer('AttachCommanderCamera', -1); -} - -//-------------------------------------------------------------------------- -// CMContextPopup: -//-------------------------------------------------------------------------- -function CMContextPopup::reset(%this) -{ - if(%this.actionMap != -1) - { - %this.actionMap.pop(); - %this.actionMap.delete(); - } - - for(%i = 0; %i < %this.numEntries; %i++) - { - %this.entryKeys[%i] = ""; - %this.entryCommands[%i] = ""; - } - - %this.visible = false; - %this.numEntries = 0; - %this.actionMap = -1; - if(%this.focusedEntry != -1) - %this.focusedEntry.lockFocus(false); - %this.focusedEntry = -1; - - %this.forceClose(); - Canvas.popDialog(CMContextPopupDlg); - - // need to delete the target if it was not used - if(isObject(%this.target)) - { - if(%this.target.getTargetId() != -1) - %this.target.delete(); - %this.target = -1; - } -} - -function CMContextPopup::display(%this) -{ - if(%this.numEntries == 0) - return; - - %this.actionMap = new ActionMap(); - - for(%i = 0; %i < %this.numEntries; %i++) - if(%this.entryKeys[%i] !$= "") - %this.actionMap.bindCmd(keyboard, %this.entryKeys[%i], "", %this @ ".onKeySelect(" @ %i @ ");"); - - %this.actionMap.bindCmd(keyboard, escape, "", %this @ ".reset();"); - %this.actionMap.push(); - - if(%this.focusedEntry != -1) - %this.focusedEntry.lockFocus(true); - %this.visible = true; - - Canvas.pushDialog(CMContextPopupDlg); - %this.forceOnAction(); -} - -function CMContextPopup::addEntry(%this, %key, %text, %command) -{ - %idx = %this.numEntries; - %this.entryKeys[%idx] = %key; - %this.entryCommands[%idx] = %command; - %this.numEntries++; - - %this.add(%text, %idx); -} - -function CMContextPopup::onKeySelect(%this, %index) -{ - %this.onSelect(%index, %this.getTextById(%index)); -} - -function CMContextPopup::onSelect(%this, %index, %value) -{ - CommanderTree.processCommand(%this.entryCommands[%index], %this.target, %this.typeTag); - %this.reset(); -} - -function CMContextPopup::onCancel( %this ) -{ - %this.reset(); -} - -//------------------------------------------------------------------------------ -// CommanderTree: -//------------------------------------------------------------------------------ -function CommanderTree::onAdd(%this) -{ - %this.headerHeight = 20; - %this.entryHeight = 20; - - %this.reset(); - - %this.addCategory("Clients", "Teammates", "clients"); - %this.addCategory("Tactical", "Tactical Assets", "targets"); - %this.addCategory("DTactical", "Deployed Tactical", "targets"); - %this.addCategory("Support", "Support Assets", "targets"); - %this.addCategory("DSupport", "Deployed Support", "targets"); - %this.addCategory("Waypoints", "Waypoints", "waypoints"); - %this.addCategory("Objectives", "Objectives", "targets"); - - // targetType entries use registered info if no ShapeBaseData exists - %this.registerEntryType("Clients", getTag('_ClientConnection'), false, "commander/MiniIcons/com_player_grey", "255 255 255"); - %this.registerEntryType("Waypoints", $CMD_WAYPOINTTYPEID, false, "commander/MiniIcons/com_waypoint_grey", "0 255 0"); - %this.registerEntryType("Waypoints", $CMD_ASSIGNEDTASKTYPEID, false, "commander/MiniIcons/com_waypoint_grey", "0 0 255"); - -// %this.registerEntryType("Waypoints", $CMD_POTENTIALTASKTYPEID, false, "commander/MiniIcons/com_waypoint_grey", "255 255 0"); -} - -function CommanderTree::onCategoryOpen(%this, %category, %open) -{ - switch$ (%category) - { - case "Clients": - CMDPlayersButton.setValue(%open); - case "Tactical": - CMDTacticalButton.setValue(%open); - case "DTactical": - CMDDeployedTacticalButton.setValue(%open); - case "Support": - CMDMiscButton.setValue(%open); - case "DSupport": - CMDDeployedMiscButton.setValue(%open); - case "Waypoints": - CMDWaypointsButton.setValue(%open); - case "Objectives": - CMDObjectivesButton.setValue(%open); - } -} - -function CommanderTree::controlObject(%this, %targetId) -{ - commandToServer('ControlObject', %targetId); -} - -//------------------------------------------------------------------------------ -// CommanderMap: -//------------------------------------------------------------------------------ -function GuiCommanderMap::onAdd(%this) -{ - %this.setMouseMode(select); - %this.setTargetTypeVisible($CMD_POTENTIALTASKTYPEID, true); - %this.setTargetTypeVisible($CMD_ASSIGNEDTASKTYPEID, true); -} - -function GuiCommanderMap::onSelect(%this, %targetId, %nameTag, %typeTag, %select) -{ - if(%select) - { - if(CommanderTV.target != %targetId) - CommanderTV.watchTarget(%targetId); - } - else - CommanderTV.watchTarget(-1); -} - -function GuiCommanderMap::openCategory(%this, %ctrl, %name, %open) -{ - %ctrl.setValue(%open); - CommanderTree.openCategory(%name, %open); -} - -function GuiCommanderMap::openAllCategories(%this) -{ - %this.openCategory(CMDPlayersButton, "Clients", 1); - %this.openCategory(CMDTacticalButton, "Tactical", 1); - %this.openCategory(CMDDeployedTacticalButton, "DTactical", 1); - %this.openCategory(CMDMiscButton, "Support", 1); - %this.openCategory(CMDDeployedMiscButton, "DSupport", 1); - %this.openCategory(CMDWaypointsButton, "Waypoints", 1); - %this.openCategory(CMDObjectivesButton, "Objectives", 1); -} - -//------------------------------------------------------------------------------ -// Issuing commands -//------------------------------------------------------------------------------ -// misc. tasks (sensor group -1 is considered friendly with these) -$CommandTask['PotentialTask', 0, text] = "\c1A\crccept"; -$CommandTask['PotentialTask', 0, tag] = 'TaskAccepted'; -$CommandTask['PotentialTask', 0, hotkey] = "a"; -$CommandTask['PotentialTask', 1, text] = "\c1D\crecline"; -$CommandTask['PotentialTask', 1, tag] = 'TaskDeclined'; -$CommandTask['PotentialTask', 1, hotkey] = "d"; - -$CommandTask['AssignedTask', 0, text] = "\c1C\crompleted"; -$CommandTask['AssignedTask', 0, tag] = 'TaskCompleted'; -$CommandTask['AssignedTask', 0, hotkey] = "c"; -$CommandTask['AssignedTask', 1, text] = "\c1R\cremove"; -$CommandTask['AssignedTask', 1, tag] = 'TaskRemoved'; -$CommandTask['AssignedTask', 1, hotkey] = "d"; - -$CommandTask['Location', 0, text] = "\c1D\crefend"; -$CommandTask['Location', 0, tag] = 'DefendLocation'; -$CommandTask['Location', 0, hotkey] = "d"; -$CommandTask['Location', 1, text] = "\c1M\creet (at)"; -$CommandTask['Location', 1, tag] = 'MeetLocation'; -$CommandTask['Location', 1, hotkey] = "m"; -$CommandTask['Location', 2, text] = "\c1B\cromb (at)"; -$CommandTask['Location', 2, tag] = 'BombLocation'; -$CommandTask['Location', 2, hotkey] = "b"; -$CommandTask['Location', 3, text] = "\c1A\crttack"; -$CommandTask['Location', 3, tag] = 'AttackLocation'; -$CommandTask['Location', 3, hotkey] = "a"; -$CommandTask['Location', 4, text] = "Deploy \c1I\crnventory"; -$CommandTask['Location', 4, tag] = 'DeployEquipment'; -$CommandTask['Location', 4, hotkey] = "i"; -$CommandTask['Location', 5, text] = "Deploy \c1T\crurrets"; -$CommandTask['Location', 5, tag] = 'DeployTurret'; -$CommandTask['Location', 5, hotkey] = "t"; -$CommandTask['Location', 6, text] = "Deploy \c1S\crensors"; -$CommandTask['Location', 6, tag] = 'DeploySensor'; -$CommandTask['Location', 6, hotkey] = "s"; -$CommandTask['Location', 7, text] = "Create \c1W\craypoint"; -$CommandTask['Location', 7, tag] = 'CreateWayPoint'; -$CommandTask['Location', 7, hotkey] = "w"; - -$CommandTask['Waypoint', 0, text] = "\c1D\crelete waypoint"; -$CommandTask['Waypoint', 0, tag] = 'DeleteWayPoint'; -$CommandTask['Waypoint', 0, hotkey] = "d"; - -// object tasks -$CommandTask['Player', 0, text] = "\c1E\crscort"; -$CommandTask['Player', 0, tag] = 'EscortPlayer'; -$CommandTask['Player', 0, hotkey] = "e"; -$CommandTask['Player', 1, text] = "\c1R\crepair"; -$CommandTask['Player', 1, tag] = 'RepairPlayer'; -$CommandTask['Player', 1, hotkey] = "r"; -$CommandTask['Player', 2, text] = "\c1A\crttack"; -$CommandTask['Player', 2, tag] = 'AttackPlayer'; -$CommandTask['Player', 2, hotkey] = "a"; -$CommandTask['Player', 2, enemy] = true; - -$CommandTask['Flag', 0, text] = "\c1D\crefend"; -$CommandTask['Flag', 0, tag] = 'DefendFlag'; -$CommandTask['Flag', 0, hotkey] = "d"; -$CommandTask['Flag', 1, text] = "\c1R\creturn"; -$CommandTask['Flag', 1, tag] = 'ReturnFlag'; -$CommandTask['Flag', 1, hotkey] = "r"; -$CommandTask['Flag', 2, text] = "\c1C\crapture"; -$CommandTask['Flag', 2, tag] = 'CaptureFlag'; -$CommandTask['Flag', 2, hotkey] = "c"; -$CommandTask['Flag', 2, enemy] = true; - -$CommandTask['Objective', 0, text] = "\c1C\crapture"; -$CommandTask['Objective', 0, tag] = 'CaptureObjective'; -$CommandTask['Objective', 0, hotkey] = "c"; -$CommandTask['Objective', 1, text] = "\c1D\crefend"; -$CommandTask['Objective', 1, tag] = 'DefendObjective'; -$CommandTask['Objective', 1, hotkey] = "d"; - -$CommandTask['Object', 0, text] = "\c1R\crepair"; -$CommandTask['Object', 0, tag] = 'RepairObject'; -$CommandTask['Object', 0, hotkey] = "r"; -$CommandTask['Object', 1, text] = "\c1D\crefend"; -$CommandTask['Object', 1, tag] = 'DefendObject'; -$CommandTask['Object', 1, hotkey] = "d"; -$CommandTask['Object', 2, text] = "\c1A\crttack"; -$CommandTask['Object', 2, tag] = 'AttackObject'; -$CommandTask['Object', 2, hotkey] = "a"; -$CommandTask['Object', 2, enemy] = true; -$CommandTask['Object', 3, text] = "\c1L\craze"; -$CommandTask['Object', 3, tag] = 'LazeObject'; -$CommandTask['Object', 3, hotkey] = "l"; -$CommandTask['Object', 3, enemy] = true; -$CommandTask['Object', 4, text] = "\c1M\crortar"; -$CommandTask['Object', 4, tag] = 'MortarObject'; -$CommandTask['Object', 4, hotkey] = "m"; -$CommandTask['Object', 4, enemy] = true; -$CommandTask['Object', 5, text] = "\c1B\cromb"; -$CommandTask['Object', 5, tag] = 'BombObject'; -$CommandTask['Object', 5, hotkey] = "b"; -$CommandTask['Object', 5, enemy] = true; - -function GuiCommanderMap::issueCommand(%this, %target, %typeTag, %nameTag, %sensorGroup, %mousePos) -{ - CMContextPopup.position = %mousePos; - CMContextPopup.clear(); - - CMContextPopup.target = %target; - CMContextPopup.typeTag = %typeTag; - CMContextPopup.nameTag = %nameTag; - CMContextPopup.sensorGroup = %sensorGroup; - - %taskType = %this.getCommandType(%typeTag); - if(%taskType $= "") - { - // script created target? - if(%target.getTargetId() == -1) - %target.delete(); - CMDContextPopup.target = -1; - return; - } - - %this.buildPopupCommands(%taskType, %sensorGroup); - CMContextPopup.display(); -} - -function GuiCommanderMap::getCommandType(%this, %typeTag) -{ - // special case (waypoints, location, tasks...) - if(%typeTag == $CMD_LOCATIONTYPEID) - return('Location'); - else if(%typeTag == $CMD_WAYPOINTTYPEID) - return('Waypoint'); - else if(%typeTag == $CMD_POTENTIALTASKTYPEID) - return('PotentialTask'); - else if(%typeTag == $CMD_ASSIGNEDTASKTYPEID) - return('AssignedTask'); - - // the handled types here (default is 'Object') - switch$(getTaggedString(%typeTag)) - { - case "_ClientConnection": - return('Player'); - case "Flag": - return('Flag'); - case "Objective": - return('Objective'); - } - return('Object'); -} - -function GuiCommanderMap::buildPopupCommands(%this, %taskType, %sensorGroup) -{ - %enemy = (%sensorGroup != ServerConnection.getSensorGroup()) && (%sensorGroup != -1); - for(%i = 0; $CommandTask[%taskType, %i, text] !$= ""; %i++) - { - if(%enemy == $CommandTask[%taskType, %i, enemy]) - { - CMContextPopup.addEntry($CommandTask[%taskType, %i, hotkey], - $CommandTask[%taskType, %i, text], - $CommandTask[%taskType, %i, tag]); - } - } -} - -//-------------------------------------------------------------------------- -// Command processing -//-------------------------------------------------------------------------- -function CommanderTree::processCommand(%this, %command, %target, %typeTag) -{ - switch$(getTaggedString(%command)) - { - // waypoints: tree owns the waypoint targets - case "CreateWayPoint": - %name = "Waypoint " @ %this.currentWaypointID++; - %target.createWaypoint(%name); - %id = %target.getTargetId(); - if(%id != -1) - { - $ClientWaypoints.add(%target); - CMContextPopup.target = -1; - } - return; - - case "DeleteWayPoint": - %target.delete(); - CMContextPopup.target = -1; - return; - - // tasks: - case "TaskAccepted": - clientAcceptTask(%target); - return; - - case "TaskDeclined": - clientDeclineTask(%target); - return; - - case "TaskCompleted": - clientTaskCompleted(); - return; - - case "TaskRemoved": - %target.delete(); - CMContextPopup.target = -1; - return; - } - - %numClients = %this.getNumTargets("Clients"); - %numSelected = %this.getNumSelectedTargets("Clients"); - - if((%numSelected == 0) || (%numSelected == %numClients)) - %team = true; - else - %team = false; - - %target.sendToServer(); - commandToServer('BuildClientTask', %command, %team); - - if(%team) - { - commandToServer('SendTaskToTeam'); - } - else - { - for(%i = 0; %i < %numSelected; %i++) - { - %targetId = %this.getSelectedTarget("Clients", %i); - commandToServer('SendTaskToClientTarget', %targetId); - } - } - - // delete target? - if(%target.getTargetId() == -1) - { - CMContextPopup.target = -1; - %target.delete(); - } -} - -//------------------------------------------------------------------------------ -function CommanderTV::watchTarget(%this, %targetId) -{ - if(%targetId < 0) - %targetId = -1; - - if(%this.attached) - commandToServer('AttachCommanderCamera', -1); - - %this.target = %targetId; - - if(%this.open && (%this.target != -1)) - commandToServer('AttachCommanderCamera', %this.target); -} - -function clientCmdCameraAttachResponse(%attached) -{ - CommanderTV.attached = %attached; -} - -//------------------------------------------------------------------------------ -// CommanderTV control -//------------------------------------------------------------------------------ -new ActionMap(CommanderTVControl); -CommanderTVControl.bind(mouse, xaxis, yaw); -CommanderTVControl.bind(mouse, yaxis, pitch); - - -function CommanderTV_ButtonPress(%val) -{ - if(%val) - { - CommanderTVControl.push(); - CursorOff(); - } - else - { - CommanderTVControl.pop(); - GlobalActionMap.unbind(mouse, button0); - - if(CommanderMapGui.open) - { - CursorOn(); - Canvas.setCursor(CMDCursorArrow); - } - } -} - -function CommanderTVScreen::onMouseEnter(%this, %mod, %pos, %count) -{ - GlobalActionMap.bind(mouse, button0, CommanderTV_ButtonPress); -} - -function CommanderTVScreen::onMouseLeave(%this, %mod, %pos, %count) -{ - GlobalActionMap.unbind(mouse, button0); -} - -//------------------------------------------------------------------------------ -// Buttons: play button down sounds here so script onAction call plays sound as well -//------------------------------------------------------------------------------ -// top buttons: -function CMDPlayersButton::onAction(%this) -{ - CommanderTree.openCategory("Clients", %this.getValue()); - alxPlay(sButtonDown, 0, 0, 0); -} - -function CMDTacticalButton::onAction(%this) -{ - CommanderTree.openCategory("Tactical", %this.getValue()); - alxPlay(sButtonDown, 0, 0, 0); -} - -function CMDDeployedTacticalButton::onAction(%this) -{ - CommanderTree.openCategory("DTactical", %this.getValue()); - alxPlay(sButtonDown, 0, 0, 0); -} - -function CMDMiscButton::onAction(%this) -{ - CommanderTree.openCategory("Support", %this.getValue()); - alxPlay(sButtonDown, 0, 0, 0); -} - -function CMDDeployedMiscButton::onAction(%this) -{ - CommanderTree.openCategory("DSupport", %this.getValue()); - alxPlay(sButtonDown, 0, 0, 0); -} - -function CMDWaypointsButton::onAction(%this) -{ - CommanderTree.openCategory("Waypoints", %this.getValue()); - alxPlay(sButtonDown, 0, 0, 0); -} - -function CMDObjectivesButton::onAction(%this) -{ - CommanderTree.openCategory("Objectives", %this.getValue()); - alxPlay(sButtonDown, 0, 0, 0); -} - -// bottom buttons: -function CMDShowSensorsButton::onAction(%this) -{ - CommanderMap.renderSensors = %this.getValue(); - alxPlay(sButtonDown, 0, 0, 0); -} - -// there should be, at most, one depressed mouse mode button -function setMouseMode(%mode) -{ - switch$(%mode) - { - case "select": - CMDMoveSelectButton.setValue(false); - CMDZoomButton.setValue(false); - - case "move": - CMDMoveSelectButton.setValue(true); - CMDZoomButton.setValue(false); - - case "zoom": - CMDMoveSelectButton.setValue(false); - CMDZoomButton.setValue(true); - } - - CommanderMap.setMouseMode(%mode); - alxPlay(sButtonDown, 0, 0, 0); -} - -function cycleMouseMode() -{ - switch$(CommanderMap.getMouseMode()) - { - case "select": - setMouseMode("move"); - case "move": - setMouseMode("zoom"); - case "zoom": - setMouseMode("select"); - } -} - -function CMDMoveSelectButton::onAction(%this) -{ - if(%this.getValue()) - setMouseMode(move); - else - setMouseMode(select); -} - -function CMDZoomButton::onAction(%this) -{ - if(%this.getValue()) - setMouseMode(zoom); - else - setMouseMode(select); -} - -function CMDCenterButton::onAction(%this) -{ - CommanderMap.followLastSelected(); - alxPlay(sButtonDown, 0, 0, 0); -} - -function CMDTextButton::onAction(%this) -{ - CommanderMap.renderText = %this.getValue(); - alxPlay(sButtonDown, 0, 0, 0); -} - -function CMDCameraButton::onAction(%this) -{ - CommanderMapGui.openCameraControl(%this.getValue()); - alxPlay(sButtonDown, 0, 0, 0); -} - -//--------------------------------------------------------------------------- -// - the server may be down and client will not be able to get out of this object -// by using the escape key; so, schedule a timeout period to reset -$ServerResponseTimeout = 1500; - -function processControlObjectEscape() -{ - if($ScheduledEscapeTask) - return; - - $ScheduledEscapeTask = schedule($ServerResonseTimeout, 0, clientCmdControlObjectReset); - commandToServer('ResetControlObject'); -} - -function clientCmdControlObjectResponse(%ack, %info) -{ - // if ack'd then %info is the tag for the object otherwise it is a decline message - if(%ack == true) - { - new ActionMap(ControlActionMap); - ControlActionMap.bindCmd(keyboard, escape, "processControlObjectEscape();", ""); - - $PlayerIsControllingObject = true; - clientCmdSetHudMode("Object", %info); - - // at this point, we are not attached to an object - CommanderTV.attached = false; - Canvas.setContent(PlayGui); - } - else - addMessageHudLine("\c3Failed to control object: \cr" @ %info); -} - -function clientCmdControlObjectReset() -{ - if($ScheduledEscapeTask) - { - cancel($ScheduledEscapeTask); - $ScheduledEscapeTask = 0; - } - - if(isObject(ControlActionMap)) - ControlActionMap.delete(); - - if ($PlayerIsControllingObject) - { - $PlayerIsControllingObject = false; - ClientCmdSetHudMode("Standard"); - } - - if(CommanderMapGui.open) - Canvas.setContent(PlayGui); -} +//-------------------------------------------------------------------------- +// ActionMap: +//-------------------------------------------------------------------------- +$CommanderMap::useMovementKeys = false; + +// help overlay toggle +function toggleCmdMapHelpGui( %val ) +{ + if ( %val) + toggleCmdMapHelpText(); +} + +// shortcuts to buttons: top buttons +function toggleAction(%control) +{ + %control.setValue(!%control.getValue()); + %control.onAction(); +} + +function bindAction(%fromMap, %command, %bindCmd, %bind1, %bind2 ) +{ + if(!isObject(%fromMap)) + return(false); + + %bind = %fromMap.getBinding(%command); + if(%bind $= "") + return(false); + + // only allow keyboard + %device = getField(%bind, 0); + if(%device !$= "keyboard") + return(false); + + %action = getField(%bind, 1); + + // bind or bindcmd? + if(%bindCmd) + CommanderKeyMap.bindCmd( %device, %action, %bind1, %bind2 ); + else + CommanderKeyMap.bind( %device, %action, %bind1 ); + + return(true); +} + +function createCommanderKeyMap() +{ + if(isObject(CommanderKeyMap)) + CommanderKeyMap.delete(); + + new ActionMap(CommanderKeyMap); + + // copy in all the binds we want from the moveMap + CommanderKeyMap.copyBind( moveMap, ToggleMessageHud ); + CommanderKeyMap.copyBind( moveMap, TeamMessageHud ); + CommanderKeyMap.copyBind( moveMap, resizeChatHud ); + CommanderKeyMap.copyBind( moveMap, pageMessageHudUp ); + CommanderKeyMap.copyBind( moveMap, pageMessageHudDown ); + CommanderKeyMap.copyBind( moveMap, activateChatMenuHud ); + + // Miscellaneous other binds: + CommanderKeyMap.copyBind( moveMap, voteYes ); + CommanderKeyMap.copyBind( moveMap, voteNo ); + CommanderKeyMap.copyBind( moveMap, toggleCommanderMap ); + CommanderKeyMap.copyBind( moveMap, toggleHelpGui ); + CommanderKeyMap.copyBind( moveMap, toggleScoreScreen); + CommanderKeyMap.copyBind( moveMap, startRecordingDemo ); + CommanderKeyMap.copyBind( moveMap, stopRecordingDemo ); + CommanderKeyMap.copyBind( moveMap, voiceCapture ); + CommanderKeyMap.bindCmd( keyboard, escape, "", "toggleCommanderMap( true );" ); + + // grab help key from movemap + if(!bindAction( moveMap, toggleHelpGui, false, toggleCmdMapHelpGui )) + CommanderKeyMap.bind( keyboard, F1, toggleCmdMapHelpGui ); + + // Bind the command assignment/response keys as well: + CommanderKeyMap.copyBind( moveMap, toggleTaskListDlg ); + CommanderKeyMap.copyBind( moveMap, fnAcceptTask ); + CommanderKeyMap.copyBind( moveMap, fnDeclineTask ); + CommanderKeyMap.copyBind( moveMap, fnTaskCompleted ); + CommanderKeyMap.copyBind( moveMap, fnResetTaskList ); + + // button shortcuts + CommanderKeyMap.bindCmd( keyboard, 1, "toggleAction(CMDPlayersButton);", "" ); + CommanderKeyMap.bindCmd( keyboard, 2, "toggleAction(CMDTacticalButton);", "" ); + CommanderKeyMap.bindCmd( keyboard, 3, "toggleAction(CMDDeployedTacticalButton);", "" ); + CommanderKeyMap.bindCmd( keyboard, 4, "toggleAction(CMDMiscButton);", "" ); + CommanderKeyMap.bindCmd( keyboard, 5, "toggleAction(CMDDeployedMiscButton);", "" ); + CommanderKeyMap.bindCmd( keyboard, 6, "toggleAction(CMDWaypointsButton);", "" ); + CommanderKeyMap.bindCmd( keyboard, 7, "toggleAction(CMDObjectivesButton);", "" ); + + // bottom buttons + CommanderKeyMap.bindCmd( keyboard, w, "toggleAction(CMDShowSensorsButton);", "" ); + CommanderKeyMap.bindCmd( keyboard, space, "cycleMouseMode();", "" ); + CommanderKeyMap.bindCmd( keyboard, q, "toggleAction(CMDCenterButton);", "" ); + CommanderKeyMap.bindCmd( keyboard, t, "toggleAction(CMDTextButton);", "" ); + CommanderKeyMap.bindCmd( keyboard, b, "toggleAction(CMDCameraButton);", "" ); + + // camera control (always arrows) + CommanderKeyMap.bindCmd( keyboard, left, "CommanderMap.cameraMove(left, true);", "commanderMap.cameraMove(left, false);" ); + CommanderKeyMap.bindCmd( keyboard, right, "CommanderMap.cameraMove(right, true);", "commanderMap.cameraMove(right, false);" ); + CommanderKeyMap.bindCmd( keyboard, up, "CommanderMap.cameraMove(up, true);", "commanderMap.cameraMove(up, false);" ); + CommanderKeyMap.bindCmd( keyboard, down, "CommanderMap.cameraMove(down, true);", "commanderMap.cameraMove(down, false);" ); + CommanderKeyMap.bindCmd( keyboard, numpadadd, "CommanderMap.cameraMove(in, true);", "commanderMap.cameraMove(in, false);" ); + CommanderKeyMap.bindCmd( keyboard, numpadminus, "CommanderMap.cameraMove(out, true);", "commanderMap.cameraMove(out, false);" ); + + CommanderKeyMap.bindCmd( keyboard, a, "CommanderMap.cameraMove(in, true);", "commanderMap.cameraMove(in, false);" ); + CommanderKeyMap.bindCmd( keyboard, z, "CommanderMap.cameraMove(out, true);", "commanderMap.cameraMove(out, false);" ); + + // steal the movement keys? (more likely than others to be a duplicate binding) + if($CommanderMap::useMovementKeys) + { + bindAction( moveMap, moveleft, true, "CommanderMap.cameraMove(left, true);", "commanderMap.cameraMove(left, false);" ); + bindAction( moveMap, moveright, true, "CommanderMap.cameraMove(right, true);", "commanderMap.cameraMove(right, false);" ); + bindAction( moveMap, moveforward, true, "CommanderMap.cameraMove(up, true);", "commanderMap.cameraMove(up, false);" ); + bindAction( moveMap, movebackward, true, "CommanderMap.cameraMove(down, true);", "commanderMap.cameraMove(down, false);" ); + } + else + { + CommanderKeyMap.bindCmd( keyboard, s, "CommanderMap.cameraMove(left, true);", "commanderMap.cameraMove(left, false);" ); + CommanderKeyMap.bindCmd( keyboard, f, "CommanderMap.cameraMove(right, true);", "commanderMap.cameraMove(right, false);" ); + CommanderKeyMap.bindCmd( keyboard, e, "CommanderMap.cameraMove(up, true);", "commanderMap.cameraMove(up, false);" ); + CommanderKeyMap.bindCmd( keyboard, d, "CommanderMap.cameraMove(down, true);", "commanderMap.cameraMove(down, false);" ); + } +} + +//-------------------------------------------------------------------------- +// Default Icons: +new CommanderIconData(CMDDefaultIcon) +{ + selectImage = "animation base_select true true looping 100"; + hilightImage = "animation base_select true true flipflop 100"; +}; + +new CommanderIconData(CMDAssignedTaskIcon) +{ + baseImage = "static diamond_not_selected true true"; + selectImage = "animation assigned_task_anim false true looping 100"; + hilightImage = "animation assigned_task_anim false true looping 100"; +}; + +new CommanderIconData(CMDPotentialTaskIcon) +{ + baseImage = "static diamond_not_selected true true"; + selectImage = "animation assigned_task_anim false true looping 100"; + hilightImage = "animation assigned_task_anim false true looping 100"; +}; + +new CommanderIconData(CMDWaypointIcon) +{ + baseImage = "animation waypoint_anim false false looping 100"; +}; + +//-------------------------------------------------------------------------- +// CommanderMapGui: +//-------------------------------------------------------------------------- +function clientCmdResetCommandMap() +{ + CommanderMapGui.reset(); +} + +function clientCmdScopeCommanderMap(%scope) +{ + if(!isPlayingDemo()) + return; + + if(%scope) + { + CommanderMap.openAllCategories(); + CommanderMapGui.open(); + } + else + CommanderMapGui.close(); +} + +function CommanderMapGui::onWake(%this) +{ + clientCmdControlObjectReset(); + + commandToServer('ScopeCommanderMap', true); + + createCommanderKeyMap(); + CommanderKeyMap.push(); + + if ( $HudHandle[CommandScreen] ) + alxStop( $HudHandle[CommandScreen] ); + alxPlay(CommandMapActivateSound, 0, 0, 0); + $HudHandle[CommandScreen] = alxPlay(CommandMapHumSound, 0, 0, 0); + + CMDTextButton.setValue(CommanderMap.renderText); + + // follow the player the first time + if(%this.firstWake) + { + CommanderMap.selectControlObject(); + CommanderMap.followLastSelected(); + %this.firstWake = false; + } + + if(CommanderTV.open) + CommanderTV.watchTarget(CommanderTV.target); + + // chat hud dialog + Canvas.pushDialog(MainChatHud); + chatHud.attach(HudMessageVector); + + %this.open = true; +} + +function CommanderMapGui::onSleep(%this) +{ + %this.open = false; + + commandToServer('ScopeCommanderMap', false); + + if(CMContextPopup.visible == true) + CMContextPopup.reset(); + + CommanderKeyMap.pop(); + Canvas.popDialog(MainChatHud); + + alxStop($HudHandle[CommandScreen]); + alxPlay(CommandMapDeactivateSound, 0, 0, 0); + $HudHandle[CommandScreen] = ""; + + // will reset the control object on this client.. should only be sent + // if this gui is being removed outside of CommanderMapGui::close() + if(CommanderTV.open && CommanderTV.attached) + commandToServer('AttachCommanderCamera', -1); + + //always set the cursor back to an arrow when you leave... + Canvas.setCursor(CMDCursorArrow); +} + +function CommanderMapGui::open(%this) +{ + if(%this.open) + return; + + commandToServer('SetPDAPose', true); + Canvas.setContent(%this); +} + +function CommanderMapGui::close(%this) +{ + if(!%this.open) + return; + + // only need to have control object reset if still attached to an object +// if(CommanderTV.open && CommanderTV.attached) +// { + commandToServer('ResetControlObject'); + + // reset the attached state since we will not be getting an attached response + CommanderTV.attached = false; +// } +// else +// clientCmdControlObjectReset(); + + commandToServer('SetPDAPose', false); +} + +function CommanderMapGui::toggle(%this) +{ + if(%this.open) + %this.close(); + else + %this.open(); +} + +function CommanderMapGui::onAdd(%this) +{ + %this.open = false; + + new GuiControl(CMContextPopupDlg) + { + profile = "GuiModelessDialogProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + + new GuiCommanderMapPopupMenu(CMContextPopup) + { + profile = "CommanderPopupProfile"; + position = "0 0"; + extent = "0 0"; + minExtent = "0 0"; + maxPopupHeight = "200"; + }; + }; + + CMContextPopup.numEntries = 0; + CMContextPopup.actionMap = -1; + CMContextPopup.focusedEntry = -1; + CMContextPopup.visible = false; + CMContextPopup.target = -1; +} + +function CommanderMapGui::reset(%this) +{ + clientCmdControlObjectReset(); + CommanderMap.openAllCategories(); + CommanderMap.resetCamera(); + CommanderTV.watchTarget(-1); + + // remove all tasks and clean task list + clientCmdResetTaskList(); + + // reset waypoints + if(isObject($ClientWaypoints)) + $ClientWaypoints.delete(); + + // this can be called when not connected to a server + if(isObject(ServerConnection)) + { + $ClientWaypoints = new SimGroup(); + ServerConnection.add($ClientWaypoints); + } + + %this.firstWake = true; + CommanderTree.currentWaypointID = 0; +} + +function CommanderMapGui::openCameraControl(%this, %open) +{ + %step = getWord(CommanderTV.extent, 1); + %x = getWord(CommanderTreeContainer.position, 0); + %y = getWord(CommanderTreeContainer.position, 1); + %w = getWord(CommanderTreeContainer.extent, 0); + %h = getWord(CommanderTreeContainer.extent, 1); + + if(%open) + %h = %h - %step; + else + %h = %h + %step; + + CommanderTreeContainer.resize(%x, %y, %w, %h); + CommanderTV.setVisible(%open); + + CommanderTV.open = %open; + CommanderTV.watchTarget(CommanderTV.target); + + if(!CommanderTV.open) + commandToServer('AttachCommanderCamera', -1); +} + +//-------------------------------------------------------------------------- +// CMContextPopup: +//-------------------------------------------------------------------------- +function CMContextPopup::reset(%this) +{ + if(%this.actionMap != -1) + { + %this.actionMap.pop(); + %this.actionMap.delete(); + } + + for(%i = 0; %i < %this.numEntries; %i++) + { + %this.entryKeys[%i] = ""; + %this.entryCommands[%i] = ""; + } + + %this.visible = false; + %this.numEntries = 0; + %this.actionMap = -1; + if(%this.focusedEntry != -1) + %this.focusedEntry.lockFocus(false); + %this.focusedEntry = -1; + + %this.forceClose(); + Canvas.popDialog(CMContextPopupDlg); + + // need to delete the target if it was not used + if(isObject(%this.target)) + { + if(%this.target.getTargetId() != -1) + %this.target.delete(); + %this.target = -1; + } +} + +function CMContextPopup::display(%this) +{ + if(%this.numEntries == 0) + return; + + %this.actionMap = new ActionMap(); + + for(%i = 0; %i < %this.numEntries; %i++) + if(%this.entryKeys[%i] !$= "") + %this.actionMap.bindCmd(keyboard, %this.entryKeys[%i], "", %this @ ".onKeySelect(" @ %i @ ");"); + + %this.actionMap.bindCmd(keyboard, escape, "", %this @ ".reset();"); + %this.actionMap.push(); + + if(%this.focusedEntry != -1) + %this.focusedEntry.lockFocus(true); + %this.visible = true; + + Canvas.pushDialog(CMContextPopupDlg); + %this.forceOnAction(); +} + +function CMContextPopup::addEntry(%this, %key, %text, %command) +{ + %idx = %this.numEntries; + %this.entryKeys[%idx] = %key; + %this.entryCommands[%idx] = %command; + %this.numEntries++; + + %this.add(%text, %idx); +} + +function CMContextPopup::onKeySelect(%this, %index) +{ + %this.onSelect(%index, %this.getTextById(%index)); +} + +function CMContextPopup::onSelect(%this, %index, %value) +{ + CommanderTree.processCommand(%this.entryCommands[%index], %this.target, %this.typeTag); + %this.reset(); +} + +function CMContextPopup::onCancel( %this ) +{ + %this.reset(); +} + +//------------------------------------------------------------------------------ +// CommanderTree: +//------------------------------------------------------------------------------ +function CommanderTree::onAdd(%this) +{ + %this.headerHeight = 20; + %this.entryHeight = 20; + + %this.reset(); + + %this.addCategory("Clients", "Teammates", "clients"); + %this.addCategory("Tactical", "Tactical Assets", "targets"); + %this.addCategory("DTactical", "Deployed Tactical", "targets"); + %this.addCategory("Support", "Support Assets", "targets"); + %this.addCategory("DSupport", "Deployed Support", "targets"); + %this.addCategory("Waypoints", "Waypoints", "waypoints"); + %this.addCategory("Objectives", "Objectives", "targets"); + + // targetType entries use registered info if no ShapeBaseData exists + %this.registerEntryType("Clients", getTag('_ClientConnection'), false, "commander/MiniIcons/com_player_grey", "255 255 255"); + %this.registerEntryType("Waypoints", $CMD_WAYPOINTTYPEID, false, "commander/MiniIcons/com_waypoint_grey", "0 255 0"); + %this.registerEntryType("Waypoints", $CMD_ASSIGNEDTASKTYPEID, false, "commander/MiniIcons/com_waypoint_grey", "0 0 255"); + +// %this.registerEntryType("Waypoints", $CMD_POTENTIALTASKTYPEID, false, "commander/MiniIcons/com_waypoint_grey", "255 255 0"); +} + +function CommanderTree::onCategoryOpen(%this, %category, %open) +{ + switch$ (%category) + { + case "Clients": + CMDPlayersButton.setValue(%open); + case "Tactical": + CMDTacticalButton.setValue(%open); + case "DTactical": + CMDDeployedTacticalButton.setValue(%open); + case "Support": + CMDMiscButton.setValue(%open); + case "DSupport": + CMDDeployedMiscButton.setValue(%open); + case "Waypoints": + CMDWaypointsButton.setValue(%open); + case "Objectives": + CMDObjectivesButton.setValue(%open); + } +} + +function CommanderTree::controlObject(%this, %targetId) +{ + commandToServer('ControlObject', %targetId); +} + +//------------------------------------------------------------------------------ +// CommanderMap: +//------------------------------------------------------------------------------ +function GuiCommanderMap::onAdd(%this) +{ + %this.setMouseMode(select); + %this.setTargetTypeVisible($CMD_POTENTIALTASKTYPEID, true); + %this.setTargetTypeVisible($CMD_ASSIGNEDTASKTYPEID, true); +} + +function GuiCommanderMap::onSelect(%this, %targetId, %nameTag, %typeTag, %select) +{ + if(%select) + { + if(CommanderTV.target != %targetId) + CommanderTV.watchTarget(%targetId); + } + else + CommanderTV.watchTarget(-1); +} + +function GuiCommanderMap::openCategory(%this, %ctrl, %name, %open) +{ + %ctrl.setValue(%open); + CommanderTree.openCategory(%name, %open); +} + +function GuiCommanderMap::openAllCategories(%this) +{ + %this.openCategory(CMDPlayersButton, "Clients", 1); + %this.openCategory(CMDTacticalButton, "Tactical", 1); + %this.openCategory(CMDDeployedTacticalButton, "DTactical", 1); + %this.openCategory(CMDMiscButton, "Support", 1); + %this.openCategory(CMDDeployedMiscButton, "DSupport", 1); + %this.openCategory(CMDWaypointsButton, "Waypoints", 1); + %this.openCategory(CMDObjectivesButton, "Objectives", 1); +} + +//------------------------------------------------------------------------------ +// Issuing commands +//------------------------------------------------------------------------------ +// misc. tasks (sensor group -1 is considered friendly with these) +$CommandTask['PotentialTask', 0, text] = "\c1A\crccept"; +$CommandTask['PotentialTask', 0, tag] = 'TaskAccepted'; +$CommandTask['PotentialTask', 0, hotkey] = "a"; +$CommandTask['PotentialTask', 1, text] = "\c1D\crecline"; +$CommandTask['PotentialTask', 1, tag] = 'TaskDeclined'; +$CommandTask['PotentialTask', 1, hotkey] = "d"; + +$CommandTask['AssignedTask', 0, text] = "\c1C\crompleted"; +$CommandTask['AssignedTask', 0, tag] = 'TaskCompleted'; +$CommandTask['AssignedTask', 0, hotkey] = "c"; +$CommandTask['AssignedTask', 1, text] = "\c1R\cremove"; +$CommandTask['AssignedTask', 1, tag] = 'TaskRemoved'; +$CommandTask['AssignedTask', 1, hotkey] = "d"; + +$CommandTask['Location', 0, text] = "\c1D\crefend"; +$CommandTask['Location', 0, tag] = 'DefendLocation'; +$CommandTask['Location', 0, hotkey] = "d"; +$CommandTask['Location', 1, text] = "\c1M\creet (at)"; +$CommandTask['Location', 1, tag] = 'MeetLocation'; +$CommandTask['Location', 1, hotkey] = "m"; +$CommandTask['Location', 2, text] = "\c1B\cromb (at)"; +$CommandTask['Location', 2, tag] = 'BombLocation'; +$CommandTask['Location', 2, hotkey] = "b"; +$CommandTask['Location', 3, text] = "\c1A\crttack"; +$CommandTask['Location', 3, tag] = 'AttackLocation'; +$CommandTask['Location', 3, hotkey] = "a"; +$CommandTask['Location', 4, text] = "Deploy \c1I\crnventory"; +$CommandTask['Location', 4, tag] = 'DeployEquipment'; +$CommandTask['Location', 4, hotkey] = "i"; +$CommandTask['Location', 5, text] = "Deploy \c1T\crurrets"; +$CommandTask['Location', 5, tag] = 'DeployTurret'; +$CommandTask['Location', 5, hotkey] = "t"; +$CommandTask['Location', 6, text] = "Deploy \c1S\crensors"; +$CommandTask['Location', 6, tag] = 'DeploySensor'; +$CommandTask['Location', 6, hotkey] = "s"; +$CommandTask['Location', 7, text] = "Create \c1W\craypoint"; +$CommandTask['Location', 7, tag] = 'CreateWayPoint'; +$CommandTask['Location', 7, hotkey] = "w"; + +$CommandTask['Waypoint', 0, text] = "\c1D\crelete waypoint"; +$CommandTask['Waypoint', 0, tag] = 'DeleteWayPoint'; +$CommandTask['Waypoint', 0, hotkey] = "d"; + +// object tasks +$CommandTask['Player', 0, text] = "\c1E\crscort"; +$CommandTask['Player', 0, tag] = 'EscortPlayer'; +$CommandTask['Player', 0, hotkey] = "e"; +$CommandTask['Player', 1, text] = "\c1R\crepair"; +$CommandTask['Player', 1, tag] = 'RepairPlayer'; +$CommandTask['Player', 1, hotkey] = "r"; +$CommandTask['Player', 2, text] = "\c1A\crttack"; +$CommandTask['Player', 2, tag] = 'AttackPlayer'; +$CommandTask['Player', 2, hotkey] = "a"; +$CommandTask['Player', 2, enemy] = true; + +$CommandTask['Flag', 0, text] = "\c1D\crefend"; +$CommandTask['Flag', 0, tag] = 'DefendFlag'; +$CommandTask['Flag', 0, hotkey] = "d"; +$CommandTask['Flag', 1, text] = "\c1R\creturn"; +$CommandTask['Flag', 1, tag] = 'ReturnFlag'; +$CommandTask['Flag', 1, hotkey] = "r"; +$CommandTask['Flag', 2, text] = "\c1C\crapture"; +$CommandTask['Flag', 2, tag] = 'CaptureFlag'; +$CommandTask['Flag', 2, hotkey] = "c"; +$CommandTask['Flag', 2, enemy] = true; + +$CommandTask['Objective', 0, text] = "\c1C\crapture"; +$CommandTask['Objective', 0, tag] = 'CaptureObjective'; +$CommandTask['Objective', 0, hotkey] = "c"; +$CommandTask['Objective', 1, text] = "\c1D\crefend"; +$CommandTask['Objective', 1, tag] = 'DefendObjective'; +$CommandTask['Objective', 1, hotkey] = "d"; + +$CommandTask['Object', 0, text] = "\c1R\crepair"; +$CommandTask['Object', 0, tag] = 'RepairObject'; +$CommandTask['Object', 0, hotkey] = "r"; +$CommandTask['Object', 1, text] = "\c1D\crefend"; +$CommandTask['Object', 1, tag] = 'DefendObject'; +$CommandTask['Object', 1, hotkey] = "d"; +$CommandTask['Object', 2, text] = "\c1A\crttack"; +$CommandTask['Object', 2, tag] = 'AttackObject'; +$CommandTask['Object', 2, hotkey] = "a"; +$CommandTask['Object', 2, enemy] = true; +$CommandTask['Object', 3, text] = "\c1L\craze"; +$CommandTask['Object', 3, tag] = 'LazeObject'; +$CommandTask['Object', 3, hotkey] = "l"; +$CommandTask['Object', 3, enemy] = true; +$CommandTask['Object', 4, text] = "\c1M\crortar"; +$CommandTask['Object', 4, tag] = 'MortarObject'; +$CommandTask['Object', 4, hotkey] = "m"; +$CommandTask['Object', 4, enemy] = true; +$CommandTask['Object', 5, text] = "\c1B\cromb"; +$CommandTask['Object', 5, tag] = 'BombObject'; +$CommandTask['Object', 5, hotkey] = "b"; +$CommandTask['Object', 5, enemy] = true; + +function GuiCommanderMap::issueCommand(%this, %target, %typeTag, %nameTag, %sensorGroup, %mousePos) +{ + CMContextPopup.position = %mousePos; + CMContextPopup.clear(); + + CMContextPopup.target = %target; + CMContextPopup.typeTag = %typeTag; + CMContextPopup.nameTag = %nameTag; + CMContextPopup.sensorGroup = %sensorGroup; + + %taskType = %this.getCommandType(%typeTag); + if(%taskType $= "") + { + // script created target? + if(%target.getTargetId() == -1) + %target.delete(); + CMDContextPopup.target = -1; + return; + } + + %this.buildPopupCommands(%taskType, %sensorGroup); + CMContextPopup.display(); +} + +function GuiCommanderMap::getCommandType(%this, %typeTag) +{ + // special case (waypoints, location, tasks...) + if(%typeTag == $CMD_LOCATIONTYPEID) + return('Location'); + else if(%typeTag == $CMD_WAYPOINTTYPEID) + return('Waypoint'); + else if(%typeTag == $CMD_POTENTIALTASKTYPEID) + return('PotentialTask'); + else if(%typeTag == $CMD_ASSIGNEDTASKTYPEID) + return('AssignedTask'); + + // the handled types here (default is 'Object') + switch$(getTaggedString(%typeTag)) + { + case "_ClientConnection": + return('Player'); + case "Flag": + return('Flag'); + case "Objective": + return('Objective'); + } + return('Object'); +} + +function GuiCommanderMap::buildPopupCommands(%this, %taskType, %sensorGroup) +{ + %enemy = (%sensorGroup != ServerConnection.getSensorGroup()) && (%sensorGroup != -1); + for(%i = 0; $CommandTask[%taskType, %i, text] !$= ""; %i++) + { + if(%enemy == $CommandTask[%taskType, %i, enemy]) + { + CMContextPopup.addEntry($CommandTask[%taskType, %i, hotkey], + $CommandTask[%taskType, %i, text], + $CommandTask[%taskType, %i, tag]); + } + } +} + +//-------------------------------------------------------------------------- +// Command processing +//-------------------------------------------------------------------------- +function CommanderTree::processCommand(%this, %command, %target, %typeTag) +{ + switch$(getTaggedString(%command)) + { + // waypoints: tree owns the waypoint targets + case "CreateWayPoint": + %name = "Waypoint " @ %this.currentWaypointID++; + %target.createWaypoint(%name); + %id = %target.getTargetId(); + if(%id != -1) + { + $ClientWaypoints.add(%target); + CMContextPopup.target = -1; + } + return; + + case "DeleteWayPoint": + %target.delete(); + CMContextPopup.target = -1; + return; + + // tasks: + case "TaskAccepted": + clientAcceptTask(%target); + return; + + case "TaskDeclined": + clientDeclineTask(%target); + return; + + case "TaskCompleted": + clientTaskCompleted(); + return; + + case "TaskRemoved": + %target.delete(); + CMContextPopup.target = -1; + return; + } + + %numClients = %this.getNumTargets("Clients"); + %numSelected = %this.getNumSelectedTargets("Clients"); + + if((%numSelected == 0) || (%numSelected == %numClients)) + %team = true; + else + %team = false; + + %target.sendToServer(); + commandToServer('BuildClientTask', %command, %team); + + if(%team) + { + commandToServer('SendTaskToTeam'); + } + else + { + for(%i = 0; %i < %numSelected; %i++) + { + %targetId = %this.getSelectedTarget("Clients", %i); + commandToServer('SendTaskToClientTarget', %targetId); + } + } + + // delete target? + if(%target.getTargetId() == -1) + { + CMContextPopup.target = -1; + %target.delete(); + } +} + +//------------------------------------------------------------------------------ +function CommanderTV::watchTarget(%this, %targetId) +{ + if(%targetId < 0) + %targetId = -1; + + if(%this.attached) + commandToServer('AttachCommanderCamera', -1); + + %this.target = %targetId; + + if(%this.open && (%this.target != -1)) + commandToServer('AttachCommanderCamera', %this.target); +} + +function clientCmdCameraAttachResponse(%attached) +{ + CommanderTV.attached = %attached; +} + +//------------------------------------------------------------------------------ +// CommanderTV control +//------------------------------------------------------------------------------ +new ActionMap(CommanderTVControl); +CommanderTVControl.bind(mouse, xaxis, yaw); +CommanderTVControl.bind(mouse, yaxis, pitch); + + +function CommanderTV_ButtonPress(%val) +{ + if(%val) + { + CommanderTVControl.push(); + CursorOff(); + } + else + { + CommanderTVControl.pop(); + GlobalActionMap.unbind(mouse, button0); + + if(CommanderMapGui.open) + { + CursorOn(); + Canvas.setCursor(CMDCursorArrow); + } + } +} + +function CommanderTVScreen::onMouseEnter(%this, %mod, %pos, %count) +{ + GlobalActionMap.bind(mouse, button0, CommanderTV_ButtonPress); +} + +function CommanderTVScreen::onMouseLeave(%this, %mod, %pos, %count) +{ + GlobalActionMap.unbind(mouse, button0); +} + +//------------------------------------------------------------------------------ +// Buttons: play button down sounds here so script onAction call plays sound as well +//------------------------------------------------------------------------------ +// top buttons: +function CMDPlayersButton::onAction(%this) +{ + CommanderTree.openCategory("Clients", %this.getValue()); + alxPlay(sButtonDown, 0, 0, 0); +} + +function CMDTacticalButton::onAction(%this) +{ + CommanderTree.openCategory("Tactical", %this.getValue()); + alxPlay(sButtonDown, 0, 0, 0); +} + +function CMDDeployedTacticalButton::onAction(%this) +{ + CommanderTree.openCategory("DTactical", %this.getValue()); + alxPlay(sButtonDown, 0, 0, 0); +} + +function CMDMiscButton::onAction(%this) +{ + CommanderTree.openCategory("Support", %this.getValue()); + alxPlay(sButtonDown, 0, 0, 0); +} + +function CMDDeployedMiscButton::onAction(%this) +{ + CommanderTree.openCategory("DSupport", %this.getValue()); + alxPlay(sButtonDown, 0, 0, 0); +} + +function CMDWaypointsButton::onAction(%this) +{ + CommanderTree.openCategory("Waypoints", %this.getValue()); + alxPlay(sButtonDown, 0, 0, 0); +} + +function CMDObjectivesButton::onAction(%this) +{ + CommanderTree.openCategory("Objectives", %this.getValue()); + alxPlay(sButtonDown, 0, 0, 0); +} + +// bottom buttons: +function CMDShowSensorsButton::onAction(%this) +{ + CommanderMap.renderSensors = %this.getValue(); + alxPlay(sButtonDown, 0, 0, 0); +} + +// there should be, at most, one depressed mouse mode button +function setMouseMode(%mode) +{ + switch$(%mode) + { + case "select": + CMDMoveSelectButton.setValue(false); + CMDZoomButton.setValue(false); + + case "move": + CMDMoveSelectButton.setValue(true); + CMDZoomButton.setValue(false); + + case "zoom": + CMDMoveSelectButton.setValue(false); + CMDZoomButton.setValue(true); + } + + CommanderMap.setMouseMode(%mode); + alxPlay(sButtonDown, 0, 0, 0); +} + +function cycleMouseMode() +{ + switch$(CommanderMap.getMouseMode()) + { + case "select": + setMouseMode("move"); + case "move": + setMouseMode("zoom"); + case "zoom": + setMouseMode("select"); + } +} + +function CMDMoveSelectButton::onAction(%this) +{ + if(%this.getValue()) + setMouseMode(move); + else + setMouseMode(select); +} + +function CMDZoomButton::onAction(%this) +{ + if(%this.getValue()) + setMouseMode(zoom); + else + setMouseMode(select); +} + +function CMDCenterButton::onAction(%this) +{ + CommanderMap.followLastSelected(); + alxPlay(sButtonDown, 0, 0, 0); +} + +function CMDTextButton::onAction(%this) +{ + CommanderMap.renderText = %this.getValue(); + alxPlay(sButtonDown, 0, 0, 0); +} + +function CMDCameraButton::onAction(%this) +{ + CommanderMapGui.openCameraControl(%this.getValue()); + alxPlay(sButtonDown, 0, 0, 0); +} + +//--------------------------------------------------------------------------- +// - the server may be down and client will not be able to get out of this object +// by using the escape key; so, schedule a timeout period to reset +$ServerResponseTimeout = 1500; + +function processControlObjectEscape() +{ + if($ScheduledEscapeTask) + return; + + $ScheduledEscapeTask = schedule($ServerResonseTimeout, 0, clientCmdControlObjectReset); + commandToServer('ResetControlObject'); +} + +function clientCmdControlObjectResponse(%ack, %info) +{ + // if ack'd then %info is the tag for the object otherwise it is a decline message + if(%ack == true) + { + new ActionMap(ControlActionMap); + ControlActionMap.bindCmd(keyboard, escape, "processControlObjectEscape();", ""); + + $PlayerIsControllingObject = true; + clientCmdSetHudMode("Object", %info); + + // at this point, we are not attached to an object + CommanderTV.attached = false; + Canvas.setContent(PlayGui); + } + else + addMessageHudLine("\c3Failed to control object: \cr" @ %info); +} + +function clientCmdControlObjectReset() +{ + if($ScheduledEscapeTask) + { + cancel($ScheduledEscapeTask); + $ScheduledEscapeTask = 0; + } + + if(isObject(ControlActionMap)) + ControlActionMap.delete(); + + if ($PlayerIsControllingObject) + { + $PlayerIsControllingObject = false; + ClientCmdSetHudMode("Standard"); + } + + if(CommanderMapGui.open) + Canvas.setContent(PlayGui); +} diff --git a/scripts/commonDialogs.cs b/scripts/commonDialogs.cs index 862ed04..5a6960d 100644 --- a/scripts/commonDialogs.cs +++ b/scripts/commonDialogs.cs @@ -1,225 +1,225 @@ -//------------------------------------------------------------------------------ -// -// commonDialogs.cs -// -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -// MessageBox OK dialog: -//------------------------------------------------------------------------------ -function MessageBoxOK( %title, %message, %callback ) -{ - MBOKFrame.setTitle( %title ); - MBOKText.setText( "" @ %message ); - //MessageBoxOKDlg.callback = %callback; - MBOKButton.command = %callback SPC "Canvas.popDialog(MessageBoxOKDlg);"; - Canvas.pushDialog( MessageBoxOKDlg ); -} - -//------------------------------------------------------------------------------ -function MessageBoxOKDlg::onWake( %this ) -{ -} - -//------------------------------------------------------------------------------ -function MessageBoxOKDlg::onSleep( %this ) -{ - %this.callback = ""; -} - -//------------------------------------------------------------------------------ -// MessageBox OK/Cancel dialog: -//------------------------------------------------------------------------------ -function MessageBoxOKCancel( %title, %message, %callback, %cancelCallback ) -{ - MBOKCancelFrame.setTitle( %title ); - MBOKCancelText.setText( "" @ %message ); - //MessageBoxOKCancelDlg.callback = %callback; - //MessageBoxOKCancelDlg.cancelCallback = %cancelCallback; - MBOKCancelButtonOK.command = %callback SPC "Canvas.popDialog(MessageBoxOKCancelDlg);"; - MBOKCancelButtonCancel.command = %cancelCallback SPC "Canvas.popDialog(MessageBoxOKCancelDlg);"; - - Canvas.pushDialog( MessageBoxOKCancelDlg ); -} - -//------------------------------------------------------------------------------ -function MessageBoxOKCancelDlg::onWake( %this ) -{ -} - -//------------------------------------------------------------------------------ -function MessageBoxOKCancelDlg::onSleep( %this ) -{ - %this.callback = ""; -} - -//------------------------------------------------------------------------------ -// MessageBox Yes/No dialog: -//------------------------------------------------------------------------------ -function MessageBoxYesNo( %title, %message, %yesCallback, %noCallback ) -{ - MBYesNoFrame.setTitle( %title ); - MBYesNoText.setText( "" @ %message ); - - //MessageBoxYesNoDlg.yesCallBack = %yesCallback; - //MessageBoxYesNoDlg.noCallback = %noCallBack; - MBYesNoButtonYes.command = %yesCallback SPC "Canvas.popDialog(MessageBoxYesNoDlg);"; - MBYesNoButtonNo.command = %noCallback SPC "Canvas.popDialog(MessageBoxYesNoDlg);"; - Canvas.pushDialog( MessageBoxYesNoDlg ); -} - -//------------------------------------------------------------------------------ -function MessageBoxYesNoDlg::onWake( %this ) -{ -} - -//------------------------------------------------------------------------------ -function MessageBoxYesNoDlg::onSleep( %this ) -{ - %this.yesCallback = ""; - %this.noCallback = ""; -} - -//------------------------------------------------------------------------------ -// Message popup dialog: -//------------------------------------------------------------------------------ -function MessagePopup( %title, %message, %delay ) -{ - // Currently two lines max. - MessagePopFrame.setTitle( %title ); - MessagePopText.setText( "" @ %message ); - Canvas.pushDialog( MessagePopupDlg ); - if ( %delay !$= "" ) - schedule( %delay, 0, CloseMessagePopup ); -} - -//------------------------------------------------------------------------------ -function CloseMessagePopup() -{ - Canvas.popDialog( MessagePopupDlg ); -} - -//------------------------------------------------------------------------------ -// MessageBox LAN Account dialog: -//------------------------------------------------------------------------------ -function LANAccountDone() -{ -if ($Pref::LANAccount::Name $= "" || $Pref::LANAccount::Password $= "") -return; - -canvas.popDialog(LANAccountCreationDLG); -if (!$ChangeSettings) -messageBoxOk("Success","Your Local Area Network (LAN) account has been created."); -else -messageBoxOk("Success","Your Local Area Network (LAN) account has been modified. Progress on any T2Bol server will be lost."); - -$Pref::LANAccount::GUID = stripNonNumericCharacters(textToHash($Pref::LANAccount::Name @ $Pref::LANAccount::Password)); -} - -//------------------------------------------------------------------------------ -// Pick Team dialog: -//------------------------------------------------------------------------------ -function PickTeamDlg::onWake( %this ) -{ -} - -//------------------------------------------------------------------------------ -function PickTeamDlg::onSleep( %this ) -{ -} - -//------------------------------------------------------------------------------ -// ex: ShellGetLoadFilename( "stuff\*.*", isLoadable, loadStuff ); -// -- only adds files that pass isLoadable -// -- calls 'loadStuff(%filename)' on dblclick or ok -//------------------------------------------------------------------------------ -function ShellGetLoadFilename( %title, %fileSpec, %validate, %callback ) -{ - $loadFileCommand = %callback @ "( getField( LOAD_FileList.getValue(), 0 ) );"; - LOAD_FileList.altCommand = $loadFileCommand SPC "Canvas.popDialog(ShellLoadFileDlg);"; - LOAD_LoadBtn.command = $loadFileCommand SPC "Canvas.popDialog(ShellLoadFileDlg);"; - - if ( %title $= "" ) - LOAD_Title.setTitle( "LOAD FILE" ); - else - LOAD_Title.setTitle( %title ); - LOAD_LoadBtn.setActive( false ); - Canvas.pushDialog( ShellLoadFileDlg ); - fillLoadSaveList( LOAD_FileList, %fileSpec, %validate, false ); -} - -//------------------------------------------------------------------------------ -function fillLoadSaveList( %ctrl, %fileSpec, %validate, %isSave ) -{ - %ctrl.clear(); - %id = 0; - for ( %file = findFirstFile( %fileSpec ); %file !$= ""; %file = findNextFile( %fileSpec ) ) - { - if ( %validate $= "" || call( %validate, %file ) ) - { - %ctrl.addRow( %id, fileBase( %file ) TAB %file ); - if ( %isSave ) - { - if ( !isWriteableFileName( "base/" @ %file ) ) - %ctrl.setRowActive( %id, false ); - } - %id++; - } - } - %ctrl.sort( 0 ); -} - -//------------------------------------------------------------------------------ -function LOAD_FileList::onSelect( %this, %id, %text ) -{ - LOAD_LoadBtn.setActive( true ); -} - -//------------------------------------------------------------------------------ -// ex: ShellGetSaveFilename( "stuff\*.*", isLoadable, saveStuff, currentName ); -// -- only adds files to list that pass isLoadable -// -- calls 'saveStuff(%filename)' on dblclick or ok -//------------------------------------------------------------------------------ -function ShellGetSaveFilename( %title, %fileSpec, %validate, %callback, %current ) -{ - SAVE_FileName.setValue( %current ); - $saveFileCommand = "if ( SAVE_FileName.getValue() !$= \"\" ) " @ %callback @ "( SAVE_FileName.getValue() );"; - SAVE_FileName.altCommand = $saveFileCommand SPC "Canvas.popDialog(ShellSaveFileDlg);"; - SAVE_SaveBtn.command = $saveFileCommand SPC "Canvas.popDialog(ShellSaveFileDlg);"; - - if ( %title $= "" ) - SAVE_Title.setTitle( "SAVE FILE" ); - else - SAVE_Title.setTitle( %title ); - - // Right now this validation stuff is worthless... - //SAVE_SaveBtn.setActive( isWriteableFileName( "base/" @ %current @ $loadSaveExt ) ); - Canvas.pushDialog( ShellSaveFileDlg ); - fillLoadSaveList( SAVE_FileList, %fileSpec, %validate, true ); -} - -//------------------------------------------------------------------------------ -function SAVE_FileList::onSelect( %this, %id, %text ) -{ - if ( %this.isRowActive( %id ) ) - SAVE_FileName.setValue( getField( %this.getValue(), 0 ) ); -} - -//------------------------------------------------------------------------------ -function SAVE_FileList::onDoubleClick( %this ) -{ - %id = %this.getSelectedId(); - if ( %this.isRowActive( %id ) ) - { - error("D'oh - double clicking is broken for PURE/DEMO executables"); - eval( $saveFileCommand ); - Canvas.popDialog( ShellSaveFileDlg ); - } -} - -//------------------------------------------------------------------------------ -function SAVE_FileName::checkValid( %this ) -{ - // Right now this validation stuff is worthless... - //SAVE_SaveBtn.setActive( isWriteableFileName( "base/" @ %this.getValue() @ $loadSaveExt ) ); -} +//------------------------------------------------------------------------------ +// +// commonDialogs.cs +// +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// MessageBox OK dialog: +//------------------------------------------------------------------------------ +function MessageBoxOK( %title, %message, %callback ) +{ + MBOKFrame.setTitle( %title ); + MBOKText.setText( "" @ %message ); + //MessageBoxOKDlg.callback = %callback; + MBOKButton.command = %callback SPC "Canvas.popDialog(MessageBoxOKDlg);"; + Canvas.pushDialog( MessageBoxOKDlg ); +} + +//------------------------------------------------------------------------------ +function MessageBoxOKDlg::onWake( %this ) +{ +} + +//------------------------------------------------------------------------------ +function MessageBoxOKDlg::onSleep( %this ) +{ + %this.callback = ""; +} + +//------------------------------------------------------------------------------ +// MessageBox OK/Cancel dialog: +//------------------------------------------------------------------------------ +function MessageBoxOKCancel( %title, %message, %callback, %cancelCallback ) +{ + MBOKCancelFrame.setTitle( %title ); + MBOKCancelText.setText( "" @ %message ); + //MessageBoxOKCancelDlg.callback = %callback; + //MessageBoxOKCancelDlg.cancelCallback = %cancelCallback; + MBOKCancelButtonOK.command = %callback SPC "Canvas.popDialog(MessageBoxOKCancelDlg);"; + MBOKCancelButtonCancel.command = %cancelCallback SPC "Canvas.popDialog(MessageBoxOKCancelDlg);"; + + Canvas.pushDialog( MessageBoxOKCancelDlg ); +} + +//------------------------------------------------------------------------------ +function MessageBoxOKCancelDlg::onWake( %this ) +{ +} + +//------------------------------------------------------------------------------ +function MessageBoxOKCancelDlg::onSleep( %this ) +{ + %this.callback = ""; +} + +//------------------------------------------------------------------------------ +// MessageBox Yes/No dialog: +//------------------------------------------------------------------------------ +function MessageBoxYesNo( %title, %message, %yesCallback, %noCallback ) +{ + MBYesNoFrame.setTitle( %title ); + MBYesNoText.setText( "" @ %message ); + + //MessageBoxYesNoDlg.yesCallBack = %yesCallback; + //MessageBoxYesNoDlg.noCallback = %noCallBack; + MBYesNoButtonYes.command = %yesCallback SPC "Canvas.popDialog(MessageBoxYesNoDlg);"; + MBYesNoButtonNo.command = %noCallback SPC "Canvas.popDialog(MessageBoxYesNoDlg);"; + Canvas.pushDialog( MessageBoxYesNoDlg ); +} + +//------------------------------------------------------------------------------ +function MessageBoxYesNoDlg::onWake( %this ) +{ +} + +//------------------------------------------------------------------------------ +function MessageBoxYesNoDlg::onSleep( %this ) +{ + %this.yesCallback = ""; + %this.noCallback = ""; +} + +//------------------------------------------------------------------------------ +// Message popup dialog: +//------------------------------------------------------------------------------ +function MessagePopup( %title, %message, %delay ) +{ + // Currently two lines max. + MessagePopFrame.setTitle( %title ); + MessagePopText.setText( "" @ %message ); + Canvas.pushDialog( MessagePopupDlg ); + if ( %delay !$= "" ) + schedule( %delay, 0, CloseMessagePopup ); +} + +//------------------------------------------------------------------------------ +function CloseMessagePopup() +{ + Canvas.popDialog( MessagePopupDlg ); +} + +//------------------------------------------------------------------------------ +// MessageBox LAN Account dialog: +//------------------------------------------------------------------------------ +function LANAccountDone() +{ +if ($Pref::LANAccount::Name $= "" || $Pref::LANAccount::Password $= "") +return; + +canvas.popDialog(LANAccountCreationDLG); +if (!$ChangeSettings) +messageBoxOk("Success","Your Local Area Network (LAN) account has been created."); +else +messageBoxOk("Success","Your Local Area Network (LAN) account has been modified. Progress on any T2Bol server will be lost."); + +$Pref::LANAccount::GUID = stripNonNumericCharacters(textToHash($Pref::LANAccount::Name @ $Pref::LANAccount::Password)); +} + +//------------------------------------------------------------------------------ +// Pick Team dialog: +//------------------------------------------------------------------------------ +function PickTeamDlg::onWake( %this ) +{ +} + +//------------------------------------------------------------------------------ +function PickTeamDlg::onSleep( %this ) +{ +} + +//------------------------------------------------------------------------------ +// ex: ShellGetLoadFilename( "stuff\*.*", isLoadable, loadStuff ); +// -- only adds files that pass isLoadable +// -- calls 'loadStuff(%filename)' on dblclick or ok +//------------------------------------------------------------------------------ +function ShellGetLoadFilename( %title, %fileSpec, %validate, %callback ) +{ + $loadFileCommand = %callback @ "( getField( LOAD_FileList.getValue(), 0 ) );"; + LOAD_FileList.altCommand = $loadFileCommand SPC "Canvas.popDialog(ShellLoadFileDlg);"; + LOAD_LoadBtn.command = $loadFileCommand SPC "Canvas.popDialog(ShellLoadFileDlg);"; + + if ( %title $= "" ) + LOAD_Title.setTitle( "LOAD FILE" ); + else + LOAD_Title.setTitle( %title ); + LOAD_LoadBtn.setActive( false ); + Canvas.pushDialog( ShellLoadFileDlg ); + fillLoadSaveList( LOAD_FileList, %fileSpec, %validate, false ); +} + +//------------------------------------------------------------------------------ +function fillLoadSaveList( %ctrl, %fileSpec, %validate, %isSave ) +{ + %ctrl.clear(); + %id = 0; + for ( %file = findFirstFile( %fileSpec ); %file !$= ""; %file = findNextFile( %fileSpec ) ) + { + if ( %validate $= "" || call( %validate, %file ) ) + { + %ctrl.addRow( %id, fileBase( %file ) TAB %file ); + if ( %isSave ) + { + if ( !isWriteableFileName( "base/" @ %file ) ) + %ctrl.setRowActive( %id, false ); + } + %id++; + } + } + %ctrl.sort( 0 ); +} + +//------------------------------------------------------------------------------ +function LOAD_FileList::onSelect( %this, %id, %text ) +{ + LOAD_LoadBtn.setActive( true ); +} + +//------------------------------------------------------------------------------ +// ex: ShellGetSaveFilename( "stuff\*.*", isLoadable, saveStuff, currentName ); +// -- only adds files to list that pass isLoadable +// -- calls 'saveStuff(%filename)' on dblclick or ok +//------------------------------------------------------------------------------ +function ShellGetSaveFilename( %title, %fileSpec, %validate, %callback, %current ) +{ + SAVE_FileName.setValue( %current ); + $saveFileCommand = "if ( SAVE_FileName.getValue() !$= \"\" ) " @ %callback @ "( SAVE_FileName.getValue() );"; + SAVE_FileName.altCommand = $saveFileCommand SPC "Canvas.popDialog(ShellSaveFileDlg);"; + SAVE_SaveBtn.command = $saveFileCommand SPC "Canvas.popDialog(ShellSaveFileDlg);"; + + if ( %title $= "" ) + SAVE_Title.setTitle( "SAVE FILE" ); + else + SAVE_Title.setTitle( %title ); + + // Right now this validation stuff is worthless... + //SAVE_SaveBtn.setActive( isWriteableFileName( "base/" @ %current @ $loadSaveExt ) ); + Canvas.pushDialog( ShellSaveFileDlg ); + fillLoadSaveList( SAVE_FileList, %fileSpec, %validate, true ); +} + +//------------------------------------------------------------------------------ +function SAVE_FileList::onSelect( %this, %id, %text ) +{ + if ( %this.isRowActive( %id ) ) + SAVE_FileName.setValue( getField( %this.getValue(), 0 ) ); +} + +//------------------------------------------------------------------------------ +function SAVE_FileList::onDoubleClick( %this ) +{ + %id = %this.getSelectedId(); + if ( %this.isRowActive( %id ) ) + { + error("D'oh - double clicking is broken for PURE/DEMO executables"); + eval( $saveFileCommand ); + Canvas.popDialog( ShellSaveFileDlg ); + } +} + +//------------------------------------------------------------------------------ +function SAVE_FileName::checkValid( %this ) +{ + // Right now this validation stuff is worthless... + //SAVE_SaveBtn.setActive( isWriteableFileName( "base/" @ %this.getValue() @ $loadSaveExt ) ); +} diff --git a/scripts/creditsGui.cs b/scripts/creditsGui.cs index a67e667..b8f95e1 100644 --- a/scripts/creditsGui.cs +++ b/scripts/creditsGui.cs @@ -1,133 +1,133 @@ -function LaunchCredits(%val) -{ - canvas.showBOLCredits = %val; - Canvas.setContent(CreditsGui); -} - -function cancelCredits() -{ - //delete the action map - CreditsActionMap.pop(); - - //kill the schedules - cancel($CreditsScrollSchedule); - cancel($CreditsSlideShow); - canvas.showBOLCredits = false; - - //kill the music & start menu music - alxMusicFadeout($pref::audio::musicvolume); - schedule(mfloor(8000*$pref::audio::musicvolume),0,"alxPlayMusic","T2BOL/music/menu.mp3"); - - //load the launch gui back... - Canvas.setContent(LaunchGui); - - //delete the contents of the ML ctrl so as to free up memory... - Credits_Text.setText(""); -} - -function CreditsGui::onWake(%this) -{ - //create an action map to use "esc" to exit the credits screen... - if (!isObject(CreditsActionMap)) - { - new ActionMap(CreditsActionMap); - CreditsActionMap.bindCmd(keyboard, anykey, "cancelCredits();", ""); - CreditsActionMap.bindCmd(keyboard, space, "cancelCredits();", ""); - CreditsActionMap.bindCmd(keyboard, escape, "cancelCredits();", ""); - CreditsActionMap.bindCmd(mouse, button0, "$CreditsPaused = true;", "$CreditsPaused = false;"); - CreditsActionMap.bindCmd(mouse, button1, "$CreditsSpeedUp = true;", "$CreditsSpeedUp = false;"); - if (!isDemo()) - CreditsActionMap.bindCmd(mouse, button2, "creditsNextPic();", ""); - } - CreditsActionMap.push(); - - //build the ML text ctrl... - if (!canvas.showBOLCredits) - exec("scripts/creditsText_default.cs"); - else - exec("scripts/creditsText.cs"); - - if (!isDemo()) - { - $CreditsPicIndex = 1; - CREDITS_Pic.setBitmap("gui/Cred_" @ $CreditsPicIndex @ ".png"); - } - else - CREDITS_Pic.setBitmap("gui/Cred_1.bm8"); - - //start the credits from the beginning - $CreditsOffset = 0.0; - %screenHeight = getWord(getResolution(), 1); - Credits_Text.resize(getWord(Credits_Text.position, 0), - mFloor(%screenHeight / 2) - 125, - getWord(Credits_Text.extent, 0), - getWord(Credits_Text.extent, 1)); - - //start the scrolling - $CreditsPaused = false; - $CreditsSpeedUp = false; - $CreditsScrollSchedule = schedule(3500, 0, scrollTheCredits); - - //start cycling the bitmaps - if (!isDemo()) - $CreditsSlideShow = schedule(5000, 0, creditsNextPic); - - //start some music - alxPlayMusic("T2BOL/music/TribesHymn.mp3"); - //alxMusicFadein(0); //Not really needed since the default music has a little bit of a delay before starting -} - -function addCreditsLine(%text, %lastLine) -{ - CREDITS_Text.addText(%text @ "\n", %lastline); -} - -function scrollTheCredits() -{ - //make sure we're not paused - if (!$CreditsPaused) - { - //if we've scrolled off the top, set the position back down to the bottom - %parentCtrl = CREDITS_Text.getGroup(); - if (getWord(Credits_Text.position, 1) + getWord(Credits_Text.extent, 1) < 0) - { - Credits_Text.position = getWord(Credits_Text.position, 0) SPC getWord(%parentCtrl.extent, 1); - $CreditsOffset = getWord(Credits_Text.position, 1); - } - - if ($CreditsSpeedUp) - %valueToScroll = 10; - else - %valueToScroll = 1; - - //scroll the control up a bit - Credits_Text.resize(getWord(Credits_Text.position, 0), - getWord(Credits_Text.position, 1) - %valueToScroll, - getWord(Credits_Text.extent, 0), - getWord(Credits_Text.extent, 1)); - } - - //schedule the next scroll... - $CreditsScrollSchedule = schedule(10, 0, scrollTheCredits); -} - -function creditsNextPic() -{ - //no slide show in the demo... - if (isDemo()) - return; - - cancel($CreditsSlideShow); - if (!$CreditsPaused) - { - $CreditsPicIndex += 1; - if ($CreditsPicIndex > 46) - $CreditsPicindex = 1; - - //set the bitmap - CREDITS_Pic.setBitmap("gui/Cred_" @ $CreditsPicIndex @ ".png"); - } - - //schedule the next bitmap - $CreditsSlideShow = schedule(5000, 0, creditsNextPic); -} +function LaunchCredits(%val) +{ + canvas.showBOLCredits = %val; + Canvas.setContent(CreditsGui); +} + +function cancelCredits() +{ + //delete the action map + CreditsActionMap.pop(); + + //kill the schedules + cancel($CreditsScrollSchedule); + cancel($CreditsSlideShow); + canvas.showBOLCredits = false; + + //kill the music & start menu music + alxMusicFadeout($pref::audio::musicvolume); + schedule(mfloor(8000*$pref::audio::musicvolume),0,"alxPlayMusic","T2BOL/music/menu.mp3"); + + //load the launch gui back... + Canvas.setContent(LaunchGui); + + //delete the contents of the ML ctrl so as to free up memory... + Credits_Text.setText(""); +} + +function CreditsGui::onWake(%this) +{ + //create an action map to use "esc" to exit the credits screen... + if (!isObject(CreditsActionMap)) + { + new ActionMap(CreditsActionMap); + CreditsActionMap.bindCmd(keyboard, anykey, "cancelCredits();", ""); + CreditsActionMap.bindCmd(keyboard, space, "cancelCredits();", ""); + CreditsActionMap.bindCmd(keyboard, escape, "cancelCredits();", ""); + CreditsActionMap.bindCmd(mouse, button0, "$CreditsPaused = true;", "$CreditsPaused = false;"); + CreditsActionMap.bindCmd(mouse, button1, "$CreditsSpeedUp = true;", "$CreditsSpeedUp = false;"); + if (!isDemo()) + CreditsActionMap.bindCmd(mouse, button2, "creditsNextPic();", ""); + } + CreditsActionMap.push(); + + //build the ML text ctrl... + if (!canvas.showBOLCredits) + exec("scripts/creditsText_default.cs"); + else + exec("scripts/creditsText.cs"); + + if (!isDemo()) + { + $CreditsPicIndex = 1; + CREDITS_Pic.setBitmap("gui/Cred_" @ $CreditsPicIndex @ ".png"); + } + else + CREDITS_Pic.setBitmap("gui/Cred_1.bm8"); + + //start the credits from the beginning + $CreditsOffset = 0.0; + %screenHeight = getWord(getResolution(), 1); + Credits_Text.resize(getWord(Credits_Text.position, 0), + mFloor(%screenHeight / 2) - 125, + getWord(Credits_Text.extent, 0), + getWord(Credits_Text.extent, 1)); + + //start the scrolling + $CreditsPaused = false; + $CreditsSpeedUp = false; + $CreditsScrollSchedule = schedule(3500, 0, scrollTheCredits); + + //start cycling the bitmaps + if (!isDemo()) + $CreditsSlideShow = schedule(5000, 0, creditsNextPic); + + //start some music + alxPlayMusic("T2BOL/music/TribesHymn.mp3"); + //alxMusicFadein(0); //Not really needed since the default music has a little bit of a delay before starting +} + +function addCreditsLine(%text, %lastLine) +{ + CREDITS_Text.addText(%text @ "\n", %lastline); +} + +function scrollTheCredits() +{ + //make sure we're not paused + if (!$CreditsPaused) + { + //if we've scrolled off the top, set the position back down to the bottom + %parentCtrl = CREDITS_Text.getGroup(); + if (getWord(Credits_Text.position, 1) + getWord(Credits_Text.extent, 1) < 0) + { + Credits_Text.position = getWord(Credits_Text.position, 0) SPC getWord(%parentCtrl.extent, 1); + $CreditsOffset = getWord(Credits_Text.position, 1); + } + + if ($CreditsSpeedUp) + %valueToScroll = 10; + else + %valueToScroll = 1; + + //scroll the control up a bit + Credits_Text.resize(getWord(Credits_Text.position, 0), + getWord(Credits_Text.position, 1) - %valueToScroll, + getWord(Credits_Text.extent, 0), + getWord(Credits_Text.extent, 1)); + } + + //schedule the next scroll... + $CreditsScrollSchedule = schedule(10, 0, scrollTheCredits); +} + +function creditsNextPic() +{ + //no slide show in the demo... + if (isDemo()) + return; + + cancel($CreditsSlideShow); + if (!$CreditsPaused) + { + $CreditsPicIndex += 1; + if ($CreditsPicIndex > 46) + $CreditsPicindex = 1; + + //set the bitmap + CREDITS_Pic.setBitmap("gui/Cred_" @ $CreditsPicIndex @ ".png"); + } + + //schedule the next bitmap + $CreditsSlideShow = schedule(5000, 0, creditsNextPic); +} diff --git a/scripts/creditsText.cs b/scripts/creditsText.cs index 3f88e2d..d9a995e 100644 --- a/scripts/creditsText.cs +++ b/scripts/creditsText.cs @@ -1,15 +1,15 @@ -// Replacement code for the original T2 credits? -if (!isFile("data/creditsText.txt")) - exec("scripts/creditsText_default.cs"); -else -{ - %read = new fileObject(); - %read.openForRead("data/creditsText.txt"); - - while (!%read.isEOF()) - { - %line = %read.readline(); - addCreditsLine(%line); - } - %read.detach(); +// Replacement code for the original T2 credits? +if (!isFile("data/creditsText.txt")) + exec("scripts/creditsText_default.cs"); +else +{ + %read = new fileObject(); + %read.openForRead("data/creditsText.txt"); + + while (!%read.isEOF()) + { + %line = %read.readline(); + addCreditsLine(%line); + } + %read.detach(); } \ No newline at end of file diff --git a/scripts/creditsText_default.cs b/scripts/creditsText_default.cs index 30837ed..86cc270 100644 --- a/scripts/creditsText_default.cs +++ b/scripts/creditsText_default.cs @@ -1,1609 +1,1609 @@ -// Credits list -addCreditsLine(""); -addCreditsLine(""); -addCreditsLine(""); -addCreditsLine(""); -addCreditsLine(""); -addCreditsLine(""); -addCreditsLine(""); -addCreditsLine(""); -addCreditsLine(""); -addCreditsLine(""); -addCreditsLine(""); -addCreditsLine(""); -addCreditsLine(""); -addCreditsLine("Producer/Director"); -addCreditsLine("Dave \"QIX\" Georgeson"); -addCreditsLine(""); -addCreditsLine("Associate Producer"); -addCreditsLine("Daryl \"Snow Leopard\" Nichols, Jr."); -addCreditsLine(""); -addCreditsLine("Lead Programmer"); -addCreditsLine("Mark \"Got Milk?\" Frohnmayer"); -addCreditsLine(""); -addCreditsLine("Software Engineers"); -addCreditsLine("John \"Sne/\\ker\" Alden"); -addCreditsLine("Kelly \"East\" Asay"); -addCreditsLine("Shawn \"Raf\" Eastley"); -addCreditsLine("Clark \"Shark\" Fagot"); -addCreditsLine("John \"ÜberBob\" Folliard"); -addCreditsLine("Brad \"BigDevDawg\" Heinz"); -addCreditsLine("\"Missing\" Lincoln Hutton"); -addCreditsLine("Greg \"Jett\" Lancaster"); -addCreditsLine("Dave \"Symlink\" Moore"); -addCreditsLine("Brian \"Twitch\" Ramage"); -addCreditsLine("Mitch \"Skeet\" Shaw"); -addCreditsLine("Tinman \"Kidney Thief\""); -addCreditsLine(""); -addCreditsLine("Designers"); -addCreditsLine("Eric \"Rated z\" Lanz"); -addCreditsLine("Dave \"Diamondback\" Meddish"); -addCreditsLine("Jesse \"DrAwkward\" Russell"); -addCreditsLine(""); -addCreditsLine("Art Direction"); -addCreditsLine("Craig \"jimmy\" Maitlen"); -addCreditsLine(""); -addCreditsLine("Artists"); -addCreditsLine("Robert \"Pelias Maximus\" Caracol"); -addCreditsLine("Ian \"ETCmodel02\" Christy "); -addCreditsLine("Jade \"FrankRizzo\" Dhabolt"); -addCreditsLine("Jon \"OrphanKazrak\" Lanz"); -addCreditsLine("Dave \"OldDawg\" Lauck"); -addCreditsLine("Matthew \"Rickets\" Reynolds"); -addCreditsLine("Paul \"Decoy\" Rheinfelder"); -addCreditsLine("Thomas \"TOMIN8R\" VanVelkinburgh"); -addCreditsLine(""); -addCreditsLine("Writer"); -addCreditsLine("Blake \"Hexabolic\" Hutchins"); -addCreditsLine(""); -addCreditsLine("HTML Community"); -addCreditsLine("Pat McCarthy"); -addCreditsLine("Joe Gartska"); -addCreditsLine(""); -addCreditsLine("Director of Quality Assurance"); -addCreditsLine("Gary \"Koros\" Stevens"); -addCreditsLine(""); -addCreditsLine("Compatibility Lab Supervisor"); -addCreditsLine("Pat \"3 Legged Dingo\" Callahan"); -addCreditsLine(""); -addCreditsLine("QA Supervisor, Core Game"); -addCreditsLine("Ken \"Sunshine\" Eaton"); -addCreditsLine(""); -addCreditsLine("Quality Assurance"); -addCreditsLine("Abhishake \"Harley\" Behl"); -addCreditsLine("Angus \"Chewtoy\" Campbell"); -addCreditsLine("Aaron \"Boomer1111\" Denke"); -addCreditsLine("Trent \"RabidSquirrel\" Donelson"); -addCreditsLine("Jonalee \"cHiLaKwEeN\" Gil"); -addCreditsLine("Phil \"Philtre\" Kuhlmey"); -addCreditsLine("Craig \"NEK\" Marshall"); -addCreditsLine("Sean \"Baby Emu\" Meichle"); -addCreditsLine("David \"Plik\" Peterson"); -addCreditsLine("Robert \"Mortal Wombat\" Quattrone"); -addCreditsLine("Connor \"der Todesritter\" Salisbury"); -addCreditsLine("Joe \"Callahan\" Smith"); -addCreditsLine("Mark \"SurferMark\" Storie"); -addCreditsLine("Sue \"Othello\" Ung"); -addCreditsLine("Cody \"Infirmo\" Yarbrough"); -addCreditsLine("Drew \"Mongo\" Zilm"); -addCreditsLine(""); -addCreditsLine("QA Internationalization:"); -addCreditsLine("Lloyd \"Tank\" Madden"); -addCreditsLine("Frank \"Schnack\" Matzke"); -addCreditsLine("Markus \"Beule\" Rafflenbeul"); -addCreditsLine(""); -addCreditsLine("Motion Capture Team"); -addCreditsLine("Technical Director: Troy McFarland"); -addCreditsLine("Performer: Cosmo Hom"); -addCreditsLine(""); -addCreditsLine("Digital Video Support Team"); -addCreditsLine("Director: Jim\"zootboy\" Carey"); -addCreditsLine("Sage \"3Dkid\" Freeman"); -addCreditsLine("Steve \"opticNerve\" Bradford"); -addCreditsLine("Tonya \"Agentmoody\" Stumphauzer"); -addCreditsLine("Troy \"cann n fodder\" McFarland"); -addCreditsLine("Kate \"reelBoss\" Alley"); -addCreditsLine(""); -addCreditsLine("Movie Intro"); -addCreditsLine("PBDigital, Inc."); -addCreditsLine(""); -addCreditsLine("Installer"); -addCreditsLine("Chris Mahnken"); -addCreditsLine(""); -addCreditsLine("Special Thanks"); -addCreditsLine("Mark Brenneman"); -addCreditsLine("Nels Bruckner"); -addCreditsLine("Barry Drew"); -addCreditsLine("Tim Gift"); -addCreditsLine("Gerald Harrison"); -addCreditsLine("Shannon Holder"); -addCreditsLine("Jared Keller"); -addCreditsLine("Ti Kwa"); -addCreditsLine("Joe Maruschak"); -addCreditsLine("Rick Overman"); -addCreditsLine("Helen Pai"); -addCreditsLine("Scott Rudi"); -addCreditsLine("Shawn Sharp"); -addCreditsLine("Neal Skorpen"); -addCreditsLine("Weston Tracy"); -addCreditsLine("Pete Walker"); -addCreditsLine("Maren Wyatt"); -addCreditsLine("Scott Youngblood"); -addCreditsLine(""); -addCreditsLine("zlib Development Team"); -addCreditsLine("libPNG Development Team"); - -// TR2 -addCreditsLine(""); -addCreditsLine("Team Rabbit 2"); -addCreditsLine("Codality, Inc."); -addCreditsLine(""); -addCreditsLine("Codality President/Designer"); -addCreditsLine("Michael \"KineticPoet\" Johnston"); -addCreditsLine(""); -addCreditsLine("Codality Developers"); -addCreditsLine("Dan \"daunt\" Kolta"); -addCreditsLine("Scott \"FSB-AO\" Estabrook"); -addCreditsLine(""); -addCreditsLine("Codality Sound Effects"); -addCreditsLine("John \"CObbler\" Carter"); -addCreditsLine("Buddy \"sLaM\" Pritchard"); -addCreditsLine(""); -addCreditsLine("Codality 3D Artist"); -addCreditsLine("Gregg \"illy\" Fellows"); -addCreditsLine(""); -addCreditsLine("Codality Additional Maps"); -addCreditsLine("Alan \"Nefilim\" Schwertel"); -addCreditsLine(""); -addCreditsLine("Codality 2D Artist"); -addCreditsLine("Kenneth \"SONOFMAN\" Cook"); -addCreditsLine(""); -addCreditsLine("Codality Special Thanks"); -addCreditsLine("Eric \"Special\" Chu"); -addCreditsLine("Jonathan \"Sojourn\" Parker"); -addCreditsLine("Matt \"aerobahn\" Willis"); -addCreditsLine("Taylor \"Banana Man\" Stewart"); -addCreditsLine("Team 5150"); -addCreditsLine("Team Euphoria"); -addCreditsLine("Team Imperial Elite"); -addCreditsLine(""); - -addCreditsLine("Business Unit Manager for Sierra Studios"); -addCreditsLine("Mark Hood"); -addCreditsLine(""); -addCreditsLine("Brand Manager"); -addCreditsLine("Lee Rossini"); -addCreditsLine(""); -addCreditsLine("European Brand Manager"); -addCreditsLine("Djamil Kemal"); -addCreditsLine(""); -addCreditsLine("Europe/Asia Marketing Manager"); -addCreditsLine("Michael Fuller"); -addCreditsLine(""); -addCreditsLine("Asia Brand Manager"); -addCreditsLine("Deana Erickson"); -addCreditsLine(""); -addCreditsLine("Director of Marketing"); -addCreditsLine("Koren Buckner"); -addCreditsLine(""); -addCreditsLine("VP of Marketing"); -addCreditsLine("Jim Veevaert"); -addCreditsLine(""); -addCreditsLine("Channel Promotions"); -addCreditsLine("Michael Whitehead"); -addCreditsLine(""); -addCreditsLine("Web Development Mgr."); -addCreditsLine("Guy Welch"); -addCreditsLine(""); -addCreditsLine("Marketing Assistant"); -addCreditsLine("Michael Cowan"); -addCreditsLine(""); -addCreditsLine("Public Relations Mgr."); -addCreditsLine("Hillary Crowley "); -addCreditsLine(""); -addCreditsLine("Director"); -addCreditsLine("Creative Services"); -addCreditsLine("Laura Kleinhofs "); -addCreditsLine(""); -addCreditsLine("Creative Director For"); -addCreditsLine("Creative Services"); -addCreditsLine("Brandon Walker"); -addCreditsLine(""); -addCreditsLine("Sr. Account Manager"); -addCreditsLine("Creative Services"); -addCreditsLine("Kevin Lamb"); -addCreditsLine(""); -addCreditsLine("Package Design"); -addCreditsLine("Moore Design Group"); -addCreditsLine(""); -addCreditsLine("Production Manager"); -addCreditsLine("Sheri-Lou Stannard"); -addCreditsLine(""); -addCreditsLine("Manual Layout"); -addCreditsLine("Kim McGovern"); -addCreditsLine(""); -addCreditsLine("Localization Coordinator"); -addCreditsLine("Warren Wright"); -addCreditsLine(""); -addCreditsLine("Sound Effects"); -addCreditsLine("EFX/Wilshire Studios"); -addCreditsLine("CS Productions Inc."); -addCreditsLine(""); -addCreditsLine("Voice Recording"); -addCreditsLine("Bad Animals"); -addCreditsLine(""); -addCreditsLine("Voice Processing"); -addCreditsLine("CS Productions Inc."); -addCreditsLine(""); -addCreditsLine("Music"); -addCreditsLine("Tim Clarke and Score! Studios"); -addCreditsLine(""); -addCreditsLine("Sierra On-Line Multiplayer Services"); -addCreditsLine("Aaron Hunt"); -addCreditsLine("Erik De Bonte"); -addCreditsLine("Bill Dewey"); -addCreditsLine("Colen Garoutte-Carson"); -addCreditsLine("Max Klaiser"); -addCreditsLine("Brent LaPoint"); -addCreditsLine("Neeraj Murarka"); -addCreditsLine("Mike Nicolino"); -addCreditsLine("Lee Olds"); -addCreditsLine("Ross Perez"); -addCreditsLine("Darren Robinson"); -addCreditsLine("Brian Rothstein"); -addCreditsLine("Jeff Routledge"); -addCreditsLine("Dean Webster"); -addCreditsLine("Kelly Zmak"); -addCreditsLine(""); -addCreditsLine("Voice Talent"); -addCreditsLine("John Armstrong"); -addCreditsLine("Mark Berry"); -addCreditsLine("Kiamalise Budak"); -addCreditsLine("Kymberli Colbourne"); -addCreditsLine("Craig English"); -addCreditsLine("Kit Harris"); -addCreditsLine("Jay Hopper"); -addCreditsLine("Mike Madeoy"); -addCreditsLine("Dex Manley"); -addCreditsLine("Kate Myre"); -addCreditsLine("Matt Reidy"); -addCreditsLine("Gary Schwartz"); -addCreditsLine("Jen Taylor"); -addCreditsLine(""); -addCreditsLine("Linux Port"); -addCreditsLine("Loki Software, Inc."); -addCreditsLine(""); -addCreditsLine("Loki President"); -addCreditsLine("Scott \"Highlander\" Draeker"); -addCreditsLine(""); -addCreditsLine("Linux Installer"); -addCreditsLine("Stephane \"Megastep\" Peter"); -addCreditsLine(""); -addCreditsLine("Linux Programming"); -addCreditsLine("Michael \"Briareos\" Vance"); -addCreditsLine("Joe \"TsaoTsao\" Valenzuela"); -addCreditsLine("Sam \"Hercules\" Lantinga"); -addCreditsLine(""); -addCreditsLine("Linux Q/A and Support"); -addCreditsLine("Andy \"Yoda\" Mecham"); -addCreditsLine("Mike \"Heimdall\" Phillips"); -addCreditsLine(""); -addCreditsLine("Linux Manual"); -addCreditsLine("Kayt \"Sigyn\" Sorhaindo"); -addCreditsLine(""); -addCreditsLine("Loki Artwork"); -addCreditsLine("Jason \"Pais\" Kim"); -addCreditsLine(""); -addCreditsLine("Loki System Support"); -addCreditsLine("Rafael \"Raistlin\" Barrero"); -addCreditsLine(""); -addCreditsLine("Loki Business Manager"); -addCreditsLine("Yvonne \"YDS\" De Sollar"); -addCreditsLine(""); -addCreditsLine("Loki Customer Support"); -addCreditsLine("Brandon \"Particle\" Carter"); -addCreditsLine(""); -addCreditsLine("Loki Beta Testers"); -addCreditsLine("James \"idcmp\" Atwill"); -addCreditsLine("Brandon \"bbeattie\" Beattie"); -addCreditsLine("Fionn Behrens"); -addCreditsLine("Jonathan \"Suraklyn\" Bowser"); -addCreditsLine("Patrick \"Phineas\" Calhoun"); -addCreditsLine("Wayne \"ttol\" Chang"); -addCreditsLine("Nash \"twostar\" Clemens"); -addCreditsLine("Mike \"madcat\" Delaney"); -addCreditsLine("Matthew \"DivineHawk\" Eaton"); -addCreditsLine("Rodney \"meff\" Gordon II"); -addCreditsLine("Pavan \"Phantom\" Gupta"); -addCreditsLine("Christopher \"Malkier\" Hahn"); -addCreditsLine("John \"OverCode\" Hall"); -addCreditsLine("Jesse \"Abysmal\" Hanna"); -addCreditsLine("Steven \"Ashari\" Hatfield"); -addCreditsLine("David \"NeoTron\" Hedbor"); -addCreditsLine("Matt \"malloc_master\" Helsley"); -addCreditsLine("Simon \"red_one\" Hill"); -addCreditsLine("Gareth \"3D-Guru\" Hughes"); -addCreditsLine("Zephaniah E. Hull"); -addCreditsLine("Guy \"Guido\" Hutchison"); -addCreditsLine("Joshua Kleiner"); -addCreditsLine("Geoff \"Rambo\" Lewis"); -addCreditsLine("Jason \"Deadman\" Lundy"); -addCreditsLine("Gregory \"Centove\" McLean"); -addCreditsLine("Patrick \"WormBoy\" McNeill"); -addCreditsLine("Jeff \"Judecca\" Mrochuk"); -addCreditsLine("Patrick \"linuxpunkr...\" Mullen"); -addCreditsLine("Prof. Dr. Nao"); -addCreditsLine("Jody \"Dweebs\" Newell"); -addCreditsLine("Bob \"Shapecharge\" O'Brien"); -addCreditsLine("Kyle \"JebusSaveMe\" Olsen"); -addCreditsLine("John \"joe\" Osborne"); -addCreditsLine("Chris \"Super-K\" Osgood"); -addCreditsLine("Jon \"Railroad\" Revie"); -addCreditsLine("Michael \"M00k3y\" Ritner"); -addCreditsLine("Aron \"Govt.Cheese\" Rosenberg"); -addCreditsLine("Yuri \"Mystro\" Sagalov"); -addCreditsLine("Marinus \"foser\" Schraal"); -addCreditsLine("SKILL5"); -addCreditsLine("Ryan Stotts"); -addCreditsLine("Dan \"XFree86\" Temple"); -addCreditsLine("Terry \"keerf\" Warner"); -addCreditsLine("Chris \"UmytBnxt\" Watkins"); -addCreditsLine("Michael \"themime\" Whitten"); -addCreditsLine(""); -addCreditsLine("GLSetup Team"); -addCreditsLine("Chris Hecker"); -addCreditsLine("Rob Felter"); -addCreditsLine(""); -addCreditsLine(""); -addCreditsLine("Thanks to all the wives, girlfriends and children of the hardworking Dev Team members. Your patience and sacrifice has allowed us to complete a project of which we are all tremendously proud. None of it would have been possible without you."); -addCreditsLine(""); -addCreditsLine(""); -addCreditsLine("Meta Testers"); -addCreditsLine("Alex Flagg"); -addCreditsLine("Alex \"LogRoller\" Ogilvie"); -addCreditsLine("Adam Mitter"); -addCreditsLine("Alan \"Otter\" Ragg"); -addCreditsLine("Alex \"SaGe\" Chappuis"); -addCreditsLine("Alexandre \"[cF]Alex\" Clerc-Gagnoux"); -addCreditsLine("Allen \"TheRedDread\" Drennan"); -addCreditsLine("Andreas Jalsovec"); -addCreditsLine("Anton Wiegert"); -addCreditsLine("Arden H. \"TF Pookie\" Nguyen"); -addCreditsLine("Bart \"=DB=Seven\" Smith"); -addCreditsLine("Ben \"Diox\" May"); -addCreditsLine("Ben \"Hypn0tik\" Tamler"); -addCreditsLine("Ben \"Stan\" Gray"); -addCreditsLine("Bobby \"Mogart\" Rider"); -addCreditsLine("Bodhi \"Heliometus Max\" Daher"); -addCreditsLine("Brad \"Bort\" Klann"); -addCreditsLine("Bret D. \"Bacchus\" Wilson"); -addCreditsLine("Brian \"Aftershock\" Parker"); -addCreditsLine("Carl \"Daddy\" Anderson"); -addCreditsLine("Charlie Schillberg"); -addCreditsLine("Chason \"Phantom Stranger\" Ellis"); -addCreditsLine("Chris \"Pie4Foo\" Abele"); -addCreditsLine("Chris \"Tythan\" Caviness"); -addCreditsLine("Chris \"Fubar\" Duncan"); -addCreditsLine("Christian \"S3 Crucifix\" Peth"); -addCreditsLine("Colin \"Dark Wraith\" Howitt"); -addCreditsLine("Cory \"Omega Man\" Altheide"); -addCreditsLine("\"Cowboy\" Ben Alman"); -addCreditsLine("Crystal McHale"); -addCreditsLine("Dan \"Avatar\" Lyons"); -addCreditsLine("Daniel \"|5150|Keyser\" Gallegos"); -addCreditsLine("Daniel \"Emp\" Arnold"); -addCreditsLine("Daniel \"Snaggs\" Soderstrom"); -addCreditsLine("Daniel \"Trebz\" Nolan"); -addCreditsLine("Daniel \"Wizard_TPG\" Neilsen"); -addCreditsLine("Daniel \"Shadow Mage\" Nichols"); -addCreditsLine("Daniel \"Spooger\" Patton"); -addCreditsLine("Danny \"OmegaRed\" Cotton"); -addCreditsLine("Darion \"Shadower\" Lowenstein"); -addCreditsLine("Darren \"Fidelio\" Mitchell"); -addCreditsLine("Dave \"Tycho\" Fried"); -addCreditsLine("David \"DOX\" Oxwell"); -addCreditsLine("David \"Killdawg\" DeBoer"); -addCreditsLine("David MacIntosh"); -addCreditsLine("Dean \"VolcoM\" Sykes"); -addCreditsLine("Dean Tate"); -addCreditsLine("Dennis \"Chickenboo\" Fox"); -addCreditsLine("Erik \"Mustard\" de Jong"); -addCreditsLine("Gabor \"Dezso a HUN\" Orban"); -addCreditsLine("Gabriel \"Warwitch\" David"); -addCreditsLine("Gavin \"Suds\" Henrick"); -addCreditsLine("Gino \"tAngGSI\" Gard"); -addCreditsLine("Glenn \"IcyHot\" Wisbey"); -addCreditsLine("Gregory \"Brak Panda\" Pesochin"); -addCreditsLine("Gregory \"Strife\" Hill"); -addCreditsLine("Hannes \"Cohen\" Wagner"); -addCreditsLine("Ian \"Kowboy\" Gonsalves"); -addCreditsLine("Ian Threadgold"); -addCreditsLine("J Alex \"Blackheart\" Wheeler"); -addCreditsLine("James \"Warbird\" Gentry III"); -addCreditsLine("James C. \"Lothos\" Hanna"); -addCreditsLine("Jason \"Circuit\" Jenkins"); -addCreditsLine("Jason \"Iron Chef\" Goodowens"); -addCreditsLine("Jason \"Lumberjack\" De Arte"); -addCreditsLine("Jeff \"Hellsfury\" Shaw"); -addCreditsLine("Jeremy \"Xevious\" Burke"); -addCreditsLine("Jerry \"Tycho Brahe\" Holkins"); -addCreditsLine("Joe \"Quadrature\" Downs"); -addCreditsLine("Joe Bell Grant"); -addCreditsLine("Joern \"Pangur\" Schnautz"); -addCreditsLine("John \"Dr.Jones\" Burnett"); -addCreditsLine("Jon \"Ratorasniki\" Naiman"); -addCreditsLine("Jonathan \"Chaser\" Bale"); -addCreditsLine("Joost \"jschuur\" Schuur"); -addCreditsLine("Josh \"Red Sirus\" Hoey"); -addCreditsLine("Kevin \"Rifter\" Rank"); -addCreditsLine("Kevin \"Kevlar\" Middleton"); -addCreditsLine("Kyle \"{DP}AzN^DoG\" Godfrey"); -addCreditsLine("Kyle \"Wiggy\" Bennett"); -addCreditsLine("Laura \"Dolph Lundgren\" Schreiner"); -addCreditsLine("Lorne \"Writer\" Laliberte"); -addCreditsLine("Mac \"McNaughton\" Miller"); -addCreditsLine("Mario \"Lone Gunman\" Batlle"); -addCreditsLine("Mark \"Ferret-of-Death\" Siciliano"); -addCreditsLine("Mark \"Old Skul\" Szabo"); -addCreditsLine("Mark \"Panama Jack\" Dickenson"); -addCreditsLine("Markus Rafflenbeul"); -addCreditsLine("Mat Bettinson"); -addCreditsLine("Matt \"{SiR}SoulJAH\" Culp"); -addCreditsLine("Matt \"Colosus\" DeWald"); -addCreditsLine("Matt Sobotka"); -addCreditsLine("Matthew \"4u2c\" McKeown"); -addCreditsLine("Mattijs \"3bird\" Jonker"); -addCreditsLine("Michael \"Optimizer\" Hamlett"); -addCreditsLine("Michael \"Rave\" Mogill"); -addCreditsLine("Michael A Nance"); -addCreditsLine("Michael James \"Tenabrae\" Edwards"); -addCreditsLine("Mike \"Ragman\" Hillebrecht"); -addCreditsLine("Mike \"Gabriel\" Krahulik"); -addCreditsLine("Mike \"Gangreen\" Burton"); -addCreditsLine("Moussa Khan"); -addCreditsLine("N. David \"MlakMavet\" Griffin"); -addCreditsLine("Nathan \"[HvC]NaTeDoGG\" Sweet"); -addCreditsLine("Nick \"Enhanced Panda\" Orlich"); -addCreditsLine("Nick \"Leb\" Petska"); -addCreditsLine("Nick S. \"Enlightened One\" Pasto"); -addCreditsLine("Nikita \"FSB-SPY\" Bogolyubov"); -addCreditsLine("Olivier \"[cf] OroX\" Roulx"); -addCreditsLine("Omar Yehia"); -addCreditsLine("Pamela A. \"Diva\" Holmberg"); -addCreditsLine("Paul \"RuinatioN\" Wright"); -addCreditsLine("Paul \"Teknoice\" Morris"); -addCreditsLine("Penny \"Killer Girl\" Miller"); -addCreditsLine("Peter \"dev\" Kazmierow"); -addCreditsLine("Ric \"Dr Chmod\" Moseley"); -addCreditsLine("\"NoFix\""); -addCreditsLine("Rob \"Coyote\" Duffy"); -addCreditsLine("Robert Huebner"); -addCreditsLine("Rod Chrenek"); -addCreditsLine("Ron Oliver II"); -addCreditsLine("Ross \"Bytor\" Carlson"); -addCreditsLine("Roy \"Cannonfodder\" Greenhalgh"); -addCreditsLine("Ryan \"Kelster\" Kelly"); -addCreditsLine("Ryan \"Onyxwulf\" Gilfillan"); -addCreditsLine("Ryan \"StoneWolf\" Thernes"); -addCreditsLine("Scott \"Smedly\" Medlin"); -addCreditsLine("Sean \"Pubknight\" Bryson "); -addCreditsLine("Sebastien \"[cF]PreD\" Guillemet"); -addCreditsLine("Shane \"Mental Trousers\" Taylor"); -addCreditsLine("Shane \"Santa\" Beaumont"); -addCreditsLine("Shane \"Shaneman\" Evans"); -addCreditsLine("Stefan Grufman"); -addCreditsLine("Stefan \"Skace\" Kiehne"); -addCreditsLine("Stephen \"Cato\" Farquhar"); -addCreditsLine("Stephen \"SL83\" Limowski"); -addCreditsLine("Steve \"Presto\" Eisner"); -addCreditsLine("Taylor \"Emo1313\" Suchan"); -addCreditsLine("Thomas \"Mantis\" Kumpik, Jr."); -addCreditsLine("Tim \"Zear\" Hammock"); -addCreditsLine("Todd \"Fuzzy Lumpkins\" Sjoblom"); -addCreditsLine("Tom \"Falcon\" Vogt"); -addCreditsLine("Tyler \"Raskal\" Jacobson"); -addCreditsLine("Tyler \"Sty\" Frans"); -addCreditsLine("Tyler Wilson"); -addCreditsLine("Werner Poetzelberger"); -addCreditsLine("Willem \"Talita\" Bison"); -addCreditsLine("William \"Altaic\" Knop"); -addCreditsLine(""); -addCreditsLine("Beta Testers"); -addCreditsLine("Aaron Brown"); -addCreditsLine("Aaron Butler"); -addCreditsLine("Aaron Reed"); -addCreditsLine("Aaron Scott Reed"); -addCreditsLine("Aaron Semeniuk"); -addCreditsLine("Aaron Wisner"); -addCreditsLine("Aaron Younger"); -addCreditsLine("Adam B. Argo"); -addCreditsLine("Adam Becker"); -addCreditsLine("Adam Corvin"); -addCreditsLine("Adam England"); -addCreditsLine("Adam King"); -addCreditsLine("Adam Kleifield "); -addCreditsLine("Adam McCreight"); -addCreditsLine("Adam Mitter"); -addCreditsLine("Adam S. Pedersen"); -addCreditsLine("Adam Toering"); -addCreditsLine("Adam Williams"); -addCreditsLine("Adrian Telfer"); -addCreditsLine("Akihiro Inoue"); -addCreditsLine("Al Harrington"); -addCreditsLine("Alan Peng"); -addCreditsLine("Alan Ragg"); -addCreditsLine("Alayton Norgard"); -addCreditsLine("Alberto Petrozzi"); -addCreditsLine("Alden Tan"); -addCreditsLine("Alex Chappuis"); -addCreditsLine("Alex Flagg"); -addCreditsLine("Alex Gourley"); -addCreditsLine("Alex Jakes JR"); -addCreditsLine("Alex Jeng"); -addCreditsLine("Alex Ogilvie"); -addCreditsLine("Alex Porter"); -addCreditsLine("Alex Taylor"); -addCreditsLine("Alex Zanfir"); -addCreditsLine("Alexander Baldoria"); -addCreditsLine("Alexander Flagg"); -addCreditsLine("Alexander Marschal"); -addCreditsLine("Alexander van Rijn"); -addCreditsLine("Alexandr Koshelev"); -addCreditsLine("Alexandre Clerc-Gagnoux"); -addCreditsLine("Alexandre Pomi"); -addCreditsLine("Alexandre Ramos"); -addCreditsLine("Alexei Sapsford"); -addCreditsLine("Allen Drennan"); -addCreditsLine("Allen Grusecki"); -addCreditsLine("Amir Assali"); -addCreditsLine("Amir Grad"); -addCreditsLine("Anatoly Ropotov"); -addCreditsLine("Andre Koch"); -addCreditsLine("Andrea Primadei"); -addCreditsLine("Andreas Leondidis"); -addCreditsLine("Andrew Baum"); -addCreditsLine("Andrew Fort"); -addCreditsLine("Andrew Price"); -addCreditsLine("Andrew Stockman"); -addCreditsLine("Andy Chong"); -addCreditsLine("Andy Swanson"); -addCreditsLine("Angus Campbell"); -addCreditsLine("Anthony Bermudez"); -addCreditsLine("Anthony Mills"); -addCreditsLine("Antonio Ferrari"); -addCreditsLine("Antti Hätinen"); -addCreditsLine("Arden H Nguyen"); -addCreditsLine("Arthur Troncoso"); -addCreditsLine("Ata Yavalar"); -addCreditsLine("Attila Fur"); -addCreditsLine("Audie Martin"); -addCreditsLine("Barbara J. Webb"); -addCreditsLine("Baret Julien"); -addCreditsLine("Baron Wolt"); -addCreditsLine("Bart Haesaerts"); -addCreditsLine("Bart Maegh"); -addCreditsLine("Bart Peiren"); -addCreditsLine("Bart Smith"); -addCreditsLine("Bart Waeterschoot"); -addCreditsLine("Beau Hale"); -addCreditsLine("Ben Anderson"); -addCreditsLine("Ben Cantwell"); -addCreditsLine("Ben Cuthbert"); -addCreditsLine("Ben De Decker"); -addCreditsLine("Ben Dobbs"); -addCreditsLine("Ben Floren"); -addCreditsLine("Ben Gray"); -addCreditsLine("Ben Lawton"); -addCreditsLine("Ben Martel"); -addCreditsLine("Ben May"); -addCreditsLine("Ben Pierson"); -addCreditsLine("Ben Stone"); -addCreditsLine("Ben Tamler"); -addCreditsLine("Benjamin Alman"); -addCreditsLine("Benjamin Denholm"); -addCreditsLine("Benjamin Luck"); -addCreditsLine("Benoît Dewaele"); -addCreditsLine("Bernd Berheide"); -addCreditsLine("Bernhard Seiser"); -addCreditsLine("Bill Eccleston"); -addCreditsLine("Bill Lewis"); -addCreditsLine("Bill Rodenbaugh"); -addCreditsLine("Bjorn Sleypen"); -addCreditsLine("Bo McCoy"); -addCreditsLine("Bodhi Daher"); -addCreditsLine("Boris Stock"); -addCreditsLine("Brad Butcher"); -addCreditsLine("Brad Conner"); -addCreditsLine("Brad DeLong"); -addCreditsLine("Brad Goehring"); -addCreditsLine("Brad Herman"); -addCreditsLine("Brad Klann"); -addCreditsLine("Bram Noëz"); -addCreditsLine("Brandon Cantrell"); -addCreditsLine("Brandon Knez"); -addCreditsLine("Brandon W. Easley"); -addCreditsLine("Brandy Straatman"); -addCreditsLine("Bret D. Wilson"); -addCreditsLine("Brett Carlson"); -addCreditsLine("Bri Pas"); -addCreditsLine("Brian Barnes"); -addCreditsLine("Brian Charles Moses"); -addCreditsLine("Brian Helms"); -addCreditsLine("Brian Hon"); -addCreditsLine("Brian Lorey"); -addCreditsLine("Brian Mercer"); -addCreditsLine("Brian Nakash"); -addCreditsLine("Brian Parker"); -addCreditsLine("Brian Vitale"); -addCreditsLine("Brian Walsh"); -addCreditsLine("Brian Weberling"); -addCreditsLine("Brian Wright"); -addCreditsLine("Brice Gharst"); -addCreditsLine("Brion Miller"); -addCreditsLine("Bruce Oberleitner"); -addCreditsLine("Bryan Heard"); -addCreditsLine("Bryan Stroop"); -addCreditsLine("Buddy Pritchard"); -addCreditsLine("C. Henrique Olifiers"); -addCreditsLine("C. Kyle Bennett"); -addCreditsLine("C.D. Thurman"); -addCreditsLine("Caleb Cauthon"); -addCreditsLine("Camere Danilo"); -addCreditsLine("Camille Castel"); -addCreditsLine("Carl Anderson"); -addCreditsLine("Carl Andersson"); -addCreditsLine("Carl Buckley"); -addCreditsLine("Carl Chambers"); -addCreditsLine("Carla Louisa Andrews"); -addCreditsLine("Carlos Delgado"); -addCreditsLine("Carolyn Manis"); -addCreditsLine("Casey O'Connor"); -addCreditsLine("Casper Lund"); -addCreditsLine("Cedric Hourcade"); -addCreditsLine("Chad Jolly"); -addCreditsLine("Channon Wong"); -addCreditsLine("Charl Theron"); -addCreditsLine("Charles Cresswell"); -addCreditsLine("Charles F. Gast"); -addCreditsLine("Charles Koelemay"); -addCreditsLine("Charlie VanDyke"); -addCreditsLine("Chason Ellis"); -addCreditsLine("Choi Byeong-Ho"); -addCreditsLine("Chow Yun"); -addCreditsLine("Chris Abele"); -addCreditsLine("Chris Aster"); -addCreditsLine("Chris Becton"); -addCreditsLine("Chris Boucher"); -addCreditsLine("Chris Boyd"); -addCreditsLine("Chris Browning"); -addCreditsLine("Chris Buckler"); -addCreditsLine("Chris Cacioppo"); -addCreditsLine("Chris Calande"); -addCreditsLine("Chris Cauthen"); -addCreditsLine("Chris Caviness"); -addCreditsLine("Chris Cullen"); -addCreditsLine("Chris Dettmann"); -addCreditsLine("Chris Duncan"); -addCreditsLine("Chris Farmer"); -addCreditsLine("Chris Fields"); -addCreditsLine("Chris Frederick"); -addCreditsLine("Chris Hersey"); -addCreditsLine("Chris Hewitt"); -addCreditsLine("Chris Holfeld"); -addCreditsLine("Chris Houston"); -addCreditsLine("Chris Jones"); -addCreditsLine("Chris Joyce"); -addCreditsLine("Chris Kissinger"); -addCreditsLine("Chris Mahnken"); -addCreditsLine("Chris Mermagen"); -addCreditsLine("Chris Walker"); -addCreditsLine("Chris Weatherwax"); -addCreditsLine("Chris Weeks"); -addCreditsLine("Chris Willis"); -addCreditsLine("Chris Wilson"); -addCreditsLine("Chris Youren"); -addCreditsLine("Christian D. Loftus"); -addCreditsLine("Christian Davis"); -addCreditsLine("Christian Peth"); -addCreditsLine("Christoher Rex Prangnell"); -addCreditsLine("Christoph Hagenbrock"); -addCreditsLine("Christoph Schwayer"); -addCreditsLine("Christopher Clarke"); -addCreditsLine("Christopher Donahue"); -addCreditsLine("Christopher Duffield"); -addCreditsLine("Christopher Forbes Davidson"); -addCreditsLine("Christopher Gray"); -addCreditsLine("Christopher J. Burden"); -addCreditsLine("Christopher Jones"); -addCreditsLine("Christopher Tan"); -addCreditsLine("Chuang Li-chung"); -addCreditsLine("Chuck Houlette"); -addCreditsLine("Chum Chancharadeth"); -addCreditsLine("Clarence Jones"); -addCreditsLine("Clark Bradley"); -addCreditsLine("Clay Reyer"); -addCreditsLine("Clay Taylor"); -addCreditsLine("Clayton Griffin"); -addCreditsLine("Cliff Yaun"); -addCreditsLine("Clint Gallon"); -addCreditsLine("Cody Edwards"); -addCreditsLine("Colin Howitt"); -addCreditsLine("Colin Korbelas"); -addCreditsLine("Colin Laughlin"); -addCreditsLine("Colin murray"); -addCreditsLine("Collin Theseira"); -addCreditsLine("Cory Altheide"); -addCreditsLine("Cory Hill"); -addCreditsLine("Cory Miller"); -addCreditsLine("Craig Beers"); -addCreditsLine("Craig Paterson"); -addCreditsLine("Crystal McHale"); -addCreditsLine("Curtis Campbell"); -addCreditsLine("Curtis Rock"); -addCreditsLine("Daire Garvey"); -addCreditsLine("Dallas Harris"); -addCreditsLine("Damien Webber"); -addCreditsLine("Damien Webber"); -addCreditsLine("Dan Ilan"); -addCreditsLine("Dan Kolta"); -addCreditsLine("Dan Lyons"); -addCreditsLine("Dan Peters"); -addCreditsLine("Dan Schmierer"); -addCreditsLine("Dan Sego"); -addCreditsLine("Dane Barber"); -addCreditsLine("Daniel Chenoweth"); -addCreditsLine("Daniel Costantini"); -addCreditsLine("Daniel Gallegos"); -addCreditsLine("Daniel J. Patton"); -addCreditsLine("Daniel Medini"); -addCreditsLine("Daniel Neilsen"); -addCreditsLine("Daniel Nolan"); -addCreditsLine("Daniel Palmer"); -addCreditsLine("Daniel Smith"); -addCreditsLine("Daniel Soderstrom"); -addCreditsLine("Danny Cotton"); -addCreditsLine("Danny Van Bronkhorst"); -addCreditsLine("Darion Lowenstein"); -addCreditsLine("Darko Miodrag"); -addCreditsLine("Darragh O' Toole"); -addCreditsLine("Darren Asato"); -addCreditsLine("Darren Menzies"); -addCreditsLine("Darren Mitchell"); -addCreditsLine("Darren Sorrell"); -addCreditsLine("Darren Tabor"); -addCreditsLine("Dave Benedict"); -addCreditsLine("Dave Calame"); -addCreditsLine("Dave Fried"); -addCreditsLine("Dave Schwinger"); -addCreditsLine("Dave Warner"); -addCreditsLine("Dave Wight"); -addCreditsLine("David Bonds"); -addCreditsLine("David Chubb"); -addCreditsLine("David De Boer"); -addCreditsLine("David Higgins"); -addCreditsLine("David Lindberg"); -addCreditsLine("David Liu"); -addCreditsLine("David Oxwell"); -addCreditsLine("David Paukstys"); -addCreditsLine("David Peterson"); -addCreditsLine("David Quinn"); -addCreditsLine("David Richards"); -addCreditsLine("David Stetz"); -addCreditsLine("David W. Atchley"); -addCreditsLine("Dean Sykes"); -addCreditsLine("Deffi"); -addCreditsLine("Denish Puspparajah"); -addCreditsLine("Dennis Fox"); -addCreditsLine("Dennis Goedbloed"); -addCreditsLine("Dennis Gurock"); -addCreditsLine("Dennis Oden"); -addCreditsLine("Dennis Price"); -addCreditsLine("Dennis vd Broek"); -addCreditsLine("Derek Bao"); -addCreditsLine("Derek McGee"); -addCreditsLine("Derek Millar"); -addCreditsLine("Derek Mulder"); -addCreditsLine("Derrick T. Woolworth"); -addCreditsLine("Devin Blair"); -addCreditsLine("Devin C. Glenn"); -addCreditsLine("Devin L. Ganger"); -addCreditsLine("Dimitri Gunsing"); -addCreditsLine("Dion Clapperton"); -addCreditsLine("Dirk Lambert"); -addCreditsLine("Dirk Moerenhout"); -addCreditsLine("Dominic Carus"); -addCreditsLine("Donald Ho"); -addCreditsLine("Donald Mills"); -addCreditsLine("Duncan Law"); -addCreditsLine("Duncan McLeod"); -addCreditsLine("Dustin Lesan"); -addCreditsLine("Dustin Miller"); -addCreditsLine("Dyanne Lee"); -addCreditsLine("Ed Molnar"); -addCreditsLine("Ed Sin"); -addCreditsLine("Eddie Manso"); -addCreditsLine("Eddie Pierce"); -addCreditsLine("Editorial GameSurf"); -addCreditsLine("Edric Borja"); -addCreditsLine("Eduardo Amaro"); -addCreditsLine("Edward Van Brunt"); -addCreditsLine("Elliot Naiman"); -addCreditsLine("Emanuele"); -addCreditsLine("Emiliano Saurin"); -addCreditsLine("Ephraim Brodsky"); -addCreditsLine("Erbil Salihoglu"); -addCreditsLine("Eric Bultman"); -addCreditsLine("Eric Hudzikiewicz"); -addCreditsLine("Eric Iovan"); -addCreditsLine("Eric Manko"); -addCreditsLine("Eric Ray"); -addCreditsLine("Eric Ross"); -addCreditsLine("Eric Soulvie"); -addCreditsLine("Eric Stankelis"); -addCreditsLine("Eric Takamoto"); -addCreditsLine("Eric Toledo"); -addCreditsLine("Erick Apeles"); -addCreditsLine("Erik de Jong"); -addCreditsLine("Erik Gulbrandsen"); -addCreditsLine("Ernie Page"); -addCreditsLine("Erwin Esener"); -addCreditsLine("Espen Andresen"); -addCreditsLine("Eugene Goh"); -addCreditsLine("Everett Whiteway"); -addCreditsLine("Fabian Ianigro"); -addCreditsLine("Faizaan Ghauri"); -addCreditsLine("Fiona Stevens"); -addCreditsLine("Francesco Sorrentino"); -addCreditsLine("Francis To"); -addCreditsLine("Frank Canedy"); -addCreditsLine("Frank Collins"); -addCreditsLine("Frank Hop"); -addCreditsLine("Frank McGee"); -addCreditsLine("Franz Töfferl"); -addCreditsLine("Fred Cheng"); -addCreditsLine("Fred Hill"); -addCreditsLine("Frederik Kruse Hannibal"); -addCreditsLine("Fulvio Tagliento"); -addCreditsLine("Gabe Othman"); -addCreditsLine("Gabor Orban"); -addCreditsLine("Gabriel David"); -addCreditsLine("Gary Caine"); -addCreditsLine("Gary J. Talley"); -addCreditsLine("Gary McWilliams"); -addCreditsLine("Gary Milante"); -addCreditsLine("Gary Schweisthal"); -addCreditsLine("Gavin Henrick"); -addCreditsLine("Geoff Dodd"); -addCreditsLine("Geoffrey Forman"); -addCreditsLine("George Campbell"); -addCreditsLine("George Ganas"); -addCreditsLine("George Wingard"); -addCreditsLine("Gilberto Barbicinti"); -addCreditsLine("Gino Gard"); -addCreditsLine("Glenn Reasor"); -addCreditsLine("Glenn Wisbey"); -addCreditsLine("Gordon Lee"); -addCreditsLine("Gordon Mak"); -addCreditsLine("Gordon Wilcox"); -addCreditsLine("Goty Liu"); -addCreditsLine("Greg Barnett"); -addCreditsLine("Greg Gilleland"); -addCreditsLine("Greg Habetler"); -addCreditsLine("Greg Milton"); -addCreditsLine("Greg Romaszka"); -addCreditsLine("Greg Walk"); -addCreditsLine("Gregory Hill"); -addCreditsLine("Gregory Peng"); -addCreditsLine("Gregory Pesochin"); -addCreditsLine("Greigg Stein"); -addCreditsLine("Guillaume Neron"); -addCreditsLine("Gunnar Schumann"); -addCreditsLine("Guy Mirisciotta"); -addCreditsLine("H.Yamao"); -addCreditsLine("Hamed Khoojinian"); -addCreditsLine("Hannes Wagner"); -addCreditsLine("Hans David Lemons"); -addCreditsLine("Harold Brown"); -addCreditsLine("Harry Glaser"); -addCreditsLine("Harry Kambouropoulos"); -addCreditsLine("Hashish HasnaIn"); -addCreditsLine("Heath Fischer"); -addCreditsLine("Helge Nesøen"); -addCreditsLine("Hendrik Bauer"); -addCreditsLine("Hendrik Strobel"); -addCreditsLine("Henk Schaefer"); -addCreditsLine("Henry Lee"); -addCreditsLine("Henry Martins"); -addCreditsLine("Hugh Norton-Smith"); -addCreditsLine("Hugh Spencer"); -addCreditsLine("Hunter Luisi"); -addCreditsLine("Ian Glenn"); -addCreditsLine("Ian Redden"); -addCreditsLine("Ian Threadgold"); -addCreditsLine("Igor Bachinsky"); -addCreditsLine("Issac Rosser"); -addCreditsLine("Iwan Khouw"); -addCreditsLine("J. Scott Randall"); -addCreditsLine("Jaap de Heer"); -addCreditsLine("Jack Mamais"); -addCreditsLine("Jaesson Yeo"); -addCreditsLine("James Balough"); -addCreditsLine("James Batty"); -addCreditsLine("James C. Hanna"); -addCreditsLine("James Ell"); -addCreditsLine("James Gentry III"); -addCreditsLine("James Logan"); -addCreditsLine("James Molson"); -addCreditsLine("James Ramsey"); -addCreditsLine("James Tucker"); -addCreditsLine("James Weisgerber"); -addCreditsLine("Jamie Reep"); -addCreditsLine("Jan Siarov"); -addCreditsLine("Jani Sundstrom"); -addCreditsLine("Janne Puonti"); -addCreditsLine("Jared Black"); -addCreditsLine("Jared Keller"); -addCreditsLine("Jarle Hauglum"); -addCreditsLine("Jason Alday"); -addCreditsLine("Jason Alombro"); -addCreditsLine("Jason Bergman"); -addCreditsLine("Jason Cross"); -addCreditsLine("Jason De Arte"); -addCreditsLine("Jason Fleming"); -addCreditsLine("Jason Gill"); -addCreditsLine("Jason Goodfellow"); -addCreditsLine("Jason Goodowens"); -addCreditsLine("Jason Jenkins"); -addCreditsLine("Jason Kinnear"); -addCreditsLine("Jason Kochan"); -addCreditsLine("Jason Newington"); -addCreditsLine("Jason Robert Nelson"); -addCreditsLine("Jason Widy"); -addCreditsLine("Javier Jiménez"); -addCreditsLine("Jay Johnson"); -addCreditsLine("Jay Weitekamp"); -addCreditsLine("Jeff Buckland"); -addCreditsLine("Jeff Chang"); -addCreditsLine("Jeff Day"); -addCreditsLine("Jeff Dotson"); -addCreditsLine("Jeff Drouet"); -addCreditsLine("Jeff Greth"); -addCreditsLine("Jeff Hedges"); -addCreditsLine("Jeff Lofgren"); -addCreditsLine("Jeff Shauger"); -addCreditsLine("Jeff Shaw"); -addCreditsLine("Jeff Streeter"); -addCreditsLine("Jeff Tom"); -addCreditsLine("Jeffrey A. Tindle"); -addCreditsLine("Jeffrey Rudolph"); -addCreditsLine("Jelle Twerda"); -addCreditsLine("Jens Larsson"); -addCreditsLine("Jeppe Christensen"); -addCreditsLine("Jeremy Burke"); -addCreditsLine("Jeremy Chookas"); -addCreditsLine("Jeremy Klemm"); -addCreditsLine("Jeremy Rogers"); -addCreditsLine("Jeremy Werkheiser"); -addCreditsLine("Jeroen Rasschaert"); -addCreditsLine("Jerry Annin"); -addCreditsLine("Jerry Holkins"); -addCreditsLine("Jerry Qassar"); -addCreditsLine("Jesse Maher"); -addCreditsLine("Jesse Smith"); -addCreditsLine("Jim Andrews"); -addCreditsLine("Jim Dale"); -addCreditsLine("Jim Gosney"); -addCreditsLine("Jim Richardson"); -addCreditsLine("Jimmy Chandler"); -addCreditsLine("Jimmy van der Have"); -addCreditsLine("Joe Diamond"); -addCreditsLine("Joe Dopp"); -addCreditsLine("Joe Downs"); -addCreditsLine("Joe Falcomata"); -addCreditsLine("Joe Kennedy"); -addCreditsLine("Joe Mauga"); -addCreditsLine("Joe McGuire"); -addCreditsLine("Joe Prowell"); -addCreditsLine("Joe Seifert"); -addCreditsLine("Joel Bruick"); -addCreditsLine("Joern Schnautz"); -addCreditsLine("Joey Snailham"); -addCreditsLine("Johan Köhne"); -addCreditsLine("John Bialick"); -addCreditsLine("John Buckingham"); -addCreditsLine("John Burnett"); -addCreditsLine("John Cain"); -addCreditsLine("John Colin Hanna"); -addCreditsLine("John Davis"); -addCreditsLine("John DeBruyn"); -addCreditsLine("John Dodds"); -addCreditsLine("John Finér"); -addCreditsLine("John Hazelden"); -addCreditsLine("John Hemaloto"); -addCreditsLine("John K. Ogi"); -addCreditsLine("John Kilmartin"); -addCreditsLine("John Kok Chung Yoong"); -addCreditsLine("John Mattison"); -addCreditsLine("John Nielsen"); -addCreditsLine("John Reque"); -addCreditsLine("John Rodriguez"); -addCreditsLine("John Tackman"); -addCreditsLine("John Titus"); -addCreditsLine("John Wolf"); -addCreditsLine("Johnny Christensen"); -addCreditsLine("Jon Callirgos"); -addCreditsLine("Jon Naiman"); -addCreditsLine("Jon Norris"); -addCreditsLine("Jon Pudge"); -addCreditsLine("Jon Simon"); -addCreditsLine("Jonas Hansen"); -addCreditsLine("Jonathan Bale"); -addCreditsLine("Jonathan Fingas"); -addCreditsLine("Jonathan Hill"); -addCreditsLine("Jonathan Hilmer"); -addCreditsLine("Jonathan Parker"); -addCreditsLine("Jonathan Peters"); -addCreditsLine("Jonathan Reed"); -addCreditsLine("Jonathan Slark"); -addCreditsLine("Jonathan W. Hebert"); -addCreditsLine("Jonathan Whitehouse"); -addCreditsLine("Jone Kajan"); -addCreditsLine("Jordan Cheetin"); -addCreditsLine("Jordan Mercier"); -addCreditsLine("Joscha Dzielak"); -addCreditsLine("Jose Magana"); -addCreditsLine("Josef Jahn"); -addCreditsLine("Joseph Downs"); -addCreditsLine("Joseph Liu"); -addCreditsLine("Joseph Walling"); -addCreditsLine("Josh Hoey"); -addCreditsLine("Joshua Geary"); -addCreditsLine("Juan Pablo Erices"); -addCreditsLine("Jurgen De Vos"); -addCreditsLine("Justin Darity"); -addCreditsLine("Justin Forward"); -addCreditsLine("Justin Meske"); -addCreditsLine("Justin Talley"); -addCreditsLine("Karen Cobb"); -addCreditsLine("Karen Holland"); -addCreditsLine("Kar-Hai Chu"); -addCreditsLine("Kari Gardner"); -addCreditsLine("Karl Heck"); -addCreditsLine("Karl Seguin"); -addCreditsLine("Karre Knudsen"); -addCreditsLine("Keith Allen Brown"); -addCreditsLine("Keith Hampe"); -addCreditsLine("Keith Lehman"); -addCreditsLine("Keith Lu"); -addCreditsLine("Kelly Christians"); -addCreditsLine("Kelvin Kim"); -addCreditsLine("Ken Herritt"); -addCreditsLine("Ken Holst"); -addCreditsLine("Kenneth Goh"); -addCreditsLine("Kenric Tam"); -addCreditsLine("Kent Daniels"); -addCreditsLine("Kenzo Iwanaga"); -addCreditsLine("Keoni van't Groenewout"); -addCreditsLine("Kevin Christian"); -addCreditsLine("Kevin Fuhst"); -addCreditsLine("Kevin Lee"); -addCreditsLine("Kevin Middleton"); -addCreditsLine("Kevin R. McGaffey"); -addCreditsLine("Kevin Rank"); -addCreditsLine("Kevin Tanghe"); -addCreditsLine("Kibeom Song"); -addCreditsLine("Kim Anderson"); -addCreditsLine("Kim Dae Uk"); -addCreditsLine("Kishan Shri"); -addCreditsLine("Kody Dickerson"); -addCreditsLine("Kohei Iwanaga"); -addCreditsLine("Kolya Rice"); -addCreditsLine("Kris Bugbee"); -addCreditsLine("Kris Thomson"); -addCreditsLine("Kristian Christensen"); -addCreditsLine("Kristo Kurtén"); -addCreditsLine("Kurt Sund"); -addCreditsLine("Kwabena Otchere"); -addCreditsLine("Kyle Doris"); -addCreditsLine("Kyle Godfrey"); -addCreditsLine("Kyle Job"); -addCreditsLine("Kyle Leveque"); -addCreditsLine("Kyle Morrison"); -addCreditsLine("Lance Tegner"); -addCreditsLine("Lars Jelstad"); -addCreditsLine("Laura Schreiner"); -addCreditsLine("Lawrence Chung"); -addCreditsLine("Lawrence Jupina"); -addCreditsLine("Lee Weaver"); -addCreditsLine("Leif Anderson"); -addCreditsLine("Leonard Pak"); -addCreditsLine("Leslie Ho Bee Chew"); -addCreditsLine("Liam Byrne"); -addCreditsLine("Lian Bredenkamp"); -addCreditsLine("Lim Eui Taek"); -addCreditsLine("Liviu Stan"); -addCreditsLine("Lon Chen"); -addCreditsLine("Lord Olav Rekve III"); -addCreditsLine("Loren Oldham"); -addCreditsLine("Lorne Laliberte"); -addCreditsLine("Louie Ramones"); -addCreditsLine("Lucas Goodwin"); -addCreditsLine("Lucas Tvrdik"); -addCreditsLine("Luis Zapata"); -addCreditsLine("Luiz Ricardo Malheiros"); -addCreditsLine("Luke McBeath"); -addCreditsLine("Manu De Gersem"); -addCreditsLine("Marc Broekhoven"); -addCreditsLine("Marc Bunin"); -addCreditsLine("Marc Chang"); -addCreditsLine("Marc Cobelens"); -addCreditsLine("Marc Elvy"); -addCreditsLine("Marc Rehder"); -addCreditsLine("Marco Amato"); -addCreditsLine("Marco Casati"); -addCreditsLine("Marcus Hurst"); -addCreditsLine("Marcus Miller"); -addCreditsLine("Mariano Porta"); -addCreditsLine("Mario Batlle"); -addCreditsLine("Mario Olivier"); -addCreditsLine("Maritza Kvalsvik"); -addCreditsLine("Marius Andre Aasly"); -addCreditsLine("Mark Brieden"); -addCreditsLine("Mark Caldwell"); -addCreditsLine("Mark de Jong"); -addCreditsLine("Mark Dickenson"); -addCreditsLine("Mark Fiore"); -addCreditsLine("Mark Hephner"); -addCreditsLine("Mark Siciliano"); -addCreditsLine("Mark Steurer"); -addCreditsLine("Mark Szabo"); -addCreditsLine("Mark Yocom"); -addCreditsLine("Markus Cichy"); -addCreditsLine("Markus Eisenblaetter"); -addCreditsLine("Markus Eskermo"); -addCreditsLine("Markus Roth"); -addCreditsLine("Martin Kremer"); -addCreditsLine("Martin Parker"); -addCreditsLine("Mat Bettinson"); -addCreditsLine("Mathew Zauher"); -addCreditsLine("Mathias Lindfeldt"); -addCreditsLine("Mathieu Bouchard"); -addCreditsLine("Matt Berkland"); -addCreditsLine("Matt Brunmeier"); -addCreditsLine("Matt Chandronait"); -addCreditsLine("Matt Cohen"); -addCreditsLine("Matt Collins"); -addCreditsLine("Matt Craw"); -addCreditsLine("Matt Culp"); -addCreditsLine("Matt Davis"); -addCreditsLine("Matt DeWald"); -addCreditsLine("Matt Grange"); -addCreditsLine("Matt Green"); -addCreditsLine("Matt McCall"); -addCreditsLine("Matt Timlin"); -addCreditsLine("Matt Vilcsak"); -addCreditsLine("Matt Wilson"); -addCreditsLine("Matthew A. Clarke"); -addCreditsLine("Matthew Frolick"); -addCreditsLine("Matthew Jenkins"); -addCreditsLine("Matthew Keen"); -addCreditsLine("Matthew Keith"); -addCreditsLine("Matthew McKeown"); -addCreditsLine("Matthew Williams"); -addCreditsLine("Matthias Schneidt"); -addCreditsLine("Maurice Kambach"); -addCreditsLine("Maurice Tan"); -addCreditsLine("Mauro Artou"); -addCreditsLine("Max Robins"); -addCreditsLine("Melissa Webb"); -addCreditsLine("Meredith Marine"); -addCreditsLine("Michael A Pratt"); -addCreditsLine("Michael Carroll"); -addCreditsLine("Michael Dunne"); -addCreditsLine("Michael Ennis"); -addCreditsLine("Michael Hamlett"); -addCreditsLine("Michael Jacovina"); -addCreditsLine("Michael Johnston"); -addCreditsLine("Michael Kenney"); -addCreditsLine("Michael Parks"); -addCreditsLine("Michael Strong"); -addCreditsLine("Michael Tan It Han"); -addCreditsLine("Michael Valera"); -addCreditsLine("Michael van Huystee"); -addCreditsLine("Michael Voigt"); -addCreditsLine("Michael Waldvogle"); -addCreditsLine("Michael Wichter"); -addCreditsLine("Michael Thornton"); -addCreditsLine("Mickey Borchardt"); -addCreditsLine("Miguel Schneeberger"); -addCreditsLine("Mika Hyvonen"); -addCreditsLine("Mikael Garde Nielsen"); -addCreditsLine("Mike Benton"); -addCreditsLine("Mike Burton"); -addCreditsLine("Mike Comroe"); -addCreditsLine("Mike Cutillo"); -addCreditsLine("Mike Dally"); -addCreditsLine("Mike Fedorov"); -addCreditsLine("Mike Hillebrecht"); -addCreditsLine("Mike Large"); -addCreditsLine("Mike Leeder"); -addCreditsLine("Mike Mann"); -addCreditsLine("Mike Plavin"); -addCreditsLine("Mike Ransom"); -addCreditsLine("Mike Swanson"); -addCreditsLine("Mike Weiss"); -addCreditsLine("Mikkel Johansen"); -addCreditsLine("Ming Jack Po"); -addCreditsLine("Minos Dounias"); -addCreditsLine("Moonja Choi"); -addCreditsLine("Morghan Laswell"); -addCreditsLine("Motohiko Kimura"); -addCreditsLine("Moussa Khan"); -addCreditsLine("Myles Angell"); -addCreditsLine("N. David Griffin"); -addCreditsLine("Naoki Yokoyama"); -addCreditsLine("Nate Timperley"); -addCreditsLine("Nathan Clark"); -addCreditsLine("Nathan Sweet"); -addCreditsLine("Neal Sample"); -addCreditsLine("Neale Guy"); -addCreditsLine("Neil Crabaugh"); -addCreditsLine("Neil Witkin"); -addCreditsLine("Nelson Billedo"); -addCreditsLine("Nemar Velasquez"); -addCreditsLine("Niall Chadwick"); -addCreditsLine("Nic Minnis"); -addCreditsLine("Nicholas Chea"); -addCreditsLine("Nicholas Paufler"); -addCreditsLine("Nick Berthet"); -addCreditsLine("Nick Bogolyubov"); -addCreditsLine("Nick Carr"); -addCreditsLine("Nick Goebel"); -addCreditsLine("Nick Martini"); -addCreditsLine("Nick Orlich"); -addCreditsLine("Nick Petska"); -addCreditsLine("Nick Rose"); -addCreditsLine("Nick S. Pasto"); -addCreditsLine("Nico Schlichting"); -addCreditsLine("Nicolas Roux"); -addCreditsLine("Niklas Westerlund"); -addCreditsLine("Nikolai Sagun"); -addCreditsLine("Octavian Busuioc"); -addCreditsLine("Ola Olsson"); -addCreditsLine("Olivier Roulx"); -addCreditsLine("Omar Yehia"); -addCreditsLine("Or Yerushalmi"); -addCreditsLine("Orlando Rojas"); -addCreditsLine("Oscar Bossi"); -addCreditsLine("P. Bryan Edge-Salois"); -addCreditsLine("P.J. Allen"); -addCreditsLine("Pamela A. Holmberg"); -addCreditsLine("Pamela McClean"); -addCreditsLine("Paolo Neé"); -addCreditsLine("Paolo Petrini"); -addCreditsLine("Pär Nordenstam"); -addCreditsLine("Pascal Buettikofer"); -addCreditsLine("Pascal Woudenberg"); -addCreditsLine("Pat Callahan"); -addCreditsLine("Pat Donovan"); -addCreditsLine("Patricio Foieri"); -addCreditsLine("Patrick Bryant"); -addCreditsLine("Patrick Fitzsimons"); -addCreditsLine("Patrick Kramer"); -addCreditsLine("Patrick Peters"); -addCreditsLine("Patrick Thomas"); -addCreditsLine("Patrick Zerr"); -addCreditsLine("Patrizia Bischof"); -addCreditsLine("Paul Adriance"); -addCreditsLine("Paul Barnes"); -addCreditsLine("Paul Doucet"); -addCreditsLine("Paul Grimes"); -addCreditsLine("Paul Hormis"); -addCreditsLine("Paul J. Paella"); -addCreditsLine("Paul Jeacock"); -addCreditsLine("Paul Magyar"); -addCreditsLine("Paul McClelland"); -addCreditsLine("Paul Morris"); -addCreditsLine("Paul Polzer"); -addCreditsLine("Paul Prestopnik"); -addCreditsLine("Paul Ruhan"); -addCreditsLine("Paul Tousignant"); -addCreditsLine("Paul Warren"); -addCreditsLine("Paul Wedgwood"); -addCreditsLine("Paul Williams"); -addCreditsLine("Paul Wright"); -addCreditsLine("Penny Miller"); -addCreditsLine("Per Kristiansen"); -addCreditsLine("Per Vestersgaard-Andersen"); -addCreditsLine("Pete Harris"); -addCreditsLine("Peter Baker"); -addCreditsLine("Peter Brindöpke"); -addCreditsLine("Peter Brock Madsen"); -addCreditsLine("Peter Davis"); -addCreditsLine("Peter Kazmierow"); -addCreditsLine("Peter Mayberry"); -addCreditsLine("Peter Pistorius"); -addCreditsLine("Peter Romano"); -addCreditsLine("Peter Vaisvil"); -addCreditsLine("Peter Wittig"); -addCreditsLine("Petter Eriksson"); -addCreditsLine("Petteri Taipale"); -addCreditsLine("Phil & Rebecca Carey"); -addCreditsLine("Phil Pappas"); -addCreditsLine("Philip Charles Maslied"); -addCreditsLine("Philip Schultz"); -addCreditsLine("Phill Curiale"); -addCreditsLine("Phillip Ervin"); -addCreditsLine("Phillip Kono"); -addCreditsLine("Phillip Ploesser"); -addCreditsLine("Phillip Stewart"); -addCreditsLine("Pöchhacker Lee"); -addCreditsLine("Prasad Galpoththawela"); -addCreditsLine("Radu Lucian"); -addCreditsLine("Rafi Zaguri"); -addCreditsLine("Ragnar Lonn"); -addCreditsLine("Ramiro Salgado Echeverria"); -addCreditsLine("Raphael Choo Boon Leck"); -addCreditsLine("Rasmus Have"); -addCreditsLine("Rene Bortko"); -addCreditsLine("Rene Wesselius"); -addCreditsLine("Ren-Wey Yang"); -addCreditsLine("Res Ngata"); -addCreditsLine("Reto Baumann"); -addCreditsLine("Ric Moseley"); -addCreditsLine("Richard Casto"); -addCreditsLine("Richard Cole"); -addCreditsLine("Richard Egglestone"); -addCreditsLine("Richard Freeouf"); -addCreditsLine("Richard Low"); -addCreditsLine("Richard McCarthy"); -addCreditsLine("Richard Shackleton"); -addCreditsLine("Richard Thurlow"); -addCreditsLine("Rick Buford"); -addCreditsLine("Ricky Fernandez"); -addCreditsLine("Rino Nielsen"); -addCreditsLine("Rob Cundiff"); -addCreditsLine("Rob Duffy"); -addCreditsLine("Rob Jones"); -addCreditsLine("Rob Rynda"); -addCreditsLine("Rob Tyre"); -addCreditsLine("Rob Weller"); -addCreditsLine("Robert Apsel"); -addCreditsLine("Robert Cass"); -addCreditsLine("Robert Hinkle"); -addCreditsLine("Robert Jahnel"); -addCreditsLine("Robert Layser"); -addCreditsLine("Robert LeBlanc"); -addCreditsLine("Robert Polzer"); -addCreditsLine("Robert Villasana"); -addCreditsLine("Roberto Toldo"); -addCreditsLine("Rocco Borg"); -addCreditsLine("Rod Chrenek"); -addCreditsLine("Rogelio Olguin"); -addCreditsLine("Roger Sewell"); -addCreditsLine("Roland Chabbey"); -addCreditsLine("Ron Anshel"); -addCreditsLine("Ronen Lazarovitch"); -addCreditsLine("Ross A. Carlson"); -addCreditsLine("Ross Carlson"); -addCreditsLine("Ross Litchfield"); -addCreditsLine("Roy Greenhalgh"); -addCreditsLine("Rozsonits László"); -addCreditsLine("Rozsonits Tibor"); -addCreditsLine("Ruben Eikeland"); -addCreditsLine("Ruben Pauwels"); -addCreditsLine("Rune Fjeld Olsen"); -addCreditsLine("Rune Håkansson"); -addCreditsLine("Rune Warhuus"); -addCreditsLine("Russ Davies"); -addCreditsLine("Russell Mein"); -addCreditsLine("Russell Thompson"); -addCreditsLine("Ryan Bailey"); -addCreditsLine("Ryan Counts"); -addCreditsLine("Ryan Gilfillan"); -addCreditsLine("Ryan Hopsecker"); -addCreditsLine("Ryan Kelly"); -addCreditsLine("Ryan Lee"); -addCreditsLine("Ryan Schoonmaker"); -addCreditsLine("Ryan Thernes"); -addCreditsLine("Sam Mackrill"); -addCreditsLine("Sam Tanis"); -addCreditsLine("Sam Whitehead"); -addCreditsLine("Samuel Heffley"); -addCreditsLine("Samuel L Jones"); -addCreditsLine("Sarah Johnstone"); -addCreditsLine("Scott Abeyta"); -addCreditsLine("Scott Allison"); -addCreditsLine("Scott Bair"); -addCreditsLine("Scott Dennis"); -addCreditsLine("Scott Egashira"); -addCreditsLine("Scott Estabrook"); -addCreditsLine("Scott Jenkins"); -addCreditsLine("Scott Kennedy"); -addCreditsLine("Scott McCulloch"); -addCreditsLine("Scott Medlin"); -addCreditsLine("Scott Miller"); -addCreditsLine("Scott Pearson"); -addCreditsLine("Scott Stahl"); -addCreditsLine("Scotty Theriot"); -addCreditsLine("Sean Brezniak"); -addCreditsLine("Sean Bryson"); -addCreditsLine("Sean Claflin"); -addCreditsLine("Sean Dawson"); -addCreditsLine("Sean Fitzsimons"); -addCreditsLine("Sean M. Davis"); -addCreditsLine("Sean Parramore"); -addCreditsLine("Sean Polzer"); -addCreditsLine("Sean Stanley"); -addCreditsLine("Sean Swayze"); -addCreditsLine("Sean Uezu"); -addCreditsLine("Sebastian Stange"); -addCreditsLine("Sebastien Guillemet"); -addCreditsLine("Sebastien Jesionka"); -addCreditsLine("Sergey Kovrov"); -addCreditsLine("Seth Buntain"); -addCreditsLine("Seth Thompson"); -addCreditsLine("Shae Pritchard-Martinez"); -addCreditsLine("Shane Beaumont"); -addCreditsLine("Shane Evans"); -addCreditsLine("Shane Froebel"); -addCreditsLine("Shane Taylor"); -addCreditsLine("Shaun Newsome"); -addCreditsLine("Shawn Christenson"); -addCreditsLine("Shelby Townsend"); -addCreditsLine("Si Donbavand"); -addCreditsLine("Simon Gooding"); -addCreditsLine("Simon Malo"); -addCreditsLine("Simon Muir"); -addCreditsLine("Simon Pedersen"); -addCreditsLine("Sing Wu"); -addCreditsLine("Sjaak Ursinus"); -addCreditsLine("Skip McIlvaine"); -addCreditsLine("Sohail Bhamani"); -addCreditsLine("Spencer Tsai"); -addCreditsLine("Stacey A Ross"); -addCreditsLine("Stan C Audle"); -addCreditsLine("Stan Ilin"); -addCreditsLine("Stan James"); -addCreditsLine("Stef Johannes Henderson"); -addCreditsLine("Stefan Grufman"); -addCreditsLine("Stefan Kiesel"); -addCreditsLine("Stefano Petrullo"); -addCreditsLine("Stefano Zanola"); -addCreditsLine("Steffen Knapp"); -addCreditsLine("Stephan Brezinsky"); -addCreditsLine("Stephen Cimprich"); -addCreditsLine("Stephen Le Petit"); -addCreditsLine("Stephen Limowski"); -addCreditsLine("Stephen Lynch"); -addCreditsLine("Stephen Summerell"); -addCreditsLine("Steve Bailey"); -addCreditsLine("Steve Batham"); -addCreditsLine("Steve Carrion"); -addCreditsLine("Steve Gibson"); -addCreditsLine("Steve Nixon"); -addCreditsLine("Steve Pompel"); -addCreditsLine("Steve Saulle"); -addCreditsLine("Steve Smith"); -addCreditsLine("Steve Stryd"); -addCreditsLine("Steve Tory"); -addCreditsLine("Steven E. Adams"); -addCreditsLine("Steven Grossman"); -addCreditsLine("Steven Kats"); -addCreditsLine("Steven Knox"); -addCreditsLine("Steven Kusewicz"); -addCreditsLine("Stewart Laufer"); -addCreditsLine("Stewart Tosh"); -addCreditsLine("Stuart Ross Robertson"); -addCreditsLine("T.J. Allard"); -addCreditsLine("Takafumi Kobayashi"); -addCreditsLine("Takashi Morikawa"); -addCreditsLine("Tal Muskal"); -addCreditsLine("Tal Nelson"); -addCreditsLine("Tan Peng Koon"); -addCreditsLine("Tanner Burgess"); -addCreditsLine("Taylor Stewart"); -addCreditsLine("Taylor Suchan"); -addCreditsLine("Teck Wong"); -addCreditsLine("Terje Alexander Barth"); -addCreditsLine("Tero Heija"); -addCreditsLine("Theresa Petersen"); -addCreditsLine("Thomas Dönnecke"); -addCreditsLine("Thomas From"); -addCreditsLine("Thomas Goemaere"); -addCreditsLine("Thomas Hardy"); -addCreditsLine("Thomas Kumpik, Jr."); -addCreditsLine("Thomas Prinz"); -addCreditsLine("Thomas R. Bissell III"); -addCreditsLine("Thomas Ribbeck"); -addCreditsLine("Tiffany Diaz"); -addCreditsLine("Tim Engelman"); -addCreditsLine("Tim Hammock"); -addCreditsLine("Tim Kautz"); -addCreditsLine("Tim ONeil"); -addCreditsLine("Tim Rider"); -addCreditsLine("Tim Smith"); -addCreditsLine("Tim Thompson"); -addCreditsLine("Tim Yeung"); -addCreditsLine("Timen Wuestman"); -addCreditsLine("Timothy C. Stanton"); -addCreditsLine("Timothy Lewis"); -addCreditsLine("Todd Northcutt"); -addCreditsLine("Todd Sjoblom"); -addCreditsLine("Tom Beijar Johansson"); -addCreditsLine("Tom Carel"); -addCreditsLine("Tom Ellis"); -addCreditsLine("Tom Fulton"); -addCreditsLine("Tom Gordon"); -addCreditsLine("Tom Roger Tranø"); -addCreditsLine("Tom Szabo"); -addCreditsLine("Tom Vogt"); -addCreditsLine("Tomi Partanen"); -addCreditsLine("Toni Ahonen"); -addCreditsLine("Tony Caskanette"); -addCreditsLine("Torbjørn Østlund"); -addCreditsLine("Travis Ramme"); -addCreditsLine("Trent Donelson"); -addCreditsLine("Trevor Lanz"); -addCreditsLine("Trevor McGuire"); -addCreditsLine("Troy H. Benson"); -addCreditsLine("Troy Lee"); -addCreditsLine("Tyler Endicott"); -addCreditsLine("Tyler Frans"); -addCreditsLine("Tyler Jacobson"); -addCreditsLine("Tyler Jensen"); -addCreditsLine("Tyler Lott"); -addCreditsLine("Uli Muller"); -addCreditsLine("Verner Fortelius"); -addCreditsLine("Vic Stelter"); -addCreditsLine("Vidar Almås Pettersen"); -addCreditsLine("Ville Halonen"); -addCreditsLine("Vincent Cunniffe"); -addCreditsLine("Vitor Coelho"); -addCreditsLine("Wai wong"); -addCreditsLine("Wasif Azmat"); -addCreditsLine("Wayne Opai"); -addCreditsLine("Wayne Tory"); -addCreditsLine("Wayne Wallace"); -addCreditsLine("Werner Pötzelberger"); -addCreditsLine("Wes Sanders"); -addCreditsLine("Will Belknap"); -addCreditsLine("Will Erickson"); -addCreditsLine("Will Preisch"); -addCreditsLine("Willem Bison"); -addCreditsLine("William Everett"); -addCreditsLine("William Goldberg"); -addCreditsLine("William Helm"); -addCreditsLine("William Houston"); -addCreditsLine("William Klimke"); -addCreditsLine("William Knop"); -addCreditsLine("William Moss"); -addCreditsLine("William Prideaux-Brune"); -addCreditsLine("William Sherriff"); -addCreditsLine("Wilson Bilkovich"); -addCreditsLine("Wing Hon Lai"); -addCreditsLine("Wu Yiheng"); -addCreditsLine("Yanai Sachs"); -addCreditsLine("YeongJin Bae"); -addCreditsLine("Yongchan Jee"); -addCreditsLine("Yves Peckstadt"); -addCreditsLine("Zach McCuin"); -addCreditsLine("Zachary Charles "); -addCreditsLine("Zachary Denholm"); -addCreditsLine("Zion Mizrahi"); -addCreditsLine("Zsolt Vincze"); -addCreditsLine(""); -addCreditsLine("Operation Big Booze"); -addCreditsLine("Phil \"Vlad\" Pappas"); -addCreditsLine("Greg \"Satan\" Romaszka"); -addCreditsLine("Steve \"Cpt.Wussie!!!\" Snow"); -addCreditsLine(""); -addCreditsLine(""); -addCreditsLine(""); -addCreditsLine(""); -addCreditsLine(""); -addCreditsLine(""); -addCreditsLine(""); -addCreditsLine(""); -addCreditsLine("So Long, and Thanks For All The Fish."); -addCreditsLine("Tribes2 Development Team", true); +// Credits list +addCreditsLine(""); +addCreditsLine(""); +addCreditsLine(""); +addCreditsLine(""); +addCreditsLine(""); +addCreditsLine(""); +addCreditsLine(""); +addCreditsLine(""); +addCreditsLine(""); +addCreditsLine(""); +addCreditsLine(""); +addCreditsLine(""); +addCreditsLine(""); +addCreditsLine("Producer/Director"); +addCreditsLine("Dave \"QIX\" Georgeson"); +addCreditsLine(""); +addCreditsLine("Associate Producer"); +addCreditsLine("Daryl \"Snow Leopard\" Nichols, Jr."); +addCreditsLine(""); +addCreditsLine("Lead Programmer"); +addCreditsLine("Mark \"Got Milk?\" Frohnmayer"); +addCreditsLine(""); +addCreditsLine("Software Engineers"); +addCreditsLine("John \"Sne/\\ker\" Alden"); +addCreditsLine("Kelly \"East\" Asay"); +addCreditsLine("Shawn \"Raf\" Eastley"); +addCreditsLine("Clark \"Shark\" Fagot"); +addCreditsLine("John \"ÜberBob\" Folliard"); +addCreditsLine("Brad \"BigDevDawg\" Heinz"); +addCreditsLine("\"Missing\" Lincoln Hutton"); +addCreditsLine("Greg \"Jett\" Lancaster"); +addCreditsLine("Dave \"Symlink\" Moore"); +addCreditsLine("Brian \"Twitch\" Ramage"); +addCreditsLine("Mitch \"Skeet\" Shaw"); +addCreditsLine("Tinman \"Kidney Thief\""); +addCreditsLine(""); +addCreditsLine("Designers"); +addCreditsLine("Eric \"Rated z\" Lanz"); +addCreditsLine("Dave \"Diamondback\" Meddish"); +addCreditsLine("Jesse \"DrAwkward\" Russell"); +addCreditsLine(""); +addCreditsLine("Art Direction"); +addCreditsLine("Craig \"jimmy\" Maitlen"); +addCreditsLine(""); +addCreditsLine("Artists"); +addCreditsLine("Robert \"Pelias Maximus\" Caracol"); +addCreditsLine("Ian \"ETCmodel02\" Christy "); +addCreditsLine("Jade \"FrankRizzo\" Dhabolt"); +addCreditsLine("Jon \"OrphanKazrak\" Lanz"); +addCreditsLine("Dave \"OldDawg\" Lauck"); +addCreditsLine("Matthew \"Rickets\" Reynolds"); +addCreditsLine("Paul \"Decoy\" Rheinfelder"); +addCreditsLine("Thomas \"TOMIN8R\" VanVelkinburgh"); +addCreditsLine(""); +addCreditsLine("Writer"); +addCreditsLine("Blake \"Hexabolic\" Hutchins"); +addCreditsLine(""); +addCreditsLine("HTML Community"); +addCreditsLine("Pat McCarthy"); +addCreditsLine("Joe Gartska"); +addCreditsLine(""); +addCreditsLine("Director of Quality Assurance"); +addCreditsLine("Gary \"Koros\" Stevens"); +addCreditsLine(""); +addCreditsLine("Compatibility Lab Supervisor"); +addCreditsLine("Pat \"3 Legged Dingo\" Callahan"); +addCreditsLine(""); +addCreditsLine("QA Supervisor, Core Game"); +addCreditsLine("Ken \"Sunshine\" Eaton"); +addCreditsLine(""); +addCreditsLine("Quality Assurance"); +addCreditsLine("Abhishake \"Harley\" Behl"); +addCreditsLine("Angus \"Chewtoy\" Campbell"); +addCreditsLine("Aaron \"Boomer1111\" Denke"); +addCreditsLine("Trent \"RabidSquirrel\" Donelson"); +addCreditsLine("Jonalee \"cHiLaKwEeN\" Gil"); +addCreditsLine("Phil \"Philtre\" Kuhlmey"); +addCreditsLine("Craig \"NEK\" Marshall"); +addCreditsLine("Sean \"Baby Emu\" Meichle"); +addCreditsLine("David \"Plik\" Peterson"); +addCreditsLine("Robert \"Mortal Wombat\" Quattrone"); +addCreditsLine("Connor \"der Todesritter\" Salisbury"); +addCreditsLine("Joe \"Callahan\" Smith"); +addCreditsLine("Mark \"SurferMark\" Storie"); +addCreditsLine("Sue \"Othello\" Ung"); +addCreditsLine("Cody \"Infirmo\" Yarbrough"); +addCreditsLine("Drew \"Mongo\" Zilm"); +addCreditsLine(""); +addCreditsLine("QA Internationalization:"); +addCreditsLine("Lloyd \"Tank\" Madden"); +addCreditsLine("Frank \"Schnack\" Matzke"); +addCreditsLine("Markus \"Beule\" Rafflenbeul"); +addCreditsLine(""); +addCreditsLine("Motion Capture Team"); +addCreditsLine("Technical Director: Troy McFarland"); +addCreditsLine("Performer: Cosmo Hom"); +addCreditsLine(""); +addCreditsLine("Digital Video Support Team"); +addCreditsLine("Director: Jim\"zootboy\" Carey"); +addCreditsLine("Sage \"3Dkid\" Freeman"); +addCreditsLine("Steve \"opticNerve\" Bradford"); +addCreditsLine("Tonya \"Agentmoody\" Stumphauzer"); +addCreditsLine("Troy \"cann n fodder\" McFarland"); +addCreditsLine("Kate \"reelBoss\" Alley"); +addCreditsLine(""); +addCreditsLine("Movie Intro"); +addCreditsLine("PBDigital, Inc."); +addCreditsLine(""); +addCreditsLine("Installer"); +addCreditsLine("Chris Mahnken"); +addCreditsLine(""); +addCreditsLine("Special Thanks"); +addCreditsLine("Mark Brenneman"); +addCreditsLine("Nels Bruckner"); +addCreditsLine("Barry Drew"); +addCreditsLine("Tim Gift"); +addCreditsLine("Gerald Harrison"); +addCreditsLine("Shannon Holder"); +addCreditsLine("Jared Keller"); +addCreditsLine("Ti Kwa"); +addCreditsLine("Joe Maruschak"); +addCreditsLine("Rick Overman"); +addCreditsLine("Helen Pai"); +addCreditsLine("Scott Rudi"); +addCreditsLine("Shawn Sharp"); +addCreditsLine("Neal Skorpen"); +addCreditsLine("Weston Tracy"); +addCreditsLine("Pete Walker"); +addCreditsLine("Maren Wyatt"); +addCreditsLine("Scott Youngblood"); +addCreditsLine(""); +addCreditsLine("zlib Development Team"); +addCreditsLine("libPNG Development Team"); + +// TR2 +addCreditsLine(""); +addCreditsLine("Team Rabbit 2"); +addCreditsLine("Codality, Inc."); +addCreditsLine(""); +addCreditsLine("Codality President/Designer"); +addCreditsLine("Michael \"KineticPoet\" Johnston"); +addCreditsLine(""); +addCreditsLine("Codality Developers"); +addCreditsLine("Dan \"daunt\" Kolta"); +addCreditsLine("Scott \"FSB-AO\" Estabrook"); +addCreditsLine(""); +addCreditsLine("Codality Sound Effects"); +addCreditsLine("John \"CObbler\" Carter"); +addCreditsLine("Buddy \"sLaM\" Pritchard"); +addCreditsLine(""); +addCreditsLine("Codality 3D Artist"); +addCreditsLine("Gregg \"illy\" Fellows"); +addCreditsLine(""); +addCreditsLine("Codality Additional Maps"); +addCreditsLine("Alan \"Nefilim\" Schwertel"); +addCreditsLine(""); +addCreditsLine("Codality 2D Artist"); +addCreditsLine("Kenneth \"SONOFMAN\" Cook"); +addCreditsLine(""); +addCreditsLine("Codality Special Thanks"); +addCreditsLine("Eric \"Special\" Chu"); +addCreditsLine("Jonathan \"Sojourn\" Parker"); +addCreditsLine("Matt \"aerobahn\" Willis"); +addCreditsLine("Taylor \"Banana Man\" Stewart"); +addCreditsLine("Team 5150"); +addCreditsLine("Team Euphoria"); +addCreditsLine("Team Imperial Elite"); +addCreditsLine(""); + +addCreditsLine("Business Unit Manager for Sierra Studios"); +addCreditsLine("Mark Hood"); +addCreditsLine(""); +addCreditsLine("Brand Manager"); +addCreditsLine("Lee Rossini"); +addCreditsLine(""); +addCreditsLine("European Brand Manager"); +addCreditsLine("Djamil Kemal"); +addCreditsLine(""); +addCreditsLine("Europe/Asia Marketing Manager"); +addCreditsLine("Michael Fuller"); +addCreditsLine(""); +addCreditsLine("Asia Brand Manager"); +addCreditsLine("Deana Erickson"); +addCreditsLine(""); +addCreditsLine("Director of Marketing"); +addCreditsLine("Koren Buckner"); +addCreditsLine(""); +addCreditsLine("VP of Marketing"); +addCreditsLine("Jim Veevaert"); +addCreditsLine(""); +addCreditsLine("Channel Promotions"); +addCreditsLine("Michael Whitehead"); +addCreditsLine(""); +addCreditsLine("Web Development Mgr."); +addCreditsLine("Guy Welch"); +addCreditsLine(""); +addCreditsLine("Marketing Assistant"); +addCreditsLine("Michael Cowan"); +addCreditsLine(""); +addCreditsLine("Public Relations Mgr."); +addCreditsLine("Hillary Crowley "); +addCreditsLine(""); +addCreditsLine("Director"); +addCreditsLine("Creative Services"); +addCreditsLine("Laura Kleinhofs "); +addCreditsLine(""); +addCreditsLine("Creative Director For"); +addCreditsLine("Creative Services"); +addCreditsLine("Brandon Walker"); +addCreditsLine(""); +addCreditsLine("Sr. Account Manager"); +addCreditsLine("Creative Services"); +addCreditsLine("Kevin Lamb"); +addCreditsLine(""); +addCreditsLine("Package Design"); +addCreditsLine("Moore Design Group"); +addCreditsLine(""); +addCreditsLine("Production Manager"); +addCreditsLine("Sheri-Lou Stannard"); +addCreditsLine(""); +addCreditsLine("Manual Layout"); +addCreditsLine("Kim McGovern"); +addCreditsLine(""); +addCreditsLine("Localization Coordinator"); +addCreditsLine("Warren Wright"); +addCreditsLine(""); +addCreditsLine("Sound Effects"); +addCreditsLine("EFX/Wilshire Studios"); +addCreditsLine("CS Productions Inc."); +addCreditsLine(""); +addCreditsLine("Voice Recording"); +addCreditsLine("Bad Animals"); +addCreditsLine(""); +addCreditsLine("Voice Processing"); +addCreditsLine("CS Productions Inc."); +addCreditsLine(""); +addCreditsLine("Music"); +addCreditsLine("Tim Clarke and Score! Studios"); +addCreditsLine(""); +addCreditsLine("Sierra On-Line Multiplayer Services"); +addCreditsLine("Aaron Hunt"); +addCreditsLine("Erik De Bonte"); +addCreditsLine("Bill Dewey"); +addCreditsLine("Colen Garoutte-Carson"); +addCreditsLine("Max Klaiser"); +addCreditsLine("Brent LaPoint"); +addCreditsLine("Neeraj Murarka"); +addCreditsLine("Mike Nicolino"); +addCreditsLine("Lee Olds"); +addCreditsLine("Ross Perez"); +addCreditsLine("Darren Robinson"); +addCreditsLine("Brian Rothstein"); +addCreditsLine("Jeff Routledge"); +addCreditsLine("Dean Webster"); +addCreditsLine("Kelly Zmak"); +addCreditsLine(""); +addCreditsLine("Voice Talent"); +addCreditsLine("John Armstrong"); +addCreditsLine("Mark Berry"); +addCreditsLine("Kiamalise Budak"); +addCreditsLine("Kymberli Colbourne"); +addCreditsLine("Craig English"); +addCreditsLine("Kit Harris"); +addCreditsLine("Jay Hopper"); +addCreditsLine("Mike Madeoy"); +addCreditsLine("Dex Manley"); +addCreditsLine("Kate Myre"); +addCreditsLine("Matt Reidy"); +addCreditsLine("Gary Schwartz"); +addCreditsLine("Jen Taylor"); +addCreditsLine(""); +addCreditsLine("Linux Port"); +addCreditsLine("Loki Software, Inc."); +addCreditsLine(""); +addCreditsLine("Loki President"); +addCreditsLine("Scott \"Highlander\" Draeker"); +addCreditsLine(""); +addCreditsLine("Linux Installer"); +addCreditsLine("Stephane \"Megastep\" Peter"); +addCreditsLine(""); +addCreditsLine("Linux Programming"); +addCreditsLine("Michael \"Briareos\" Vance"); +addCreditsLine("Joe \"TsaoTsao\" Valenzuela"); +addCreditsLine("Sam \"Hercules\" Lantinga"); +addCreditsLine(""); +addCreditsLine("Linux Q/A and Support"); +addCreditsLine("Andy \"Yoda\" Mecham"); +addCreditsLine("Mike \"Heimdall\" Phillips"); +addCreditsLine(""); +addCreditsLine("Linux Manual"); +addCreditsLine("Kayt \"Sigyn\" Sorhaindo"); +addCreditsLine(""); +addCreditsLine("Loki Artwork"); +addCreditsLine("Jason \"Pais\" Kim"); +addCreditsLine(""); +addCreditsLine("Loki System Support"); +addCreditsLine("Rafael \"Raistlin\" Barrero"); +addCreditsLine(""); +addCreditsLine("Loki Business Manager"); +addCreditsLine("Yvonne \"YDS\" De Sollar"); +addCreditsLine(""); +addCreditsLine("Loki Customer Support"); +addCreditsLine("Brandon \"Particle\" Carter"); +addCreditsLine(""); +addCreditsLine("Loki Beta Testers"); +addCreditsLine("James \"idcmp\" Atwill"); +addCreditsLine("Brandon \"bbeattie\" Beattie"); +addCreditsLine("Fionn Behrens"); +addCreditsLine("Jonathan \"Suraklyn\" Bowser"); +addCreditsLine("Patrick \"Phineas\" Calhoun"); +addCreditsLine("Wayne \"ttol\" Chang"); +addCreditsLine("Nash \"twostar\" Clemens"); +addCreditsLine("Mike \"madcat\" Delaney"); +addCreditsLine("Matthew \"DivineHawk\" Eaton"); +addCreditsLine("Rodney \"meff\" Gordon II"); +addCreditsLine("Pavan \"Phantom\" Gupta"); +addCreditsLine("Christopher \"Malkier\" Hahn"); +addCreditsLine("John \"OverCode\" Hall"); +addCreditsLine("Jesse \"Abysmal\" Hanna"); +addCreditsLine("Steven \"Ashari\" Hatfield"); +addCreditsLine("David \"NeoTron\" Hedbor"); +addCreditsLine("Matt \"malloc_master\" Helsley"); +addCreditsLine("Simon \"red_one\" Hill"); +addCreditsLine("Gareth \"3D-Guru\" Hughes"); +addCreditsLine("Zephaniah E. Hull"); +addCreditsLine("Guy \"Guido\" Hutchison"); +addCreditsLine("Joshua Kleiner"); +addCreditsLine("Geoff \"Rambo\" Lewis"); +addCreditsLine("Jason \"Deadman\" Lundy"); +addCreditsLine("Gregory \"Centove\" McLean"); +addCreditsLine("Patrick \"WormBoy\" McNeill"); +addCreditsLine("Jeff \"Judecca\" Mrochuk"); +addCreditsLine("Patrick \"linuxpunkr...\" Mullen"); +addCreditsLine("Prof. Dr. Nao"); +addCreditsLine("Jody \"Dweebs\" Newell"); +addCreditsLine("Bob \"Shapecharge\" O'Brien"); +addCreditsLine("Kyle \"JebusSaveMe\" Olsen"); +addCreditsLine("John \"joe\" Osborne"); +addCreditsLine("Chris \"Super-K\" Osgood"); +addCreditsLine("Jon \"Railroad\" Revie"); +addCreditsLine("Michael \"M00k3y\" Ritner"); +addCreditsLine("Aron \"Govt.Cheese\" Rosenberg"); +addCreditsLine("Yuri \"Mystro\" Sagalov"); +addCreditsLine("Marinus \"foser\" Schraal"); +addCreditsLine("SKILL5"); +addCreditsLine("Ryan Stotts"); +addCreditsLine("Dan \"XFree86\" Temple"); +addCreditsLine("Terry \"keerf\" Warner"); +addCreditsLine("Chris \"UmytBnxt\" Watkins"); +addCreditsLine("Michael \"themime\" Whitten"); +addCreditsLine(""); +addCreditsLine("GLSetup Team"); +addCreditsLine("Chris Hecker"); +addCreditsLine("Rob Felter"); +addCreditsLine(""); +addCreditsLine(""); +addCreditsLine("Thanks to all the wives, girlfriends and children of the hardworking Dev Team members. Your patience and sacrifice has allowed us to complete a project of which we are all tremendously proud. None of it would have been possible without you."); +addCreditsLine(""); +addCreditsLine(""); +addCreditsLine("Meta Testers"); +addCreditsLine("Alex Flagg"); +addCreditsLine("Alex \"LogRoller\" Ogilvie"); +addCreditsLine("Adam Mitter"); +addCreditsLine("Alan \"Otter\" Ragg"); +addCreditsLine("Alex \"SaGe\" Chappuis"); +addCreditsLine("Alexandre \"[cF]Alex\" Clerc-Gagnoux"); +addCreditsLine("Allen \"TheRedDread\" Drennan"); +addCreditsLine("Andreas Jalsovec"); +addCreditsLine("Anton Wiegert"); +addCreditsLine("Arden H. \"TF Pookie\" Nguyen"); +addCreditsLine("Bart \"=DB=Seven\" Smith"); +addCreditsLine("Ben \"Diox\" May"); +addCreditsLine("Ben \"Hypn0tik\" Tamler"); +addCreditsLine("Ben \"Stan\" Gray"); +addCreditsLine("Bobby \"Mogart\" Rider"); +addCreditsLine("Bodhi \"Heliometus Max\" Daher"); +addCreditsLine("Brad \"Bort\" Klann"); +addCreditsLine("Bret D. \"Bacchus\" Wilson"); +addCreditsLine("Brian \"Aftershock\" Parker"); +addCreditsLine("Carl \"Daddy\" Anderson"); +addCreditsLine("Charlie Schillberg"); +addCreditsLine("Chason \"Phantom Stranger\" Ellis"); +addCreditsLine("Chris \"Pie4Foo\" Abele"); +addCreditsLine("Chris \"Tythan\" Caviness"); +addCreditsLine("Chris \"Fubar\" Duncan"); +addCreditsLine("Christian \"S3 Crucifix\" Peth"); +addCreditsLine("Colin \"Dark Wraith\" Howitt"); +addCreditsLine("Cory \"Omega Man\" Altheide"); +addCreditsLine("\"Cowboy\" Ben Alman"); +addCreditsLine("Crystal McHale"); +addCreditsLine("Dan \"Avatar\" Lyons"); +addCreditsLine("Daniel \"|5150|Keyser\" Gallegos"); +addCreditsLine("Daniel \"Emp\" Arnold"); +addCreditsLine("Daniel \"Snaggs\" Soderstrom"); +addCreditsLine("Daniel \"Trebz\" Nolan"); +addCreditsLine("Daniel \"Wizard_TPG\" Neilsen"); +addCreditsLine("Daniel \"Shadow Mage\" Nichols"); +addCreditsLine("Daniel \"Spooger\" Patton"); +addCreditsLine("Danny \"OmegaRed\" Cotton"); +addCreditsLine("Darion \"Shadower\" Lowenstein"); +addCreditsLine("Darren \"Fidelio\" Mitchell"); +addCreditsLine("Dave \"Tycho\" Fried"); +addCreditsLine("David \"DOX\" Oxwell"); +addCreditsLine("David \"Killdawg\" DeBoer"); +addCreditsLine("David MacIntosh"); +addCreditsLine("Dean \"VolcoM\" Sykes"); +addCreditsLine("Dean Tate"); +addCreditsLine("Dennis \"Chickenboo\" Fox"); +addCreditsLine("Erik \"Mustard\" de Jong"); +addCreditsLine("Gabor \"Dezso a HUN\" Orban"); +addCreditsLine("Gabriel \"Warwitch\" David"); +addCreditsLine("Gavin \"Suds\" Henrick"); +addCreditsLine("Gino \"tAngGSI\" Gard"); +addCreditsLine("Glenn \"IcyHot\" Wisbey"); +addCreditsLine("Gregory \"Brak Panda\" Pesochin"); +addCreditsLine("Gregory \"Strife\" Hill"); +addCreditsLine("Hannes \"Cohen\" Wagner"); +addCreditsLine("Ian \"Kowboy\" Gonsalves"); +addCreditsLine("Ian Threadgold"); +addCreditsLine("J Alex \"Blackheart\" Wheeler"); +addCreditsLine("James \"Warbird\" Gentry III"); +addCreditsLine("James C. \"Lothos\" Hanna"); +addCreditsLine("Jason \"Circuit\" Jenkins"); +addCreditsLine("Jason \"Iron Chef\" Goodowens"); +addCreditsLine("Jason \"Lumberjack\" De Arte"); +addCreditsLine("Jeff \"Hellsfury\" Shaw"); +addCreditsLine("Jeremy \"Xevious\" Burke"); +addCreditsLine("Jerry \"Tycho Brahe\" Holkins"); +addCreditsLine("Joe \"Quadrature\" Downs"); +addCreditsLine("Joe Bell Grant"); +addCreditsLine("Joern \"Pangur\" Schnautz"); +addCreditsLine("John \"Dr.Jones\" Burnett"); +addCreditsLine("Jon \"Ratorasniki\" Naiman"); +addCreditsLine("Jonathan \"Chaser\" Bale"); +addCreditsLine("Joost \"jschuur\" Schuur"); +addCreditsLine("Josh \"Red Sirus\" Hoey"); +addCreditsLine("Kevin \"Rifter\" Rank"); +addCreditsLine("Kevin \"Kevlar\" Middleton"); +addCreditsLine("Kyle \"{DP}AzN^DoG\" Godfrey"); +addCreditsLine("Kyle \"Wiggy\" Bennett"); +addCreditsLine("Laura \"Dolph Lundgren\" Schreiner"); +addCreditsLine("Lorne \"Writer\" Laliberte"); +addCreditsLine("Mac \"McNaughton\" Miller"); +addCreditsLine("Mario \"Lone Gunman\" Batlle"); +addCreditsLine("Mark \"Ferret-of-Death\" Siciliano"); +addCreditsLine("Mark \"Old Skul\" Szabo"); +addCreditsLine("Mark \"Panama Jack\" Dickenson"); +addCreditsLine("Markus Rafflenbeul"); +addCreditsLine("Mat Bettinson"); +addCreditsLine("Matt \"{SiR}SoulJAH\" Culp"); +addCreditsLine("Matt \"Colosus\" DeWald"); +addCreditsLine("Matt Sobotka"); +addCreditsLine("Matthew \"4u2c\" McKeown"); +addCreditsLine("Mattijs \"3bird\" Jonker"); +addCreditsLine("Michael \"Optimizer\" Hamlett"); +addCreditsLine("Michael \"Rave\" Mogill"); +addCreditsLine("Michael A Nance"); +addCreditsLine("Michael James \"Tenabrae\" Edwards"); +addCreditsLine("Mike \"Ragman\" Hillebrecht"); +addCreditsLine("Mike \"Gabriel\" Krahulik"); +addCreditsLine("Mike \"Gangreen\" Burton"); +addCreditsLine("Moussa Khan"); +addCreditsLine("N. David \"MlakMavet\" Griffin"); +addCreditsLine("Nathan \"[HvC]NaTeDoGG\" Sweet"); +addCreditsLine("Nick \"Enhanced Panda\" Orlich"); +addCreditsLine("Nick \"Leb\" Petska"); +addCreditsLine("Nick S. \"Enlightened One\" Pasto"); +addCreditsLine("Nikita \"FSB-SPY\" Bogolyubov"); +addCreditsLine("Olivier \"[cf] OroX\" Roulx"); +addCreditsLine("Omar Yehia"); +addCreditsLine("Pamela A. \"Diva\" Holmberg"); +addCreditsLine("Paul \"RuinatioN\" Wright"); +addCreditsLine("Paul \"Teknoice\" Morris"); +addCreditsLine("Penny \"Killer Girl\" Miller"); +addCreditsLine("Peter \"dev\" Kazmierow"); +addCreditsLine("Ric \"Dr Chmod\" Moseley"); +addCreditsLine("\"NoFix\""); +addCreditsLine("Rob \"Coyote\" Duffy"); +addCreditsLine("Robert Huebner"); +addCreditsLine("Rod Chrenek"); +addCreditsLine("Ron Oliver II"); +addCreditsLine("Ross \"Bytor\" Carlson"); +addCreditsLine("Roy \"Cannonfodder\" Greenhalgh"); +addCreditsLine("Ryan \"Kelster\" Kelly"); +addCreditsLine("Ryan \"Onyxwulf\" Gilfillan"); +addCreditsLine("Ryan \"StoneWolf\" Thernes"); +addCreditsLine("Scott \"Smedly\" Medlin"); +addCreditsLine("Sean \"Pubknight\" Bryson "); +addCreditsLine("Sebastien \"[cF]PreD\" Guillemet"); +addCreditsLine("Shane \"Mental Trousers\" Taylor"); +addCreditsLine("Shane \"Santa\" Beaumont"); +addCreditsLine("Shane \"Shaneman\" Evans"); +addCreditsLine("Stefan Grufman"); +addCreditsLine("Stefan \"Skace\" Kiehne"); +addCreditsLine("Stephen \"Cato\" Farquhar"); +addCreditsLine("Stephen \"SL83\" Limowski"); +addCreditsLine("Steve \"Presto\" Eisner"); +addCreditsLine("Taylor \"Emo1313\" Suchan"); +addCreditsLine("Thomas \"Mantis\" Kumpik, Jr."); +addCreditsLine("Tim \"Zear\" Hammock"); +addCreditsLine("Todd \"Fuzzy Lumpkins\" Sjoblom"); +addCreditsLine("Tom \"Falcon\" Vogt"); +addCreditsLine("Tyler \"Raskal\" Jacobson"); +addCreditsLine("Tyler \"Sty\" Frans"); +addCreditsLine("Tyler Wilson"); +addCreditsLine("Werner Poetzelberger"); +addCreditsLine("Willem \"Talita\" Bison"); +addCreditsLine("William \"Altaic\" Knop"); +addCreditsLine(""); +addCreditsLine("Beta Testers"); +addCreditsLine("Aaron Brown"); +addCreditsLine("Aaron Butler"); +addCreditsLine("Aaron Reed"); +addCreditsLine("Aaron Scott Reed"); +addCreditsLine("Aaron Semeniuk"); +addCreditsLine("Aaron Wisner"); +addCreditsLine("Aaron Younger"); +addCreditsLine("Adam B. Argo"); +addCreditsLine("Adam Becker"); +addCreditsLine("Adam Corvin"); +addCreditsLine("Adam England"); +addCreditsLine("Adam King"); +addCreditsLine("Adam Kleifield "); +addCreditsLine("Adam McCreight"); +addCreditsLine("Adam Mitter"); +addCreditsLine("Adam S. Pedersen"); +addCreditsLine("Adam Toering"); +addCreditsLine("Adam Williams"); +addCreditsLine("Adrian Telfer"); +addCreditsLine("Akihiro Inoue"); +addCreditsLine("Al Harrington"); +addCreditsLine("Alan Peng"); +addCreditsLine("Alan Ragg"); +addCreditsLine("Alayton Norgard"); +addCreditsLine("Alberto Petrozzi"); +addCreditsLine("Alden Tan"); +addCreditsLine("Alex Chappuis"); +addCreditsLine("Alex Flagg"); +addCreditsLine("Alex Gourley"); +addCreditsLine("Alex Jakes JR"); +addCreditsLine("Alex Jeng"); +addCreditsLine("Alex Ogilvie"); +addCreditsLine("Alex Porter"); +addCreditsLine("Alex Taylor"); +addCreditsLine("Alex Zanfir"); +addCreditsLine("Alexander Baldoria"); +addCreditsLine("Alexander Flagg"); +addCreditsLine("Alexander Marschal"); +addCreditsLine("Alexander van Rijn"); +addCreditsLine("Alexandr Koshelev"); +addCreditsLine("Alexandre Clerc-Gagnoux"); +addCreditsLine("Alexandre Pomi"); +addCreditsLine("Alexandre Ramos"); +addCreditsLine("Alexei Sapsford"); +addCreditsLine("Allen Drennan"); +addCreditsLine("Allen Grusecki"); +addCreditsLine("Amir Assali"); +addCreditsLine("Amir Grad"); +addCreditsLine("Anatoly Ropotov"); +addCreditsLine("Andre Koch"); +addCreditsLine("Andrea Primadei"); +addCreditsLine("Andreas Leondidis"); +addCreditsLine("Andrew Baum"); +addCreditsLine("Andrew Fort"); +addCreditsLine("Andrew Price"); +addCreditsLine("Andrew Stockman"); +addCreditsLine("Andy Chong"); +addCreditsLine("Andy Swanson"); +addCreditsLine("Angus Campbell"); +addCreditsLine("Anthony Bermudez"); +addCreditsLine("Anthony Mills"); +addCreditsLine("Antonio Ferrari"); +addCreditsLine("Antti Hätinen"); +addCreditsLine("Arden H Nguyen"); +addCreditsLine("Arthur Troncoso"); +addCreditsLine("Ata Yavalar"); +addCreditsLine("Attila Fur"); +addCreditsLine("Audie Martin"); +addCreditsLine("Barbara J. Webb"); +addCreditsLine("Baret Julien"); +addCreditsLine("Baron Wolt"); +addCreditsLine("Bart Haesaerts"); +addCreditsLine("Bart Maegh"); +addCreditsLine("Bart Peiren"); +addCreditsLine("Bart Smith"); +addCreditsLine("Bart Waeterschoot"); +addCreditsLine("Beau Hale"); +addCreditsLine("Ben Anderson"); +addCreditsLine("Ben Cantwell"); +addCreditsLine("Ben Cuthbert"); +addCreditsLine("Ben De Decker"); +addCreditsLine("Ben Dobbs"); +addCreditsLine("Ben Floren"); +addCreditsLine("Ben Gray"); +addCreditsLine("Ben Lawton"); +addCreditsLine("Ben Martel"); +addCreditsLine("Ben May"); +addCreditsLine("Ben Pierson"); +addCreditsLine("Ben Stone"); +addCreditsLine("Ben Tamler"); +addCreditsLine("Benjamin Alman"); +addCreditsLine("Benjamin Denholm"); +addCreditsLine("Benjamin Luck"); +addCreditsLine("Benoît Dewaele"); +addCreditsLine("Bernd Berheide"); +addCreditsLine("Bernhard Seiser"); +addCreditsLine("Bill Eccleston"); +addCreditsLine("Bill Lewis"); +addCreditsLine("Bill Rodenbaugh"); +addCreditsLine("Bjorn Sleypen"); +addCreditsLine("Bo McCoy"); +addCreditsLine("Bodhi Daher"); +addCreditsLine("Boris Stock"); +addCreditsLine("Brad Butcher"); +addCreditsLine("Brad Conner"); +addCreditsLine("Brad DeLong"); +addCreditsLine("Brad Goehring"); +addCreditsLine("Brad Herman"); +addCreditsLine("Brad Klann"); +addCreditsLine("Bram Noëz"); +addCreditsLine("Brandon Cantrell"); +addCreditsLine("Brandon Knez"); +addCreditsLine("Brandon W. Easley"); +addCreditsLine("Brandy Straatman"); +addCreditsLine("Bret D. Wilson"); +addCreditsLine("Brett Carlson"); +addCreditsLine("Bri Pas"); +addCreditsLine("Brian Barnes"); +addCreditsLine("Brian Charles Moses"); +addCreditsLine("Brian Helms"); +addCreditsLine("Brian Hon"); +addCreditsLine("Brian Lorey"); +addCreditsLine("Brian Mercer"); +addCreditsLine("Brian Nakash"); +addCreditsLine("Brian Parker"); +addCreditsLine("Brian Vitale"); +addCreditsLine("Brian Walsh"); +addCreditsLine("Brian Weberling"); +addCreditsLine("Brian Wright"); +addCreditsLine("Brice Gharst"); +addCreditsLine("Brion Miller"); +addCreditsLine("Bruce Oberleitner"); +addCreditsLine("Bryan Heard"); +addCreditsLine("Bryan Stroop"); +addCreditsLine("Buddy Pritchard"); +addCreditsLine("C. Henrique Olifiers"); +addCreditsLine("C. Kyle Bennett"); +addCreditsLine("C.D. Thurman"); +addCreditsLine("Caleb Cauthon"); +addCreditsLine("Camere Danilo"); +addCreditsLine("Camille Castel"); +addCreditsLine("Carl Anderson"); +addCreditsLine("Carl Andersson"); +addCreditsLine("Carl Buckley"); +addCreditsLine("Carl Chambers"); +addCreditsLine("Carla Louisa Andrews"); +addCreditsLine("Carlos Delgado"); +addCreditsLine("Carolyn Manis"); +addCreditsLine("Casey O'Connor"); +addCreditsLine("Casper Lund"); +addCreditsLine("Cedric Hourcade"); +addCreditsLine("Chad Jolly"); +addCreditsLine("Channon Wong"); +addCreditsLine("Charl Theron"); +addCreditsLine("Charles Cresswell"); +addCreditsLine("Charles F. Gast"); +addCreditsLine("Charles Koelemay"); +addCreditsLine("Charlie VanDyke"); +addCreditsLine("Chason Ellis"); +addCreditsLine("Choi Byeong-Ho"); +addCreditsLine("Chow Yun"); +addCreditsLine("Chris Abele"); +addCreditsLine("Chris Aster"); +addCreditsLine("Chris Becton"); +addCreditsLine("Chris Boucher"); +addCreditsLine("Chris Boyd"); +addCreditsLine("Chris Browning"); +addCreditsLine("Chris Buckler"); +addCreditsLine("Chris Cacioppo"); +addCreditsLine("Chris Calande"); +addCreditsLine("Chris Cauthen"); +addCreditsLine("Chris Caviness"); +addCreditsLine("Chris Cullen"); +addCreditsLine("Chris Dettmann"); +addCreditsLine("Chris Duncan"); +addCreditsLine("Chris Farmer"); +addCreditsLine("Chris Fields"); +addCreditsLine("Chris Frederick"); +addCreditsLine("Chris Hersey"); +addCreditsLine("Chris Hewitt"); +addCreditsLine("Chris Holfeld"); +addCreditsLine("Chris Houston"); +addCreditsLine("Chris Jones"); +addCreditsLine("Chris Joyce"); +addCreditsLine("Chris Kissinger"); +addCreditsLine("Chris Mahnken"); +addCreditsLine("Chris Mermagen"); +addCreditsLine("Chris Walker"); +addCreditsLine("Chris Weatherwax"); +addCreditsLine("Chris Weeks"); +addCreditsLine("Chris Willis"); +addCreditsLine("Chris Wilson"); +addCreditsLine("Chris Youren"); +addCreditsLine("Christian D. Loftus"); +addCreditsLine("Christian Davis"); +addCreditsLine("Christian Peth"); +addCreditsLine("Christoher Rex Prangnell"); +addCreditsLine("Christoph Hagenbrock"); +addCreditsLine("Christoph Schwayer"); +addCreditsLine("Christopher Clarke"); +addCreditsLine("Christopher Donahue"); +addCreditsLine("Christopher Duffield"); +addCreditsLine("Christopher Forbes Davidson"); +addCreditsLine("Christopher Gray"); +addCreditsLine("Christopher J. Burden"); +addCreditsLine("Christopher Jones"); +addCreditsLine("Christopher Tan"); +addCreditsLine("Chuang Li-chung"); +addCreditsLine("Chuck Houlette"); +addCreditsLine("Chum Chancharadeth"); +addCreditsLine("Clarence Jones"); +addCreditsLine("Clark Bradley"); +addCreditsLine("Clay Reyer"); +addCreditsLine("Clay Taylor"); +addCreditsLine("Clayton Griffin"); +addCreditsLine("Cliff Yaun"); +addCreditsLine("Clint Gallon"); +addCreditsLine("Cody Edwards"); +addCreditsLine("Colin Howitt"); +addCreditsLine("Colin Korbelas"); +addCreditsLine("Colin Laughlin"); +addCreditsLine("Colin murray"); +addCreditsLine("Collin Theseira"); +addCreditsLine("Cory Altheide"); +addCreditsLine("Cory Hill"); +addCreditsLine("Cory Miller"); +addCreditsLine("Craig Beers"); +addCreditsLine("Craig Paterson"); +addCreditsLine("Crystal McHale"); +addCreditsLine("Curtis Campbell"); +addCreditsLine("Curtis Rock"); +addCreditsLine("Daire Garvey"); +addCreditsLine("Dallas Harris"); +addCreditsLine("Damien Webber"); +addCreditsLine("Damien Webber"); +addCreditsLine("Dan Ilan"); +addCreditsLine("Dan Kolta"); +addCreditsLine("Dan Lyons"); +addCreditsLine("Dan Peters"); +addCreditsLine("Dan Schmierer"); +addCreditsLine("Dan Sego"); +addCreditsLine("Dane Barber"); +addCreditsLine("Daniel Chenoweth"); +addCreditsLine("Daniel Costantini"); +addCreditsLine("Daniel Gallegos"); +addCreditsLine("Daniel J. Patton"); +addCreditsLine("Daniel Medini"); +addCreditsLine("Daniel Neilsen"); +addCreditsLine("Daniel Nolan"); +addCreditsLine("Daniel Palmer"); +addCreditsLine("Daniel Smith"); +addCreditsLine("Daniel Soderstrom"); +addCreditsLine("Danny Cotton"); +addCreditsLine("Danny Van Bronkhorst"); +addCreditsLine("Darion Lowenstein"); +addCreditsLine("Darko Miodrag"); +addCreditsLine("Darragh O' Toole"); +addCreditsLine("Darren Asato"); +addCreditsLine("Darren Menzies"); +addCreditsLine("Darren Mitchell"); +addCreditsLine("Darren Sorrell"); +addCreditsLine("Darren Tabor"); +addCreditsLine("Dave Benedict"); +addCreditsLine("Dave Calame"); +addCreditsLine("Dave Fried"); +addCreditsLine("Dave Schwinger"); +addCreditsLine("Dave Warner"); +addCreditsLine("Dave Wight"); +addCreditsLine("David Bonds"); +addCreditsLine("David Chubb"); +addCreditsLine("David De Boer"); +addCreditsLine("David Higgins"); +addCreditsLine("David Lindberg"); +addCreditsLine("David Liu"); +addCreditsLine("David Oxwell"); +addCreditsLine("David Paukstys"); +addCreditsLine("David Peterson"); +addCreditsLine("David Quinn"); +addCreditsLine("David Richards"); +addCreditsLine("David Stetz"); +addCreditsLine("David W. Atchley"); +addCreditsLine("Dean Sykes"); +addCreditsLine("Deffi"); +addCreditsLine("Denish Puspparajah"); +addCreditsLine("Dennis Fox"); +addCreditsLine("Dennis Goedbloed"); +addCreditsLine("Dennis Gurock"); +addCreditsLine("Dennis Oden"); +addCreditsLine("Dennis Price"); +addCreditsLine("Dennis vd Broek"); +addCreditsLine("Derek Bao"); +addCreditsLine("Derek McGee"); +addCreditsLine("Derek Millar"); +addCreditsLine("Derek Mulder"); +addCreditsLine("Derrick T. Woolworth"); +addCreditsLine("Devin Blair"); +addCreditsLine("Devin C. Glenn"); +addCreditsLine("Devin L. Ganger"); +addCreditsLine("Dimitri Gunsing"); +addCreditsLine("Dion Clapperton"); +addCreditsLine("Dirk Lambert"); +addCreditsLine("Dirk Moerenhout"); +addCreditsLine("Dominic Carus"); +addCreditsLine("Donald Ho"); +addCreditsLine("Donald Mills"); +addCreditsLine("Duncan Law"); +addCreditsLine("Duncan McLeod"); +addCreditsLine("Dustin Lesan"); +addCreditsLine("Dustin Miller"); +addCreditsLine("Dyanne Lee"); +addCreditsLine("Ed Molnar"); +addCreditsLine("Ed Sin"); +addCreditsLine("Eddie Manso"); +addCreditsLine("Eddie Pierce"); +addCreditsLine("Editorial GameSurf"); +addCreditsLine("Edric Borja"); +addCreditsLine("Eduardo Amaro"); +addCreditsLine("Edward Van Brunt"); +addCreditsLine("Elliot Naiman"); +addCreditsLine("Emanuele"); +addCreditsLine("Emiliano Saurin"); +addCreditsLine("Ephraim Brodsky"); +addCreditsLine("Erbil Salihoglu"); +addCreditsLine("Eric Bultman"); +addCreditsLine("Eric Hudzikiewicz"); +addCreditsLine("Eric Iovan"); +addCreditsLine("Eric Manko"); +addCreditsLine("Eric Ray"); +addCreditsLine("Eric Ross"); +addCreditsLine("Eric Soulvie"); +addCreditsLine("Eric Stankelis"); +addCreditsLine("Eric Takamoto"); +addCreditsLine("Eric Toledo"); +addCreditsLine("Erick Apeles"); +addCreditsLine("Erik de Jong"); +addCreditsLine("Erik Gulbrandsen"); +addCreditsLine("Ernie Page"); +addCreditsLine("Erwin Esener"); +addCreditsLine("Espen Andresen"); +addCreditsLine("Eugene Goh"); +addCreditsLine("Everett Whiteway"); +addCreditsLine("Fabian Ianigro"); +addCreditsLine("Faizaan Ghauri"); +addCreditsLine("Fiona Stevens"); +addCreditsLine("Francesco Sorrentino"); +addCreditsLine("Francis To"); +addCreditsLine("Frank Canedy"); +addCreditsLine("Frank Collins"); +addCreditsLine("Frank Hop"); +addCreditsLine("Frank McGee"); +addCreditsLine("Franz Töfferl"); +addCreditsLine("Fred Cheng"); +addCreditsLine("Fred Hill"); +addCreditsLine("Frederik Kruse Hannibal"); +addCreditsLine("Fulvio Tagliento"); +addCreditsLine("Gabe Othman"); +addCreditsLine("Gabor Orban"); +addCreditsLine("Gabriel David"); +addCreditsLine("Gary Caine"); +addCreditsLine("Gary J. Talley"); +addCreditsLine("Gary McWilliams"); +addCreditsLine("Gary Milante"); +addCreditsLine("Gary Schweisthal"); +addCreditsLine("Gavin Henrick"); +addCreditsLine("Geoff Dodd"); +addCreditsLine("Geoffrey Forman"); +addCreditsLine("George Campbell"); +addCreditsLine("George Ganas"); +addCreditsLine("George Wingard"); +addCreditsLine("Gilberto Barbicinti"); +addCreditsLine("Gino Gard"); +addCreditsLine("Glenn Reasor"); +addCreditsLine("Glenn Wisbey"); +addCreditsLine("Gordon Lee"); +addCreditsLine("Gordon Mak"); +addCreditsLine("Gordon Wilcox"); +addCreditsLine("Goty Liu"); +addCreditsLine("Greg Barnett"); +addCreditsLine("Greg Gilleland"); +addCreditsLine("Greg Habetler"); +addCreditsLine("Greg Milton"); +addCreditsLine("Greg Romaszka"); +addCreditsLine("Greg Walk"); +addCreditsLine("Gregory Hill"); +addCreditsLine("Gregory Peng"); +addCreditsLine("Gregory Pesochin"); +addCreditsLine("Greigg Stein"); +addCreditsLine("Guillaume Neron"); +addCreditsLine("Gunnar Schumann"); +addCreditsLine("Guy Mirisciotta"); +addCreditsLine("H.Yamao"); +addCreditsLine("Hamed Khoojinian"); +addCreditsLine("Hannes Wagner"); +addCreditsLine("Hans David Lemons"); +addCreditsLine("Harold Brown"); +addCreditsLine("Harry Glaser"); +addCreditsLine("Harry Kambouropoulos"); +addCreditsLine("Hashish HasnaIn"); +addCreditsLine("Heath Fischer"); +addCreditsLine("Helge Nesøen"); +addCreditsLine("Hendrik Bauer"); +addCreditsLine("Hendrik Strobel"); +addCreditsLine("Henk Schaefer"); +addCreditsLine("Henry Lee"); +addCreditsLine("Henry Martins"); +addCreditsLine("Hugh Norton-Smith"); +addCreditsLine("Hugh Spencer"); +addCreditsLine("Hunter Luisi"); +addCreditsLine("Ian Glenn"); +addCreditsLine("Ian Redden"); +addCreditsLine("Ian Threadgold"); +addCreditsLine("Igor Bachinsky"); +addCreditsLine("Issac Rosser"); +addCreditsLine("Iwan Khouw"); +addCreditsLine("J. Scott Randall"); +addCreditsLine("Jaap de Heer"); +addCreditsLine("Jack Mamais"); +addCreditsLine("Jaesson Yeo"); +addCreditsLine("James Balough"); +addCreditsLine("James Batty"); +addCreditsLine("James C. Hanna"); +addCreditsLine("James Ell"); +addCreditsLine("James Gentry III"); +addCreditsLine("James Logan"); +addCreditsLine("James Molson"); +addCreditsLine("James Ramsey"); +addCreditsLine("James Tucker"); +addCreditsLine("James Weisgerber"); +addCreditsLine("Jamie Reep"); +addCreditsLine("Jan Siarov"); +addCreditsLine("Jani Sundstrom"); +addCreditsLine("Janne Puonti"); +addCreditsLine("Jared Black"); +addCreditsLine("Jared Keller"); +addCreditsLine("Jarle Hauglum"); +addCreditsLine("Jason Alday"); +addCreditsLine("Jason Alombro"); +addCreditsLine("Jason Bergman"); +addCreditsLine("Jason Cross"); +addCreditsLine("Jason De Arte"); +addCreditsLine("Jason Fleming"); +addCreditsLine("Jason Gill"); +addCreditsLine("Jason Goodfellow"); +addCreditsLine("Jason Goodowens"); +addCreditsLine("Jason Jenkins"); +addCreditsLine("Jason Kinnear"); +addCreditsLine("Jason Kochan"); +addCreditsLine("Jason Newington"); +addCreditsLine("Jason Robert Nelson"); +addCreditsLine("Jason Widy"); +addCreditsLine("Javier Jiménez"); +addCreditsLine("Jay Johnson"); +addCreditsLine("Jay Weitekamp"); +addCreditsLine("Jeff Buckland"); +addCreditsLine("Jeff Chang"); +addCreditsLine("Jeff Day"); +addCreditsLine("Jeff Dotson"); +addCreditsLine("Jeff Drouet"); +addCreditsLine("Jeff Greth"); +addCreditsLine("Jeff Hedges"); +addCreditsLine("Jeff Lofgren"); +addCreditsLine("Jeff Shauger"); +addCreditsLine("Jeff Shaw"); +addCreditsLine("Jeff Streeter"); +addCreditsLine("Jeff Tom"); +addCreditsLine("Jeffrey A. Tindle"); +addCreditsLine("Jeffrey Rudolph"); +addCreditsLine("Jelle Twerda"); +addCreditsLine("Jens Larsson"); +addCreditsLine("Jeppe Christensen"); +addCreditsLine("Jeremy Burke"); +addCreditsLine("Jeremy Chookas"); +addCreditsLine("Jeremy Klemm"); +addCreditsLine("Jeremy Rogers"); +addCreditsLine("Jeremy Werkheiser"); +addCreditsLine("Jeroen Rasschaert"); +addCreditsLine("Jerry Annin"); +addCreditsLine("Jerry Holkins"); +addCreditsLine("Jerry Qassar"); +addCreditsLine("Jesse Maher"); +addCreditsLine("Jesse Smith"); +addCreditsLine("Jim Andrews"); +addCreditsLine("Jim Dale"); +addCreditsLine("Jim Gosney"); +addCreditsLine("Jim Richardson"); +addCreditsLine("Jimmy Chandler"); +addCreditsLine("Jimmy van der Have"); +addCreditsLine("Joe Diamond"); +addCreditsLine("Joe Dopp"); +addCreditsLine("Joe Downs"); +addCreditsLine("Joe Falcomata"); +addCreditsLine("Joe Kennedy"); +addCreditsLine("Joe Mauga"); +addCreditsLine("Joe McGuire"); +addCreditsLine("Joe Prowell"); +addCreditsLine("Joe Seifert"); +addCreditsLine("Joel Bruick"); +addCreditsLine("Joern Schnautz"); +addCreditsLine("Joey Snailham"); +addCreditsLine("Johan Köhne"); +addCreditsLine("John Bialick"); +addCreditsLine("John Buckingham"); +addCreditsLine("John Burnett"); +addCreditsLine("John Cain"); +addCreditsLine("John Colin Hanna"); +addCreditsLine("John Davis"); +addCreditsLine("John DeBruyn"); +addCreditsLine("John Dodds"); +addCreditsLine("John Finér"); +addCreditsLine("John Hazelden"); +addCreditsLine("John Hemaloto"); +addCreditsLine("John K. Ogi"); +addCreditsLine("John Kilmartin"); +addCreditsLine("John Kok Chung Yoong"); +addCreditsLine("John Mattison"); +addCreditsLine("John Nielsen"); +addCreditsLine("John Reque"); +addCreditsLine("John Rodriguez"); +addCreditsLine("John Tackman"); +addCreditsLine("John Titus"); +addCreditsLine("John Wolf"); +addCreditsLine("Johnny Christensen"); +addCreditsLine("Jon Callirgos"); +addCreditsLine("Jon Naiman"); +addCreditsLine("Jon Norris"); +addCreditsLine("Jon Pudge"); +addCreditsLine("Jon Simon"); +addCreditsLine("Jonas Hansen"); +addCreditsLine("Jonathan Bale"); +addCreditsLine("Jonathan Fingas"); +addCreditsLine("Jonathan Hill"); +addCreditsLine("Jonathan Hilmer"); +addCreditsLine("Jonathan Parker"); +addCreditsLine("Jonathan Peters"); +addCreditsLine("Jonathan Reed"); +addCreditsLine("Jonathan Slark"); +addCreditsLine("Jonathan W. Hebert"); +addCreditsLine("Jonathan Whitehouse"); +addCreditsLine("Jone Kajan"); +addCreditsLine("Jordan Cheetin"); +addCreditsLine("Jordan Mercier"); +addCreditsLine("Joscha Dzielak"); +addCreditsLine("Jose Magana"); +addCreditsLine("Josef Jahn"); +addCreditsLine("Joseph Downs"); +addCreditsLine("Joseph Liu"); +addCreditsLine("Joseph Walling"); +addCreditsLine("Josh Hoey"); +addCreditsLine("Joshua Geary"); +addCreditsLine("Juan Pablo Erices"); +addCreditsLine("Jurgen De Vos"); +addCreditsLine("Justin Darity"); +addCreditsLine("Justin Forward"); +addCreditsLine("Justin Meske"); +addCreditsLine("Justin Talley"); +addCreditsLine("Karen Cobb"); +addCreditsLine("Karen Holland"); +addCreditsLine("Kar-Hai Chu"); +addCreditsLine("Kari Gardner"); +addCreditsLine("Karl Heck"); +addCreditsLine("Karl Seguin"); +addCreditsLine("Karre Knudsen"); +addCreditsLine("Keith Allen Brown"); +addCreditsLine("Keith Hampe"); +addCreditsLine("Keith Lehman"); +addCreditsLine("Keith Lu"); +addCreditsLine("Kelly Christians"); +addCreditsLine("Kelvin Kim"); +addCreditsLine("Ken Herritt"); +addCreditsLine("Ken Holst"); +addCreditsLine("Kenneth Goh"); +addCreditsLine("Kenric Tam"); +addCreditsLine("Kent Daniels"); +addCreditsLine("Kenzo Iwanaga"); +addCreditsLine("Keoni van't Groenewout"); +addCreditsLine("Kevin Christian"); +addCreditsLine("Kevin Fuhst"); +addCreditsLine("Kevin Lee"); +addCreditsLine("Kevin Middleton"); +addCreditsLine("Kevin R. McGaffey"); +addCreditsLine("Kevin Rank"); +addCreditsLine("Kevin Tanghe"); +addCreditsLine("Kibeom Song"); +addCreditsLine("Kim Anderson"); +addCreditsLine("Kim Dae Uk"); +addCreditsLine("Kishan Shri"); +addCreditsLine("Kody Dickerson"); +addCreditsLine("Kohei Iwanaga"); +addCreditsLine("Kolya Rice"); +addCreditsLine("Kris Bugbee"); +addCreditsLine("Kris Thomson"); +addCreditsLine("Kristian Christensen"); +addCreditsLine("Kristo Kurtén"); +addCreditsLine("Kurt Sund"); +addCreditsLine("Kwabena Otchere"); +addCreditsLine("Kyle Doris"); +addCreditsLine("Kyle Godfrey"); +addCreditsLine("Kyle Job"); +addCreditsLine("Kyle Leveque"); +addCreditsLine("Kyle Morrison"); +addCreditsLine("Lance Tegner"); +addCreditsLine("Lars Jelstad"); +addCreditsLine("Laura Schreiner"); +addCreditsLine("Lawrence Chung"); +addCreditsLine("Lawrence Jupina"); +addCreditsLine("Lee Weaver"); +addCreditsLine("Leif Anderson"); +addCreditsLine("Leonard Pak"); +addCreditsLine("Leslie Ho Bee Chew"); +addCreditsLine("Liam Byrne"); +addCreditsLine("Lian Bredenkamp"); +addCreditsLine("Lim Eui Taek"); +addCreditsLine("Liviu Stan"); +addCreditsLine("Lon Chen"); +addCreditsLine("Lord Olav Rekve III"); +addCreditsLine("Loren Oldham"); +addCreditsLine("Lorne Laliberte"); +addCreditsLine("Louie Ramones"); +addCreditsLine("Lucas Goodwin"); +addCreditsLine("Lucas Tvrdik"); +addCreditsLine("Luis Zapata"); +addCreditsLine("Luiz Ricardo Malheiros"); +addCreditsLine("Luke McBeath"); +addCreditsLine("Manu De Gersem"); +addCreditsLine("Marc Broekhoven"); +addCreditsLine("Marc Bunin"); +addCreditsLine("Marc Chang"); +addCreditsLine("Marc Cobelens"); +addCreditsLine("Marc Elvy"); +addCreditsLine("Marc Rehder"); +addCreditsLine("Marco Amato"); +addCreditsLine("Marco Casati"); +addCreditsLine("Marcus Hurst"); +addCreditsLine("Marcus Miller"); +addCreditsLine("Mariano Porta"); +addCreditsLine("Mario Batlle"); +addCreditsLine("Mario Olivier"); +addCreditsLine("Maritza Kvalsvik"); +addCreditsLine("Marius Andre Aasly"); +addCreditsLine("Mark Brieden"); +addCreditsLine("Mark Caldwell"); +addCreditsLine("Mark de Jong"); +addCreditsLine("Mark Dickenson"); +addCreditsLine("Mark Fiore"); +addCreditsLine("Mark Hephner"); +addCreditsLine("Mark Siciliano"); +addCreditsLine("Mark Steurer"); +addCreditsLine("Mark Szabo"); +addCreditsLine("Mark Yocom"); +addCreditsLine("Markus Cichy"); +addCreditsLine("Markus Eisenblaetter"); +addCreditsLine("Markus Eskermo"); +addCreditsLine("Markus Roth"); +addCreditsLine("Martin Kremer"); +addCreditsLine("Martin Parker"); +addCreditsLine("Mat Bettinson"); +addCreditsLine("Mathew Zauher"); +addCreditsLine("Mathias Lindfeldt"); +addCreditsLine("Mathieu Bouchard"); +addCreditsLine("Matt Berkland"); +addCreditsLine("Matt Brunmeier"); +addCreditsLine("Matt Chandronait"); +addCreditsLine("Matt Cohen"); +addCreditsLine("Matt Collins"); +addCreditsLine("Matt Craw"); +addCreditsLine("Matt Culp"); +addCreditsLine("Matt Davis"); +addCreditsLine("Matt DeWald"); +addCreditsLine("Matt Grange"); +addCreditsLine("Matt Green"); +addCreditsLine("Matt McCall"); +addCreditsLine("Matt Timlin"); +addCreditsLine("Matt Vilcsak"); +addCreditsLine("Matt Wilson"); +addCreditsLine("Matthew A. Clarke"); +addCreditsLine("Matthew Frolick"); +addCreditsLine("Matthew Jenkins"); +addCreditsLine("Matthew Keen"); +addCreditsLine("Matthew Keith"); +addCreditsLine("Matthew McKeown"); +addCreditsLine("Matthew Williams"); +addCreditsLine("Matthias Schneidt"); +addCreditsLine("Maurice Kambach"); +addCreditsLine("Maurice Tan"); +addCreditsLine("Mauro Artou"); +addCreditsLine("Max Robins"); +addCreditsLine("Melissa Webb"); +addCreditsLine("Meredith Marine"); +addCreditsLine("Michael A Pratt"); +addCreditsLine("Michael Carroll"); +addCreditsLine("Michael Dunne"); +addCreditsLine("Michael Ennis"); +addCreditsLine("Michael Hamlett"); +addCreditsLine("Michael Jacovina"); +addCreditsLine("Michael Johnston"); +addCreditsLine("Michael Kenney"); +addCreditsLine("Michael Parks"); +addCreditsLine("Michael Strong"); +addCreditsLine("Michael Tan It Han"); +addCreditsLine("Michael Valera"); +addCreditsLine("Michael van Huystee"); +addCreditsLine("Michael Voigt"); +addCreditsLine("Michael Waldvogle"); +addCreditsLine("Michael Wichter"); +addCreditsLine("Michael Thornton"); +addCreditsLine("Mickey Borchardt"); +addCreditsLine("Miguel Schneeberger"); +addCreditsLine("Mika Hyvonen"); +addCreditsLine("Mikael Garde Nielsen"); +addCreditsLine("Mike Benton"); +addCreditsLine("Mike Burton"); +addCreditsLine("Mike Comroe"); +addCreditsLine("Mike Cutillo"); +addCreditsLine("Mike Dally"); +addCreditsLine("Mike Fedorov"); +addCreditsLine("Mike Hillebrecht"); +addCreditsLine("Mike Large"); +addCreditsLine("Mike Leeder"); +addCreditsLine("Mike Mann"); +addCreditsLine("Mike Plavin"); +addCreditsLine("Mike Ransom"); +addCreditsLine("Mike Swanson"); +addCreditsLine("Mike Weiss"); +addCreditsLine("Mikkel Johansen"); +addCreditsLine("Ming Jack Po"); +addCreditsLine("Minos Dounias"); +addCreditsLine("Moonja Choi"); +addCreditsLine("Morghan Laswell"); +addCreditsLine("Motohiko Kimura"); +addCreditsLine("Moussa Khan"); +addCreditsLine("Myles Angell"); +addCreditsLine("N. David Griffin"); +addCreditsLine("Naoki Yokoyama"); +addCreditsLine("Nate Timperley"); +addCreditsLine("Nathan Clark"); +addCreditsLine("Nathan Sweet"); +addCreditsLine("Neal Sample"); +addCreditsLine("Neale Guy"); +addCreditsLine("Neil Crabaugh"); +addCreditsLine("Neil Witkin"); +addCreditsLine("Nelson Billedo"); +addCreditsLine("Nemar Velasquez"); +addCreditsLine("Niall Chadwick"); +addCreditsLine("Nic Minnis"); +addCreditsLine("Nicholas Chea"); +addCreditsLine("Nicholas Paufler"); +addCreditsLine("Nick Berthet"); +addCreditsLine("Nick Bogolyubov"); +addCreditsLine("Nick Carr"); +addCreditsLine("Nick Goebel"); +addCreditsLine("Nick Martini"); +addCreditsLine("Nick Orlich"); +addCreditsLine("Nick Petska"); +addCreditsLine("Nick Rose"); +addCreditsLine("Nick S. Pasto"); +addCreditsLine("Nico Schlichting"); +addCreditsLine("Nicolas Roux"); +addCreditsLine("Niklas Westerlund"); +addCreditsLine("Nikolai Sagun"); +addCreditsLine("Octavian Busuioc"); +addCreditsLine("Ola Olsson"); +addCreditsLine("Olivier Roulx"); +addCreditsLine("Omar Yehia"); +addCreditsLine("Or Yerushalmi"); +addCreditsLine("Orlando Rojas"); +addCreditsLine("Oscar Bossi"); +addCreditsLine("P. Bryan Edge-Salois"); +addCreditsLine("P.J. Allen"); +addCreditsLine("Pamela A. Holmberg"); +addCreditsLine("Pamela McClean"); +addCreditsLine("Paolo Neé"); +addCreditsLine("Paolo Petrini"); +addCreditsLine("Pär Nordenstam"); +addCreditsLine("Pascal Buettikofer"); +addCreditsLine("Pascal Woudenberg"); +addCreditsLine("Pat Callahan"); +addCreditsLine("Pat Donovan"); +addCreditsLine("Patricio Foieri"); +addCreditsLine("Patrick Bryant"); +addCreditsLine("Patrick Fitzsimons"); +addCreditsLine("Patrick Kramer"); +addCreditsLine("Patrick Peters"); +addCreditsLine("Patrick Thomas"); +addCreditsLine("Patrick Zerr"); +addCreditsLine("Patrizia Bischof"); +addCreditsLine("Paul Adriance"); +addCreditsLine("Paul Barnes"); +addCreditsLine("Paul Doucet"); +addCreditsLine("Paul Grimes"); +addCreditsLine("Paul Hormis"); +addCreditsLine("Paul J. Paella"); +addCreditsLine("Paul Jeacock"); +addCreditsLine("Paul Magyar"); +addCreditsLine("Paul McClelland"); +addCreditsLine("Paul Morris"); +addCreditsLine("Paul Polzer"); +addCreditsLine("Paul Prestopnik"); +addCreditsLine("Paul Ruhan"); +addCreditsLine("Paul Tousignant"); +addCreditsLine("Paul Warren"); +addCreditsLine("Paul Wedgwood"); +addCreditsLine("Paul Williams"); +addCreditsLine("Paul Wright"); +addCreditsLine("Penny Miller"); +addCreditsLine("Per Kristiansen"); +addCreditsLine("Per Vestersgaard-Andersen"); +addCreditsLine("Pete Harris"); +addCreditsLine("Peter Baker"); +addCreditsLine("Peter Brindöpke"); +addCreditsLine("Peter Brock Madsen"); +addCreditsLine("Peter Davis"); +addCreditsLine("Peter Kazmierow"); +addCreditsLine("Peter Mayberry"); +addCreditsLine("Peter Pistorius"); +addCreditsLine("Peter Romano"); +addCreditsLine("Peter Vaisvil"); +addCreditsLine("Peter Wittig"); +addCreditsLine("Petter Eriksson"); +addCreditsLine("Petteri Taipale"); +addCreditsLine("Phil & Rebecca Carey"); +addCreditsLine("Phil Pappas"); +addCreditsLine("Philip Charles Maslied"); +addCreditsLine("Philip Schultz"); +addCreditsLine("Phill Curiale"); +addCreditsLine("Phillip Ervin"); +addCreditsLine("Phillip Kono"); +addCreditsLine("Phillip Ploesser"); +addCreditsLine("Phillip Stewart"); +addCreditsLine("Pöchhacker Lee"); +addCreditsLine("Prasad Galpoththawela"); +addCreditsLine("Radu Lucian"); +addCreditsLine("Rafi Zaguri"); +addCreditsLine("Ragnar Lonn"); +addCreditsLine("Ramiro Salgado Echeverria"); +addCreditsLine("Raphael Choo Boon Leck"); +addCreditsLine("Rasmus Have"); +addCreditsLine("Rene Bortko"); +addCreditsLine("Rene Wesselius"); +addCreditsLine("Ren-Wey Yang"); +addCreditsLine("Res Ngata"); +addCreditsLine("Reto Baumann"); +addCreditsLine("Ric Moseley"); +addCreditsLine("Richard Casto"); +addCreditsLine("Richard Cole"); +addCreditsLine("Richard Egglestone"); +addCreditsLine("Richard Freeouf"); +addCreditsLine("Richard Low"); +addCreditsLine("Richard McCarthy"); +addCreditsLine("Richard Shackleton"); +addCreditsLine("Richard Thurlow"); +addCreditsLine("Rick Buford"); +addCreditsLine("Ricky Fernandez"); +addCreditsLine("Rino Nielsen"); +addCreditsLine("Rob Cundiff"); +addCreditsLine("Rob Duffy"); +addCreditsLine("Rob Jones"); +addCreditsLine("Rob Rynda"); +addCreditsLine("Rob Tyre"); +addCreditsLine("Rob Weller"); +addCreditsLine("Robert Apsel"); +addCreditsLine("Robert Cass"); +addCreditsLine("Robert Hinkle"); +addCreditsLine("Robert Jahnel"); +addCreditsLine("Robert Layser"); +addCreditsLine("Robert LeBlanc"); +addCreditsLine("Robert Polzer"); +addCreditsLine("Robert Villasana"); +addCreditsLine("Roberto Toldo"); +addCreditsLine("Rocco Borg"); +addCreditsLine("Rod Chrenek"); +addCreditsLine("Rogelio Olguin"); +addCreditsLine("Roger Sewell"); +addCreditsLine("Roland Chabbey"); +addCreditsLine("Ron Anshel"); +addCreditsLine("Ronen Lazarovitch"); +addCreditsLine("Ross A. Carlson"); +addCreditsLine("Ross Carlson"); +addCreditsLine("Ross Litchfield"); +addCreditsLine("Roy Greenhalgh"); +addCreditsLine("Rozsonits László"); +addCreditsLine("Rozsonits Tibor"); +addCreditsLine("Ruben Eikeland"); +addCreditsLine("Ruben Pauwels"); +addCreditsLine("Rune Fjeld Olsen"); +addCreditsLine("Rune Håkansson"); +addCreditsLine("Rune Warhuus"); +addCreditsLine("Russ Davies"); +addCreditsLine("Russell Mein"); +addCreditsLine("Russell Thompson"); +addCreditsLine("Ryan Bailey"); +addCreditsLine("Ryan Counts"); +addCreditsLine("Ryan Gilfillan"); +addCreditsLine("Ryan Hopsecker"); +addCreditsLine("Ryan Kelly"); +addCreditsLine("Ryan Lee"); +addCreditsLine("Ryan Schoonmaker"); +addCreditsLine("Ryan Thernes"); +addCreditsLine("Sam Mackrill"); +addCreditsLine("Sam Tanis"); +addCreditsLine("Sam Whitehead"); +addCreditsLine("Samuel Heffley"); +addCreditsLine("Samuel L Jones"); +addCreditsLine("Sarah Johnstone"); +addCreditsLine("Scott Abeyta"); +addCreditsLine("Scott Allison"); +addCreditsLine("Scott Bair"); +addCreditsLine("Scott Dennis"); +addCreditsLine("Scott Egashira"); +addCreditsLine("Scott Estabrook"); +addCreditsLine("Scott Jenkins"); +addCreditsLine("Scott Kennedy"); +addCreditsLine("Scott McCulloch"); +addCreditsLine("Scott Medlin"); +addCreditsLine("Scott Miller"); +addCreditsLine("Scott Pearson"); +addCreditsLine("Scott Stahl"); +addCreditsLine("Scotty Theriot"); +addCreditsLine("Sean Brezniak"); +addCreditsLine("Sean Bryson"); +addCreditsLine("Sean Claflin"); +addCreditsLine("Sean Dawson"); +addCreditsLine("Sean Fitzsimons"); +addCreditsLine("Sean M. Davis"); +addCreditsLine("Sean Parramore"); +addCreditsLine("Sean Polzer"); +addCreditsLine("Sean Stanley"); +addCreditsLine("Sean Swayze"); +addCreditsLine("Sean Uezu"); +addCreditsLine("Sebastian Stange"); +addCreditsLine("Sebastien Guillemet"); +addCreditsLine("Sebastien Jesionka"); +addCreditsLine("Sergey Kovrov"); +addCreditsLine("Seth Buntain"); +addCreditsLine("Seth Thompson"); +addCreditsLine("Shae Pritchard-Martinez"); +addCreditsLine("Shane Beaumont"); +addCreditsLine("Shane Evans"); +addCreditsLine("Shane Froebel"); +addCreditsLine("Shane Taylor"); +addCreditsLine("Shaun Newsome"); +addCreditsLine("Shawn Christenson"); +addCreditsLine("Shelby Townsend"); +addCreditsLine("Si Donbavand"); +addCreditsLine("Simon Gooding"); +addCreditsLine("Simon Malo"); +addCreditsLine("Simon Muir"); +addCreditsLine("Simon Pedersen"); +addCreditsLine("Sing Wu"); +addCreditsLine("Sjaak Ursinus"); +addCreditsLine("Skip McIlvaine"); +addCreditsLine("Sohail Bhamani"); +addCreditsLine("Spencer Tsai"); +addCreditsLine("Stacey A Ross"); +addCreditsLine("Stan C Audle"); +addCreditsLine("Stan Ilin"); +addCreditsLine("Stan James"); +addCreditsLine("Stef Johannes Henderson"); +addCreditsLine("Stefan Grufman"); +addCreditsLine("Stefan Kiesel"); +addCreditsLine("Stefano Petrullo"); +addCreditsLine("Stefano Zanola"); +addCreditsLine("Steffen Knapp"); +addCreditsLine("Stephan Brezinsky"); +addCreditsLine("Stephen Cimprich"); +addCreditsLine("Stephen Le Petit"); +addCreditsLine("Stephen Limowski"); +addCreditsLine("Stephen Lynch"); +addCreditsLine("Stephen Summerell"); +addCreditsLine("Steve Bailey"); +addCreditsLine("Steve Batham"); +addCreditsLine("Steve Carrion"); +addCreditsLine("Steve Gibson"); +addCreditsLine("Steve Nixon"); +addCreditsLine("Steve Pompel"); +addCreditsLine("Steve Saulle"); +addCreditsLine("Steve Smith"); +addCreditsLine("Steve Stryd"); +addCreditsLine("Steve Tory"); +addCreditsLine("Steven E. Adams"); +addCreditsLine("Steven Grossman"); +addCreditsLine("Steven Kats"); +addCreditsLine("Steven Knox"); +addCreditsLine("Steven Kusewicz"); +addCreditsLine("Stewart Laufer"); +addCreditsLine("Stewart Tosh"); +addCreditsLine("Stuart Ross Robertson"); +addCreditsLine("T.J. Allard"); +addCreditsLine("Takafumi Kobayashi"); +addCreditsLine("Takashi Morikawa"); +addCreditsLine("Tal Muskal"); +addCreditsLine("Tal Nelson"); +addCreditsLine("Tan Peng Koon"); +addCreditsLine("Tanner Burgess"); +addCreditsLine("Taylor Stewart"); +addCreditsLine("Taylor Suchan"); +addCreditsLine("Teck Wong"); +addCreditsLine("Terje Alexander Barth"); +addCreditsLine("Tero Heija"); +addCreditsLine("Theresa Petersen"); +addCreditsLine("Thomas Dönnecke"); +addCreditsLine("Thomas From"); +addCreditsLine("Thomas Goemaere"); +addCreditsLine("Thomas Hardy"); +addCreditsLine("Thomas Kumpik, Jr."); +addCreditsLine("Thomas Prinz"); +addCreditsLine("Thomas R. Bissell III"); +addCreditsLine("Thomas Ribbeck"); +addCreditsLine("Tiffany Diaz"); +addCreditsLine("Tim Engelman"); +addCreditsLine("Tim Hammock"); +addCreditsLine("Tim Kautz"); +addCreditsLine("Tim ONeil"); +addCreditsLine("Tim Rider"); +addCreditsLine("Tim Smith"); +addCreditsLine("Tim Thompson"); +addCreditsLine("Tim Yeung"); +addCreditsLine("Timen Wuestman"); +addCreditsLine("Timothy C. Stanton"); +addCreditsLine("Timothy Lewis"); +addCreditsLine("Todd Northcutt"); +addCreditsLine("Todd Sjoblom"); +addCreditsLine("Tom Beijar Johansson"); +addCreditsLine("Tom Carel"); +addCreditsLine("Tom Ellis"); +addCreditsLine("Tom Fulton"); +addCreditsLine("Tom Gordon"); +addCreditsLine("Tom Roger Tranø"); +addCreditsLine("Tom Szabo"); +addCreditsLine("Tom Vogt"); +addCreditsLine("Tomi Partanen"); +addCreditsLine("Toni Ahonen"); +addCreditsLine("Tony Caskanette"); +addCreditsLine("Torbjørn Østlund"); +addCreditsLine("Travis Ramme"); +addCreditsLine("Trent Donelson"); +addCreditsLine("Trevor Lanz"); +addCreditsLine("Trevor McGuire"); +addCreditsLine("Troy H. Benson"); +addCreditsLine("Troy Lee"); +addCreditsLine("Tyler Endicott"); +addCreditsLine("Tyler Frans"); +addCreditsLine("Tyler Jacobson"); +addCreditsLine("Tyler Jensen"); +addCreditsLine("Tyler Lott"); +addCreditsLine("Uli Muller"); +addCreditsLine("Verner Fortelius"); +addCreditsLine("Vic Stelter"); +addCreditsLine("Vidar Almås Pettersen"); +addCreditsLine("Ville Halonen"); +addCreditsLine("Vincent Cunniffe"); +addCreditsLine("Vitor Coelho"); +addCreditsLine("Wai wong"); +addCreditsLine("Wasif Azmat"); +addCreditsLine("Wayne Opai"); +addCreditsLine("Wayne Tory"); +addCreditsLine("Wayne Wallace"); +addCreditsLine("Werner Pötzelberger"); +addCreditsLine("Wes Sanders"); +addCreditsLine("Will Belknap"); +addCreditsLine("Will Erickson"); +addCreditsLine("Will Preisch"); +addCreditsLine("Willem Bison"); +addCreditsLine("William Everett"); +addCreditsLine("William Goldberg"); +addCreditsLine("William Helm"); +addCreditsLine("William Houston"); +addCreditsLine("William Klimke"); +addCreditsLine("William Knop"); +addCreditsLine("William Moss"); +addCreditsLine("William Prideaux-Brune"); +addCreditsLine("William Sherriff"); +addCreditsLine("Wilson Bilkovich"); +addCreditsLine("Wing Hon Lai"); +addCreditsLine("Wu Yiheng"); +addCreditsLine("Yanai Sachs"); +addCreditsLine("YeongJin Bae"); +addCreditsLine("Yongchan Jee"); +addCreditsLine("Yves Peckstadt"); +addCreditsLine("Zach McCuin"); +addCreditsLine("Zachary Charles "); +addCreditsLine("Zachary Denholm"); +addCreditsLine("Zion Mizrahi"); +addCreditsLine("Zsolt Vincze"); +addCreditsLine(""); +addCreditsLine("Operation Big Booze"); +addCreditsLine("Phil \"Vlad\" Pappas"); +addCreditsLine("Greg \"Satan\" Romaszka"); +addCreditsLine("Steve \"Cpt.Wussie!!!\" Snow"); +addCreditsLine(""); +addCreditsLine(""); +addCreditsLine(""); +addCreditsLine(""); +addCreditsLine(""); +addCreditsLine(""); +addCreditsLine(""); +addCreditsLine(""); +addCreditsLine("So Long, and Thanks For All The Fish."); +addCreditsLine("Tribes2 Development Team", true); diff --git a/scripts/damageTypes.cs b/scripts/damageTypes.cs index 416a5ed..4b8e30f 100644 --- a/scripts/damageTypes.cs +++ b/scripts/damageTypes.cs @@ -1,720 +1,720 @@ -//-------------------------------------------------------------------------- -// TYPES OF ALLOWED DAMAGE -//-------------------------------------------------------------------------- - -$DamageType::Default = 0; -$DamageType::Blaster = 1; -$DamageType::Plasma = 2; -$DamageType::Bullet = 3; -$DamageType::Disc = 4; -$DamageType::Grenade = 5; -$DamageType::Laser = 6; // NOTE: This value is referenced directly in code. DO NOT CHANGE! -$DamageType::ELF = 7; -$DamageType::Mortar = 8; -$DamageType::Missile = 9; -$DamageType::ShockLance = 10; -$DamageType::Mine = 11; -$DamageType::Explosion = 12; -$DamageType::Impact = 13; // Object to object collisions -$DamageType::Ground = 14; // Object to ground collisions -$DamageType::Turret = 15; - -$DamageType::PlasmaTurret = 16; -$DamageType::AATurret = 17; -$DamageType::ElfTurret = 18; -$DamageType::MortarTurret = 19; -$DamageType::MissileTurret = 20; -$DamageType::IndoorDepTurret = 21; -$DamageType::OutdoorDepTurret = 22; -$DamageType::SentryTurret = 23; - -$DamageType::OutOfBounds = 24; -$DamageType::Lava = 25; - -$DamageType::ShrikeBlaster = 26; -$DamageType::BellyTurret = 27; -$DamageType::BomberBombs = 28; -$DamageType::TankChaingun = 29; -$DamageType::TankMortar = 30; -$DamageType::SatchelCharge = 31; -$DamageType::MPBMissile = 32; -$DamageType::Lightning = 33; -$DamageType::VehicleSpawn = 34; -$DamageType::ForceFieldPowerup = 35; -$DamageType::Crash = 36; -$DamageType::Flame = 37; - -// DMM -- added so MPBs that blow up under water get a message -$DamageType::Water = 97; - -//Tinman - used in Hunters for cheap bastards ;) -$DamageType::NexusCamping = 98; - -// MES -- added so CTRL-K can get a distinctive message -$DamageType::Suicide = 99; - -// Etc, etc. - -$DamageTypeText[0] = 'default'; -$DamageTypeText[1] = 'blaster'; -$DamageTypeText[2] = 'plasma'; -$DamageTypeText[3] = 'chaingun'; -$DamageTypeText[4] = 'disc'; -$DamageTypeText[5] = 'grenade'; -$DamageTypeText[6] = 'laser'; -$DamageTypeText[7] = 'ELF'; -$DamageTypeText[8] = 'mortar'; -$DamageTypeText[9] = 'missile'; -$DamageTypeText[10] = 'shocklance'; -$DamageTypeText[11] = 'mine'; -$DamageTypeText[12] = 'explosion'; -$DamageTypeText[13] = 'impact'; -$DamageTypeText[14] = 'ground'; -$DamageTypeText[15] = 'turret'; -$DamageTypeText[16] = 'plasma turret'; -$DamageTypeText[17] = 'AA turret'; -$DamageTypeText[18] = 'ELF turret'; -$DamageTypeText[19] = 'mortar turret'; -$DamageTypeText[20] = 'missile turret'; -$DamageTypeText[21] = 'clamp turret'; -$DamageTypeText[22] = 'spike turret'; -$DamageTypeText[23] = 'sentry turret'; -$DamageTypeText[24] = 'out of bounds'; -$DamageTypeText[25] = 'lava'; -$DamageTypeText[26] = 'shrike blaster'; -$DamageTypeText[27] = 'belly turret'; -$DamageTypeText[28] = 'bomber bomb'; -$DamageTypeText[29] = 'tank chaingun'; -$DamageTypeText[30] = 'tank mortar'; -$DamageTypeText[31] = 'satchel charge'; -$DamageTypeText[32] = 'MPB missile'; -$DamageTypeText[33] = 'lighting'; -$DamageTypeText[35] = 'ForceField'; -$DamageTypeText[36] = 'Crash'; -$DamageTypeText[37] = 'flame breath'; -$DamageTypeText[98] = 'nexus camping'; -$DamageTypeText[99] = 'suicide'; - - -// ##### PLEASE DO NOT REORDER THE DAMAGE PROFILE TABLES BELOW ##### -// (They are set up in the same order as the "Weapons Matrix.xls" sheet for ease of reference when balancing) - -//---------------------------------------------------------------------------- -// VEHICLE DAMAGE PROFILES -//---------------------------------------------------------------------------- - -//**** SHRIKE SCOUT FIGHTER **** -datablock SimDataBlock(ShrikeDamageProfile) -{ - shieldDamageScale[$DamageType::Blaster] = 1.75; - shieldDamageScale[$DamageType::Bullet] = 1.75; - shieldDamageScale[$DamageType::ELF] = 1.0; - shieldDamageScale[$DamageType::ShockLance] = 0.5; - shieldDamageScale[$DamageType::Laser] = 1.0; - shieldDamageScale[$DamageType::ShrikeBlaster] = 4.0; - shieldDamageScale[$DamageType::BellyTurret] = 2.0; - shieldDamageScale[$DamageType::AATurret] = 3.0; - shieldDamageScale[$DamageType::IndoorDepTurret] = 2.5; - shieldDamageScale[$DamageType::OutdoorDepTurret] = 2.5; - shieldDamageScale[$DamageType::SentryTurret] = 2.5; - shieldDamageScale[$DamageType::Disc] = 1.5; - shieldDamageScale[$DamageType::Grenade] = 1.0; - shieldDamageScale[$DamageType::Mine] = 3.0; - shieldDamageScale[$DamageType::Missile] = 3.0; - shieldDamageScale[$DamageType::Mortar] = 2.0; - shieldDamageScale[$DamageType::Plasma] = 1.0; - shieldDamageScale[$DamageType::BomberBombs] = 3.0; - shieldDamageScale[$DamageType::TankChaingun] = 3.0; - shieldDamageScale[$DamageType::TankMortar] = 2.0; - shieldDamageScale[$DamageType::MissileTurret] = 3.0; - shieldDamageScale[$DamageType::MortarTurret] = 2.0; - shieldDamageScale[$DamageType::PlasmaTurret] = 2.0; - shieldDamageScale[$DamageType::SatchelCharge] = 3.5; - shieldDamageScale[$DamageType::Default] = 1.0; - shieldDamageScale[$DamageType::Impact] = 1.1; - shieldDamageScale[$DamageType::Ground] = 1.0; - shieldDamageScale[$DamageType::Explosion] = 3.0; - shieldDamageScale[$DamageType::Lightning] = 10.0; - - damageScale[$DamageType::Blaster] = 1.0; - damageScale[$DamageType::Bullet] = 1.0; - damageScale[$DamageType::ELF] = 0.0; - damageScale[$DamageType::ShockLance] = 0.50; - damageScale[$DamageType::Laser] = 1.0; - damageScale[$DamageType::ShrikeBlaster] = 3.5; - damageScale[$DamageType::BellyTurret] = 1.2; - damageScale[$DamageType::AATurret] = 1.5; - damageScale[$DamageType::IndoorDepTurret] = 1.5; - damageScale[$DamageType::OutdoorDepTurret] = 1.5; - damageScale[$DamageType::SentryTurret] = 1.5; - damageScale[$DamageType::Disc] = 1.25; - damageScale[$DamageType::Grenade] = 0.75; - damageScale[$DamageType::Mine] = 4.0; - damageScale[$DamageType::Missile] = 2.0; - damageScale[$DamageType::Mortar] = 2.0; - damageScale[$DamageType::Plasma] = 0.5; - damageScale[$DamageType::BomberBombs] = 2.0; - damageScale[$DamageType::TankChaingun] = 2.0; - damageScale[$DamageType::TankMortar] = 2.0; - damageScale[$DamageType::MissileTurret] = 1.5; - damageScale[$DamageType::MortarTurret] = 2.0; - damageScale[$DamageType::PlasmaTurret] = 2.0; - damageScale[$DamageType::SatchelCharge] = 3.5; - damageScale[$DamageType::Default] = 1.0; - damageScale[$DamageType::Impact] = 1.1; - damageScale[$DamageType::Ground] = 1.0; - damageScale[$DamageType::Explosion] = 2.0; - damageScale[$DamageType::Lightning] = 10.0; -}; - -//**** THUNDERSWORD BOMBER **** -datablock SimDataBlock(BomberDamageProfile) -{ - shieldDamageScale[$DamageType::Blaster] = 1.0; - shieldDamageScale[$DamageType::Bullet] = 1.0; - shieldDamageScale[$DamageType::ELF] = 1.0; - shieldDamageScale[$DamageType::ShockLance] = 0.5; - shieldDamageScale[$DamageType::Laser] = 1.0; - shieldDamageScale[$DamageType::ShrikeBlaster] = 3.5; - shieldDamageScale[$DamageType::BellyTurret] = 2.0; - shieldDamageScale[$DamageType::AATurret] = 3.0; - shieldDamageScale[$DamageType::IndoorDepTurret] = 2.25; - shieldDamageScale[$DamageType::OutdoorDepTurret] = 2.25; - shieldDamageScale[$DamageType::SentryTurret] = 2.25; - shieldDamageScale[$DamageType::Disc] = 1.0; - shieldDamageScale[$DamageType::Grenade] = 1.0; - shieldDamageScale[$DamageType::Mine] = 3.0; - shieldDamageScale[$DamageType::Missile] = 3.0; - shieldDamageScale[$DamageType::Mortar] = 2.0; - shieldDamageScale[$DamageType::Plasma] = 1.0; - shieldDamageScale[$DamageType::BomberBombs] = 3.0; - shieldDamageScale[$DamageType::TankChaingun] = 3.0; - shieldDamageScale[$DamageType::TankMortar] = 2.0; - shieldDamageScale[$DamageType::MissileTurret] = 3.0; - shieldDamageScale[$DamageType::MortarTurret] = 2.0; - shieldDamageScale[$DamageType::PlasmaTurret] = 2.0; - shieldDamageScale[$DamageType::SatchelCharge] = 3.5; - shieldDamageScale[$DamageType::Default] = 1.0; - shieldDamageScale[$DamageType::Impact] = 0.8; - shieldDamageScale[$DamageType::Ground] = 1.0; - shieldDamageScale[$DamageType::Explosion] = 3.0; - shieldDamageScale[$DamageType::Lightning] = 10.0; - - damageScale[$DamageType::Blaster] = 0.75; - damageScale[$DamageType::Bullet] = 0.75; - damageScale[$DamageType::ELF] = 0.0; - damageScale[$DamageType::ShockLance] = 0.50; - damageScale[$DamageType::Laser] = 1.0; - damageScale[$DamageType::ShrikeBlaster] = 2.5; - damageScale[$DamageType::BellyTurret] = 1.2; - damageScale[$DamageType::AATurret] = 1.5; - damageScale[$DamageType::IndoorDepTurret] = 1.25; - damageScale[$DamageType::OutdoorDepTurret] = 1.25; - damageScale[$DamageType::SentryTurret] = 1.25; - damageScale[$DamageType::Disc] = 1.0; - damageScale[$DamageType::Grenade] = 0.75; - damageScale[$DamageType::Mine] = 4.0; - damageScale[$DamageType::Missile] = 1.5; - damageScale[$DamageType::Mortar] = 2.0; - damageScale[$DamageType::Plasma] = 0.5; - damageScale[$DamageType::BomberBombs] = 2.0; - damageScale[$DamageType::TankChaingun] = 2.0; - damageScale[$DamageType::TankMortar] = 2.0; - damageScale[$DamageType::MissileTurret] = 1.5; - damageScale[$DamageType::MortarTurret] = 2.0; - damageScale[$DamageType::PlasmaTurret] = 2.0; - damageScale[$DamageType::SatchelCharge] = 3.5; - damageScale[$DamageType::Default] = 1.0; - damageScale[$DamageType::Impact] = 0.8; - damageScale[$DamageType::Ground] = 1.0; - damageScale[$DamageType::Explosion] = 2.0; - damageScale[$DamageType::Lightning] = 10.0; -}; - -//**** HAVOC TRANSPORT **** -datablock SimDataBlock(HavocDamageProfile) -{ - shieldDamageScale[$DamageType::Blaster] = 1.0; - shieldDamageScale[$DamageType::Bullet] = 1.0; - shieldDamageScale[$DamageType::ELF] = 1.0; - shieldDamageScale[$DamageType::ShockLance] = 0.5; - shieldDamageScale[$DamageType::Laser] = 1.0; - shieldDamageScale[$DamageType::ShrikeBlaster] = 3.5; - shieldDamageScale[$DamageType::BellyTurret] = 2.0; - shieldDamageScale[$DamageType::AATurret] = 3.0; - shieldDamageScale[$DamageType::IndoorDepTurret] = 2.25; - shieldDamageScale[$DamageType::OutdoorDepTurret] = 2.25; - shieldDamageScale[$DamageType::SentryTurret] = 2.25; - shieldDamageScale[$DamageType::Disc] = 1.0; - shieldDamageScale[$DamageType::Grenade] = 1.0; - shieldDamageScale[$DamageType::Mine] = 3.0; - shieldDamageScale[$DamageType::Missile] = 3.0; - shieldDamageScale[$DamageType::Mortar] = 2.0; - shieldDamageScale[$DamageType::Plasma] = 1.0; - shieldDamageScale[$DamageType::BomberBombs] = 3.0; - shieldDamageScale[$DamageType::TankChaingun] = 3.0; - shieldDamageScale[$DamageType::TankMortar] = 2.0; - shieldDamageScale[$DamageType::MissileTurret] = 3.0; - shieldDamageScale[$DamageType::MortarTurret] = 2.0; - shieldDamageScale[$DamageType::PlasmaTurret] = 2.0; - shieldDamageScale[$DamageType::SatchelCharge] = 3.5; - shieldDamageScale[$DamageType::Default] = 1.0; - shieldDamageScale[$DamageType::Impact] = 0.5; - shieldDamageScale[$DamageType::Ground] = 1.0; - shieldDamageScale[$DamageType::Explosion] = 3.0; - shieldDamageScale[$DamageType::Lightning] = 10.0; - - damageScale[$DamageType::Blaster] = 0.75; - damageScale[$DamageType::Bullet] = 0.75; - damageScale[$DamageType::ELF] = 0.0; - damageScale[$DamageType::ShockLance] = 0.50; - damageScale[$DamageType::Laser] = 1.0; - damageScale[$DamageType::ShrikeBlaster] = 2.5; - damageScale[$DamageType::BellyTurret] = 1.2; - damageScale[$DamageType::AATurret] = 1.5; - damageScale[$DamageType::IndoorDepTurret] = 1.25; - damageScale[$DamageType::OutdoorDepTurret] = 1.25; - damageScale[$DamageType::SentryTurret] = 1.25; - damageScale[$DamageType::Disc] = 1.0; - damageScale[$DamageType::Grenade] = 0.75; - damageScale[$DamageType::Mine] = 4.0; - damageScale[$DamageType::Missile] = 1.5; - damageScale[$DamageType::Mortar] = 2.0; - damageScale[$DamageType::Plasma] = 0.5; - damageScale[$DamageType::BomberBombs] = 2.0; - damageScale[$DamageType::TankChaingun] = 2.0; - damageScale[$DamageType::TankMortar] = 2.0; - damageScale[$DamageType::MissileTurret] = 1.5; - damageScale[$DamageType::MortarTurret] = 2.0; - damageScale[$DamageType::PlasmaTurret] = 2.0; - damageScale[$DamageType::SatchelCharge] = 3.5; - damageScale[$DamageType::Default] = 1.0; - damageScale[$DamageType::Impact] = 0.5; - damageScale[$DamageType::Ground] = 1.0; - damageScale[$DamageType::Explosion] = 2.0; - damageScale[$DamageType::Lightning] = 10.0; -}; - -//**** WILDCAT GRAV CYCLE **** -datablock SimDataBlock(WildcatDamageProfile) -{ - shieldDamageScale[$DamageType::Blaster] = 2.0; - shieldDamageScale[$DamageType::Bullet] = 2.5; - shieldDamageScale[$DamageType::ELF] = 1.0; - shieldDamageScale[$DamageType::ShockLance] = 1.0; - shieldDamageScale[$DamageType::Laser] = 4.0; - shieldDamageScale[$DamageType::ShrikeBlaster] = 6.0; - shieldDamageScale[$DamageType::BellyTurret] = 2.0; - shieldDamageScale[$DamageType::AATurret] = 2.0; - shieldDamageScale[$DamageType::IndoorDepTurret] = 2.5; - shieldDamageScale[$DamageType::OutdoorDepTurret] = 2.5; - shieldDamageScale[$DamageType::Disc] = 2.5; - shieldDamageScale[$DamageType::Grenade] = 2.0; - shieldDamageScale[$DamageType::Mine] = 4.0; - shieldDamageScale[$DamageType::Missile] = 4.0; - shieldDamageScale[$DamageType::Mortar] = 2.0; - shieldDamageScale[$DamageType::Plasma] = 2.0; - shieldDamageScale[$DamageType::BomberBombs] = 2.5; - shieldDamageScale[$DamageType::TankChaingun] = 3.0; - shieldDamageScale[$DamageType::TankMortar] = 2.0; - shieldDamageScale[$DamageType::MissileTurret] = 4.0; - shieldDamageScale[$DamageType::MortarTurret] = 2.0; - shieldDamageScale[$DamageType::PlasmaTurret] = 2.0; - shieldDamageScale[$DamageType::SatchelCharge] = 3.0; - shieldDamageScale[$DamageType::Default] = 1.0; - shieldDamageScale[$DamageType::Impact] = 1.25; - shieldDamageScale[$DamageType::Ground] = 1.0; - shieldDamageScale[$DamageType::Explosion] = 2.0; - shieldDamageScale[$DamageType::Lightning] = 5.0; - - damageScale[$DamageType::Blaster] = 1.5; - damageScale[$DamageType::Bullet] = 1.2; - damageScale[$DamageType::ELF] = 0.0; - damageScale[$DamageType::ShockLance] = 0.50; - damageScale[$DamageType::Laser] = 2.0; - damageScale[$DamageType::ShrikeBlaster] = 4.0; - damageScale[$DamageType::BellyTurret] = 1.5; - damageScale[$DamageType::AATurret] = 1.0; - damageScale[$DamageType::IndoorDepTurret] = 1.0; - damageScale[$DamageType::OutdoorDepTurret] = 1.0; - damageScale[$DamageType::Disc] = 1.25; - damageScale[$DamageType::Grenade] = 1.0; - damageScale[$DamageType::Mine] = 4.0; - damageScale[$DamageType::Missile] = 1.2; - damageScale[$DamageType::Mortar] = 1.0; - damageScale[$DamageType::Plasma] = 1.5; - damageScale[$DamageType::BomberBombs] = 2.0; - damageScale[$DamageType::TankChaingun] = 2.0; - damageScale[$DamageType::TankMortar] = 1.0; - damageScale[$DamageType::MissileTurret] = 1.2; - damageScale[$DamageType::MortarTurret] = 1.0; - damageScale[$DamageType::PlasmaTurret] = 1.0; - damageScale[$DamageType::SatchelCharge] = 2.2; - damageScale[$DamageType::Default] = 1.0; - damageScale[$DamageType::Impact] = 1.25; - damageScale[$DamageType::Ground] = 1.0; - damageScale[$DamageType::Explosion] = 1.0; - damageScale[$DamageType::Lightning] = 5.0; -}; - -//**** BEOWULF TANK **** -datablock SimDataBlock(TankDamageProfile) -{ - shieldDamageScale[$DamageType::Blaster] = 0.6; - shieldDamageScale[$DamageType::Bullet] = 0.75; - shieldDamageScale[$DamageType::ELF] = 1.0; - shieldDamageScale[$DamageType::ShockLance] = 0.5; - shieldDamageScale[$DamageType::Laser] = 1.0; - shieldDamageScale[$DamageType::ShrikeBlaster] = 1.75; - shieldDamageScale[$DamageType::BellyTurret] = 1.25; - shieldDamageScale[$DamageType::AATurret] = 0.8; - shieldDamageScale[$DamageType::IndoorDepTurret] = 1.0; - shieldDamageScale[$DamageType::OutdoorDepTurret] = 1.0; - shieldDamageScale[$DamageType::Disc] = 0.8; - shieldDamageScale[$DamageType::Grenade] = 0.8; - shieldDamageScale[$DamageType::Mine] = 3.25; - shieldDamageScale[$DamageType::Missile] = 2.0; - shieldDamageScale[$DamageType::Mortar] = 1.7; - shieldDamageScale[$DamageType::Plasma] = 1.0; - shieldDamageScale[$DamageType::BomberBombs] = 1.5; - shieldDamageScale[$DamageType::TankChaingun] = 1.5; - shieldDamageScale[$DamageType::TankMortar] = 1.8; - shieldDamageScale[$DamageType::MissileTurret] = 1.25; - shieldDamageScale[$DamageType::MortarTurret] = 1.0; - shieldDamageScale[$DamageType::PlasmaTurret] = 1.25; - shieldDamageScale[$DamageType::SatchelCharge] = 2.0; - shieldDamageScale[$DamageType::Default] = 1.0; - shieldDamageScale[$DamageType::Impact] = 0.75; - shieldDamageScale[$DamageType::Ground] = 0.75; - shieldDamageScale[$DamageType::Explosion] = 2.0; - shieldDamageScale[$DamageType::Lightning] = 10.0; - - damageScale[$DamageType::Blaster] = 0.75; - damageScale[$DamageType::Bullet] = 0.75; - damageScale[$DamageType::ELF] = 0.0; - damageScale[$DamageType::ShockLance] = 0.50; - damageScale[$DamageType::Laser] = 1.0; - damageScale[$DamageType::ShrikeBlaster] = 2.0; - damageScale[$DamageType::BellyTurret] = 1.0; - damageScale[$DamageType::AATurret] = 1.0; - damageScale[$DamageType::IndoorDepTurret] = 1.0; - damageScale[$DamageType::OutdoorDepTurret] = 1.0; - damageScale[$DamageType::Disc] = 1.0; - damageScale[$DamageType::Grenade] = 1.0; - damageScale[$DamageType::Mine] = 2.25; - damageScale[$DamageType::Missile] = 1.25; - damageScale[$DamageType::Mortar] = 1.4; - damageScale[$DamageType::Plasma] = 0.5; - damageScale[$DamageType::BomberBombs] = 1.0; - damageScale[$DamageType::TankChaingun] = 0.75; - damageScale[$DamageType::TankMortar] = 1.6; - damageScale[$DamageType::MissileTurret] = 1.25; - damageScale[$DamageType::MortarTurret] = 1.0; - damageScale[$DamageType::PlasmaTurret] = 1.0; - damageScale[$DamageType::SatchelCharge] = 2.0; - damageScale[$DamageType::Default] = 1.0; - damageScale[$DamageType::Impact] = 0.75; - damageScale[$DamageType::Ground] = 0.75; - damageScale[$DamageType::Explosion] = 1.0; - damageScale[$DamageType::Lightning] = 10.0; -}; - -//**** JERICHO MPB **** -datablock SimDataBlock(MPBDamageProfile) -{ - shieldDamageScale[$DamageType::Blaster] = 0.6; - shieldDamageScale[$DamageType::Bullet] = 0.75; - shieldDamageScale[$DamageType::ELF] = 1.0; - shieldDamageScale[$DamageType::ShockLance] = 0.5; - shieldDamageScale[$DamageType::Laser] = 1.0; - shieldDamageScale[$DamageType::ShrikeBlaster] = 1.75; - shieldDamageScale[$DamageType::BellyTurret] = 1.25; - shieldDamageScale[$DamageType::AATurret] = 0.8; - shieldDamageScale[$DamageType::IndoorDepTurret] = 1.0; - shieldDamageScale[$DamageType::OutdoorDepTurret] = 1.0; - shieldDamageScale[$DamageType::Disc] = 0.8; - shieldDamageScale[$DamageType::Grenade] = 0.8; - shieldDamageScale[$DamageType::Mine] = 3.25; - shieldDamageScale[$DamageType::Missile] = 2.0; - shieldDamageScale[$DamageType::Mortar] = 0.8; - shieldDamageScale[$DamageType::Plasma] = 1.0; - shieldDamageScale[$DamageType::BomberBombs] = 1.5; - shieldDamageScale[$DamageType::TankChaingun] = 1.5; - shieldDamageScale[$DamageType::TankMortar] = 1.4; - shieldDamageScale[$DamageType::MissileTurret] = 1.25; - shieldDamageScale[$DamageType::MortarTurret] = 1.0; - shieldDamageScale[$DamageType::PlasmaTurret] = 1.25; - shieldDamageScale[$DamageType::SatchelCharge] = 2.0; - shieldDamageScale[$DamageType::Default] = 1.0; - shieldDamageScale[$DamageType::Impact] = 0.5; - shieldDamageScale[$DamageType::Ground] = 0.5; - shieldDamageScale[$DamageType::Explosion] = 2.0; - shieldDamageScale[$DamageType::Lightning] = 10.0; - - damageScale[$DamageType::Blaster] = 0.75; - damageScale[$DamageType::Bullet] = 0.75; - damageScale[$DamageType::ELF] = 0.0; - damageScale[$DamageType::ShockLance] = 0.50; - damageScale[$DamageType::Laser] = 1.0; - damageScale[$DamageType::ShrikeBlaster] = 2.0; - damageScale[$DamageType::BellyTurret] = 1.0; - damageScale[$DamageType::AATurret] = 1.0; - damageScale[$DamageType::IndoorDepTurret] = 1.0; - damageScale[$DamageType::OutdoorDepTurret] = 1.0; - damageScale[$DamageType::Disc] = 1.0; - damageScale[$DamageType::Grenade] = 1.0; - damageScale[$DamageType::Mine] = 2.25; - damageScale[$DamageType::Missile] = 1.25; - damageScale[$DamageType::Mortar] = 1.0; - damageScale[$DamageType::Plasma] = 0.5; - damageScale[$DamageType::BomberBombs] = 1.0; - damageScale[$DamageType::TankChaingun] = 0.75; - damageScale[$DamageType::TankMortar] = 1.0; - damageScale[$DamageType::MissileTurret] = 1.25; - damageScale[$DamageType::MortarTurret] = 1.0; - damageScale[$DamageType::PlasmaTurret] = 1.0; - damageScale[$DamageType::SatchelCharge] = 2.0; - damageScale[$DamageType::Default] = 1.0; - damageScale[$DamageType::Impact] = 0.5; - damageScale[$DamageType::Ground] = 0.5; - damageScale[$DamageType::Explosion] = 1.0; - damageScale[$DamageType::Lightning] = 10.0; -}; - -//---------------------------------------------------------------------------- -// TURRET DAMAGE PROFILES -//---------------------------------------------------------------------------- - -datablock SimDataBlock(TurretDamageProfile) -{ - shieldDamageScale[$DamageType::Blaster] = 0.8; - shieldDamageScale[$DamageType::Bullet] = 0.8; - shieldDamageScale[$DamageType::ELF] = 1.0; - shieldDamageScale[$DamageType::ShockLance] = 0.5; - shieldDamageScale[$DamageType::Laser] = 1.0; - shieldDamageScale[$DamageType::ShrikeBlaster] = 3.0; - shieldDamageScale[$DamageType::BellyTurret] = 2.0; - shieldDamageScale[$DamageType::AATurret] = 1.0; - shieldDamageScale[$DamageType::IndoorDepTurret] = 1.0; - shieldDamageScale[$DamageType::OutdoorDepTurret] = 1.0; - shieldDamageScale[$DamageType::SentryTurret] = 1.0; - shieldDamageScale[$DamageType::Disc] = 1.0; - shieldDamageScale[$DamageType::Grenade] = 1.5; - shieldDamageScale[$DamageType::Mine] = 3.0; - shieldDamageScale[$DamageType::Missile] = 3.0; - shieldDamageScale[$DamageType::Mortar] = 3.0; - shieldDamageScale[$DamageType::Plasma] = 1.0; - shieldDamageScale[$DamageType::BomberBombs] = 2.0; - shieldDamageScale[$DamageType::TankChaingun] = 1.5; - shieldDamageScale[$DamageType::TankMortar] = 3.0; - shieldDamageScale[$DamageType::MissileTurret] = 3.0; - shieldDamageScale[$DamageType::MortarTurret] = 3.0; - shieldDamageScale[$DamageType::PlasmaTurret] = 2.0; - shieldDamageScale[$DamageType::SatchelCharge] = 4.5; - shieldDamageScale[$DamageType::Default] = 1.0; - shieldDamageScale[$DamageType::Impact] = 1.0; - shieldDamageScale[$DamageType::Ground] = 1.0; - shieldDamageScale[$DamageType::Explosion] = 2.0; - shieldDamageScale[$DamageType::Lightning] = 5.0; - - damageScale[$DamageType::Blaster] = 0.8; - damageScale[$DamageType::Bullet] = 0.9; - damageScale[$DamageType::ELF] = 0.0; - damageScale[$DamageType::ShockLance] = 0.50; - damageScale[$DamageType::Laser] = 1.0; - damageScale[$DamageType::ShrikeBlaster] = 1.0; - damageScale[$DamageType::BellyTurret] = 0.6; - damageScale[$DamageType::AATurret] = 1.0; - damageScale[$DamageType::IndoorDepTurret] = 1.0; - damageScale[$DamageType::OutdoorDepTurret] = 1.0; - damageScale[$DamageType::SentryTurret] = 1.0; - damageScale[$DamageType::Disc] = 1.1; - damageScale[$DamageType::Grenade] = 1.0; - damageScale[$DamageType::Mine] = 1.5; - damageScale[$DamageType::Missile] = 1.25; - damageScale[$DamageType::Mortar] = 1.25; - damageScale[$DamageType::Plasma] = 0.75; - damageScale[$DamageType::BomberBombs] = 1.0; - damageScale[$DamageType::TankChaingun] = 1.25; - damageScale[$DamageType::TankMortar] = 1.25; - damageScale[$DamageType::MissileTurret] = 1.25; - damageScale[$DamageType::MortarTurret] = 1.25; - damageScale[$DamageType::PlasmaTurret] = 1.25; - damageScale[$DamageType::SatchelCharge] = 1.5; - damageScale[$DamageType::Default] = 1.0; - damageScale[$DamageType::Impact] = 1.0; - damageScale[$DamageType::Ground] = 1.0; - damageScale[$DamageType::Explosion] = 1.0; - damageScale[$DamageType::Lightning] = 5.0; -}; - -//---------------------------------------------------------------------------- -// STATIC SHAPE DAMAGE PROFILES -//---------------------------------------------------------------------------- - -datablock SimDataBlock(StaticShapeDamageProfile) -{ - shieldDamageScale[$DamageType::Blaster] = 0.8; - shieldDamageScale[$DamageType::Bullet] = 1.0; - shieldDamageScale[$DamageType::ELF] = 1.0; - shieldDamageScale[$DamageType::ShockLance] = 1.0; - shieldDamageScale[$DamageType::Laser] = 1.0; - shieldDamageScale[$DamageType::ShrikeBlaster] = 2.0; - shieldDamageScale[$DamageType::BellyTurret] = 1.5; - shieldDamageScale[$DamageType::AATurret] = 1.0; - shieldDamageScale[$DamageType::IndoorDepTurret] = 1.0; - shieldDamageScale[$DamageType::OutdoorDepTurret] = 1.0; - shieldDamageScale[$DamageType::Turret] = 1.0; - shieldDamageScale[$DamageType::SentryTurret] = 1.0; - shieldDamageScale[$DamageType::Disc] = 1.0; - shieldDamageScale[$DamageType::Grenade] = 1.2; - shieldDamageScale[$DamageType::Mine] = 0.5; // z0dd - ZOD, 10/09/02. Was 2.0 - shieldDamageScale[$DamageType::Missile] = 3.0; - shieldDamageScale[$DamageType::Mortar] = 3.0; - shieldDamageScale[$DamageType::Plasma] = 1.5; - shieldDamageScale[$DamageType::BomberBombs] = 2.0; - shieldDamageScale[$DamageType::TankChaingun] = 1.5; - shieldDamageScale[$DamageType::TankMortar] = 3.0; - shieldDamageScale[$DamageType::MissileTurret] = 3.0; - shieldDamageScale[$DamageType::MortarTurret] = 3.0; - shieldDamageScale[$DamageType::PlasmaTurret] = 2.0; - shieldDamageScale[$DamageType::SatchelCharge] = 6.0; - shieldDamageScale[$DamageType::Default] = 1.0; - shieldDamageScale[$DamageType::Impact] = 1.25; - shieldDamageScale[$DamageType::Ground] = 1.0; - shieldDamageScale[$DamageType::Explosion] = 2.0; - shieldDamageScale[$DamageType::Lightning] = 5.0; - - damageScale[$DamageType::Blaster] = 1.0; - damageScale[$DamageType::Bullet] = 1.0; - damageScale[$DamageType::ELF] = 0.0; - damageScale[$DamageType::ShockLance] = 1.0; - damageScale[$DamageType::Laser] = 1.0; - damageScale[$DamageType::ShrikeBlaster] = 2.0; - damageScale[$DamageType::BellyTurret] = 1.2; - damageScale[$DamageType::AATurret] = 1.0; - damageScale[$DamageType::IndoorDepTurret] = 1.0; - damageScale[$DamageType::OutdoorDepTurret] = 1.0; - damageScale[$DamageType::SentryTurret] = 1.0; - damageScale[$DamageType::Disc] = 1.15; - damageScale[$DamageType::Grenade] = 1.2; - damageScale[$DamageType::Mine] = 0.5; // z0dd - ZOD, 10/09/02. Was 2.0 - damageScale[$DamageType::Missile] = 2.0; - damageScale[$DamageType::Mortar] = 2.0; - damageScale[$DamageType::Plasma] = 1.25; - damageScale[$DamageType::BomberBombs] = 1.0; - damageScale[$DamageType::TankChaingun] = 1.0; - damageScale[$DamageType::TankMortar] = 2.0; - damageScale[$DamageType::MissileTurret] = 2.0; - damageScale[$DamageType::MortarTurret] = 2.0; - damageScale[$DamageType::PlasmaTurret] = 2.0; - damageScale[$DamageType::SatchelCharge] = 4.0; - damageScale[$DamageType::Default] = 1.0; - damageScale[$DamageType::Impact] = 1.25; - damageScale[$DamageType::Ground] = 1.0; - damageScale[$DamageType::Explosion] = 1.0; - damageScale[$DamageType::Lightning] = 5.0; -}; - -//---------------------------------------------------------------------------- -// PLAYER DAMAGE PROFILES -//---------------------------------------------------------------------------- - -datablock SimDataBlock(LightPlayerDamageProfile) -{ - damageScale[$DamageType::Blaster] = 1.3; - damageScale[$DamageType::Bullet] = 1.2; - damageScale[$DamageType::ELF] = 0.75; - damageScale[$DamageType::ShockLance] = 1.0; - damageScale[$DamageType::Laser] = 1.12; - damageScale[$DamageType::ShrikeBlaster] = 1.10; - damageScale[$DamageType::BellyTurret] = 1.0; - damageScale[$DamageType::AATurret] = 0.7; - damageScale[$DamageType::IndoorDepTurret] = 1.3; - damageScale[$DamageType::OutdoorDepTurret] = 1.3; - damageScale[$DamageType::SentryTurret] = 1.0; - damageScale[$DamageType::Disc] = 1.0; - damageScale[$DamageType::Grenade] = 1.2; - damageScale[$DamageType::Mine] = 1.0; - damageScale[$DamageType::Missile] = 1.0; - damageScale[$DamageType::Mortar] = 1.3; - damageScale[$DamageType::Plasma] = 1.0; - damageScale[$DamageType::BomberBombs] = 3.0; - damageScale[$DamageType::TankChaingun] = 1.7; - damageScale[$DamageType::TankMortar] = 1.0; - damageScale[$DamageType::MissileTurret] = 1.0; - damageScale[$DamageType::MortarTurret] = 1.3; - damageScale[$DamageType::PlasmaTurret] = 0.45; // z0dd - ZOD 3/30/02. was 1.0 - damageScale[$DamageType::SatchelCharge] = 3.0; - damageScale[$DamageType::Default] = 1.0; - damageScale[$DamageType::Impact] = 1.2; - damageScale[$DamageType::Ground] = 1.0; - damageScale[$DamageType::Explosion] = 1.0; - damageScale[$DamageType::Lightning] = 1.0; -}; - -datablock SimDataBlock(MediumPlayerDamageProfile) -{ - damageScale[$DamageType::Blaster] = 1.0; - damageScale[$DamageType::Bullet] = 1.0; - damageScale[$DamageType::ELF] = 0.75; - damageScale[$DamageType::ShockLance] = 1.0; - damageScale[$DamageType::Laser] = 1.1; - damageScale[$DamageType::ShrikeBlaster] = 1.0; - damageScale[$DamageType::BellyTurret] = 1.0; - damageScale[$DamageType::AATurret] = 0.7; - damageScale[$DamageType::IndoorDepTurret] = 1.0; - damageScale[$DamageType::OutdoorDepTurret] = 1.0; - damageScale[$DamageType::SentryTurret] = 1.0; - damageScale[$DamageType::Disc] = 0.6; - damageScale[$DamageType::Grenade] = 1.0; - damageScale[$DamageType::Mine] = 0.9; - damageScale[$DamageType::Missile] = 0.8; - damageScale[$DamageType::Mortar] = 1.0; - damageScale[$DamageType::Plasma] = 0.65; - damageScale[$DamageType::BomberBombs] = 3.0; - damageScale[$DamageType::TankChaingun] = 1.5; - damageScale[$DamageType::TankMortar] = 0.85; - damageScale[$DamageType::MissileTurret] = 0.8; - damageScale[$DamageType::MortarTurret] = 1.0; - damageScale[$DamageType::PlasmaTurret] = 0.60; // z0dd - ZOD, 4/12/02. Was 0.65 - damageScale[$DamageType::SatchelCharge] = 3.0; - damageScale[$DamageType::Default] = 1.0; - damageScale[$DamageType::Impact] = 1.0; - damageScale[$DamageType::Ground] = 1.0; - damageScale[$DamageType::Explosion] = 0.8; - damageScale[$DamageType::Lightning] = 1.2; -}; - -datablock SimDataBlock(HeavyPlayerDamageProfile) -{ - damageScale[$DamageType::Blaster] = 0.7; - damageScale[$DamageType::Bullet] = 0.6; - damageScale[$DamageType::ELF] = 0.75; - damageScale[$DamageType::ShockLance] = 1.0; - damageScale[$DamageType::Laser] = 0.67; - damageScale[$DamageType::ShrikeBlaster] = 0.8; - damageScale[$DamageType::BellyTurret] = 0.8; - damageScale[$DamageType::AATurret] = 0.6; - damageScale[$DamageType::IndoorDepTurret] = 0.7; - damageScale[$DamageType::OutdoorDepTurret] = 0.7; - damageScale[$DamageType::SentryTurret] = 1.0; - damageScale[$DamageType::Disc] = 0.60; - damageScale[$DamageType::Grenade] = 0.8; - damageScale[$DamageType::Mine] = 0.8; - damageScale[$DamageType::Missile] = 0.6; - damageScale[$DamageType::Mortar] = 0.7; - damageScale[$DamageType::Plasma] = 0.4; - damageScale[$DamageType::BomberBombs] = 3.0; - damageScale[$DamageType::TankChaingun] = 1.3; - damageScale[$DamageType::TankMortar] = 0.7; - damageScale[$DamageType::MissileTurret] = 0.6; - damageScale[$DamageType::MortarTurret] = 0.6; - damageScale[$DamageType::PlasmaTurret] = 0.45; // z0dd - ZOD, 4/12/02. Was 0.4 - damageScale[$DamageType::SatchelCharge] = 3.0; - damageScale[$DamageType::Default] = 1.0; - damageScale[$DamageType::Impact] = 0.8; - damageScale[$DamageType::Ground] = 1.0; - damageScale[$DamageType::Explosion] = 0.6; - damageScale[$DamageType::Lightning] = 1.4; -}; +//-------------------------------------------------------------------------- +// TYPES OF ALLOWED DAMAGE +//-------------------------------------------------------------------------- + +$DamageType::Default = 0; +$DamageType::Blaster = 1; +$DamageType::Plasma = 2; +$DamageType::Bullet = 3; +$DamageType::Disc = 4; +$DamageType::Grenade = 5; +$DamageType::Laser = 6; // NOTE: This value is referenced directly in code. DO NOT CHANGE! +$DamageType::ELF = 7; +$DamageType::Mortar = 8; +$DamageType::Missile = 9; +$DamageType::ShockLance = 10; +$DamageType::Mine = 11; +$DamageType::Explosion = 12; +$DamageType::Impact = 13; // Object to object collisions +$DamageType::Ground = 14; // Object to ground collisions +$DamageType::Turret = 15; + +$DamageType::PlasmaTurret = 16; +$DamageType::AATurret = 17; +$DamageType::ElfTurret = 18; +$DamageType::MortarTurret = 19; +$DamageType::MissileTurret = 20; +$DamageType::IndoorDepTurret = 21; +$DamageType::OutdoorDepTurret = 22; +$DamageType::SentryTurret = 23; + +$DamageType::OutOfBounds = 24; +$DamageType::Lava = 25; + +$DamageType::ShrikeBlaster = 26; +$DamageType::BellyTurret = 27; +$DamageType::BomberBombs = 28; +$DamageType::TankChaingun = 29; +$DamageType::TankMortar = 30; +$DamageType::SatchelCharge = 31; +$DamageType::MPBMissile = 32; +$DamageType::Lightning = 33; +$DamageType::VehicleSpawn = 34; +$DamageType::ForceFieldPowerup = 35; +$DamageType::Crash = 36; +$DamageType::Flame = 37; + +// DMM -- added so MPBs that blow up under water get a message +$DamageType::Water = 97; + +//Tinman - used in Hunters for cheap bastards ;) +$DamageType::NexusCamping = 98; + +// MES -- added so CTRL-K can get a distinctive message +$DamageType::Suicide = 99; + +// Etc, etc. + +$DamageTypeText[0] = 'default'; +$DamageTypeText[1] = 'blaster'; +$DamageTypeText[2] = 'plasma'; +$DamageTypeText[3] = 'chaingun'; +$DamageTypeText[4] = 'disc'; +$DamageTypeText[5] = 'grenade'; +$DamageTypeText[6] = 'laser'; +$DamageTypeText[7] = 'ELF'; +$DamageTypeText[8] = 'mortar'; +$DamageTypeText[9] = 'missile'; +$DamageTypeText[10] = 'shocklance'; +$DamageTypeText[11] = 'mine'; +$DamageTypeText[12] = 'explosion'; +$DamageTypeText[13] = 'impact'; +$DamageTypeText[14] = 'ground'; +$DamageTypeText[15] = 'turret'; +$DamageTypeText[16] = 'plasma turret'; +$DamageTypeText[17] = 'AA turret'; +$DamageTypeText[18] = 'ELF turret'; +$DamageTypeText[19] = 'mortar turret'; +$DamageTypeText[20] = 'missile turret'; +$DamageTypeText[21] = 'clamp turret'; +$DamageTypeText[22] = 'spike turret'; +$DamageTypeText[23] = 'sentry turret'; +$DamageTypeText[24] = 'out of bounds'; +$DamageTypeText[25] = 'lava'; +$DamageTypeText[26] = 'shrike blaster'; +$DamageTypeText[27] = 'belly turret'; +$DamageTypeText[28] = 'bomber bomb'; +$DamageTypeText[29] = 'tank chaingun'; +$DamageTypeText[30] = 'tank mortar'; +$DamageTypeText[31] = 'satchel charge'; +$DamageTypeText[32] = 'MPB missile'; +$DamageTypeText[33] = 'lighting'; +$DamageTypeText[35] = 'ForceField'; +$DamageTypeText[36] = 'Crash'; +$DamageTypeText[37] = 'flame breath'; +$DamageTypeText[98] = 'nexus camping'; +$DamageTypeText[99] = 'suicide'; + + +// ##### PLEASE DO NOT REORDER THE DAMAGE PROFILE TABLES BELOW ##### +// (They are set up in the same order as the "Weapons Matrix.xls" sheet for ease of reference when balancing) + +//---------------------------------------------------------------------------- +// VEHICLE DAMAGE PROFILES +//---------------------------------------------------------------------------- + +//**** SHRIKE SCOUT FIGHTER **** +datablock SimDataBlock(ShrikeDamageProfile) +{ + shieldDamageScale[$DamageType::Blaster] = 1.75; + shieldDamageScale[$DamageType::Bullet] = 1.75; + shieldDamageScale[$DamageType::ELF] = 1.0; + shieldDamageScale[$DamageType::ShockLance] = 0.5; + shieldDamageScale[$DamageType::Laser] = 1.0; + shieldDamageScale[$DamageType::ShrikeBlaster] = 4.0; + shieldDamageScale[$DamageType::BellyTurret] = 2.0; + shieldDamageScale[$DamageType::AATurret] = 3.0; + shieldDamageScale[$DamageType::IndoorDepTurret] = 2.5; + shieldDamageScale[$DamageType::OutdoorDepTurret] = 2.5; + shieldDamageScale[$DamageType::SentryTurret] = 2.5; + shieldDamageScale[$DamageType::Disc] = 1.5; + shieldDamageScale[$DamageType::Grenade] = 1.0; + shieldDamageScale[$DamageType::Mine] = 3.0; + shieldDamageScale[$DamageType::Missile] = 3.0; + shieldDamageScale[$DamageType::Mortar] = 2.0; + shieldDamageScale[$DamageType::Plasma] = 1.0; + shieldDamageScale[$DamageType::BomberBombs] = 3.0; + shieldDamageScale[$DamageType::TankChaingun] = 3.0; + shieldDamageScale[$DamageType::TankMortar] = 2.0; + shieldDamageScale[$DamageType::MissileTurret] = 3.0; + shieldDamageScale[$DamageType::MortarTurret] = 2.0; + shieldDamageScale[$DamageType::PlasmaTurret] = 2.0; + shieldDamageScale[$DamageType::SatchelCharge] = 3.5; + shieldDamageScale[$DamageType::Default] = 1.0; + shieldDamageScale[$DamageType::Impact] = 1.1; + shieldDamageScale[$DamageType::Ground] = 1.0; + shieldDamageScale[$DamageType::Explosion] = 3.0; + shieldDamageScale[$DamageType::Lightning] = 10.0; + + damageScale[$DamageType::Blaster] = 1.0; + damageScale[$DamageType::Bullet] = 1.0; + damageScale[$DamageType::ELF] = 0.0; + damageScale[$DamageType::ShockLance] = 0.50; + damageScale[$DamageType::Laser] = 1.0; + damageScale[$DamageType::ShrikeBlaster] = 3.5; + damageScale[$DamageType::BellyTurret] = 1.2; + damageScale[$DamageType::AATurret] = 1.5; + damageScale[$DamageType::IndoorDepTurret] = 1.5; + damageScale[$DamageType::OutdoorDepTurret] = 1.5; + damageScale[$DamageType::SentryTurret] = 1.5; + damageScale[$DamageType::Disc] = 1.25; + damageScale[$DamageType::Grenade] = 0.75; + damageScale[$DamageType::Mine] = 4.0; + damageScale[$DamageType::Missile] = 2.0; + damageScale[$DamageType::Mortar] = 2.0; + damageScale[$DamageType::Plasma] = 0.5; + damageScale[$DamageType::BomberBombs] = 2.0; + damageScale[$DamageType::TankChaingun] = 2.0; + damageScale[$DamageType::TankMortar] = 2.0; + damageScale[$DamageType::MissileTurret] = 1.5; + damageScale[$DamageType::MortarTurret] = 2.0; + damageScale[$DamageType::PlasmaTurret] = 2.0; + damageScale[$DamageType::SatchelCharge] = 3.5; + damageScale[$DamageType::Default] = 1.0; + damageScale[$DamageType::Impact] = 1.1; + damageScale[$DamageType::Ground] = 1.0; + damageScale[$DamageType::Explosion] = 2.0; + damageScale[$DamageType::Lightning] = 10.0; +}; + +//**** THUNDERSWORD BOMBER **** +datablock SimDataBlock(BomberDamageProfile) +{ + shieldDamageScale[$DamageType::Blaster] = 1.0; + shieldDamageScale[$DamageType::Bullet] = 1.0; + shieldDamageScale[$DamageType::ELF] = 1.0; + shieldDamageScale[$DamageType::ShockLance] = 0.5; + shieldDamageScale[$DamageType::Laser] = 1.0; + shieldDamageScale[$DamageType::ShrikeBlaster] = 3.5; + shieldDamageScale[$DamageType::BellyTurret] = 2.0; + shieldDamageScale[$DamageType::AATurret] = 3.0; + shieldDamageScale[$DamageType::IndoorDepTurret] = 2.25; + shieldDamageScale[$DamageType::OutdoorDepTurret] = 2.25; + shieldDamageScale[$DamageType::SentryTurret] = 2.25; + shieldDamageScale[$DamageType::Disc] = 1.0; + shieldDamageScale[$DamageType::Grenade] = 1.0; + shieldDamageScale[$DamageType::Mine] = 3.0; + shieldDamageScale[$DamageType::Missile] = 3.0; + shieldDamageScale[$DamageType::Mortar] = 2.0; + shieldDamageScale[$DamageType::Plasma] = 1.0; + shieldDamageScale[$DamageType::BomberBombs] = 3.0; + shieldDamageScale[$DamageType::TankChaingun] = 3.0; + shieldDamageScale[$DamageType::TankMortar] = 2.0; + shieldDamageScale[$DamageType::MissileTurret] = 3.0; + shieldDamageScale[$DamageType::MortarTurret] = 2.0; + shieldDamageScale[$DamageType::PlasmaTurret] = 2.0; + shieldDamageScale[$DamageType::SatchelCharge] = 3.5; + shieldDamageScale[$DamageType::Default] = 1.0; + shieldDamageScale[$DamageType::Impact] = 0.8; + shieldDamageScale[$DamageType::Ground] = 1.0; + shieldDamageScale[$DamageType::Explosion] = 3.0; + shieldDamageScale[$DamageType::Lightning] = 10.0; + + damageScale[$DamageType::Blaster] = 0.75; + damageScale[$DamageType::Bullet] = 0.75; + damageScale[$DamageType::ELF] = 0.0; + damageScale[$DamageType::ShockLance] = 0.50; + damageScale[$DamageType::Laser] = 1.0; + damageScale[$DamageType::ShrikeBlaster] = 2.5; + damageScale[$DamageType::BellyTurret] = 1.2; + damageScale[$DamageType::AATurret] = 1.5; + damageScale[$DamageType::IndoorDepTurret] = 1.25; + damageScale[$DamageType::OutdoorDepTurret] = 1.25; + damageScale[$DamageType::SentryTurret] = 1.25; + damageScale[$DamageType::Disc] = 1.0; + damageScale[$DamageType::Grenade] = 0.75; + damageScale[$DamageType::Mine] = 4.0; + damageScale[$DamageType::Missile] = 1.5; + damageScale[$DamageType::Mortar] = 2.0; + damageScale[$DamageType::Plasma] = 0.5; + damageScale[$DamageType::BomberBombs] = 2.0; + damageScale[$DamageType::TankChaingun] = 2.0; + damageScale[$DamageType::TankMortar] = 2.0; + damageScale[$DamageType::MissileTurret] = 1.5; + damageScale[$DamageType::MortarTurret] = 2.0; + damageScale[$DamageType::PlasmaTurret] = 2.0; + damageScale[$DamageType::SatchelCharge] = 3.5; + damageScale[$DamageType::Default] = 1.0; + damageScale[$DamageType::Impact] = 0.8; + damageScale[$DamageType::Ground] = 1.0; + damageScale[$DamageType::Explosion] = 2.0; + damageScale[$DamageType::Lightning] = 10.0; +}; + +//**** HAVOC TRANSPORT **** +datablock SimDataBlock(HavocDamageProfile) +{ + shieldDamageScale[$DamageType::Blaster] = 1.0; + shieldDamageScale[$DamageType::Bullet] = 1.0; + shieldDamageScale[$DamageType::ELF] = 1.0; + shieldDamageScale[$DamageType::ShockLance] = 0.5; + shieldDamageScale[$DamageType::Laser] = 1.0; + shieldDamageScale[$DamageType::ShrikeBlaster] = 3.5; + shieldDamageScale[$DamageType::BellyTurret] = 2.0; + shieldDamageScale[$DamageType::AATurret] = 3.0; + shieldDamageScale[$DamageType::IndoorDepTurret] = 2.25; + shieldDamageScale[$DamageType::OutdoorDepTurret] = 2.25; + shieldDamageScale[$DamageType::SentryTurret] = 2.25; + shieldDamageScale[$DamageType::Disc] = 1.0; + shieldDamageScale[$DamageType::Grenade] = 1.0; + shieldDamageScale[$DamageType::Mine] = 3.0; + shieldDamageScale[$DamageType::Missile] = 3.0; + shieldDamageScale[$DamageType::Mortar] = 2.0; + shieldDamageScale[$DamageType::Plasma] = 1.0; + shieldDamageScale[$DamageType::BomberBombs] = 3.0; + shieldDamageScale[$DamageType::TankChaingun] = 3.0; + shieldDamageScale[$DamageType::TankMortar] = 2.0; + shieldDamageScale[$DamageType::MissileTurret] = 3.0; + shieldDamageScale[$DamageType::MortarTurret] = 2.0; + shieldDamageScale[$DamageType::PlasmaTurret] = 2.0; + shieldDamageScale[$DamageType::SatchelCharge] = 3.5; + shieldDamageScale[$DamageType::Default] = 1.0; + shieldDamageScale[$DamageType::Impact] = 0.5; + shieldDamageScale[$DamageType::Ground] = 1.0; + shieldDamageScale[$DamageType::Explosion] = 3.0; + shieldDamageScale[$DamageType::Lightning] = 10.0; + + damageScale[$DamageType::Blaster] = 0.75; + damageScale[$DamageType::Bullet] = 0.75; + damageScale[$DamageType::ELF] = 0.0; + damageScale[$DamageType::ShockLance] = 0.50; + damageScale[$DamageType::Laser] = 1.0; + damageScale[$DamageType::ShrikeBlaster] = 2.5; + damageScale[$DamageType::BellyTurret] = 1.2; + damageScale[$DamageType::AATurret] = 1.5; + damageScale[$DamageType::IndoorDepTurret] = 1.25; + damageScale[$DamageType::OutdoorDepTurret] = 1.25; + damageScale[$DamageType::SentryTurret] = 1.25; + damageScale[$DamageType::Disc] = 1.0; + damageScale[$DamageType::Grenade] = 0.75; + damageScale[$DamageType::Mine] = 4.0; + damageScale[$DamageType::Missile] = 1.5; + damageScale[$DamageType::Mortar] = 2.0; + damageScale[$DamageType::Plasma] = 0.5; + damageScale[$DamageType::BomberBombs] = 2.0; + damageScale[$DamageType::TankChaingun] = 2.0; + damageScale[$DamageType::TankMortar] = 2.0; + damageScale[$DamageType::MissileTurret] = 1.5; + damageScale[$DamageType::MortarTurret] = 2.0; + damageScale[$DamageType::PlasmaTurret] = 2.0; + damageScale[$DamageType::SatchelCharge] = 3.5; + damageScale[$DamageType::Default] = 1.0; + damageScale[$DamageType::Impact] = 0.5; + damageScale[$DamageType::Ground] = 1.0; + damageScale[$DamageType::Explosion] = 2.0; + damageScale[$DamageType::Lightning] = 10.0; +}; + +//**** WILDCAT GRAV CYCLE **** +datablock SimDataBlock(WildcatDamageProfile) +{ + shieldDamageScale[$DamageType::Blaster] = 2.0; + shieldDamageScale[$DamageType::Bullet] = 2.5; + shieldDamageScale[$DamageType::ELF] = 1.0; + shieldDamageScale[$DamageType::ShockLance] = 1.0; + shieldDamageScale[$DamageType::Laser] = 4.0; + shieldDamageScale[$DamageType::ShrikeBlaster] = 6.0; + shieldDamageScale[$DamageType::BellyTurret] = 2.0; + shieldDamageScale[$DamageType::AATurret] = 2.0; + shieldDamageScale[$DamageType::IndoorDepTurret] = 2.5; + shieldDamageScale[$DamageType::OutdoorDepTurret] = 2.5; + shieldDamageScale[$DamageType::Disc] = 2.5; + shieldDamageScale[$DamageType::Grenade] = 2.0; + shieldDamageScale[$DamageType::Mine] = 4.0; + shieldDamageScale[$DamageType::Missile] = 4.0; + shieldDamageScale[$DamageType::Mortar] = 2.0; + shieldDamageScale[$DamageType::Plasma] = 2.0; + shieldDamageScale[$DamageType::BomberBombs] = 2.5; + shieldDamageScale[$DamageType::TankChaingun] = 3.0; + shieldDamageScale[$DamageType::TankMortar] = 2.0; + shieldDamageScale[$DamageType::MissileTurret] = 4.0; + shieldDamageScale[$DamageType::MortarTurret] = 2.0; + shieldDamageScale[$DamageType::PlasmaTurret] = 2.0; + shieldDamageScale[$DamageType::SatchelCharge] = 3.0; + shieldDamageScale[$DamageType::Default] = 1.0; + shieldDamageScale[$DamageType::Impact] = 1.25; + shieldDamageScale[$DamageType::Ground] = 1.0; + shieldDamageScale[$DamageType::Explosion] = 2.0; + shieldDamageScale[$DamageType::Lightning] = 5.0; + + damageScale[$DamageType::Blaster] = 1.5; + damageScale[$DamageType::Bullet] = 1.2; + damageScale[$DamageType::ELF] = 0.0; + damageScale[$DamageType::ShockLance] = 0.50; + damageScale[$DamageType::Laser] = 2.0; + damageScale[$DamageType::ShrikeBlaster] = 4.0; + damageScale[$DamageType::BellyTurret] = 1.5; + damageScale[$DamageType::AATurret] = 1.0; + damageScale[$DamageType::IndoorDepTurret] = 1.0; + damageScale[$DamageType::OutdoorDepTurret] = 1.0; + damageScale[$DamageType::Disc] = 1.25; + damageScale[$DamageType::Grenade] = 1.0; + damageScale[$DamageType::Mine] = 4.0; + damageScale[$DamageType::Missile] = 1.2; + damageScale[$DamageType::Mortar] = 1.0; + damageScale[$DamageType::Plasma] = 1.5; + damageScale[$DamageType::BomberBombs] = 2.0; + damageScale[$DamageType::TankChaingun] = 2.0; + damageScale[$DamageType::TankMortar] = 1.0; + damageScale[$DamageType::MissileTurret] = 1.2; + damageScale[$DamageType::MortarTurret] = 1.0; + damageScale[$DamageType::PlasmaTurret] = 1.0; + damageScale[$DamageType::SatchelCharge] = 2.2; + damageScale[$DamageType::Default] = 1.0; + damageScale[$DamageType::Impact] = 1.25; + damageScale[$DamageType::Ground] = 1.0; + damageScale[$DamageType::Explosion] = 1.0; + damageScale[$DamageType::Lightning] = 5.0; +}; + +//**** BEOWULF TANK **** +datablock SimDataBlock(TankDamageProfile) +{ + shieldDamageScale[$DamageType::Blaster] = 0.6; + shieldDamageScale[$DamageType::Bullet] = 0.75; + shieldDamageScale[$DamageType::ELF] = 1.0; + shieldDamageScale[$DamageType::ShockLance] = 0.5; + shieldDamageScale[$DamageType::Laser] = 1.0; + shieldDamageScale[$DamageType::ShrikeBlaster] = 1.75; + shieldDamageScale[$DamageType::BellyTurret] = 1.25; + shieldDamageScale[$DamageType::AATurret] = 0.8; + shieldDamageScale[$DamageType::IndoorDepTurret] = 1.0; + shieldDamageScale[$DamageType::OutdoorDepTurret] = 1.0; + shieldDamageScale[$DamageType::Disc] = 0.8; + shieldDamageScale[$DamageType::Grenade] = 0.8; + shieldDamageScale[$DamageType::Mine] = 3.25; + shieldDamageScale[$DamageType::Missile] = 2.0; + shieldDamageScale[$DamageType::Mortar] = 1.7; + shieldDamageScale[$DamageType::Plasma] = 1.0; + shieldDamageScale[$DamageType::BomberBombs] = 1.5; + shieldDamageScale[$DamageType::TankChaingun] = 1.5; + shieldDamageScale[$DamageType::TankMortar] = 1.8; + shieldDamageScale[$DamageType::MissileTurret] = 1.25; + shieldDamageScale[$DamageType::MortarTurret] = 1.0; + shieldDamageScale[$DamageType::PlasmaTurret] = 1.25; + shieldDamageScale[$DamageType::SatchelCharge] = 2.0; + shieldDamageScale[$DamageType::Default] = 1.0; + shieldDamageScale[$DamageType::Impact] = 0.75; + shieldDamageScale[$DamageType::Ground] = 0.75; + shieldDamageScale[$DamageType::Explosion] = 2.0; + shieldDamageScale[$DamageType::Lightning] = 10.0; + + damageScale[$DamageType::Blaster] = 0.75; + damageScale[$DamageType::Bullet] = 0.75; + damageScale[$DamageType::ELF] = 0.0; + damageScale[$DamageType::ShockLance] = 0.50; + damageScale[$DamageType::Laser] = 1.0; + damageScale[$DamageType::ShrikeBlaster] = 2.0; + damageScale[$DamageType::BellyTurret] = 1.0; + damageScale[$DamageType::AATurret] = 1.0; + damageScale[$DamageType::IndoorDepTurret] = 1.0; + damageScale[$DamageType::OutdoorDepTurret] = 1.0; + damageScale[$DamageType::Disc] = 1.0; + damageScale[$DamageType::Grenade] = 1.0; + damageScale[$DamageType::Mine] = 2.25; + damageScale[$DamageType::Missile] = 1.25; + damageScale[$DamageType::Mortar] = 1.4; + damageScale[$DamageType::Plasma] = 0.5; + damageScale[$DamageType::BomberBombs] = 1.0; + damageScale[$DamageType::TankChaingun] = 0.75; + damageScale[$DamageType::TankMortar] = 1.6; + damageScale[$DamageType::MissileTurret] = 1.25; + damageScale[$DamageType::MortarTurret] = 1.0; + damageScale[$DamageType::PlasmaTurret] = 1.0; + damageScale[$DamageType::SatchelCharge] = 2.0; + damageScale[$DamageType::Default] = 1.0; + damageScale[$DamageType::Impact] = 0.75; + damageScale[$DamageType::Ground] = 0.75; + damageScale[$DamageType::Explosion] = 1.0; + damageScale[$DamageType::Lightning] = 10.0; +}; + +//**** JERICHO MPB **** +datablock SimDataBlock(MPBDamageProfile) +{ + shieldDamageScale[$DamageType::Blaster] = 0.6; + shieldDamageScale[$DamageType::Bullet] = 0.75; + shieldDamageScale[$DamageType::ELF] = 1.0; + shieldDamageScale[$DamageType::ShockLance] = 0.5; + shieldDamageScale[$DamageType::Laser] = 1.0; + shieldDamageScale[$DamageType::ShrikeBlaster] = 1.75; + shieldDamageScale[$DamageType::BellyTurret] = 1.25; + shieldDamageScale[$DamageType::AATurret] = 0.8; + shieldDamageScale[$DamageType::IndoorDepTurret] = 1.0; + shieldDamageScale[$DamageType::OutdoorDepTurret] = 1.0; + shieldDamageScale[$DamageType::Disc] = 0.8; + shieldDamageScale[$DamageType::Grenade] = 0.8; + shieldDamageScale[$DamageType::Mine] = 3.25; + shieldDamageScale[$DamageType::Missile] = 2.0; + shieldDamageScale[$DamageType::Mortar] = 0.8; + shieldDamageScale[$DamageType::Plasma] = 1.0; + shieldDamageScale[$DamageType::BomberBombs] = 1.5; + shieldDamageScale[$DamageType::TankChaingun] = 1.5; + shieldDamageScale[$DamageType::TankMortar] = 1.4; + shieldDamageScale[$DamageType::MissileTurret] = 1.25; + shieldDamageScale[$DamageType::MortarTurret] = 1.0; + shieldDamageScale[$DamageType::PlasmaTurret] = 1.25; + shieldDamageScale[$DamageType::SatchelCharge] = 2.0; + shieldDamageScale[$DamageType::Default] = 1.0; + shieldDamageScale[$DamageType::Impact] = 0.5; + shieldDamageScale[$DamageType::Ground] = 0.5; + shieldDamageScale[$DamageType::Explosion] = 2.0; + shieldDamageScale[$DamageType::Lightning] = 10.0; + + damageScale[$DamageType::Blaster] = 0.75; + damageScale[$DamageType::Bullet] = 0.75; + damageScale[$DamageType::ELF] = 0.0; + damageScale[$DamageType::ShockLance] = 0.50; + damageScale[$DamageType::Laser] = 1.0; + damageScale[$DamageType::ShrikeBlaster] = 2.0; + damageScale[$DamageType::BellyTurret] = 1.0; + damageScale[$DamageType::AATurret] = 1.0; + damageScale[$DamageType::IndoorDepTurret] = 1.0; + damageScale[$DamageType::OutdoorDepTurret] = 1.0; + damageScale[$DamageType::Disc] = 1.0; + damageScale[$DamageType::Grenade] = 1.0; + damageScale[$DamageType::Mine] = 2.25; + damageScale[$DamageType::Missile] = 1.25; + damageScale[$DamageType::Mortar] = 1.0; + damageScale[$DamageType::Plasma] = 0.5; + damageScale[$DamageType::BomberBombs] = 1.0; + damageScale[$DamageType::TankChaingun] = 0.75; + damageScale[$DamageType::TankMortar] = 1.0; + damageScale[$DamageType::MissileTurret] = 1.25; + damageScale[$DamageType::MortarTurret] = 1.0; + damageScale[$DamageType::PlasmaTurret] = 1.0; + damageScale[$DamageType::SatchelCharge] = 2.0; + damageScale[$DamageType::Default] = 1.0; + damageScale[$DamageType::Impact] = 0.5; + damageScale[$DamageType::Ground] = 0.5; + damageScale[$DamageType::Explosion] = 1.0; + damageScale[$DamageType::Lightning] = 10.0; +}; + +//---------------------------------------------------------------------------- +// TURRET DAMAGE PROFILES +//---------------------------------------------------------------------------- + +datablock SimDataBlock(TurretDamageProfile) +{ + shieldDamageScale[$DamageType::Blaster] = 0.8; + shieldDamageScale[$DamageType::Bullet] = 0.8; + shieldDamageScale[$DamageType::ELF] = 1.0; + shieldDamageScale[$DamageType::ShockLance] = 0.5; + shieldDamageScale[$DamageType::Laser] = 1.0; + shieldDamageScale[$DamageType::ShrikeBlaster] = 3.0; + shieldDamageScale[$DamageType::BellyTurret] = 2.0; + shieldDamageScale[$DamageType::AATurret] = 1.0; + shieldDamageScale[$DamageType::IndoorDepTurret] = 1.0; + shieldDamageScale[$DamageType::OutdoorDepTurret] = 1.0; + shieldDamageScale[$DamageType::SentryTurret] = 1.0; + shieldDamageScale[$DamageType::Disc] = 1.0; + shieldDamageScale[$DamageType::Grenade] = 1.5; + shieldDamageScale[$DamageType::Mine] = 3.0; + shieldDamageScale[$DamageType::Missile] = 3.0; + shieldDamageScale[$DamageType::Mortar] = 3.0; + shieldDamageScale[$DamageType::Plasma] = 1.0; + shieldDamageScale[$DamageType::BomberBombs] = 2.0; + shieldDamageScale[$DamageType::TankChaingun] = 1.5; + shieldDamageScale[$DamageType::TankMortar] = 3.0; + shieldDamageScale[$DamageType::MissileTurret] = 3.0; + shieldDamageScale[$DamageType::MortarTurret] = 3.0; + shieldDamageScale[$DamageType::PlasmaTurret] = 2.0; + shieldDamageScale[$DamageType::SatchelCharge] = 4.5; + shieldDamageScale[$DamageType::Default] = 1.0; + shieldDamageScale[$DamageType::Impact] = 1.0; + shieldDamageScale[$DamageType::Ground] = 1.0; + shieldDamageScale[$DamageType::Explosion] = 2.0; + shieldDamageScale[$DamageType::Lightning] = 5.0; + + damageScale[$DamageType::Blaster] = 0.8; + damageScale[$DamageType::Bullet] = 0.9; + damageScale[$DamageType::ELF] = 0.0; + damageScale[$DamageType::ShockLance] = 0.50; + damageScale[$DamageType::Laser] = 1.0; + damageScale[$DamageType::ShrikeBlaster] = 1.0; + damageScale[$DamageType::BellyTurret] = 0.6; + damageScale[$DamageType::AATurret] = 1.0; + damageScale[$DamageType::IndoorDepTurret] = 1.0; + damageScale[$DamageType::OutdoorDepTurret] = 1.0; + damageScale[$DamageType::SentryTurret] = 1.0; + damageScale[$DamageType::Disc] = 1.1; + damageScale[$DamageType::Grenade] = 1.0; + damageScale[$DamageType::Mine] = 1.5; + damageScale[$DamageType::Missile] = 1.25; + damageScale[$DamageType::Mortar] = 1.25; + damageScale[$DamageType::Plasma] = 0.75; + damageScale[$DamageType::BomberBombs] = 1.0; + damageScale[$DamageType::TankChaingun] = 1.25; + damageScale[$DamageType::TankMortar] = 1.25; + damageScale[$DamageType::MissileTurret] = 1.25; + damageScale[$DamageType::MortarTurret] = 1.25; + damageScale[$DamageType::PlasmaTurret] = 1.25; + damageScale[$DamageType::SatchelCharge] = 1.5; + damageScale[$DamageType::Default] = 1.0; + damageScale[$DamageType::Impact] = 1.0; + damageScale[$DamageType::Ground] = 1.0; + damageScale[$DamageType::Explosion] = 1.0; + damageScale[$DamageType::Lightning] = 5.0; +}; + +//---------------------------------------------------------------------------- +// STATIC SHAPE DAMAGE PROFILES +//---------------------------------------------------------------------------- + +datablock SimDataBlock(StaticShapeDamageProfile) +{ + shieldDamageScale[$DamageType::Blaster] = 0.8; + shieldDamageScale[$DamageType::Bullet] = 1.0; + shieldDamageScale[$DamageType::ELF] = 1.0; + shieldDamageScale[$DamageType::ShockLance] = 1.0; + shieldDamageScale[$DamageType::Laser] = 1.0; + shieldDamageScale[$DamageType::ShrikeBlaster] = 2.0; + shieldDamageScale[$DamageType::BellyTurret] = 1.5; + shieldDamageScale[$DamageType::AATurret] = 1.0; + shieldDamageScale[$DamageType::IndoorDepTurret] = 1.0; + shieldDamageScale[$DamageType::OutdoorDepTurret] = 1.0; + shieldDamageScale[$DamageType::Turret] = 1.0; + shieldDamageScale[$DamageType::SentryTurret] = 1.0; + shieldDamageScale[$DamageType::Disc] = 1.0; + shieldDamageScale[$DamageType::Grenade] = 1.2; + shieldDamageScale[$DamageType::Mine] = 0.5; // z0dd - ZOD, 10/09/02. Was 2.0 + shieldDamageScale[$DamageType::Missile] = 3.0; + shieldDamageScale[$DamageType::Mortar] = 3.0; + shieldDamageScale[$DamageType::Plasma] = 1.5; + shieldDamageScale[$DamageType::BomberBombs] = 2.0; + shieldDamageScale[$DamageType::TankChaingun] = 1.5; + shieldDamageScale[$DamageType::TankMortar] = 3.0; + shieldDamageScale[$DamageType::MissileTurret] = 3.0; + shieldDamageScale[$DamageType::MortarTurret] = 3.0; + shieldDamageScale[$DamageType::PlasmaTurret] = 2.0; + shieldDamageScale[$DamageType::SatchelCharge] = 6.0; + shieldDamageScale[$DamageType::Default] = 1.0; + shieldDamageScale[$DamageType::Impact] = 1.25; + shieldDamageScale[$DamageType::Ground] = 1.0; + shieldDamageScale[$DamageType::Explosion] = 2.0; + shieldDamageScale[$DamageType::Lightning] = 5.0; + + damageScale[$DamageType::Blaster] = 1.0; + damageScale[$DamageType::Bullet] = 1.0; + damageScale[$DamageType::ELF] = 0.0; + damageScale[$DamageType::ShockLance] = 1.0; + damageScale[$DamageType::Laser] = 1.0; + damageScale[$DamageType::ShrikeBlaster] = 2.0; + damageScale[$DamageType::BellyTurret] = 1.2; + damageScale[$DamageType::AATurret] = 1.0; + damageScale[$DamageType::IndoorDepTurret] = 1.0; + damageScale[$DamageType::OutdoorDepTurret] = 1.0; + damageScale[$DamageType::SentryTurret] = 1.0; + damageScale[$DamageType::Disc] = 1.15; + damageScale[$DamageType::Grenade] = 1.2; + damageScale[$DamageType::Mine] = 0.5; // z0dd - ZOD, 10/09/02. Was 2.0 + damageScale[$DamageType::Missile] = 2.0; + damageScale[$DamageType::Mortar] = 2.0; + damageScale[$DamageType::Plasma] = 1.25; + damageScale[$DamageType::BomberBombs] = 1.0; + damageScale[$DamageType::TankChaingun] = 1.0; + damageScale[$DamageType::TankMortar] = 2.0; + damageScale[$DamageType::MissileTurret] = 2.0; + damageScale[$DamageType::MortarTurret] = 2.0; + damageScale[$DamageType::PlasmaTurret] = 2.0; + damageScale[$DamageType::SatchelCharge] = 4.0; + damageScale[$DamageType::Default] = 1.0; + damageScale[$DamageType::Impact] = 1.25; + damageScale[$DamageType::Ground] = 1.0; + damageScale[$DamageType::Explosion] = 1.0; + damageScale[$DamageType::Lightning] = 5.0; +}; + +//---------------------------------------------------------------------------- +// PLAYER DAMAGE PROFILES +//---------------------------------------------------------------------------- + +datablock SimDataBlock(LightPlayerDamageProfile) +{ + damageScale[$DamageType::Blaster] = 1.3; + damageScale[$DamageType::Bullet] = 1.2; + damageScale[$DamageType::ELF] = 0.75; + damageScale[$DamageType::ShockLance] = 1.0; + damageScale[$DamageType::Laser] = 1.12; + damageScale[$DamageType::ShrikeBlaster] = 1.10; + damageScale[$DamageType::BellyTurret] = 1.0; + damageScale[$DamageType::AATurret] = 0.7; + damageScale[$DamageType::IndoorDepTurret] = 1.3; + damageScale[$DamageType::OutdoorDepTurret] = 1.3; + damageScale[$DamageType::SentryTurret] = 1.0; + damageScale[$DamageType::Disc] = 1.0; + damageScale[$DamageType::Grenade] = 1.2; + damageScale[$DamageType::Mine] = 1.0; + damageScale[$DamageType::Missile] = 1.0; + damageScale[$DamageType::Mortar] = 1.3; + damageScale[$DamageType::Plasma] = 1.0; + damageScale[$DamageType::BomberBombs] = 3.0; + damageScale[$DamageType::TankChaingun] = 1.7; + damageScale[$DamageType::TankMortar] = 1.0; + damageScale[$DamageType::MissileTurret] = 1.0; + damageScale[$DamageType::MortarTurret] = 1.3; + damageScale[$DamageType::PlasmaTurret] = 0.45; // z0dd - ZOD 3/30/02. was 1.0 + damageScale[$DamageType::SatchelCharge] = 3.0; + damageScale[$DamageType::Default] = 1.0; + damageScale[$DamageType::Impact] = 1.2; + damageScale[$DamageType::Ground] = 1.0; + damageScale[$DamageType::Explosion] = 1.0; + damageScale[$DamageType::Lightning] = 1.0; +}; + +datablock SimDataBlock(MediumPlayerDamageProfile) +{ + damageScale[$DamageType::Blaster] = 1.0; + damageScale[$DamageType::Bullet] = 1.0; + damageScale[$DamageType::ELF] = 0.75; + damageScale[$DamageType::ShockLance] = 1.0; + damageScale[$DamageType::Laser] = 1.1; + damageScale[$DamageType::ShrikeBlaster] = 1.0; + damageScale[$DamageType::BellyTurret] = 1.0; + damageScale[$DamageType::AATurret] = 0.7; + damageScale[$DamageType::IndoorDepTurret] = 1.0; + damageScale[$DamageType::OutdoorDepTurret] = 1.0; + damageScale[$DamageType::SentryTurret] = 1.0; + damageScale[$DamageType::Disc] = 0.6; + damageScale[$DamageType::Grenade] = 1.0; + damageScale[$DamageType::Mine] = 0.9; + damageScale[$DamageType::Missile] = 0.8; + damageScale[$DamageType::Mortar] = 1.0; + damageScale[$DamageType::Plasma] = 0.65; + damageScale[$DamageType::BomberBombs] = 3.0; + damageScale[$DamageType::TankChaingun] = 1.5; + damageScale[$DamageType::TankMortar] = 0.85; + damageScale[$DamageType::MissileTurret] = 0.8; + damageScale[$DamageType::MortarTurret] = 1.0; + damageScale[$DamageType::PlasmaTurret] = 0.60; // z0dd - ZOD, 4/12/02. Was 0.65 + damageScale[$DamageType::SatchelCharge] = 3.0; + damageScale[$DamageType::Default] = 1.0; + damageScale[$DamageType::Impact] = 1.0; + damageScale[$DamageType::Ground] = 1.0; + damageScale[$DamageType::Explosion] = 0.8; + damageScale[$DamageType::Lightning] = 1.2; +}; + +datablock SimDataBlock(HeavyPlayerDamageProfile) +{ + damageScale[$DamageType::Blaster] = 0.7; + damageScale[$DamageType::Bullet] = 0.6; + damageScale[$DamageType::ELF] = 0.75; + damageScale[$DamageType::ShockLance] = 1.0; + damageScale[$DamageType::Laser] = 0.67; + damageScale[$DamageType::ShrikeBlaster] = 0.8; + damageScale[$DamageType::BellyTurret] = 0.8; + damageScale[$DamageType::AATurret] = 0.6; + damageScale[$DamageType::IndoorDepTurret] = 0.7; + damageScale[$DamageType::OutdoorDepTurret] = 0.7; + damageScale[$DamageType::SentryTurret] = 1.0; + damageScale[$DamageType::Disc] = 0.60; + damageScale[$DamageType::Grenade] = 0.8; + damageScale[$DamageType::Mine] = 0.8; + damageScale[$DamageType::Missile] = 0.6; + damageScale[$DamageType::Mortar] = 0.7; + damageScale[$DamageType::Plasma] = 0.4; + damageScale[$DamageType::BomberBombs] = 3.0; + damageScale[$DamageType::TankChaingun] = 1.3; + damageScale[$DamageType::TankMortar] = 0.7; + damageScale[$DamageType::MissileTurret] = 0.6; + damageScale[$DamageType::MortarTurret] = 0.6; + damageScale[$DamageType::PlasmaTurret] = 0.45; // z0dd - ZOD, 4/12/02. Was 0.4 + damageScale[$DamageType::SatchelCharge] = 3.0; + damageScale[$DamageType::Default] = 1.0; + damageScale[$DamageType::Impact] = 0.8; + damageScale[$DamageType::Ground] = 1.0; + damageScale[$DamageType::Explosion] = 0.6; + damageScale[$DamageType::Lightning] = 1.4; +}; diff --git a/scripts/deathMessages.cs b/scripts/deathMessages.cs index 30b350b..66692df 100644 --- a/scripts/deathMessages.cs +++ b/scripts/deathMessages.cs @@ -1,403 +1,403 @@ -///////////////////////////////////////////////////////////////////////////////////////////////// -// %1 = Victim's name // -// %2 = Victim's gender (value will be either "him" or "her") // -// %3 = Victim's possessive gender (value will be either "his" or "her") // -// %4 = Killer's name // -// %5 = Killer's gender (value will be either "him" or "her") // -// %6 = Killer's possessive gender (value will be either "his" or "her") // -// %7 = implement that killed the victim (value is the object number of the bullet, disc, etc) // -// %10 = Victim gender (value will be either "he" or "she") // -// %11 = Killer gender (value will be either "he" or "she") // -///////////////////////////////////////////////////////////////////////////////////////////////// - -$DeathMessageCampingCount = 1; -$DeathMessageCamping[0] = '\c0%1 was killed for camping near the Nexus.'; - - //Out of Bounds deaths -$DeathMessageOOBCount = 2; -$DeathMessageOOB[0] = '\c0%1 was killed for loitering outside the mission area.'; -$DeathMessageOOB[1] = '\c0%1 was eaten by a Grue.'; - -$DeathMessageLavaCount = 4; -$DeathMessageLava[0] = '\c0%1\'s last thought before falling into the lava : \'Oops\'.'; -$DeathMessageLava[1] = '\c0%1 makes the supreme sacrifice to the lava gods.'; -$DeathMessageLava[2] = '\c0%1 looks surprised by the lava - but only briefly.'; -$DeathMessageLava[3] = '\c0%1 wimps out by jumping into the lava and trying to make it look like an accident.'; - -$DeathMessageLightningCount = 3; -$DeathMessageLightning[0] = '\c0%1 was killed by lightning!'; -$DeathMessageLightning[1] = '\c0%1 caught a lightning bolt!'; -$DeathMessageLightning[2] = '\c0%1 stuck %3 finger in Mother Nature\'s light socket.'; - -//these used when a player presses ctrl-k -$DeathMessageSuicideCount = 5; -$DeathMessageSuicide[0] = '\c0%1 blows %3 own head off!'; -$DeathMessageSuicide[1] = '\c0%1 ends it all. Cue violin music.'; -$DeathMessageSuicide[2] = '\c0%1 kills %2self.'; -$DeathMessageSuicide[3] = '\c0%1 goes for the quick and dirty respawn.'; -$DeathMessageSuicide[4] = '\c0%1 self-destructs in a fit of ennui.'; - -$DeathMessageVehPadCount = 1; -$DeathMessageVehPad[0] = '\c0%1 got caught in a vehicle\'s spawn field.'; - -$DeathMessageFFPowerupCount = 1; -$DeathMessageFFPowerup[0] = '\c0%1 got caught up in a forcefield during power up.'; - -$DeathMessageRogueMineCount = 1; -$DeathMessageRogueMine[$DamageType::Mine, 0] = '\c0%1 is all mine.'; - -//these used when a player kills himself (other than by using ctrl - k) -$DeathMessageSelfKillCount = 5; -$DeathMessageSelfKill[$DamageType::Blaster, 0] = '\c0%1 kills %2self with a blaster.'; -$DeathMessageSelfKill[$DamageType::Blaster, 1] = '\c0%1 makes a note to watch out for blaster ricochets.'; -$DeathMessageSelfKill[$DamageType::Blaster, 2] = '\c0%1\'s blaster kills its hapless owner.'; -$DeathMessageSelfKill[$DamageType::Blaster, 3] = '\c0%1 deftly guns %2self down with %3 own blaster.'; -$DeathMessageSelfKill[$DamageType::Blaster, 4] = '\c0%1 has a fatal encounter with %3 own blaster.'; - -$DeathMessageSelfKill[$DamageType::Plasma, 0] = '\c0%1 kills %2self with plasma.'; -$DeathMessageSelfKill[$DamageType::Plasma, 1] = '\c0%1 turns %2self into plasma-charred briquettes.'; -$DeathMessageSelfKill[$DamageType::Plasma, 2] = '\c0%1 swallows a white-hot mouthful of %3 own plasma.'; -$DeathMessageSelfKill[$DamageType::Plasma, 3] = '\c0%1 immolates %2self.'; -$DeathMessageSelfKill[$DamageType::Plasma, 4] = '\c0%1 experiences the joy of cooking %2self.'; - -$DeathMessageSelfKill[$DamageType::Disc, 0] = '\c0%1 kills %2self with a disc.'; -$DeathMessageSelfKill[$DamageType::Disc, 1] = '\c0%1 catches %3 own spinfusor disc.'; -$DeathMessageSelfKill[$DamageType::Disc, 2] = '\c0%1 heroically falls on %3 own disc.'; -$DeathMessageSelfKill[$DamageType::Disc, 3] = '\c0%1 helpfully jumps into %3 own disc\'s explosion.'; -$DeathMessageSelfKill[$DamageType::Disc, 4] = '\c0%1 plays Russian roulette with %3 spinfusor.'; - -$DeathMessageSelfKill[$DamageType::Grenade, 0] = '\c0%1 destroys %2self with a grenade!'; //applies to hand grenades *and* grenade launcher grenades -$DeathMessageSelfKill[$DamageType::Grenade, 1] = '\c0%1 took a bad bounce from %3 own grenade!'; -$DeathMessageSelfKill[$DamageType::Grenade, 2] = '\c0%1 pulled the pin a shade early.'; -$DeathMessageSelfKill[$DamageType::Grenade, 3] = '\c0%1\'s own grenade turns on %2.'; -$DeathMessageSelfKill[$DamageType::Grenade, 4] = '\c0%1 blows %2self up real good.'; - -$DeathMessageSelfKill[$DamageType::Mortar, 0] = '\c0%1 kills %2self with a mortar!'; -$DeathMessageSelfKill[$DamageType::Mortar, 1] = '\c0%1 hugs %3 own big green boomie.'; -$DeathMessageSelfKill[$DamageType::Mortar, 2] = '\c0%1 mortars %2self all over the map.'; -$DeathMessageSelfKill[$DamageType::Mortar, 3] = '\c0%1 experiences %3 mortar\'s payload up close.'; -$DeathMessageSelfKill[$DamageType::Mortar, 4] = '\c0%1 suffered the wrath of %3 own mortar.'; - -$DeathMessageSelfKill[$DamageType::Missile, 0] = '\c0%1 kills %2self with a missile!'; -$DeathMessageSelfKill[$DamageType::Missile, 1] = '\c0%1 runs a missile up %3 own tailpipe.'; -$DeathMessageSelfKill[$DamageType::Missile, 2] = '\c0%1 tests the missile\'s shaped charge on %2self.'; -$DeathMessageSelfKill[$DamageType::Missile, 3] = '\c0%1 achieved missile lock on %2self.'; -$DeathMessageSelfKill[$DamageType::Missile, 4] = '\c0%1 gracefully smoked %2self with a missile!'; - -$DeathMessageSelfKill[$DamageType::Mine, 0] = '\c0%1 kills %2self with a mine!'; -$DeathMessageSelfKill[$DamageType::Mine, 1] = '\c0%1\'s mine violently reminds %2 of its existence.'; -$DeathMessageSelfKill[$DamageType::Mine, 2] = '\c0%1 plants a decisive foot on %3 own mine!'; -$DeathMessageSelfKill[$DamageType::Mine, 3] = '\c0%1 fatally trips on %3 own mine!'; -$DeathMessageSelfKill[$DamageType::Mine, 4] = '\c0%1 makes a note not to run over %3 own mines.'; - -$DeathMessageSelfKill[$DamageType::SatchelCharge, 0] = '\c0%1 goes out with a bang!'; //applies to most explosion types -$DeathMessageSelfKill[$DamageType::SatchelCharge, 1] = '\c0%1 fall down...go boom.'; -$DeathMessageSelfKill[$DamageType::SatchelCharge, 2] = '\c0%1 explodes in that fatal kind of way.'; -$DeathMessageSelfKill[$DamageType::SatchelCharge, 3] = '\c0%1 experiences explosive decompression!'; -$DeathMessageSelfKill[$DamageType::SatchelCharge, 4] = '\c0%1 splashes all over the map.'; - -$DeathMessageSelfKill[$DamageType::Ground, 0] = '\c0%1 lands too hard.'; -$DeathMessageSelfKill[$DamageType::Ground, 1] = '\c0%1 finds gravity unforgiving.'; -$DeathMessageSelfKill[$DamageType::Ground, 2] = '\c0%1 craters on impact.'; -$DeathMessageSelfKill[$DamageType::Ground, 3] = '\c0%1 pancakes upon landing.'; -$DeathMessageSelfKill[$DamageType::Ground, 4] = '\c0%1 loses a game of chicken with the ground.'; - -$DeathMessageSelfKill[$DamageType::Flame, 0] = '\c0%1 needed a mint - %10 killed %2self.'; -$DeathMessageSelfKill[$DamageType::Flame, 1] = '\c0%1 burned.'; -$DeathMessageSelfKill[$DamageType::Flame, 2] = '\c0%1 over-cooked %2self.'; -$DeathMessageSelfKill[$DamageType::Flame, 3] = '\c0%1 thought %10 was flame retardent.'; -$DeathMessageSelfKill[$DamageType::Flame, 4] = '\c0%1 was dumb enough to test %3 ability to resist fire.'; - - -//used when a player is killed by a teammate -$DeathMessageTeamKillCount = 1; -$DeathMessageTeamKill[$DamageType::Blaster, 0] = '\c0%4 TEAMKILLED %1 with a blaster!'; -$DeathMessageTeamKill[$DamageType::Plasma, 0] = '\c0%4 TEAMKILLED %1 with a plasma rifle!'; -$DeathMessageTeamKill[$DamageType::Bullet, 0] = '\c0%4 TEAMKILLED %1 with a chaingun!'; -$DeathMessageTeamKill[$DamageType::Disc, 0] = '\c0%4 TEAMKILLED %1 with a spinfusor!'; -$DeathMessageTeamKill[$DamageType::Grenade, 0] = '\c0%4 TEAMKILLED %1 with a grenade!'; -$DeathMessageTeamKill[$DamageType::Laser, 0] = '\c0%4 TEAMKILLED %1 with a laser rifle!'; -$DeathMessageTeamKill[$DamageType::Elf, 0] = '\c0%4 TEAMKILLED %1 with an ELF projector!'; -$DeathMessageTeamKill[$DamageType::Mortar, 0] = '\c0%4 TEAMKILLED %1 with a mortar!'; -$DeathMessageTeamKill[$DamageType::Missile, 0] = '\c0%4 TEAMKILLED %1 with a missile!'; -$DeathMessageTeamKill[$DamageType::Shocklance, 0] = '\c0%4 TEAMKILLED %1 with a shocklance!'; -$DeathMessageTeamKill[$DamageType::Mine, 0] = '\c0%4 TEAMKILLED %1 with a mine!'; -$DeathMessageTeamKill[$DamageType::SatchelCharge, 0] = '\c0%4 blew up TEAMMATE %1!'; -$DeathMessageTeamKill[$DamageType::Impact, 0] = '\c0%4 runs down TEAMMATE %1!'; -$DeathMessageTeamKill[$DamageType::Flame, 0] = '\c0%4 roasts TEAMMATE %1!'; - - - -//these used when a player is killed by an enemy -$DeathMessageCount = 5; -$DeathMessage[$DamageType::Blaster, 0] = '\c0%4 kills %1 with a blaster.'; -$DeathMessage[$DamageType::Blaster, 1] = '\c0%4 pings %1 to death.'; -$DeathMessage[$DamageType::Blaster, 2] = '\c0%1 gets a pointer in blaster use from %4.'; -$DeathMessage[$DamageType::Blaster, 3] = '\c0%4 fatally embarrasses %1 with %6 pea shooter.'; -$DeathMessage[$DamageType::Blaster, 4] = '\c0%4 unleashes a terminal blaster barrage into %1.'; - -$DeathMessage[$DamageType::Plasma, 0] = '\c0%4 roasts %1 with the plasma rifle.'; -$DeathMessage[$DamageType::Plasma, 1] = '\c0%4 gooses %1 with an extra-friendly burst of plasma.'; -$DeathMessage[$DamageType::Plasma, 2] = '\c0%4 entices %1 to try a faceful of plasma.'; -$DeathMessage[$DamageType::Plasma, 3] = '\c0%4 introduces %1 to the plasma immolation dance.'; -$DeathMessage[$DamageType::Plasma, 4] = '\c0%4 slaps The Hot Kiss of Death on %1.'; - -$DeathMessage[$DamageType::Bullet, 0] = '\c0%4 rips %1 up with the chaingun.'; -$DeathMessage[$DamageType::Bullet, 1] = '\c0%4 happily chews %1 into pieces with %6 chaingun.'; -$DeathMessage[$DamageType::Bullet, 2] = '\c0%4 administers a dose of Vitamin Lead to %1.'; -$DeathMessage[$DamageType::Bullet, 3] = '\c0%1 suffers a serious hosing from %4\'s chaingun.'; -$DeathMessage[$DamageType::Bullet, 4] = '\c0%4 bestows the blessings of %6 chaingun on %1.'; - -$DeathMessage[$DamageType::Disc, 0] = '\c0%4 demolishes %1 with the spinfusor.'; -$DeathMessage[$DamageType::Disc, 1] = '\c0%4 serves %1 a blue plate special.'; -$DeathMessage[$DamageType::Disc, 2] = '\c0%4 shares a little blue friend with %1.'; -$DeathMessage[$DamageType::Disc, 3] = '\c0%4 puts a little spin into %1.'; -$DeathMessage[$DamageType::Disc, 4] = '\c0%1 becomes one of %4\'s greatest hits.'; - -$DeathMessage[$DamageType::Grenade, 0] = '\c0%4 eliminates %1 with a grenade.'; //applies to hand grenades *and* grenade launcher grenades -$DeathMessage[$DamageType::Grenade, 1] = '\c0%4 blows up %1 real good!'; -$DeathMessage[$DamageType::Grenade, 2] = '\c0%1 gets annihilated by %4\'s grenade.'; -$DeathMessage[$DamageType::Grenade, 3] = '\c0%1 receives a kaboom lesson from %4.'; -$DeathMessage[$DamageType::Grenade, 4] = '\c0%4 turns %1 into grenade salad.'; - -$DeathMessage[$DamageType::Laser, 0] = '\c0%1 becomes %4\'s latest pincushion.'; -$DeathMessage[$DamageType::Laser, 1] = '\c0%4 picks off %1 with %6 laser rifle.'; -$DeathMessage[$DamageType::Laser, 2] = '\c0%4 uses %1 as the targeting dummy in a sniping demonstration.'; -$DeathMessage[$DamageType::Laser, 3] = '\c0%4 pokes a shiny new hole in %1 with %6 laser rifle.'; -$DeathMessage[$DamageType::Laser, 4] = '\c0%4 caresses %1 with a couple hundred megajoules of laser.'; - -$DeathMessage[$DamageType::Elf, 0] = '\c0%4 fries %1 with the ELF projector.'; -$DeathMessage[$DamageType::Elf, 1] = '\c0%4 bug zaps %1 with %6 ELF.'; -$DeathMessage[$DamageType::Elf, 2] = '\c0%1 learns the shocking truth about %4\'s ELF skills.'; -$DeathMessage[$DamageType::Elf, 3] = '\c0%4 electrocutes %1 without a sponge.'; -$DeathMessage[$DamageType::Elf, 4] = '\c0%4\'s ELF projector leaves %1 a crispy critter.'; - -$DeathMessage[$DamageType::Mortar, 0] = '\c0%4 obliterates %1 with the mortar.'; -$DeathMessage[$DamageType::Mortar, 1] = '\c0%4 drops a mortar round right in %1\'s lap.'; -$DeathMessage[$DamageType::Mortar, 2] = '\c0%4 delivers a mortar payload straight to %1.'; -$DeathMessage[$DamageType::Mortar, 3] = '\c0%4 offers a little "heavy love" to %1.'; -$DeathMessage[$DamageType::Mortar, 4] = '\c0%1 stumbles into %4\'s mortar reticle.'; - -$DeathMessage[$DamageType::Missile, 0] = '\c0%4 intercepts %1 with a missile.'; -$DeathMessage[$DamageType::Missile, 1] = '\c0%4 watches %6 missile touch %1 and go boom.'; -$DeathMessage[$DamageType::Missile, 2] = '\c0%4 got sweet tone on %1.'; -$DeathMessage[$DamageType::Missile, 3] = '\c0By now, %1 has realized %4\'s missile killed %2.'; -$DeathMessage[$DamageType::Missile, 4] = '\c0%4\'s missile rains little pieces of %1 all over the ground.'; - -$DeathMessage[$DamageType::Shocklance, 0] = '\c0%4 reaps a harvest of %1 with the shocklance.'; -$DeathMessage[$DamageType::Shocklance, 1] = '\c0%4 feeds %1 the business end of %6 shocklance.'; -$DeathMessage[$DamageType::Shocklance, 2] = '\c0%4 stops %1 dead with the shocklance.'; -$DeathMessage[$DamageType::Shocklance, 3] = '\c0%4 eliminates %1 in close combat.'; -$DeathMessage[$DamageType::Shocklance, 4] = '\c0%4 ruins %1\'s day with one zap of a shocklance.'; - -$DeathMessage[$DamageType::Mine, 0] = '\c0%4 kills %1 with a mine.'; -$DeathMessage[$DamageType::Mine, 1] = '\c0%1 doesn\'t see %4\'s mine in time.'; -$DeathMessage[$DamageType::Mine, 2] = '\c0%4 gets a sapper kill on %1.'; -$DeathMessage[$DamageType::Mine, 3] = '\c0%1 puts his foot on %4\'s mine.'; -$DeathMessage[$DamageType::Mine, 4] = '\c0One small step for %1, one giant mine kill for %4.'; - -$DeathMessage[$DamageType::Flame, 0] = '\c0%4 cooked %1 extra crispy.'; -$DeathMessage[$DamageType::Flame, 1] = '\c0%4 roasts %1.'; -$DeathMessage[$DamageType::Flame, 2] = '\c0%4 ignited %1.'; -$DeathMessage[$DamageType::Flame, 3] = '\c0%4 lit up %1 - literally.'; -$DeathMessage[$DamageType::Flame, 4] = '\c0%4 magically turned %1 to ash.'; - -$DeathMessage[$DamageType::SatchelCharge, 0] = '\c0%4 buys %1 a ticket to the moon.'; //satchel charge only -$DeathMessage[$DamageType::SatchelCharge, 1] = '\c0%4 blows %1 into low orbit.'; -$DeathMessage[$DamageType::SatchelCharge, 2] = '\c0%4 makes %1 a hugely explosive offer.'; -$DeathMessage[$DamageType::SatchelCharge, 3] = '\c0%4 turns %1 into a cloud of satchel-vaporized armor.'; -$DeathMessage[$DamageType::SatchelCharge, 4] = '\c0%4\'s satchel charge leaves %1 nothin\' but smokin\' boots.'; - -$DeathMessageHeadshotCount = 3; -$DeathMessageHeadshot[$DamageType::Laser, 0] = '\c0%4 drills right through %1\'s braincase with %6 laser.'; -$DeathMessageHeadshot[$DamageType::Laser, 1] = '\c0%4 pops %1\'s head like a cheap balloon.'; -$DeathMessageHeadshot[$DamageType::Laser, 2] = '\c0%1 loses %3 head over %4\'s laser skill.'; - -// z0dd - ZOD, 8/25/02. Added Lance rear shot messages -$DeathMessageRearshotCount = 3; -$DeathMessageRearshot[$DamageType::ShockLance, 0] = '\c0%4 delivers a backdoor Lance to %1.'; -$DeathMessageRearshot[$DamageType::ShockLance, 1] = '\c0%4 sends high voltage up %1\'s bum.'; -$DeathMessageRearshot[$DamageType::ShockLance, 2] = '\c0%1 receives %4\'s rear-entry Lance attack.'; - -//These used when a player is run over by a vehicle -$DeathMessageVehicleCount = 5; -$DeathMessageVehicle[0] = '\c0%4 runs down %1.'; -$DeathMessageVehicle[1] = '\c0%1 acquires that run-down feeling from %4.'; -$DeathMessageVehicle[2] = '\c0%4 transforms %1 into tribal roadkill.'; -$DeathMessageVehicle[3] = '\c0%1 makes a painfully close examination of %4\'s front bumper.'; -$DeathMessageVehicle[4] = '\c0%1\'s messy death leaves a mark on %4\'s vehicle finish.'; - -$DeathMessageVehicleCrashCount = 5; -$DeathMessageVehicleCrash[ $DamageType::Crash, 0 ] = '\c0%1 fails to eject in time.'; -$DeathMessageVehicleCrash[ $DamageType::Crash, 1 ] = '\c0%1 becomes one with his vehicle dashboard.'; -$DeathMessageVehicleCrash[ $DamageType::Crash, 2 ] = '\c0%1 drives under the influence of death.'; -$DeathMessageVehicleCrash[ $DamageType::Crash, 3 ] = '\c0%1 makes a perfect three hundred point landing.'; -$DeathMessageVehicleCrash[ $DamageType::Crash, 4 ] = '\c0%1 heroically pilots his vehicle into something really, really hard.'; - -$DeathMessageVehicleFriendlyCount = 3; -$DeathMessageVehicleFriendly[0] = '\c0%1 gets in the way of a friendly vehicle.'; -$DeathMessageVehicleFriendly[1] = '\c0Sadly, a friendly vehicle turns %1 into roadkill.'; -$DeathMessageVehicleFriendly[2] = '\c0%1 becomes an unsightly ornament on a team vehicle\'s hood.'; - -$DeathMessageVehicleUnmannedCount = 3; -$DeathMessageVehicleUnmanned[0] = '\c0%1 gets in the way of a runaway vehicle.'; -$DeathMessageVehicleUnmanned[1] = '\c0An unmanned vehicle kills the pathetic %1.'; -$DeathMessageVehicleUnmanned[2] = '\c0%1 is struck down by an empty vehicle.'; - -//These used when a player is killed by a nearby equipment explosion -$DeathMessageExplosionCount = 3; -$DeathMessageExplosion[0] = '\c0%1 was killed by exploding equipment!'; -$DeathMessageExplosion[1] = '\c0%1 stood a little too close to the action!'; -$DeathMessageExplosion[2] = '\c0%1 learns how to be collateral damage.'; - -//These used when an automated turret kills an enemy player -$DeathMessageTurretKillCount = 3; -$DeathMessageTurretKill[$DamageType::PlasmaTurret, 0] = '\c0%1 is killed by a plasma turret.'; -$DeathMessageTurretKill[$DamageType::PlasmaTurret, 1] = '\c0%1\'s body now marks the location of a plasma turret.'; -$DeathMessageTurretKill[$DamageType::PlasmaTurret, 2] = '\c0%1 is fried by a plasma turret.'; - -$DeathMessageTurretKill[$DamageType::AATurret, 0] = '\c0%1 is killed by an AA turret.'; -$DeathMessageTurretKill[$DamageType::AATurret, 1] = '\c0%1 is shot down by an AA turret.'; -$DeathMessageTurretKill[$DamageType::AATurret, 2] = '\c0%1 takes fatal flak from an AA turret.'; - -$DeathMessageTurretKill[$DamageType::ElfTurret, 0] = '\c0%1 is killed by an ELF turret.'; -$DeathMessageTurretKill[$DamageType::ElfTurret, 1] = '\c0%1 is zapped by an ELF turret.'; -$DeathMessageTurretKill[$DamageType::ElfTurret, 2] = '\c0%1 is short-circuited by an ELF turret.'; - -$DeathMessageTurretKill[$DamageType::MortarTurret, 0] = '\c0%1 is killed by a mortar turret.'; -$DeathMessageTurretKill[$DamageType::MortarTurret, 1] = '\c0%1 enjoys a mortar turret\'s attention.'; -$DeathMessageTurretKill[$DamageType::MortarTurret, 2] = '\c0%1 is blown to kibble by a mortar turret.'; - -$DeathMessageTurretKill[$DamageType::MissileTurret, 0] = '\c0%1 is killed by a missile turret.'; -$DeathMessageTurretKill[$DamageType::MissileTurret, 1] = '\c0%1 is shot down by a missile turret.'; -$DeathMessageTurretKill[$DamageType::MissileTurret, 2] = '\c0%1 is blown away by a missile turret.'; - -$DeathMessageTurretKill[$DamageType::IndoorDepTurret, 0] = '\c0%1 is killed by a clamp turret.'; -$DeathMessageTurretKill[$DamageType::IndoorDepTurret, 1] = '\c0%1 gets burned by a clamp turret.'; -$DeathMessageTurretKill[$DamageType::IndoorDepTurret, 2] = '\c0A clamp turret eliminates %1.'; - -$DeathMessageTurretKill[$DamageType::OutdoorDepTurret, 0] = '\c0A spike turret neatly drills %1.'; -$DeathMessageTurretKill[$DamageType::OutdoorDepTurret, 1] = '\c0%1 gets taken out by a spike turret.'; -$DeathMessageTurretKill[$DamageType::OutdoorDepTurret, 2] = '\c0%1 dies under a spike turret\'s love.'; - -$DeathMessageTurretKill[$DamageType::SentryTurret, 0] = '\c0%1 didn\'t see that Sentry turret, but it saw %2...'; -$DeathMessageTurretKill[$DamageType::SentryTurret, 1] = '\c0%1 needs to watch for Sentry turrets.'; -$DeathMessageTurretKill[$DamageType::SentryTurret, 2] = '\c0%1 now understands how Sentry turrets work.'; - - -//used when a player is killed by a teammate controlling a turret -$DeathMessageCTurretTeamKillCount = 1; -$DeathMessageCTurretTeamKill[$DamageType::PlasmaTurret, 0] = '\c0%4 TEAMKILLED %1 with a plasma turret!'; - -$DeathMessageCTurretTeamKill[$DamageType::AATurret, 0] = '\c0%4 TEAMKILLED %1 with an AA turret!'; - -$DeathMessageCTurretTeamKill[$DamageType::ELFTurret, 0] = '\c0%4 TEAMKILLED %1 with an ELF turret!'; - -$DeathMessageCTurretTeamKill[$DamageType::MortarTurret, 0] = '\c0%4 TEAMKILLED %1 with a mortar turret!'; - -$DeathMessageCTurretTeamKill[$DamageType::MissileTurret, 0] = '\c0%4 TEAMKILLED %1 with a missile turret!'; - -$DeathMessageCTurretTeamKill[$DamageType::IndoorDepTurret, 0] = '\c0%4 TEAMKILLED %1 with a clamp turret!'; - -$DeathMessageCTurretTeamKill[$DamageType::OutdoorDepTurret, 0] = '\c0%4 TEAMKILLED %1 with a spike turret!'; - -$DeathMessageCTurretTeamKill[$DamageType::SentryTurret, 0] = '\c0%4 TEAMKILLED %1 with a sentry turret!'; - -$DeathMessageCTurretTeamKill[$DamageType::BomberBombs, 0] = '\c0%4 TEAMKILLED %1 in a bombastic explosion of raining death.'; - -$DeathMessageCTurretTeamKill[$DamageType::BellyTurret, 0] = '\c0%4 TEAMKILLED %1 by annihilating him from a belly turret.'; - -$DeathMessageCTurretTeamKill[$DamageType::TankChainGun, 0] = '\c0%4 TEAMKILLED %1 with his tank\'s chaingun.'; - -$DeathMessageCTurretTeamKill[$DamageType::TankMortar, 0] = '\c0%4 TEAMKILLED %1 by lobbing the BIG green death from a tank.'; - -$DeathMessageCTurretTeamKill[$DamageType::ShrikeBlaster, 0] = '\c0%4 TEAMKILLED %1 by strafing from a Shrike.'; - -$DeathMessageCTurretTeamKill[$DamageType::MPBMissile, 0] = '\c0%4 TEAMKILLED %1 when the MPB locked onto him.'; - - - -//used when a player is killed by an uncontrolled, friendly turret -$DeathMessageCTurretAccdtlKillCount = 1; -$DeathMessageCTurretAccdtlKill[$DamageType::PlasmaTurret, 0] = '\c0%1 got in the way of a plasma turret!'; - -$DeathMessageCTurretAccdtlKill[$DamageType::AATurret, 0] = '\c0%1 got in the way of an AA turret!'; - -$DeathMessageCTurretAccdtlKill[$DamageType::ELFTurret, 0] = '\c0%1 got in the way of an ELF turret!'; - -$DeathMessageCTurretAccdtlKill[$DamageType::MortarTurret, 0] = '\c0%1 got in the way of a mortar turret!'; - -$DeathMessageCTurretAccdtlKill[$DamageType::MissileTurret, 0] = '\c0%1 got in the way of a missile turret!'; - -$DeathMessageCTurretAccdtlKill[$DamageType::IndoorDepTurret, 0] = '\c0%1 got in the way of a clamp turret!'; - -$DeathMessageCTurretAccdtlKill[$DamageType::OutdoorDepTurret, 0] = '\c0%1 got in the way of a spike turret!'; - -$DeathMessageCTurretAccdtlKill[$DamageType::SentryTurret, 0] = '\c0%1 got in the way of a Sentry turret!'; - - -//these messages for owned or controlled turrets -$DeathMessageCTurretKillCount = 3; -$DeathMessageCTurretKill[$DamageType::PlasmaTurret, 0] = '\c0%4 torches %1 with a plasma turret!'; -$DeathMessageCTurretKill[$DamageType::PlasmaTurret, 1] = '\c0%4 fries %1 with a plasma turret!'; -$DeathMessageCTurretKill[$DamageType::PlasmaTurret, 2] = '\c0%4 lights up %1 with a plasma turret!'; - -$DeathMessageCTurretKill[$DamageType::AATurret, 0] = '\c0%4 shoots down %1 with an AA turret.'; -$DeathMessageCTurretKill[$DamageType::AATurret, 1] = '\c0%1 gets shot down by %1\'s AA turret.'; -$DeathMessageCTurretKill[$DamageType::AATurret, 2] = '\c0%4 takes out %1 with an AA turret.'; - -$DeathMessageCTurretKill[$DamageType::ElfTurret, 0] = '\c0%1 gets zapped by ELF gunner %4.'; -$DeathMessageCTurretKill[$DamageType::ElfTurret, 1] = '\c0%1 gets barbecued by ELF gunner %4.'; -$DeathMessageCTurretKill[$DamageType::ElfTurret, 2] = '\c0%1 gets shocked by ELF gunner %4.'; - -$DeathMessageCTurretKill[$DamageType::MortarTurret, 0] = '\c0%1 is annihilated by %4\'s mortar turret.'; -$DeathMessageCTurretKill[$DamageType::MortarTurret, 1] = '\c0%1 is blown away by %4\'s mortar turret.'; -$DeathMessageCTurretKill[$DamageType::MortarTurret, 2] = '\c0%1 is pureed by %4\'s mortar turret.'; - -$DeathMessageCTurretKill[$DamageType::MissileTurret, 0] = '\c0%4 shows %1 a new world of pain with a missile turret.'; -$DeathMessageCTurretKill[$DamageType::MissileTurret, 1] = '\c0%4 pops %1 with a missile turret.'; -$DeathMessageCTurretKill[$DamageType::MissileTurret, 2] = '\c0%4\'s missile turret lights up %1\'s, uh, ex-life.'; - -$DeathMessageCTurretKill[$DamageType::IndoorDepTurret, 0] = '\c0%1 is chewed up and spat out by %4\'s clamp turret.'; -$DeathMessageCTurretKill[$DamageType::IndoorDepTurret, 1] = '\c0%1 is knocked out by %4\'s clamp turret.'; -$DeathMessageCTurretKill[$DamageType::IndoorDepTurret, 2] = '\c0%4\'s clamp turret drills %1 nicely.'; - -$DeathMessageCTurretKill[$DamageType::OutdoorDepTurret, 0] = '\c0%1 is chewed up by %4\'s spike turret.'; -$DeathMessageCTurretKill[$DamageType::OutdoorDepTurret, 1] = '\c0%1 feels the burn from %4\'s spike turret.'; -$DeathMessageCTurretKill[$DamageType::OutdoorDepTurret, 2] = '\c0%1 is nailed by %4\'s spike turret.'; - -$DeathMessageCTurretKill[$DamageType::SentryTurret, 0] = '\c0%4 caught %1 by surprise with a turret.'; -$DeathMessageCTurretKill[$DamageType::SentryTurret, 1] = '\c0%4\'s turret took out %1.'; -$DeathMessageCTurretKill[$DamageType::SentryTurret, 2] = '\c0%4 blasted %1 with a turret.'; - -$DeathMessageCTurretKill[$DamageType::BomberBombs, 0] = '\c0%1 catches %4\'s bomb in both teeth.'; -$DeathMessageCTurretKill[$DamageType::BomberBombs, 1] = '\c0%4 leaves %1 a smoking bomb crater.'; -$DeathMessageCTurretKill[$DamageType::BomberBombs, 2] = '\c0%4 bombs %1 back to the 20th century.'; - -$DeathMessageCTurretKill[$DamageType::BellyTurret, 0] = '\c0%1 eats a big helping of %4\'s belly turret bolt.'; -$DeathMessageCTurretKill[$DamageType::BellyTurret, 1] = '\c0%4 plants a belly turret bolt in %1\'s belly.'; -$DeathMessageCTurretKill[$DamageType::BellyTurret, 2] = '\c0%1 fails to evade %4\'s deft bomber strafing.'; - -$DeathMessageCTurretKill[$DamageType::TankChainGun, 0] = '\c0%1 enjoys the rich, metallic taste of %4\'s tank slug.'; -$DeathMessageCTurretKill[$DamageType::TankChainGun, 1] = '\c0%4\'s tank chaingun plays sweet music all over %1.'; -$DeathMessageCTurretKill[$DamageType::TankChainGun, 2] = '\c0%1 receives a stellar exit wound from %4\'s tank slug.'; - -$DeathMessageCTurretKill[$DamageType::TankMortar, 0] = '\c0Whoops! %1 + %4\'s tank mortar = Dead %1.'; -$DeathMessageCTurretKill[$DamageType::TankMortar, 1] = '\c0%1 learns the happy explosion dance from %4\'s tank mortar.'; -$DeathMessageCTurretKill[$DamageType::TankMortar, 2] = '\c0%4\'s tank mortar has a blast with %1.'; - -$DeathMessageCTurretKill[$DamageType::ShrikeBlaster, 0] = '\c0%1 dines on a Shrike blaster sandwich, courtesy of %4.'; -$DeathMessageCTurretKill[$DamageType::ShrikeBlaster, 1] = '\c0The blaster of %4\'s Shrike turns %1 into finely shredded meat.'; -$DeathMessageCTurretKill[$DamageType::ShrikeBlaster, 2] = '\c0%1 gets drilled big-time by the blaster of %4\'s Shrike.'; - -$DeathMessageCTurretKill[$DamageType::MPBMissile, 0] = '\c0%1 intersects nicely with %4\'s MPB Missile.'; -$DeathMessageCTurretKill[$DamageType::MPBMissile, 1] = '\c0%4\'s MPB Missile makes armored chowder out of %1.'; -$DeathMessageCTurretKill[$DamageType::MPBMissile, 2] = '\c0%1 has a brief, explosive fling with %4\'s MPB Missile.'; - -$DeathMessageTurretSelfKillCount = 3; -$DeathMessageTurretSelfKill[0] = '\c0%1 somehow kills %2self with a turret.'; -$DeathMessageTurretSelfKill[1] = '\c0%1 apparently didn\'t know the turret was loaded.'; -$DeathMessageTurretSelfKill[2] = '\c0%1 helps his team by killing himself with a turret.'; - - - +///////////////////////////////////////////////////////////////////////////////////////////////// +// %1 = Victim's name // +// %2 = Victim's gender (value will be either "him" or "her") // +// %3 = Victim's possessive gender (value will be either "his" or "her") // +// %4 = Killer's name // +// %5 = Killer's gender (value will be either "him" or "her") // +// %6 = Killer's possessive gender (value will be either "his" or "her") // +// %7 = implement that killed the victim (value is the object number of the bullet, disc, etc) // +// %10 = Victim gender (value will be either "he" or "she") // +// %11 = Killer gender (value will be either "he" or "she") // +///////////////////////////////////////////////////////////////////////////////////////////////// + +$DeathMessageCampingCount = 1; +$DeathMessageCamping[0] = '\c0%1 was killed for camping near the Nexus.'; + + //Out of Bounds deaths +$DeathMessageOOBCount = 2; +$DeathMessageOOB[0] = '\c0%1 was killed for loitering outside the mission area.'; +$DeathMessageOOB[1] = '\c0%1 was eaten by a Grue.'; + +$DeathMessageLavaCount = 4; +$DeathMessageLava[0] = '\c0%1\'s last thought before falling into the lava : \'Oops\'.'; +$DeathMessageLava[1] = '\c0%1 makes the supreme sacrifice to the lava gods.'; +$DeathMessageLava[2] = '\c0%1 looks surprised by the lava - but only briefly.'; +$DeathMessageLava[3] = '\c0%1 wimps out by jumping into the lava and trying to make it look like an accident.'; + +$DeathMessageLightningCount = 3; +$DeathMessageLightning[0] = '\c0%1 was killed by lightning!'; +$DeathMessageLightning[1] = '\c0%1 caught a lightning bolt!'; +$DeathMessageLightning[2] = '\c0%1 stuck %3 finger in Mother Nature\'s light socket.'; + +//these used when a player presses ctrl-k +$DeathMessageSuicideCount = 5; +$DeathMessageSuicide[0] = '\c0%1 blows %3 own head off!'; +$DeathMessageSuicide[1] = '\c0%1 ends it all. Cue violin music.'; +$DeathMessageSuicide[2] = '\c0%1 kills %2self.'; +$DeathMessageSuicide[3] = '\c0%1 goes for the quick and dirty respawn.'; +$DeathMessageSuicide[4] = '\c0%1 self-destructs in a fit of ennui.'; + +$DeathMessageVehPadCount = 1; +$DeathMessageVehPad[0] = '\c0%1 got caught in a vehicle\'s spawn field.'; + +$DeathMessageFFPowerupCount = 1; +$DeathMessageFFPowerup[0] = '\c0%1 got caught up in a forcefield during power up.'; + +$DeathMessageRogueMineCount = 1; +$DeathMessageRogueMine[$DamageType::Mine, 0] = '\c0%1 is all mine.'; + +//these used when a player kills himself (other than by using ctrl - k) +$DeathMessageSelfKillCount = 5; +$DeathMessageSelfKill[$DamageType::Blaster, 0] = '\c0%1 kills %2self with a blaster.'; +$DeathMessageSelfKill[$DamageType::Blaster, 1] = '\c0%1 makes a note to watch out for blaster ricochets.'; +$DeathMessageSelfKill[$DamageType::Blaster, 2] = '\c0%1\'s blaster kills its hapless owner.'; +$DeathMessageSelfKill[$DamageType::Blaster, 3] = '\c0%1 deftly guns %2self down with %3 own blaster.'; +$DeathMessageSelfKill[$DamageType::Blaster, 4] = '\c0%1 has a fatal encounter with %3 own blaster.'; + +$DeathMessageSelfKill[$DamageType::Plasma, 0] = '\c0%1 kills %2self with plasma.'; +$DeathMessageSelfKill[$DamageType::Plasma, 1] = '\c0%1 turns %2self into plasma-charred briquettes.'; +$DeathMessageSelfKill[$DamageType::Plasma, 2] = '\c0%1 swallows a white-hot mouthful of %3 own plasma.'; +$DeathMessageSelfKill[$DamageType::Plasma, 3] = '\c0%1 immolates %2self.'; +$DeathMessageSelfKill[$DamageType::Plasma, 4] = '\c0%1 experiences the joy of cooking %2self.'; + +$DeathMessageSelfKill[$DamageType::Disc, 0] = '\c0%1 kills %2self with a disc.'; +$DeathMessageSelfKill[$DamageType::Disc, 1] = '\c0%1 catches %3 own spinfusor disc.'; +$DeathMessageSelfKill[$DamageType::Disc, 2] = '\c0%1 heroically falls on %3 own disc.'; +$DeathMessageSelfKill[$DamageType::Disc, 3] = '\c0%1 helpfully jumps into %3 own disc\'s explosion.'; +$DeathMessageSelfKill[$DamageType::Disc, 4] = '\c0%1 plays Russian roulette with %3 spinfusor.'; + +$DeathMessageSelfKill[$DamageType::Grenade, 0] = '\c0%1 destroys %2self with a grenade!'; //applies to hand grenades *and* grenade launcher grenades +$DeathMessageSelfKill[$DamageType::Grenade, 1] = '\c0%1 took a bad bounce from %3 own grenade!'; +$DeathMessageSelfKill[$DamageType::Grenade, 2] = '\c0%1 pulled the pin a shade early.'; +$DeathMessageSelfKill[$DamageType::Grenade, 3] = '\c0%1\'s own grenade turns on %2.'; +$DeathMessageSelfKill[$DamageType::Grenade, 4] = '\c0%1 blows %2self up real good.'; + +$DeathMessageSelfKill[$DamageType::Mortar, 0] = '\c0%1 kills %2self with a mortar!'; +$DeathMessageSelfKill[$DamageType::Mortar, 1] = '\c0%1 hugs %3 own big green boomie.'; +$DeathMessageSelfKill[$DamageType::Mortar, 2] = '\c0%1 mortars %2self all over the map.'; +$DeathMessageSelfKill[$DamageType::Mortar, 3] = '\c0%1 experiences %3 mortar\'s payload up close.'; +$DeathMessageSelfKill[$DamageType::Mortar, 4] = '\c0%1 suffered the wrath of %3 own mortar.'; + +$DeathMessageSelfKill[$DamageType::Missile, 0] = '\c0%1 kills %2self with a missile!'; +$DeathMessageSelfKill[$DamageType::Missile, 1] = '\c0%1 runs a missile up %3 own tailpipe.'; +$DeathMessageSelfKill[$DamageType::Missile, 2] = '\c0%1 tests the missile\'s shaped charge on %2self.'; +$DeathMessageSelfKill[$DamageType::Missile, 3] = '\c0%1 achieved missile lock on %2self.'; +$DeathMessageSelfKill[$DamageType::Missile, 4] = '\c0%1 gracefully smoked %2self with a missile!'; + +$DeathMessageSelfKill[$DamageType::Mine, 0] = '\c0%1 kills %2self with a mine!'; +$DeathMessageSelfKill[$DamageType::Mine, 1] = '\c0%1\'s mine violently reminds %2 of its existence.'; +$DeathMessageSelfKill[$DamageType::Mine, 2] = '\c0%1 plants a decisive foot on %3 own mine!'; +$DeathMessageSelfKill[$DamageType::Mine, 3] = '\c0%1 fatally trips on %3 own mine!'; +$DeathMessageSelfKill[$DamageType::Mine, 4] = '\c0%1 makes a note not to run over %3 own mines.'; + +$DeathMessageSelfKill[$DamageType::SatchelCharge, 0] = '\c0%1 goes out with a bang!'; //applies to most explosion types +$DeathMessageSelfKill[$DamageType::SatchelCharge, 1] = '\c0%1 fall down...go boom.'; +$DeathMessageSelfKill[$DamageType::SatchelCharge, 2] = '\c0%1 explodes in that fatal kind of way.'; +$DeathMessageSelfKill[$DamageType::SatchelCharge, 3] = '\c0%1 experiences explosive decompression!'; +$DeathMessageSelfKill[$DamageType::SatchelCharge, 4] = '\c0%1 splashes all over the map.'; + +$DeathMessageSelfKill[$DamageType::Ground, 0] = '\c0%1 lands too hard.'; +$DeathMessageSelfKill[$DamageType::Ground, 1] = '\c0%1 finds gravity unforgiving.'; +$DeathMessageSelfKill[$DamageType::Ground, 2] = '\c0%1 craters on impact.'; +$DeathMessageSelfKill[$DamageType::Ground, 3] = '\c0%1 pancakes upon landing.'; +$DeathMessageSelfKill[$DamageType::Ground, 4] = '\c0%1 loses a game of chicken with the ground.'; + +$DeathMessageSelfKill[$DamageType::Flame, 0] = '\c0%1 needed a mint - %10 killed %2self.'; +$DeathMessageSelfKill[$DamageType::Flame, 1] = '\c0%1 burned.'; +$DeathMessageSelfKill[$DamageType::Flame, 2] = '\c0%1 over-cooked %2self.'; +$DeathMessageSelfKill[$DamageType::Flame, 3] = '\c0%1 thought %10 was flame retardent.'; +$DeathMessageSelfKill[$DamageType::Flame, 4] = '\c0%1 was dumb enough to test %3 ability to resist fire.'; + + +//used when a player is killed by a teammate +$DeathMessageTeamKillCount = 1; +$DeathMessageTeamKill[$DamageType::Blaster, 0] = '\c0%4 TEAMKILLED %1 with a blaster!'; +$DeathMessageTeamKill[$DamageType::Plasma, 0] = '\c0%4 TEAMKILLED %1 with a plasma rifle!'; +$DeathMessageTeamKill[$DamageType::Bullet, 0] = '\c0%4 TEAMKILLED %1 with a chaingun!'; +$DeathMessageTeamKill[$DamageType::Disc, 0] = '\c0%4 TEAMKILLED %1 with a spinfusor!'; +$DeathMessageTeamKill[$DamageType::Grenade, 0] = '\c0%4 TEAMKILLED %1 with a grenade!'; +$DeathMessageTeamKill[$DamageType::Laser, 0] = '\c0%4 TEAMKILLED %1 with a laser rifle!'; +$DeathMessageTeamKill[$DamageType::Elf, 0] = '\c0%4 TEAMKILLED %1 with an ELF projector!'; +$DeathMessageTeamKill[$DamageType::Mortar, 0] = '\c0%4 TEAMKILLED %1 with a mortar!'; +$DeathMessageTeamKill[$DamageType::Missile, 0] = '\c0%4 TEAMKILLED %1 with a missile!'; +$DeathMessageTeamKill[$DamageType::Shocklance, 0] = '\c0%4 TEAMKILLED %1 with a shocklance!'; +$DeathMessageTeamKill[$DamageType::Mine, 0] = '\c0%4 TEAMKILLED %1 with a mine!'; +$DeathMessageTeamKill[$DamageType::SatchelCharge, 0] = '\c0%4 blew up TEAMMATE %1!'; +$DeathMessageTeamKill[$DamageType::Impact, 0] = '\c0%4 runs down TEAMMATE %1!'; +$DeathMessageTeamKill[$DamageType::Flame, 0] = '\c0%4 roasts TEAMMATE %1!'; + + + +//these used when a player is killed by an enemy +$DeathMessageCount = 5; +$DeathMessage[$DamageType::Blaster, 0] = '\c0%4 kills %1 with a blaster.'; +$DeathMessage[$DamageType::Blaster, 1] = '\c0%4 pings %1 to death.'; +$DeathMessage[$DamageType::Blaster, 2] = '\c0%1 gets a pointer in blaster use from %4.'; +$DeathMessage[$DamageType::Blaster, 3] = '\c0%4 fatally embarrasses %1 with %6 pea shooter.'; +$DeathMessage[$DamageType::Blaster, 4] = '\c0%4 unleashes a terminal blaster barrage into %1.'; + +$DeathMessage[$DamageType::Plasma, 0] = '\c0%4 roasts %1 with the plasma rifle.'; +$DeathMessage[$DamageType::Plasma, 1] = '\c0%4 gooses %1 with an extra-friendly burst of plasma.'; +$DeathMessage[$DamageType::Plasma, 2] = '\c0%4 entices %1 to try a faceful of plasma.'; +$DeathMessage[$DamageType::Plasma, 3] = '\c0%4 introduces %1 to the plasma immolation dance.'; +$DeathMessage[$DamageType::Plasma, 4] = '\c0%4 slaps The Hot Kiss of Death on %1.'; + +$DeathMessage[$DamageType::Bullet, 0] = '\c0%4 rips %1 up with the chaingun.'; +$DeathMessage[$DamageType::Bullet, 1] = '\c0%4 happily chews %1 into pieces with %6 chaingun.'; +$DeathMessage[$DamageType::Bullet, 2] = '\c0%4 administers a dose of Vitamin Lead to %1.'; +$DeathMessage[$DamageType::Bullet, 3] = '\c0%1 suffers a serious hosing from %4\'s chaingun.'; +$DeathMessage[$DamageType::Bullet, 4] = '\c0%4 bestows the blessings of %6 chaingun on %1.'; + +$DeathMessage[$DamageType::Disc, 0] = '\c0%4 demolishes %1 with the spinfusor.'; +$DeathMessage[$DamageType::Disc, 1] = '\c0%4 serves %1 a blue plate special.'; +$DeathMessage[$DamageType::Disc, 2] = '\c0%4 shares a little blue friend with %1.'; +$DeathMessage[$DamageType::Disc, 3] = '\c0%4 puts a little spin into %1.'; +$DeathMessage[$DamageType::Disc, 4] = '\c0%1 becomes one of %4\'s greatest hits.'; + +$DeathMessage[$DamageType::Grenade, 0] = '\c0%4 eliminates %1 with a grenade.'; //applies to hand grenades *and* grenade launcher grenades +$DeathMessage[$DamageType::Grenade, 1] = '\c0%4 blows up %1 real good!'; +$DeathMessage[$DamageType::Grenade, 2] = '\c0%1 gets annihilated by %4\'s grenade.'; +$DeathMessage[$DamageType::Grenade, 3] = '\c0%1 receives a kaboom lesson from %4.'; +$DeathMessage[$DamageType::Grenade, 4] = '\c0%4 turns %1 into grenade salad.'; + +$DeathMessage[$DamageType::Laser, 0] = '\c0%1 becomes %4\'s latest pincushion.'; +$DeathMessage[$DamageType::Laser, 1] = '\c0%4 picks off %1 with %6 laser rifle.'; +$DeathMessage[$DamageType::Laser, 2] = '\c0%4 uses %1 as the targeting dummy in a sniping demonstration.'; +$DeathMessage[$DamageType::Laser, 3] = '\c0%4 pokes a shiny new hole in %1 with %6 laser rifle.'; +$DeathMessage[$DamageType::Laser, 4] = '\c0%4 caresses %1 with a couple hundred megajoules of laser.'; + +$DeathMessage[$DamageType::Elf, 0] = '\c0%4 fries %1 with the ELF projector.'; +$DeathMessage[$DamageType::Elf, 1] = '\c0%4 bug zaps %1 with %6 ELF.'; +$DeathMessage[$DamageType::Elf, 2] = '\c0%1 learns the shocking truth about %4\'s ELF skills.'; +$DeathMessage[$DamageType::Elf, 3] = '\c0%4 electrocutes %1 without a sponge.'; +$DeathMessage[$DamageType::Elf, 4] = '\c0%4\'s ELF projector leaves %1 a crispy critter.'; + +$DeathMessage[$DamageType::Mortar, 0] = '\c0%4 obliterates %1 with the mortar.'; +$DeathMessage[$DamageType::Mortar, 1] = '\c0%4 drops a mortar round right in %1\'s lap.'; +$DeathMessage[$DamageType::Mortar, 2] = '\c0%4 delivers a mortar payload straight to %1.'; +$DeathMessage[$DamageType::Mortar, 3] = '\c0%4 offers a little "heavy love" to %1.'; +$DeathMessage[$DamageType::Mortar, 4] = '\c0%1 stumbles into %4\'s mortar reticle.'; + +$DeathMessage[$DamageType::Missile, 0] = '\c0%4 intercepts %1 with a missile.'; +$DeathMessage[$DamageType::Missile, 1] = '\c0%4 watches %6 missile touch %1 and go boom.'; +$DeathMessage[$DamageType::Missile, 2] = '\c0%4 got sweet tone on %1.'; +$DeathMessage[$DamageType::Missile, 3] = '\c0By now, %1 has realized %4\'s missile killed %2.'; +$DeathMessage[$DamageType::Missile, 4] = '\c0%4\'s missile rains little pieces of %1 all over the ground.'; + +$DeathMessage[$DamageType::Shocklance, 0] = '\c0%4 reaps a harvest of %1 with the shocklance.'; +$DeathMessage[$DamageType::Shocklance, 1] = '\c0%4 feeds %1 the business end of %6 shocklance.'; +$DeathMessage[$DamageType::Shocklance, 2] = '\c0%4 stops %1 dead with the shocklance.'; +$DeathMessage[$DamageType::Shocklance, 3] = '\c0%4 eliminates %1 in close combat.'; +$DeathMessage[$DamageType::Shocklance, 4] = '\c0%4 ruins %1\'s day with one zap of a shocklance.'; + +$DeathMessage[$DamageType::Mine, 0] = '\c0%4 kills %1 with a mine.'; +$DeathMessage[$DamageType::Mine, 1] = '\c0%1 doesn\'t see %4\'s mine in time.'; +$DeathMessage[$DamageType::Mine, 2] = '\c0%4 gets a sapper kill on %1.'; +$DeathMessage[$DamageType::Mine, 3] = '\c0%1 puts his foot on %4\'s mine.'; +$DeathMessage[$DamageType::Mine, 4] = '\c0One small step for %1, one giant mine kill for %4.'; + +$DeathMessage[$DamageType::Flame, 0] = '\c0%4 cooked %1 extra crispy.'; +$DeathMessage[$DamageType::Flame, 1] = '\c0%4 roasts %1.'; +$DeathMessage[$DamageType::Flame, 2] = '\c0%4 ignited %1.'; +$DeathMessage[$DamageType::Flame, 3] = '\c0%4 lit up %1 - literally.'; +$DeathMessage[$DamageType::Flame, 4] = '\c0%4 magically turned %1 to ash.'; + +$DeathMessage[$DamageType::SatchelCharge, 0] = '\c0%4 buys %1 a ticket to the moon.'; //satchel charge only +$DeathMessage[$DamageType::SatchelCharge, 1] = '\c0%4 blows %1 into low orbit.'; +$DeathMessage[$DamageType::SatchelCharge, 2] = '\c0%4 makes %1 a hugely explosive offer.'; +$DeathMessage[$DamageType::SatchelCharge, 3] = '\c0%4 turns %1 into a cloud of satchel-vaporized armor.'; +$DeathMessage[$DamageType::SatchelCharge, 4] = '\c0%4\'s satchel charge leaves %1 nothin\' but smokin\' boots.'; + +$DeathMessageHeadshotCount = 3; +$DeathMessageHeadshot[$DamageType::Laser, 0] = '\c0%4 drills right through %1\'s braincase with %6 laser.'; +$DeathMessageHeadshot[$DamageType::Laser, 1] = '\c0%4 pops %1\'s head like a cheap balloon.'; +$DeathMessageHeadshot[$DamageType::Laser, 2] = '\c0%1 loses %3 head over %4\'s laser skill.'; + +// z0dd - ZOD, 8/25/02. Added Lance rear shot messages +$DeathMessageRearshotCount = 3; +$DeathMessageRearshot[$DamageType::ShockLance, 0] = '\c0%4 delivers a backdoor Lance to %1.'; +$DeathMessageRearshot[$DamageType::ShockLance, 1] = '\c0%4 sends high voltage up %1\'s bum.'; +$DeathMessageRearshot[$DamageType::ShockLance, 2] = '\c0%1 receives %4\'s rear-entry Lance attack.'; + +//These used when a player is run over by a vehicle +$DeathMessageVehicleCount = 5; +$DeathMessageVehicle[0] = '\c0%4 runs down %1.'; +$DeathMessageVehicle[1] = '\c0%1 acquires that run-down feeling from %4.'; +$DeathMessageVehicle[2] = '\c0%4 transforms %1 into tribal roadkill.'; +$DeathMessageVehicle[3] = '\c0%1 makes a painfully close examination of %4\'s front bumper.'; +$DeathMessageVehicle[4] = '\c0%1\'s messy death leaves a mark on %4\'s vehicle finish.'; + +$DeathMessageVehicleCrashCount = 5; +$DeathMessageVehicleCrash[ $DamageType::Crash, 0 ] = '\c0%1 fails to eject in time.'; +$DeathMessageVehicleCrash[ $DamageType::Crash, 1 ] = '\c0%1 becomes one with his vehicle dashboard.'; +$DeathMessageVehicleCrash[ $DamageType::Crash, 2 ] = '\c0%1 drives under the influence of death.'; +$DeathMessageVehicleCrash[ $DamageType::Crash, 3 ] = '\c0%1 makes a perfect three hundred point landing.'; +$DeathMessageVehicleCrash[ $DamageType::Crash, 4 ] = '\c0%1 heroically pilots his vehicle into something really, really hard.'; + +$DeathMessageVehicleFriendlyCount = 3; +$DeathMessageVehicleFriendly[0] = '\c0%1 gets in the way of a friendly vehicle.'; +$DeathMessageVehicleFriendly[1] = '\c0Sadly, a friendly vehicle turns %1 into roadkill.'; +$DeathMessageVehicleFriendly[2] = '\c0%1 becomes an unsightly ornament on a team vehicle\'s hood.'; + +$DeathMessageVehicleUnmannedCount = 3; +$DeathMessageVehicleUnmanned[0] = '\c0%1 gets in the way of a runaway vehicle.'; +$DeathMessageVehicleUnmanned[1] = '\c0An unmanned vehicle kills the pathetic %1.'; +$DeathMessageVehicleUnmanned[2] = '\c0%1 is struck down by an empty vehicle.'; + +//These used when a player is killed by a nearby equipment explosion +$DeathMessageExplosionCount = 3; +$DeathMessageExplosion[0] = '\c0%1 was killed by exploding equipment!'; +$DeathMessageExplosion[1] = '\c0%1 stood a little too close to the action!'; +$DeathMessageExplosion[2] = '\c0%1 learns how to be collateral damage.'; + +//These used when an automated turret kills an enemy player +$DeathMessageTurretKillCount = 3; +$DeathMessageTurretKill[$DamageType::PlasmaTurret, 0] = '\c0%1 is killed by a plasma turret.'; +$DeathMessageTurretKill[$DamageType::PlasmaTurret, 1] = '\c0%1\'s body now marks the location of a plasma turret.'; +$DeathMessageTurretKill[$DamageType::PlasmaTurret, 2] = '\c0%1 is fried by a plasma turret.'; + +$DeathMessageTurretKill[$DamageType::AATurret, 0] = '\c0%1 is killed by an AA turret.'; +$DeathMessageTurretKill[$DamageType::AATurret, 1] = '\c0%1 is shot down by an AA turret.'; +$DeathMessageTurretKill[$DamageType::AATurret, 2] = '\c0%1 takes fatal flak from an AA turret.'; + +$DeathMessageTurretKill[$DamageType::ElfTurret, 0] = '\c0%1 is killed by an ELF turret.'; +$DeathMessageTurretKill[$DamageType::ElfTurret, 1] = '\c0%1 is zapped by an ELF turret.'; +$DeathMessageTurretKill[$DamageType::ElfTurret, 2] = '\c0%1 is short-circuited by an ELF turret.'; + +$DeathMessageTurretKill[$DamageType::MortarTurret, 0] = '\c0%1 is killed by a mortar turret.'; +$DeathMessageTurretKill[$DamageType::MortarTurret, 1] = '\c0%1 enjoys a mortar turret\'s attention.'; +$DeathMessageTurretKill[$DamageType::MortarTurret, 2] = '\c0%1 is blown to kibble by a mortar turret.'; + +$DeathMessageTurretKill[$DamageType::MissileTurret, 0] = '\c0%1 is killed by a missile turret.'; +$DeathMessageTurretKill[$DamageType::MissileTurret, 1] = '\c0%1 is shot down by a missile turret.'; +$DeathMessageTurretKill[$DamageType::MissileTurret, 2] = '\c0%1 is blown away by a missile turret.'; + +$DeathMessageTurretKill[$DamageType::IndoorDepTurret, 0] = '\c0%1 is killed by a clamp turret.'; +$DeathMessageTurretKill[$DamageType::IndoorDepTurret, 1] = '\c0%1 gets burned by a clamp turret.'; +$DeathMessageTurretKill[$DamageType::IndoorDepTurret, 2] = '\c0A clamp turret eliminates %1.'; + +$DeathMessageTurretKill[$DamageType::OutdoorDepTurret, 0] = '\c0A spike turret neatly drills %1.'; +$DeathMessageTurretKill[$DamageType::OutdoorDepTurret, 1] = '\c0%1 gets taken out by a spike turret.'; +$DeathMessageTurretKill[$DamageType::OutdoorDepTurret, 2] = '\c0%1 dies under a spike turret\'s love.'; + +$DeathMessageTurretKill[$DamageType::SentryTurret, 0] = '\c0%1 didn\'t see that Sentry turret, but it saw %2...'; +$DeathMessageTurretKill[$DamageType::SentryTurret, 1] = '\c0%1 needs to watch for Sentry turrets.'; +$DeathMessageTurretKill[$DamageType::SentryTurret, 2] = '\c0%1 now understands how Sentry turrets work.'; + + +//used when a player is killed by a teammate controlling a turret +$DeathMessageCTurretTeamKillCount = 1; +$DeathMessageCTurretTeamKill[$DamageType::PlasmaTurret, 0] = '\c0%4 TEAMKILLED %1 with a plasma turret!'; + +$DeathMessageCTurretTeamKill[$DamageType::AATurret, 0] = '\c0%4 TEAMKILLED %1 with an AA turret!'; + +$DeathMessageCTurretTeamKill[$DamageType::ELFTurret, 0] = '\c0%4 TEAMKILLED %1 with an ELF turret!'; + +$DeathMessageCTurretTeamKill[$DamageType::MortarTurret, 0] = '\c0%4 TEAMKILLED %1 with a mortar turret!'; + +$DeathMessageCTurretTeamKill[$DamageType::MissileTurret, 0] = '\c0%4 TEAMKILLED %1 with a missile turret!'; + +$DeathMessageCTurretTeamKill[$DamageType::IndoorDepTurret, 0] = '\c0%4 TEAMKILLED %1 with a clamp turret!'; + +$DeathMessageCTurretTeamKill[$DamageType::OutdoorDepTurret, 0] = '\c0%4 TEAMKILLED %1 with a spike turret!'; + +$DeathMessageCTurretTeamKill[$DamageType::SentryTurret, 0] = '\c0%4 TEAMKILLED %1 with a sentry turret!'; + +$DeathMessageCTurretTeamKill[$DamageType::BomberBombs, 0] = '\c0%4 TEAMKILLED %1 in a bombastic explosion of raining death.'; + +$DeathMessageCTurretTeamKill[$DamageType::BellyTurret, 0] = '\c0%4 TEAMKILLED %1 by annihilating him from a belly turret.'; + +$DeathMessageCTurretTeamKill[$DamageType::TankChainGun, 0] = '\c0%4 TEAMKILLED %1 with his tank\'s chaingun.'; + +$DeathMessageCTurretTeamKill[$DamageType::TankMortar, 0] = '\c0%4 TEAMKILLED %1 by lobbing the BIG green death from a tank.'; + +$DeathMessageCTurretTeamKill[$DamageType::ShrikeBlaster, 0] = '\c0%4 TEAMKILLED %1 by strafing from a Shrike.'; + +$DeathMessageCTurretTeamKill[$DamageType::MPBMissile, 0] = '\c0%4 TEAMKILLED %1 when the MPB locked onto him.'; + + + +//used when a player is killed by an uncontrolled, friendly turret +$DeathMessageCTurretAccdtlKillCount = 1; +$DeathMessageCTurretAccdtlKill[$DamageType::PlasmaTurret, 0] = '\c0%1 got in the way of a plasma turret!'; + +$DeathMessageCTurretAccdtlKill[$DamageType::AATurret, 0] = '\c0%1 got in the way of an AA turret!'; + +$DeathMessageCTurretAccdtlKill[$DamageType::ELFTurret, 0] = '\c0%1 got in the way of an ELF turret!'; + +$DeathMessageCTurretAccdtlKill[$DamageType::MortarTurret, 0] = '\c0%1 got in the way of a mortar turret!'; + +$DeathMessageCTurretAccdtlKill[$DamageType::MissileTurret, 0] = '\c0%1 got in the way of a missile turret!'; + +$DeathMessageCTurretAccdtlKill[$DamageType::IndoorDepTurret, 0] = '\c0%1 got in the way of a clamp turret!'; + +$DeathMessageCTurretAccdtlKill[$DamageType::OutdoorDepTurret, 0] = '\c0%1 got in the way of a spike turret!'; + +$DeathMessageCTurretAccdtlKill[$DamageType::SentryTurret, 0] = '\c0%1 got in the way of a Sentry turret!'; + + +//these messages for owned or controlled turrets +$DeathMessageCTurretKillCount = 3; +$DeathMessageCTurretKill[$DamageType::PlasmaTurret, 0] = '\c0%4 torches %1 with a plasma turret!'; +$DeathMessageCTurretKill[$DamageType::PlasmaTurret, 1] = '\c0%4 fries %1 with a plasma turret!'; +$DeathMessageCTurretKill[$DamageType::PlasmaTurret, 2] = '\c0%4 lights up %1 with a plasma turret!'; + +$DeathMessageCTurretKill[$DamageType::AATurret, 0] = '\c0%4 shoots down %1 with an AA turret.'; +$DeathMessageCTurretKill[$DamageType::AATurret, 1] = '\c0%1 gets shot down by %1\'s AA turret.'; +$DeathMessageCTurretKill[$DamageType::AATurret, 2] = '\c0%4 takes out %1 with an AA turret.'; + +$DeathMessageCTurretKill[$DamageType::ElfTurret, 0] = '\c0%1 gets zapped by ELF gunner %4.'; +$DeathMessageCTurretKill[$DamageType::ElfTurret, 1] = '\c0%1 gets barbecued by ELF gunner %4.'; +$DeathMessageCTurretKill[$DamageType::ElfTurret, 2] = '\c0%1 gets shocked by ELF gunner %4.'; + +$DeathMessageCTurretKill[$DamageType::MortarTurret, 0] = '\c0%1 is annihilated by %4\'s mortar turret.'; +$DeathMessageCTurretKill[$DamageType::MortarTurret, 1] = '\c0%1 is blown away by %4\'s mortar turret.'; +$DeathMessageCTurretKill[$DamageType::MortarTurret, 2] = '\c0%1 is pureed by %4\'s mortar turret.'; + +$DeathMessageCTurretKill[$DamageType::MissileTurret, 0] = '\c0%4 shows %1 a new world of pain with a missile turret.'; +$DeathMessageCTurretKill[$DamageType::MissileTurret, 1] = '\c0%4 pops %1 with a missile turret.'; +$DeathMessageCTurretKill[$DamageType::MissileTurret, 2] = '\c0%4\'s missile turret lights up %1\'s, uh, ex-life.'; + +$DeathMessageCTurretKill[$DamageType::IndoorDepTurret, 0] = '\c0%1 is chewed up and spat out by %4\'s clamp turret.'; +$DeathMessageCTurretKill[$DamageType::IndoorDepTurret, 1] = '\c0%1 is knocked out by %4\'s clamp turret.'; +$DeathMessageCTurretKill[$DamageType::IndoorDepTurret, 2] = '\c0%4\'s clamp turret drills %1 nicely.'; + +$DeathMessageCTurretKill[$DamageType::OutdoorDepTurret, 0] = '\c0%1 is chewed up by %4\'s spike turret.'; +$DeathMessageCTurretKill[$DamageType::OutdoorDepTurret, 1] = '\c0%1 feels the burn from %4\'s spike turret.'; +$DeathMessageCTurretKill[$DamageType::OutdoorDepTurret, 2] = '\c0%1 is nailed by %4\'s spike turret.'; + +$DeathMessageCTurretKill[$DamageType::SentryTurret, 0] = '\c0%4 caught %1 by surprise with a turret.'; +$DeathMessageCTurretKill[$DamageType::SentryTurret, 1] = '\c0%4\'s turret took out %1.'; +$DeathMessageCTurretKill[$DamageType::SentryTurret, 2] = '\c0%4 blasted %1 with a turret.'; + +$DeathMessageCTurretKill[$DamageType::BomberBombs, 0] = '\c0%1 catches %4\'s bomb in both teeth.'; +$DeathMessageCTurretKill[$DamageType::BomberBombs, 1] = '\c0%4 leaves %1 a smoking bomb crater.'; +$DeathMessageCTurretKill[$DamageType::BomberBombs, 2] = '\c0%4 bombs %1 back to the 20th century.'; + +$DeathMessageCTurretKill[$DamageType::BellyTurret, 0] = '\c0%1 eats a big helping of %4\'s belly turret bolt.'; +$DeathMessageCTurretKill[$DamageType::BellyTurret, 1] = '\c0%4 plants a belly turret bolt in %1\'s belly.'; +$DeathMessageCTurretKill[$DamageType::BellyTurret, 2] = '\c0%1 fails to evade %4\'s deft bomber strafing.'; + +$DeathMessageCTurretKill[$DamageType::TankChainGun, 0] = '\c0%1 enjoys the rich, metallic taste of %4\'s tank slug.'; +$DeathMessageCTurretKill[$DamageType::TankChainGun, 1] = '\c0%4\'s tank chaingun plays sweet music all over %1.'; +$DeathMessageCTurretKill[$DamageType::TankChainGun, 2] = '\c0%1 receives a stellar exit wound from %4\'s tank slug.'; + +$DeathMessageCTurretKill[$DamageType::TankMortar, 0] = '\c0Whoops! %1 + %4\'s tank mortar = Dead %1.'; +$DeathMessageCTurretKill[$DamageType::TankMortar, 1] = '\c0%1 learns the happy explosion dance from %4\'s tank mortar.'; +$DeathMessageCTurretKill[$DamageType::TankMortar, 2] = '\c0%4\'s tank mortar has a blast with %1.'; + +$DeathMessageCTurretKill[$DamageType::ShrikeBlaster, 0] = '\c0%1 dines on a Shrike blaster sandwich, courtesy of %4.'; +$DeathMessageCTurretKill[$DamageType::ShrikeBlaster, 1] = '\c0The blaster of %4\'s Shrike turns %1 into finely shredded meat.'; +$DeathMessageCTurretKill[$DamageType::ShrikeBlaster, 2] = '\c0%1 gets drilled big-time by the blaster of %4\'s Shrike.'; + +$DeathMessageCTurretKill[$DamageType::MPBMissile, 0] = '\c0%1 intersects nicely with %4\'s MPB Missile.'; +$DeathMessageCTurretKill[$DamageType::MPBMissile, 1] = '\c0%4\'s MPB Missile makes armored chowder out of %1.'; +$DeathMessageCTurretKill[$DamageType::MPBMissile, 2] = '\c0%1 has a brief, explosive fling with %4\'s MPB Missile.'; + +$DeathMessageTurretSelfKillCount = 3; +$DeathMessageTurretSelfKill[0] = '\c0%1 somehow kills %2self with a turret.'; +$DeathMessageTurretSelfKill[1] = '\c0%1 apparently didn\'t know the turret was loaded.'; +$DeathMessageTurretSelfKill[2] = '\c0%1 helps his team by killing himself with a turret.'; + + + diff --git a/scripts/defaultGame.cs b/scripts/defaultGame.cs index 438fe6e..8b9646e 100644 --- a/scripts/defaultGame.cs +++ b/scripts/defaultGame.cs @@ -1,3812 +1,3812 @@ -//$MissionName is the file name of the mission -//$MapName is the displayed name(no underscore,spaces) -//$GameType (CTF,Hunters) - - -function DefaultGame::activatePackages(%game) -{ - // activate the default package for the game type - activatePackage(DefaultGame); - if(isPackage(%game.class) && %game.class !$= DefaultGame) - activatePackage(%game.class); -} - -function DefaultGame::deactivatePackages(%game) -{ - deactivatePackage(DefaultGame); - if(isPackage(%game.class) && %game.class !$= DefaultGame) - deactivatePackage(%game.class); -} - -package DefaultGame { - -function FlipFlop::objectiveInit(%data, %flipflop) -{ - // add this flipflop to missioncleanup - %flipflopSet = nameToID("MissionCleanup/FlipFlops"); - if(%flipflopSet <= 0) { - %flipflopSet = new SimSet("FlipFlops"); - MissionCleanup.add(%flipflopSet); - } - %flipflopSet.add(%flipflop); - - // see if there's a holo projector associated with this flipflop - // search the flipflop's folder for a holo projector - // if one exists, associate it with the flipflop - - %flipflop.projector = 0; - %folder = %flipflop.getGroup(); - for(%i = 0; %i < %folder.getCount(); %i++) - { - %proj = %folder.getObject(%i); - // weird, but line below prevents console error - if(%proj.getClassName() !$= "SimGroup" && %proj.getClassName() !$= "InteriorInstance") - if(%proj.getDatablock().getName() $= "LogoProjector") - { - %flipflop.projector = %proj; - %flipflop.projector.holo = 0; - break; - } - } - - // may have been hidden - %target = %flipFlop.getTarget(); - if(%target != -1) - { - // set flipflop to base skin - setTargetSkin(%target, $teamSkin[0]); - - // make this always visible in the commander map - setTargetAlwaysVisMask(%target, 0xffffffff); - - // make this always visible in the commander list - setTargetRenderMask(%target, getTargetRenderMask(%target) | $TargetInfo::CommanderListRender); - } -} - -function FlipFlop::playerTouch(%data, %flipflop, %player) -{ - %client = %player.client; - %flipTeam = %flipflop.team; - - if(%flipTeam == %client.team) - return false; - - %teamName = game.getTeamName(%client.team); - // Let the observers know: - messageTeam( 0, 'MsgClaimFlipFlop', '\c2%1 claimed %2 for %3.~wfx/misc/flipflop_taken.wav', %client.name, Game.cleanWord( %flipflop.name ), %teamName ); - // Let the teammates know: - messageTeam( %client.team, 'MsgClaimFlipFlop', '\c2%1 claimed %2 for %3.~wfx/misc/flipflop_taken.wav', %client.name, Game.cleanWord( %flipflop.name ), %teamName ); - // Let the other team know: - %losers = %client.team == 1 ? 2 : 1; - messageTeam( %losers, 'MsgClaimFlipFlop', '\c2%1 claimed %2 for %3.~wfx/packs/shield_hit.wav', %client.name, Game.cleanWord( %flipflop.name ), %teamName ); // z0dd - ZOD, 10/30/02. Change flipflop lost sound - - logEcho(%client.nameBase@" (pl "@%player@"/cl "@%client@") claimed flipflop "@%flipflop@" for team "@%client.team); - - //change the skin on the switch to claiming team's logo - setTargetSkin(%flipflop.getTarget(), game.getTeamSkin(%player.team)); - setTargetSensorGroup(%flipflop.getTarget(), %player.team); - - // if there is a "projector" associated with this flipflop, put the claiming team's logo there - if(%flipflop.projector > 0) - { - %projector = %flipflop.projector; - // axe the old projected holo, if one exists - if(%projector.holo > 0) - %projector.holo.delete(); - - %newHolo = getTaggedString(game.getTeamSkin(%client.team)) @ "Logo"; - - %projTransform = %projector.getTransform(); - // below two functions are from deployables.cs - %projRot = rotFromTransform(%projTransform); - %projPos = posFromTransform(%projTransform); - // place the holo above the projector (default 10 meters) - %hHeight = %projector.holoHeight; - if(%hHeight $= "") - %hHeight = 10; - %holoZ = getWord(%projPos, 2) + %hHeight; - %holoPos = firstWord(%projPos) SPC getWord(%projPos,1) SPC %holoZ; - - %holo = new StaticShape() - { - rotation = %projRot; - position = %holoPos; - dataBlock = %newHolo; - }; - // dump the hologram into MissionCleanup - MissionCleanup.add(%holo); - // associate the holo with the projector - %projector.holo = %holo; - } - - // convert the resources associated with the flipflop - Game.claimFlipflopResources(%flipflop, %client.team); - - if(Game.countFlips()) - for(%i = 1; %i <= Game.numTeams; %i++) - { - %teamHeld = Game.countFlipsHeld(%i); - messageAll('MsgFlipFlopsHeld', "", %i, %teamHeld); - } - - //call the ai function - Game.AIplayerCaptureFlipFlop(%player, %flipflop); - return true; -} - -}; - -//--------- DEFAULT SCORING, SUPERCEDE IN GAMETYPE FILE ------------------ - -function DefaultGame::initGameVars(%game) -{ - %game.SCORE_PER_SUICIDE = 0; - %game.SCORE_PER_TEAMKILL = 0; - %game.SCORE_PER_DEATH = 0; - - %game.SCORE_PER_KILL = 0; - - %game.SCORE_PER_TURRET_KILL = 0; -} - -//-- tracking --- -// .deaths .kills .suicides .teamKills .turretKills - -function DefaultGame::claimFlipflopResources(%game, %flipflop, %team) -{ - %group = %flipflop.getGroup(); - %group.setTeam(%team); - - // make this always visible in the commander map (gets reset when sensor group gets changed) - setTargetAlwaysVisMask(%flipflop.getTarget(), 0xffffffff); -} - -//------------------------------------------------------------------------------ -function DefaultGame::selectSpawnSphere(%game, %team) -{ - // - walks the objects in the 'teamdrops' group for this team - // - find a random spawn point which has a running sum less more than - // 0->total sphere weight - - %teamDropsGroup = "MissionCleanup/TeamDrops" @ %team; - - %group = nameToID(%teamDropsGroup); - if (%group != -1) - { - %count = %group.getCount(); - if (%count != 0) - { - // Get total weight of those spheres not filtered by mission types list- - %overallWeight = 0; - for (%i = 0; %i < %count; %i++) - { - %sphereObj = %group.getObject(%i); - if ( ! %sphereObj.isHidden() ) - %overallWeight += %sphereObj.sphereWeight; - } - - if (%overallWeight > 0) - { - // Subtract a little from this as hedge against any rounding offness- - %randSum = getRandom(%overallWeight) - 0.05; - // echo("randSum = " @ %randSum); - - for (%i = 0; %i < %count; %i++) - { - %sphereObj = %group.getObject(%i); - if (! %sphereObj.isHidden()) - { - %randSum -= %sphereObj.sphereWeight; - if (%randSum <= 0) - { - // echo("Chose sphere " @ %i); - return %group.getObject(%i); // Found our sphere - } - } - } - error("Random spawn sphere selection didn't work"); - } - else - error("No non-hidden spawnspheres were found in " @ %teamDropsGroup); - } - else - error("No spawnspheres found in " @ %teamDropsGroup); - } - else - error(%teamDropsGroup @ " not found in selectSpawnSphere()."); - - return -1; -} - -function DefaultGame::selectSpawnZone(%game, %sphere) -{ - // determines if this should spawn inside or outside - %overallWeight = %sphere.indoorWeight + %sphere.outdoorWeight; - %index = mFloor(getRandom() * (%overallWeight - 0.1)) + 1; - if ((%index - %sphere.indoorWeight) > 0) - return false; //do not pick an indoor spawn - else - return true; //pick an indoor spawn -} - -function DefaultGame::selectSpawnFacing(%game, %src, %target, %zone) -{ - //this used only when spawn loc is not on an interior. This points spawning player to the ctr of spawnshpere - %target = setWord(%target, 2, 0); - %src = setWord(%src, 2, 0); - - if(VectorDist(%target, %src) == 0) - return " 0 0 1 0 "; - %vec = VectorNormalize(VectorSub(%target, %src)); - %angle = mAcos(getWord(%vec, 1)); - - if(%src < %target) - return(" 0 0 1 " @ %angle); - else - return(" 0 0 1 " @ -%angle); -} - -function DefaultGame::pickTeamSpawn(%game, %team) -{ - // early exit if no nav graph - if (!navGraphExists()) - { - echo("No navigation graph is present. Build one."); - return -1; - } - - for (%attempt = 0; %attempt < 20; %attempt++) - { - // finds a random spawn sphere - // selects inside/outside on this random sphere - // if the navgraph exists, then uses it to grab a random node as spawn - // location/rotation - %sphere = %game.selectSpawnSphere(%team); - if (%sphere == -1) - { - echo("No spawn spheres found for team " @ %team); - return -1; - } - - %zone = %game.selectSpawnZone(%sphere); - %useIndoor = %zone; - %useOutdoor = !%zone; - if (%zone) - %area = "indoor"; - else - %area = "outdoor"; - - %radius = %sphere.radius; - %sphereTrans = %sphere.getTransform(); - %sphereCtr = getWord(%sphereTrans, 0) @ " " @ getWord(%sphereTrans, 1) @ " " @ getWord(%sphereTrans, 2); //don't need full transform here, just x, y, z - //echo("Selected Sphere is " @ %sphereCtr @ " with a radius of " @ %radius @ " meters. Selecting from " @ %area @ " zone."); - - %avoidThese = $TypeMasks::VehicleObjectType | $TypeMasks::MoveableObjectType | - $TypeMasks::PlayerObjectType | $TypeMasks::TurretObjectType; - - for (%tries = 0; %tries < 10; %tries++) - { - %nodeIndex = navGraph.randNode(%sphereCtr, %radius, %useIndoor, %useOutdoor); - if (%nodeIndex >= 0) - { - %loc = navGraph.randNodeLoc(%nodeIndex); - %adjUp = VectorAdd(%loc, "0 0 1.0"); // don't go much below - - if (ContainerBoxEmpty( %avoidThese, %adjUp, 2.0)) - break; - } - } - - if (%nodeIndex >= 0) - { - %loc = navGraph.randNodeLoc(%nodeIndex); - if (%zone) - { - %trns = %loc @ " 0 0 1 0"; - %spawnLoc = whereToLook(%trns); - } - else - { - %rot = %game.selectSpawnFacing(%loc, %sphereCtr, %zone); - %spawnLoc = %loc @ %rot; - } - return %spawnLoc; - } - } -} - -//------------------------------------------------------------ - -function DefaultGame::pickObserverSpawn(%game, %client, %next) -{ - %group = nameToID("MissionGroup/ObserverDropPoints"); - %count = %group.getCount(); - - if(!%count || %group == -1) - { - echo("no observer spawn points found"); - return -1; - } - - if(%client.lastObserverSpawn == -1) - { - %client.lastObserverSpawn = 0; - return(%group.getObject(%client.lastObserverSpawn)); - } - - if(%next == true) - %spawnIdx = %client.lastObserverSpawn + 1; - else - %spawnIdx = %client.lastObserverSpawn - 1; - - if(%spawnIdx < 0) - %spawnIdx = %count - 1; - else if(%spawnIdx >= %count) - %spawnIdx = 0; - - %client.lastObserverSpawn = %spawnIdx; - //echo("Observer spawn point found"); - return %group.getObject(%spawnIdx); -} - -//------------------------------------------------------------ -function DefaultGame::spawnPlayer( %game, %client, %respawn ) -{ - %client.lastSpawnPoint = %game.pickPlayerSpawn( %client, false ); - %client.suicidePickRespawnTime = getSimTime() + 20000; - %game.createPlayer( %client, %client.lastSpawnPoint, %respawn ); -} - -//------------------------------------------------------------ -function DefaultGame::playerSpawned(%game, %player) -{ - if( %player.client.respawnTimer ) - cancel(%player.client.respawnTimer); - - %player.client.observerStartTime = ""; - %game.equip(%player); - - //set the spawn time (for use by the AI system) - %player.client.spawnTime = getSimTime(); - -// jff: this should probably be checking the team of the client - //update anyone observing this client - %count = ClientGroup.getCount(); - for (%i = 0; %i < %count; %i++) - { - %cl = ClientGroup.getObject(%i); - if (%cl.camera.mode $= "observerFollow" && %cl.observeClient == %player.client) - { - %transform = %player.getTransform(); - %cl.camera.setOrbitMode(%player, %transform, 0.5, 4.5, 4.5); - %cl.camera.targetObj = %player; - } - } -} - -function DefaultGame::equip(%game, %player) -{ - for(%i =0; %i<$InventoryHudCount; %i++) - %player.client.setInventoryHudItem($InventoryHudData[%i, itemDataName], 0, 1); - %player.client.clearBackpackIcon(); - - //%player.setArmor("Light"); - %player.setInventory(RepairKit,1); - %player.setInventory(Grenade,6); - %player.setInventory(Blaster,1); - %player.setInventory(Disc,1); - %player.setInventory(Chaingun, 1); - %player.setInventory(ChaingunAmmo, 100); - %player.setInventory(DiscAmmo, 20); - %player.setInventory(Beacon, 3); - %player.setInventory(TargetingLaser, 1); - %player.weaponCount = 3; - - if (%player.client.race $= "Draakan") - %player.setInventory(Flamer,1); - - %player.use("Blaster"); -} - -//------------------------------------------------------------ -function DefaultGame::pickPlayerSpawn(%game, %client, %respawn) -{ - // place this client on his own team, '%respawn' does not ever seem to be used - //we no longer care whether it is a respawn since all spawns use same points. - return %game.pickTeamSpawn(%client.team); -} - -//------------------------------------------------------------ -function DefaultGame::createPlayer(%game, %client, %spawnLoc, %respawn) -{ - // do not allow a new player if there is one (not destroyed) on this client - if(isObject(%client.player) && (%client.player.getState() !$= "Dead")) - return; - - // clients and cameras can exist in team 0, but players should not - if(%client.team == 0) - error("Players should not be added to team0!"); - - // defaultplayerarmor is in 'players.cs' - if(%spawnLoc == -1) - %spawnLoc = "0 0 300 1 0 0 0"; - //else - // echo("Spawning player at " @ %spawnLoc); - - //Apparent game errors for bots spawned manually. - if (%client.race $= "") - %client.race = "Human"; - if (%client.sex $= "") - %client.sex = "Male"; - - // copied from player.cs - if (%client.race $= "Bioderm") - // Only have male bioderms. - %armor = $DefaultPlayerArmor @ "Male" @ %client.race @ Armor; - else - %armor = $DefaultPlayerArmor @ %client.sex @ %client.race @ Armor; - %client.armor = $DefaultPlayerArmor; - - - %player = new Player() { - //dataBlock = $DefaultPlayerArmor; - dataBlock = %armor; - shouldBurn = true; //So the Draakans can burn meh. - }; - - - if(%respawn) - { - %player.setInvincible(true); - //%player.setCloaked(true); // z0dd - ZOD, 8/6/02. Don't spawn players cloaked - %player.setInvincibleMode($InvincibleTime,0.02); - //%player.respawnCloakThread = %player.schedule($InvincibleTime * 1000, "setRespawnCloakOff"); // z0dd - ZOD, 8/6/02. Don't spawn players cloaked - %player.schedule($InvincibleTime * 1000, "setInvincible", false); - } - - %player.setTransform( %spawnLoc ); - MissionCleanup.add(%player); - - // setup some info - %player.setOwnerClient(%client); - %player.team = %client.team; - %client.outOfBounds = false; - %player.setEnergyLevel(60); - %client.player = %player; - - // updates client's target info for this player - %player.setTarget(%client.target); - setTargetDataBlock(%client.target, %player.getDatablock()); - setTargetSensorData(%client.target, PlayerSensor); - setTargetSensorGroup(%client.target, %client.team); - %client.setSensorGroup(%client.team); - - //make sure the player has been added to the team rank array... - %game.populateTeamRankArray(%client); - - %game.playerSpawned(%client.player); -} - -function Player::setRespawnCloakOff(%player) -{ - %player.setCloaked(false); - %player.respawnCloakThread = ""; -} - -//------------------------------------------------------------ - -function DefaultGame::startMatch(%game) -{ - echo("START MATCH"); - MessageAll('MsgMissionStart', "\c2Match started!"); - - //the match has been started, clear the team rank array, and repopulate it... - for (%i = 0; %i < 32; %i++) - %game.clearTeamRankArray(%i); - - //used in BountyGame, prolly in a few others as well... - $matchStarted = true; - - %game.clearDeployableMaxes(); - - $missionStartTime = getSimTime(); - %curTimeLeftMS = ($Host::TimeLimit * 60 * 1000); - - // schedule first timeLimit check for 20 seconds - if(%game.class !$= "SiegeGame") - { - %game.timeCheck = %game.schedule(20000, "checkTimeLimit"); - } - - //schedule the end of match countdown - EndCountdown($Host::TimeLimit * 60 * 1000); - - //reset everyone's score and add them to the team rank array - for (%i = 0; %i < ClientGroup.getCount(); %i++) - { - %cl = ClientGroup.getObject(%i); - %game.resetScore(%cl); - %game.populateTeamRankArray(%cl); - } - - // set all clients control to their player - %count = ClientGroup.getCount(); - for( %i = 0; %i < %count; %i++ ) - { - %cl = ClientGroup.getObject(%i); - - // Siege game will set the clock differently - if(%game.class !$= "SiegeGame") - messageClient(%cl, 'MsgSystemClock', "", $Host::TimeLimit, %curTimeLeftMS); - - if( !$Host::TournamentMode && %cl.matchStartReady && %cl.camera.mode $= "pre-game") - { - commandToClient(%cl, 'setHudMode', 'Standard'); - %cl.setControlObject( %cl.player ); - } - else - { - if( %cl.matchStartReady ) - { - if(%cl.camera.mode $= "pre-game") - { - %cl.observerMode = ""; - commandToClient(%cl, 'setHudMode', 'Standard'); - - if(isObject(%cl.player)) - %cl.setControlObject( %cl.player ); - else - echo("can't set control for client: " @ %cl @ ", no player object found!"); - } - else - %cl.observerMode = "observerFly"; - } - } - } - - // on with the show this is it! - AISystemEnabled( true ); -} - -function DefaultGame::gameOver( %game ) -{ - //set the bool - $missionRunning = false; - - //Since gameOver can't be called for RPG, tell the game to save any vars in memory - saveGame(); - - CancelCountdown(); - CancelEndCountdown(); - - //loop through all the clients, and do any cleanup... - %count = ClientGroup.getCount(); - for (%i = 0; %i < %count; %i++) - { - %client = ClientGroup.getObject(%i); - %player = %client.player; - - // z0dd - ZOD, 6/13/02. Need to remove this for random teams by Founder (founder@mechina.com). - if($CurrentMissionType $= TR2) // z0dd - ZOD, 9/17/02. Check for Team Rabbit 2 - %client.lastTeam = %client.team; - - if ( !%client.isAiControlled() ) - { - %client.endMission(); - messageClient( %client, 'MsgClearDebrief', "" ); - %game.sendDebriefing( %client ); - - if(%client.player.isBomber) - commandToClient(%client, 'endBomberSight'); - - //clear the score hud... - messageClient( %client, 'SetScoreHudHeader', "", "" ); - messageClient( %client, 'SetScoreHudSubheader', "", ""); - messageClient( %client, 'ClearHud', "", 'scoreScreen', 0 ); - - // clean up the players' HUDs: - %client.setWeaponsHudClearAll(); - %client.setInventoryHudClearAll(); - } - } - // z0dd - ZOD, 6/22/02. Setup random teams by Founder (founder@mechina.com). - if($CurrentMissionType !$= TR2) // z0dd - ZOD, 9/17/02. Check for Team Rabbit 2 - %game.setupClientTeams(); - - // Default game does nothing... except lets the AI know the mission is over - AIMissionEnd(); -} - -//------------------------------------------------------------------------------ -function DefaultGame::sendDebriefing( %game, %client ) -{ - if ( %game.numTeams == 1 ) - { - // Mission result: - %winner = $TeamRank[0, 0]; - if ( %winner.score > 0 ) - messageClient( %client, 'MsgDebriefResult', "", '%1 wins!', $TeamRank[0, 0].name ); - else - messageClient( %client, 'MsgDebriefResult', "", 'Nobody wins.' ); - - // Player scores: - %count = $TeamRank[0, count]; - messageClient( %client, 'MsgDebriefAddLine', "", 'PLAYERSCOREKILLS' ); - for ( %i = 0; %i < %count; %i++ ) - { - %cl = $TeamRank[0, %i]; - if ( %cl.score $= "" ) - %score = 0; - else - %score = %cl.score; - if ( %cl.kills $= "" ) - %kills = 0; - else - %kills = %cl.kills; - messageClient( %client, 'MsgDebriefAddLine', "", ' %1 %2 %3', %cl.name, %score, %kills ); - } - } - else - { - %topScore = ""; - %topCount = 0; - for ( %team = 1; %team <= %game.numTeams; %team++ ) - { - if ( %topScore $= "" || $TeamScore[%team] > %topScore ) - { - %topScore = $TeamScore[%team]; - %firstTeam = %team; - %topCount = 1; - } - else if ( $TeamScore[%team] == %topScore ) - { - %secondTeam = %team; - %topCount++; - } - } - - // Mission result: - if ( %topCount == 1 ) - messageClient( %client, 'MsgDebriefResult', "", 'Team %1 wins!', %game.getTeamName(%firstTeam) ); - else if ( %topCount == 2 ) - messageClient( %client, 'MsgDebriefResult', "", 'Team %1 and Team %2 tie!', %game.getTeamName(%firstTeam), %game.getTeamName(%secondTeam) ); - else - messageClient( %client, 'MsgDebriefResult', "", 'The mission ended in a tie.' ); - - // Team scores: - messageClient( %client, 'MsgDebriefAddLine', "", 'TEAMSCORE' ); - for ( %team = 1; %team - 1 < %game.numTeams; %team++ ) - { - if ( $TeamScore[%team] $= "" ) - %score = 0; - else - %score = $TeamScore[%team]; - messageClient( %client, 'MsgDebriefAddLine', "", ' %1 %2', %game.getTeamName(%team), %score ); - } - - // Player scores: - messageClient( %client, 'MsgDebriefAddLine', "", '\nPLAYERTEAMSCOREKILLS' ); - for ( %team = 1; %team - 1 < %game.numTeams; %team++ ) - %count[%team] = 0; - - %notDone = true; - while ( %notDone ) - { - // Get the highest remaining score: - %highScore = ""; - for ( %team = 1; %team <= %game.numTeams; %team++ ) - { - if ( %count[%team] < $TeamRank[%team, count] && ( %highScore $= "" || $TeamRank[%team, %count[%team]].score > %highScore ) ) - { - %highScore = $TeamRank[%team, %count[%team]].score; - %highTeam = %team; - } - } - - // Send the debrief line: - %cl = $TeamRank[%highTeam, %count[%highTeam]]; - %score = %cl.score $= "" ? 0 : %cl.score; - %kills = %cl.kills $= "" ? 0 : %cl.kills; - messageClient( %client, 'MsgDebriefAddLine', "", ' %1 %2 %3 %4', %cl.name, %game.getTeamName(%cl.team), %score, %kills ); - - %count[%highTeam]++; - %notDone = false; - for ( %team = 1; %team - 1 < %game.numTeams; %team++ ) - { - if ( %count[%team] < $TeamRank[%team, count] ) - { - %notDone = true; - break; - } - } - } - } - - //now go through an list all the observers: - %count = ClientGroup.getCount(); - %printedHeader = false; - for (%i = 0; %i < %count; %i++) - { - %cl = ClientGroup.getObject(%i); - if (%cl.team <= 0) - { - //print the header only if we actually find an observer - if (!%printedHeader) - { - %printedHeader = true; - messageClient(%client, 'MsgDebriefAddLine', "", '\nOBSERVERSSCORE'); - } - - //print out the client - %score = %cl.score $= "" ? 0 : %cl.score; - messageClient( %client, 'MsgDebriefAddLine', "", ' %1 %2', %cl.name, %score); - } - } -} - -//------------------------------------------------------------ -function DefaultGame::clearDeployableMaxes(%game) -{ - for(%i = 0; %i <= %game.numTeams; %i++) - { - $TeamDeployedCount[%i, TurretIndoorDeployable] = 0; - $TeamDeployedCount[%i, TurretOutdoorDeployable] = 0; - $TeamDeployedCount[%i, PulseSensorDeployable] = 0; - $TeamDeployedCount[%i, MotionSensorDeployable] = 0; - $TeamDeployedCount[%i, InventoryDeployable] = 0; - $TeamDeployedCount[%i, DeployedCamera] = 0; - $TeamDeployedCount[%i, MineDeployed] = 0; - $TeamDeployedCount[%i, TargetBeacon] = 0; - $TeamDeployedCount[%i, MarkerBeacon] = 0; - } -} - -// called from player scripts -function DefaultGame::onClientDamaged(%game, %clVictim, %clAttacker, %damageType, %sourceObject) -{ - //set the vars if it was a turret - if (isObject(%sourceObject)) - { - %sourceClassType = %sourceObject.getDataBlock().getClassName(); - %sourceType = %sourceObject.getDataBlock().getName(); - } - - if (%sourceClassType $= "TurretData") - { - // jff: are there special turret types which makes this needed? - // tinman: yes, we don't want bots stopping to fire on the big outdoor turrets, which they - // will just get mowed down. deployables only. - if (%sourceType $= "TurretDeployedFloorIndoor" || %sourceType $= "TurretDeployedWallIndoor" || - %sourceType $= "TurretDeployedCeilingIndoor" || %sourceType $= "TurretDeployedOutdoor") - { - %clVictim.lastDamageTurretTime = getSimTime(); - %clVictim.lastDamageTurret = %sourceObject; - } - - %turretAttacker = %sourceObject.getControllingClient(); - - //------------------------------------------------------------------- - // z0dd - ZOD, 5/29/02. Play a sound to client when they hit a player - if(%turretAttacker) - { - %client = %turretAttacker; - } - //------------------------------------------------------------------- - - // should get a damagae message from friendly fire turrets also - if(%turretAttacker && %turretAttacker != %clVictim && %turretAttacker.team == %clVictim.team) - { - if (%game.numTeams > 1 && %turretAttacker.player.causedRecentDamage != %clVictim.player) //is a teamgame & player just damaged a teammate - { - %turretAttacker.player.causedRecentDamage = %clVictim.player; - %turretAttacker.player.schedule(1000, "causedRecentDamage", ""); //allow friendly fire message every x ms - %game.friendlyFireMessage(%clVictim, %turretAttacker); - } - } - } - else if (%sourceClassType $= "PlayerData") - { - %client = %clAttacker; // z0dd - ZOD, 5/29/02. Play a sound to client when they hit a player - //now see if both were on the same team - if(%clAttacker && %clAttacker != %clVictim && %clVictim.team == %clAttacker.team) - { - if (%game.numTeams > 1 && %clAttacker.player.causedRecentDamage != %clVictim.player) //is a teamgame & player just damaged a teammate - { - %clAttacker.player.causedRecentDamage = %clVictim.player; - %clAttacker.player.schedule(1000, "causedRecentDamage", ""); //allow friendly fire message every x ms - %game.friendlyFireMessage(%clVictim, %clAttacker); - } - } - if (%clAttacker && %clAttacker != %clVictim) - { - %clVictim.lastDamageTime = getSimTime(); - %clVictim.lastDamageClient = %clAttacker; - if (%clVictim.isAIControlled()) - %clVictim.clientDetected(%clAttacker); - } - } - // ------------------------------------------------------------------ - // z0dd - ZOD, 5/29/02. Play a sound to client when they hit a player - else if( %sourceClassType $= "WheeledVehicleData" || - %sourceClassType $= "FlyingVehicleData" || - %sourceClassType $= "HoverVehicleData" ) - { - if (%sourceObject.getControllingClient()) - { - %client = %sourceObject.getControllingClient(); - } - } - - if ( %client && %client.playerHitSound && ($CurrentMissionType !$= TR2)) - { - // 1) Blaster - // 2) Plasma Gun - // 3) Chaingun - // 4) Disc - // 5) Grenades (GL and hand) - // 6) Laser - // 8) Mortar - // 9) Missile - // 10) ShockLance - - // 13) Impact (object to object) - - // 16) Plasma Turret - // 17) AA Turret - // 18) ELF Turret - // 19) Mortar Turret - // 20) Missile Turret - // 21) Indoor Deployable Turret - // 22) Outdoor Deployable Turret - // 23) Sentry Turret - - // 26) Shrike Blaster - // 27) Bobmer Plasma - // 28) Bomber Bomb - // 29) Tank Chaingun - // 30) Tank Mortar - // 31) Satchel - if (%client.team != %clVictim.team) - { - if ((%damageType > 0 && %damageType < 11) || - (%damageType == 13) || - (%damageType > 15 && %damageType < 24) || - (%damageType > 25 && %damageType < 32)) - { - messageClient(%client, 'MsgClientHit', %client.playerHitWav); - } - } - } - // ------------------------------------------------------------------ - - //call the game specific AI routines... - if (isObject(%clVictim) && %clVictim.isAIControlled()) - %game.onAIDamaged(%clVictim, %clAttacker, %damageType, %sourceObject); - if (isObject(%clAttacker) && %clAttacker.isAIControlled()) - %game.onAIFriendlyFire(%clVictim, %clAttacker, %damageType, %sourceObject); -} - -function DefaultGame::friendlyFireMessage(%game, %damaged, %damager) -{ - messageClient(%damaged, 'MsgDamagedByTeam', '\c1You were harmed by teammate %1', %damager.name); - messageClient(%damager, 'MsgDamagedTeam', '\c1You just harmed teammate %1.', %damaged.name); -} - -function DefaultGame::clearWaitRespawn(%game, %client) -{ - %client.waitRespawn = 0; -} - -// called from player scripts -function DefaultGame::onClientKilled(%game, %clVictim, %clKiller, %damageType, %implement, %damageLocation) -{ - -if ($CurrentMissionType !$= "RPG") -{ - if (%clVictim == %clKiller) //We suicided. - $Data::Suicides[%clVictim.guid]++; - - //Increment killer's kill count and victim's death count - if (%clKiller != %clVictim && isObject(%clKiller)) - { - $Data::Kills[%clKiller.guid]++; - $Data::Deaths[%clVictim.guid]++; - } -} - - %plVictim = %clVictim.player; - %plKiller = %clKiller.player; - %clVictim.plyrPointOfDeath = %plVictim.position; - %clVictim.plyrDiedHoldingFlag = %plVictim.holdingFlag; - %clVictim.waitRespawn = 1; - - cancel(%obj.reloadSchedule); // z0dd - ZOD, 9/3/02. Cancel rapid wpn fire fix scheduler - cancel( %plVictim.reCloak ); - cancel(%clVictim.respawnTimer); - %clVictim.respawnTimer = %game.schedule(($Host::PlayerRespawnTimeout * 1000), "forceObserver", %clVictim, "spawnTimeout" ); - - // reset the alarm for out of bounds - if(%clVictim.outOfBounds) - messageClient(%clVictim, 'EnterMissionArea', ""); - - if (%damageType == $DamageType::suicide) - %respawnDelay = 2; // z0dd - ZOD, 4/24/02. Was 10 - else - %respawnDelay = 2; - - %game.schedule(%respawnDelay*1000, "clearWaitRespawn", %clVictim); - // if victim had an undetonated satchel charge pack, get rid of it - if(%plVictim.thrownChargeId != 0) - if(!%plVictim.thrownChargeId.kaboom) - %plVictim.thrownChargeId.delete(); - - if(%plVictim.lastVehicle !$= "") - { - schedule(15000, %plVictim.lastVehicle,"vehicleAbandonTimeOut", %plVictim.lastVehicle); - %plVictim.lastVehicle.lastPilot = ""; - } - - // unmount pilot or remove sight from bomber - if(%plVictim.isMounted()) - { - if(%plVictim.vehicleTurret) - %plVictim.vehicleTurret.getDataBlock().playerDismount(%plVictim.vehicleTurret); - else - { - %plVictim.getDataBlock().doDismount(%plVictim, true); - %plVictim.mountVehicle = false; - } - } - - if(%plVictim.inStation) - commandToClient(%plVictim.client,'setStationKeys', false); - %clVictim.camera.mode = "playerDeath"; - - // reset who triggered this station and cancel outstanding armor switch thread - if(%plVictim.station) - { - %plVictim.station.triggeredBy = ""; - %plVictim.station.getDataBlock().stationTriggered(%plVictim.station,0); - if(%plVictim.armorSwitchSchedule) - cancel(%plVictim.armorSwitchSchedule); - } - - //Close huds if player dies... - messageClient(%clVictim, 'CloseHud', "", 'inventoryScreen'); - messageClient(%clVictim, 'CloseHud', "", 'vehicleHud'); - commandToClient(%clVictim, 'setHudMode', 'Standard', "", 0); - - // $weaponslot from item.cs - %plVictim.setRepairRate(0); - %plVictim.setImageTrigger($WeaponSlot, false); - - playDeathAnimation(%plVictim, %damageLocation, %damageType); - playDeathCry(%plVictim); - - %victimName = %clVictim.name; - - %game.displayDeathMessages(%clVictim, %clKiller, %damageType, %implement); - %game.updateKillScores(%clVictim, %clKiller, %damageType, %implement); - - // toss whatever is being carried, '$flagslot' from item.cs - // MES - had to move this to after death message display because of Rabbit game type - for(%index = 0 ; %index < 8; %index++) - { - %image = %plVictim.getMountedImage(%index); - if(%image) - { - if(%index == $FlagSlot) - %plVictim.throwObject(%plVictim.holdingFlag); - else - %plVictim.throw(%image.item); - } - } - - // target manager update - setTargetDataBlock(%clVictim.target, 0); - setTargetSensorData(%clVictim.target, 0); - - // clear the hud - %clVictim.SetWeaponsHudClearAll(); - %clVictim.SetInventoryHudClearAll(); - %clVictim.setAmmoHudCount(-1); - - // clear out weapons, inventory and pack huds - messageClient(%clVictim, 'msgDeploySensorOff', ""); //make sure the deploy hud gets shut off - messageClient(%clVictim, 'msgPackIconOff', ""); // clear the pack icon - - //clear the deployable HUD - %plVictim.client.deployPack = false; - cancel(%plVictim.deployCheckThread); - deactivateDeploySensor(%plVictim); - - //if the killer was an AI... - if (isObject(%clKiller) && %clKiller.isAIControlled()) - %game.onAIKilledClient(%clVictim, %clKiller, %damageType, %implement); - - - // reset control object on this player: also sets 'playgui' as content - serverCmdResetControlObject(%clVictim); - - // set control object to the camera - %clVictim.player = 0; - %transform = %plVictim.getTransform(); - - //note, AI's don't have a camera... - if (isObject(%clVictim.camera)) - { - %clVictim.camera.setTransform(%transform); - %clVictim.camera.setOrbitMode(%plVictim, %plVictim.getTransform(), 0.5, 4.5, 4.5); - %clVictim.setControlObject(%clVictim.camera); - } - - //hook in the AI specific code for when a client dies - if (%clVictim.isAIControlled()) - { - aiReleaseHumanControl(%clVictim.controlByHuman, %clVictim); - %game.onAIKilled(%clVictim, %clKiller, %damageType, %implement); - } - else - aiReleaseHumanControl(%clVictim, %clVictim.controlAI); - - //used to track corpses so the AI can get ammo, etc... - AICorpseAdded(%plVictim); - - //if the death was a suicide, prevent respawning for 5 seconds... - %clVictim.lastDeathSuicide = false; - if (%damageType == $DamageType::Suicide) - { - %clVictim.lastDeathSuicide = true; - %clVictim.suicideRespawnTime = getSimTime() + 1000; // z0dd - ZOD, 4/24/02. Was 5000 - } -} - -function DefaultGame::forceObserver( %game, %client, %reason ) -{ - //make sure we have a valid client... - if (%client <= 0) - return; - - // first kill this player - if(%client.player) - %client.player.scriptKill(0); - - if( %client.respawnTimer ) - cancel(%client.respawnTimer); - - %client.respawnTimer = ""; - - // remove them from the team rank array - %game.removeFromTeamRankArray(%client); - - // place them in observer mode - %client.lastObserverSpawn = -1; - %client.observerStartTime = getSimTime(); - %adminForce = 0; - - switch$ ( %reason ) - { - case "playerChoose": - %client.camera.getDataBlock().setMode( %client.camera, "observerFly" ); - messageClient(%client, 'MsgClientJoinTeam', '\c2You have become an observer.', %client.name, %game.getTeamName(0), %client, 0 ); - logEcho(%client.nameBase@" (cl "@%client@") entered observer mode"); - %client.lastTeam = %client.team; - - case "AdminForce": - %client.camera.getDataBlock().setMode( %client.camera, "observerFly" ); - messageClient(%client, 'MsgClientJoinTeam', '\c2You have been forced into observer mode by the admin.', %client.name, %game.getTeamName(0), %client, 0 ); - logEcho(%client.nameBase@" (cl "@%client@") was forced into observer mode by admin"); - %client.lastTeam = %client.team; - %adminForce = 1; - - if($Host::TournamentMode) - { - if(!$matchStarted) - { - if(%client.camera.Mode $= "pickingTeam") - { - commandToClient( %client, 'processPickTeam'); - clearBottomPrint( %client ); - } - else - { - clearCenterPrint(%client); - %client.notReady = true; - } - } - } - - case "spawnTimeout": - // DDDX: Fix for AI's derping this up - if (!IsObject(%client)) - return; - %client.camera.getDataBlock().setMode( %client.camera, "observerTimeout" ); - messageClient(%client, 'MsgClientJoinTeam', '\c2You have been placed in observer mode due to delay in respawning.', %client.name, %game.getTeamName(0), %client, 0 ); - logEcho(%client.nameBase@" (cl "@%client@") was placed in observer mode due to spawn delay"); - // save the team the player was on - only if this was a delay in respawning - %client.lastTeam = %client.team; - } - - // switch client to team 0 (observer) - %client.team = 0; - %client.player.team = 0; - setTargetSensorGroup( %client.target, %client.team ); - %client.setSensorGroup( %client.team ); - - // set their control to the obs. cam - %client.setControlObject( %client.camera ); - commandToClient(%client, 'setHudMode', 'Observer'); - - // display the hud - //displayObserverHud(%client, 0); - updateObserverFlyHud(%client); - - - // message everyone about this event - if( !%adminForce ) - messageAllExcept(%client, -1, 'MsgClientJoinTeam', '\c2%1 has become an observer.', %client.name, %game.getTeamName(0), %client, 0 ); - else - messageAllExcept(%client, -1, 'MsgClientJoinTeam', '\c2The admin has forced %1 to become an observer.', %client.name, %game.getTeamName(0), %client, 0 ); - - updateCanListenState( %client ); - - // call the onEvent for this game type - %game.onClientEnterObserverMode(%client); //Bounty uses this to remove this client from others' hit lists -} - -function DefaultGame::displayDeathMessages(%game, %clVictim, %clKiller, %damageType, %implement) -{ - // ---------------------------------------------------------------------------------- - // z0dd - ZOD, 6/18/02. From Panama Jack, send the damageTypeText as the last varible - // in each death message so client knows what weapon it was that killed them. - - // Handle Draakan genders - %victimSex = %clVictim.sex; - if (%victimSex $= "A" || %victimSex $= "B" || %victimSex $= "C") - %victimSex = "Male"; - %victimGender = (%victimSex $= "Male" ? 'him' : 'her'); - %victimPoss = (%victimSex $= "Male" ? 'his' : 'her'); - - %killerGender = (%clKiller.sex $= "Male" ? 'him' : 'her'); - %killerPoss = (%clKiller.sex $= "Male" ? 'his' : 'her'); - %victimGenderPoss = (%clVictim.sex $= "Male" ? 'he' : 'she'); - %killerGenderPoss = (%clKiller.sex $= "Male" ? 'he' : 'she'); - %victimName = %clVictim.name; - %killerName = %clKiller.name; - - //error("DamageType = " @ %damageType @ ", implement = " @ %implement @ ", implement class = " @ %implement.getClassName() @ ", is controlled = " @ %implement.getControllingClient()); - - if(%damageType == $DamageType::Explosion) - { - messageAll('msgExplosionKill', $DeathMessageExplosion[mFloor(getRandom() * $DeathMessageExplosionCount)], %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); - logEcho(%clVictim.nameBase@" (pl "@%clVictim.player@"/cl "@%clVictim@") killed by a nearby explosion."); - } - else if(%damageType == $DamageType::Suicide) //player presses cntrl-k - { - messageAll('msgSuicide', $DeathMessageSuicide[mFloor(getRandom() * $DeathMessageSuicideCount)], %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); - logEcho(%clVictim.nameBase@" (pl "@%clVictim.player@"/cl "@%clVictim@") committed suicide (CTRL-K)"); - } - else if(%damageType == $DamageType::VehicleSpawn) - { - messageAll('msgVehicleSpawnKill', $DeathMessageVehPad[mFloor(getRandom() * $DeathMessageVehPadCount)], %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); - logEcho(%clVictim.nameBase@" (pl "@%clVictim.player@"/cl "@%clVictim@") killed by vehicle spawn"); - } - else if(%damageType == $DamageType::ForceFieldPowerup) - { - messageAll('msgVehicleSpawnKill', $DeathMessageFFPowerup[mFloor(getRandom() * $DeathMessageFFPowerupCount)], %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); - logEcho(%clVictim.nameBase@" (pl "@%clVictim.player@"/cl "@%clVictim@") killed by Force Field Powerup"); - } - else if(%damageType == $DamageType::Crash) - { - messageAll('msgVehicleCrash', $DeathMessageVehicleCrash[%damageType, mFloor(getRandom() * $DeathMessageVehicleCrashCount)], %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); - logEcho(%clVictim.nameBase@" (pl "@%clVictim.player@"/cl "@%clVictim@") crashes a vehicle."); - } - else if(%damageType == $DamageType::Impact) // run down by vehicle - { - if( ( %controller = %implement.getControllingClient() ) > 0) - { - %killerGender = (%controller.sex $= "Male" ? 'him' : 'her'); - %killerPoss = (%controller.sex $= "Male" ? 'his' : 'her'); - %killerName = %controller.name; - messageAll('msgVehicleKill', $DeathMessageVehicle[mFloor(getRandom() * $DeathMessageVehicleCount)], %victimName, %victimGender, %victimPoss, %killerName ,%killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); - logEcho(%clVictim.nameBase@" (pl "@%clVictim.player@"/cl "@%clVictim@") killed by a vehicle controlled by "@%controller); - } - else - { - messageAll('msgVehicleKill', $DeathMessageVehicleUnmanned[mFloor(getRandom() * $DeathMessageVehicleUnmannedCount)], %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); - logEcho(%clVictim.nameBase@" (pl "@%clVictim.player@"/cl "@%clVictim@") killed by a vehicle (unmanned)"); - } - } - // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - // z0dd - ZOD, 5/15/02. Added Hover Vehicle so we get proper - // death messages when killed with Wildcat chaingun - //else if (isObject(%implement) && (%implement.getClassName() $= "Turret" || %implement.getClassName() $= "VehicleTurret" || %implement.getClassName() $= "FlyingVehicle")) //player killed by a turret - else if (isObject(%implement) && (%implement.getClassName() $= "Turret" || %implement.getClassName() $= "VehicleTurret" || %implement.getClassName() $= "FlyingVehicle" || %implement.getClassName() $= "HoverVehicle")) - { - if (%implement.getControllingClient() != 0) //is turret being controlled? - { - %controller = %implement.getControllingClient(); - %killerGender = (%controller.sex $= "Male" ? 'him' : 'her'); - %killerPoss = (%controller.sex $= "Male" ? 'his' : 'her'); - %killerName = %controller.name; - - if (%controller == %clVictim) - messageAll('msgTurretSelfKill', $DeathMessageTurretSelfKill[mFloor(getRandom() * $DeathMessageTurretSelfKillCount)],%victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); - else if (%controller.team == %clVictim.team) //controller TK'd a friendly - messageAll('msgCTurretKill', $DeathMessageCTurretTeamKill[%damageType, mFloor(getRandom() * $DeathMessageCTurretTeamKillCount)],%victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); - else //controller killed an enemy - messageAll('msgCTurretKill', $DeathMessageCTurretKill[%damageType, mFloor(getRandom() * $DeathMessageCTurretKillCount)],%victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); - logEcho(%clVictim.nameBase@" (pl "@%clVictim.player@"/cl "@%clVictim@") killed by a turret controlled by "@%controller); - } - // use the handle associated with the deployed object to verify valid owner - else if (isObject(%implement.owner)) - { - %owner = %implement.owner; - //error("Owner is " @ %owner @ " Handle is " @ %implement.ownerHandle); - //error("Turret is still owned"); - //turret is uncontrolled, but is owned - treat the same as controlled. - %killerGender = (%owner.sex $= "Male" ? 'him' : 'her'); - %killerPoss = (%owner.sex $= "Male" ? 'his' : 'her'); - %killerName = %owner.name; - - if (%owner.team == %clVictim.team) //player got in the way of a teammates deployed but uncontrolled turret. - messageAll('msgCTurretKill', $DeathMessageCTurretAccdtlKill[%damageType,mFloor(getRandom() * $DeathMessageCTurretAccdtlKillCount)],%victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); - else //deployed, uncontrolled turret killed an enemy - messageAll('msgCTurretKill', $DeathMessageCTurretKill[%damageType,mFloor(getRandom() * $DeathMessageCTurretKillCount)],%victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); - logEcho(%clVictim.nameBase@" (pl "@%clVictim.player@"/cl "@%clVictim@") was killed by turret (automated)"); - } - else //turret is not a placed (owned) turret (or owner is no longer on it's team), and is not being controlled - { - messageAll('msgTurretKill', $DeathMessageTurretKill[%damageType,mFloor(getRandom() * $DeathMessageTurretKillCount)],%victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); - logEcho(%clVictim.nameBase@" (pl "@%clVictim.player@"/cl "@%clVictim@") killed by turret"); - } - } - else if((%clKiller == %clVictim) || (%damageType == $DamageType::Ground)) //player killed himself or fell to death - { - messageAll('msgSelfKill', $DeathMessageSelfKill[%damageType,mFloor(getRandom() * $DeathMessageSelfKillCount)], %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); - logEcho(%clVictim.nameBase @ "(pl " @ %clVictim.player @ "/cl " @ %clVictim @ ") killed self (" @ getTaggedString($DamageTypeText[%damageType]) @ ")"); - } - - else if (%damageType == $DamageType::OutOfBounds) //killer died due to Out-of-Bounds damage - { - messageAll('msgOOBKill', $DeathMessageOOB[mFloor(getRandom() * $DeathMessageOOBCount)], %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); - logEcho(%clVictim.nameBase@" (pl "@%clVictim.player@"/cl "@%clVictim@") killed by out-of-bounds damage"); - } - - else if (%damageType == $DamageType::NexusCamping) //Victim died from camping near the nexus... - { - messageAll('msgCampKill', $DeathMessageCamping[mFloor(getRandom() * $DeathMessageCampingCount)], %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); - logEcho(%clVictim.nameBase@" (pl "@%clVictim.player@"/cl "@%clVictim@") killed for nexus camping"); - } - - else if(%clKiller.team == %clVictim.team) //was a TK - { - messageAll('msgTeamKill', $DeathMessageTeamKill[%damageType, mFloor(getRandom() * $DeathMessageTeamKillCount)], %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); - logEcho(%clVictim.nameBase@" (pl "@%clVictim.player@"/cl "@%clVictim@") teamkilled by "@%clKiller.nameBase@" (pl "@%clKiller.player@"/cl "@%clKiller@")"); - } - - else if (%damageType == $DamageType::Lava) //player died by falling in lava - { - messageAll('msgLavaKill', $DeathMessageLava[mFloor(getRandom() * $DeathMessageLavaCount)], %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); - logEcho(%clVictim.nameBase@" (pl "@%clVictim.player@"/cl "@%clVictim@") killed by lava"); - } - else if ( %damageType == $DamageType::Lightning ) // player was struck by lightning - { - messageAll('msgLightningKill', $DeathMessageLightning[mFloor(getRandom() * $DeathMessageLightningCount)], %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); - logEcho(%clVictim.nameBase@" (pl "@%clVictim.player@"/cl "@%clVictim@") killed by lightning"); - } - else if ( %damageType == $DamageType::Mine && !isObject(%clKiller) ) - { - error("Mine kill w/o source"); - messageAll('MsgRogueMineKill', $DeathMessageRogueMine[%damageType, mFloor(getRandom() * $DeathMessageRogueMineCount)], %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); - } - else //was a legitimate enemy kill - { - if(%damageType == 6 && (%clVictim.headShot)) - { - // laser headshot just occurred - messageAll('MsgHeadshotKill', $DeathMessageHeadshot[%damageType, mFloor(getRandom() * $DeathMessageHeadshotCount)], %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); - } - // ---------------------------------------------------- - // z0dd - ZOD, 8/25/02. Rear Lance hits - else if (%damageType == 10 && (%clVictim.rearshot)) - { - // shocklance rearshot just occurred - messageAll('MsgRearshotKill', $DeathMessageRearshot[%damageType, mFloor(getRandom() * $DeathMessageRearshotCount)], %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); - } - // ---------------------------------------------------- - else - messageAll('MsgLegitKill', $DeathMessage[%damageType, mFloor(getRandom() * $DeathMessageCount)], %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); - logEcho(%clVictim.nameBase @ " (pl " @ %clVictim.player @ "/cl " @ %clVictim @ ") killed by " @ %clKiller.nameBase @ " (pl " @ %clKiller.player @ "/cl " @%clKiller @ ") using " @ getTaggedString($DamageTypeText[%damageType])); - } -} - -function DefaultGame::assignClientTeam(%game, %client, %respawn ) -{ -//error("DefaultGame::assignClientTeam"); - // this function is overwritten in non-team mission types (e.g. DM) - // so these lines won't do anything - //if(!%game.numTeams) - //{ - // setTargetSkin(%client.target, %client.skin); - // return; - //} - - // camera is responsible for creating a player - // - counts the number of players per team - // - puts this player on the least player count team - // - sets the client's skin to the servers default - - %numPlayers = ClientGroup.getCount(); - for(%i = 0; %i <= %game.numTeams; %i++) - %numTeamPlayers[%i] = 0; - - for(%i = 0; %i < %numPlayers; %i = %i + 1) - { - %cl = ClientGroup.getObject(%i); - if(%cl != %client) - %numTeamPlayers[%cl.team]++; - } - %leastPlayers = %numTeamPlayers[1]; - %leastTeam = 1; - for(%i = 2; %i <= %game.numTeams; %i++) - { - if( (%numTeamPlayers[%i] < %leastPlayers) || - ( (%numTeamPlayers[%i] == %leastPlayers) && - ($teamScore[%i] < $teamScore[%leastTeam] ) )) - { - %leastTeam = %i; - %leastPlayers = %numTeamPlayers[%i]; - } - } - - %client.team = %leastTeam; - %client.lastTeam = %team; - - // Assign the team skin: - if ( %client.isAIControlled() ) - { - if ( %leastTeam & 1 ) - { - %client.skin = addTaggedString( "basebot" ); - setTargetSkin( %client.target, 'basebot' ); - } - else - { - %client.skin = addTaggedString( "basebbot" ); - setTargetSkin( %client.target, 'basebbot' ); - } - } - else - setTargetSkin( %client.target, %game.getTeamSkin(%client.team) ); - //setTargetSkin( %client.target, %client.skin ); - - // might as well standardize the messages - //messageAllExcept( %client, -1, 'MsgClientJoinTeam', '\c1%1 joined %2.', %client.name, $teamName[%leastTeam], %client, %leastTeam ); - //messageClient( %client, 'MsgClientJoinTeam', '\c1You joined the %2 team.', $client.name, $teamName[%client.team], %client, %client.team ); - messageAllExcept( %client, -1, 'MsgClientJoinTeam', '\c1%1 joined %2.', %client.name, %game.getTeamName(%client.team), %client, %client.team ); - messageClient( %client, 'MsgClientJoinTeam', '\c1You joined the %2 team.', %client.name, %game.getTeamName(%client.team), %client, %client.team ); - - updateCanListenState( %client ); - - logEcho(%client.nameBase@" (cl "@%client@") joined team "@%client.team); -} - -function DefaultGame::getTeamSkin(%game, %team) -{ - //error("DefaultGame::getTeamSkin"); - %skin = $teamSkin[%team]; - //error("%skin = " SPC getTaggedString(%skin)); - return %skin; -} - -function DefaultGame::getTeamName(%game, %team) -{ - //error("DefaultGame::getTeamName"); - %name = $teamName[%team]; - //error("name = " SPC getTaggedString(%name)); - return %name; -} - -function DefaultGame::clientJoinTeam( %game, %client, %team, %respawn ) -{ -//error("DefaultGame::clientJoinTeam"); - if ( %team < 1 || %team > %game.numTeams ) - return; - - if( %respawn $= "" ) - %respawn = 1; - - %client.team = %team; - %client.lastTeam = %team; - setTargetSkin( %client.target, %game.getTeamSkin(%team) ); - setTargetSensorGroup( %client.target, %team ); - %client.setSensorGroup( %team ); - - // Spawn the player: - %game.spawnPlayer( %client, %respawn ); - - messageAllExcept( %client, -1, 'MsgClientJoinTeam', '\c1%1 joined %2.', %client.name, %game.getTeamName(%team), %client, %team ); - messageClient( %client, 'MsgClientJoinTeam', '\c1You joined the %2 team.', $client.name, %game.getTeamName(%client.team), %client, %client.team ); - - updateCanListenState( %client ); - - logEcho(%client.nameBase@" (cl "@%client@") joined team "@%client.team); -} - -function DefaultGame::AIHasJoined(%game, %client) -{ - //defined to prevent console spam -} - -function DefaultGame::AIChangeTeam(%game, %client, %newTeam) -{ - //make sure we're trying to drop an AI - if (!isObject(%client) || !%client.isAIControlled()) - return; - - //clear the ai from any objectives, etc... - AIUnassignClient(%client); - %client.stop(); - %client.clearTasks(); - %client.clearStep(); - %client.lastDamageClient = -1; - %client.lastDamageTurret = -1; - %client.shouldEngage = -1; - %client.setEngageTarget(-1); - %client.setTargetObject(-1); - %client.pilotVehicle = false; - %client.defaultTasksAdded = false; - - //kill the player, which should cause the Game object to perform whatever cleanup is required. - if (isObject(%client.player)) - %client.player.scriptKill(0); - - //clean up the team rank array - %game.removeFromTeamRankArray(%client); - - //assign the new team - %client.team = %newTeam; - if (%newTeam < 0) - Game.assignClientTeam(%client); - else - { - if ( %client.team & 1 ) - { - %client.skin = addTaggedString( "basebot" ); - setTargetSkin( %client.target, 'basebot' ); - } - else - { - %client.skin = addTaggedString( "basebbot" ); - setTargetSkin( %client.target, 'basebbot' ); - } - } - - messageAllExcept( %client, -1, 'MsgClientJoinTeam', '\c1bot %1 has switched to team %2.', %client.name, %game.getTeamName(%client.team), %client, %client.team ); -} - -function DefaultGame::clientChangeTeam(%game, %client, %team, %fromObs, %respawned) // z0dd - ZOD, 6/06/02. Don't send a message if player used respawn feature. Added %respawned -{ -//error("DefaultGame::clientChangeTeam"); - //first, remove the client from the team rank array - //the player will be added to the new team array as soon as he respawns... - %game.removeFromTeamRankArray(%client); - - %pl = %client.player; - if(isObject(%pl)) - { - if(%pl.isMounted()) - %pl.getDataBlock().doDismount(%pl); - %pl.scriptKill(0); - } - - // reset the client's targets and tasks only - clientResetTargets(%client, true); - - // give this client a new handle to disassociate ownership of deployed objects - if( %team $= "" && (%team > 0 && %team <= %game.numTeams)) - { - if( %client.team == 1 ) - %client.team = 2; - else - %client.team = 1; - } - else - %client.team = %team; - - // Set the client's skin: - if (!%client.isAIControlled()) - setTargetSkin( %client.target, %game.getTeamSkin(%client.team) ); - setTargetSensorGroup( %client.target, %client.team ); - %client.setSensorGroup( %client.team ); - - // Spawn the player: - %client.lastSpawnPoint = %game.pickPlayerSpawn( %client ); - - %game.createPlayer( %client, %client.lastSpawnPoint, $MatchStarted ); - - if($MatchStarted) - %client.setControlObject(%client.player); - else - { - %client.camera.getDataBlock().setMode(%client.camera, "pre-game", %client.player); - %client.setControlObject(%client.camera); - } - - // call the onEvent for this game type - %game.onClientEnterObserverMode(%client); //Bounty uses this to remove this client from others' hit lists - - if(%fromObs $= "" || !%fromObs) - { - //------------------------------------------------------------------------- - // z0dd - ZOD, 6/06/02. Don't send a message if player used respawn feature - if(!%respawned) - { - messageAllExcept( %client, -1, 'MsgClientJoinTeam', '\c1%1 switched to team %2.', %client.name, %game.getTeamName(%client.team), %client, %client.team ); - messageClient( %client, 'MsgClientJoinTeam', '\c1You switched to team %2.', $client.name, %game.getTeamName(%client.team), %client, %client.team ); - } - //------------------------------------------------------------------------- - } - else - { - messageAllExcept( %client, -1, 'MsgClientJoinTeam', '\c1%1 joined team %2.', %client.name, %game.getTeamName(%client.team), %client, %team ); - messageClient( %client, 'MsgClientJoinTeam', '\c1You joined team %2.', $client.name, %game.getTeamName(%client.team), %client, %client.team ); - } - - updateCanListenState( %client ); - - // MES - switch objective hud lines when client switches teams - messageClient(%client, 'MsgCheckTeamLines', "", %client.team); - logEcho(%client.nameBase@" (cl "@%client@") switched to team "@%client.team); -} - -// missioncleanup and missiongroup are checked prior to entering game code -function DefaultGame::missionLoadDone(%game) -{ - // walks through the mission group and sets the power stuff up - // - groups get initialized with power count 0 then iterated to - // increment powercount if an object within is powered - // - powers objects up/down - //MissionGroup.objectiveInit(); - MissionGroup.clearPower(); - MissionGroup.powerInit(0); - - %game.initGameVars(); //set up scoring variables and other game specific globals - - // make team0 visible/friendly to all - setSensorGroupAlwaysVisMask(0, 0xffffffff); - setSensorGroupFriendlyMask(0, 0xffffffff); - - // update colors: - // - enemy teams are red - // - same team is green - // - team 0 is white - for(%i = 0; %i < 32; %i++) - { - %team = (1 << %i); - setSensorGroupColor(%i, %team, "0 255 0 255"); - setSensorGroupColor(%i, ~%team, "255 0 0 255"); - setSensorGroupColor(%i, 1, "255 255 255 255"); - - // setup the team targets (alwyas friendly and visible to same team) - setTargetAlwaysVisMask(%i, %team); - setTargetFriendlyMask(%i, %team); - } - - //set up the teams - %game.setUpTeams(); - - //clear out the team rank array... - for (%i = 0; %i < 32; %i++) - $TeamRank[%i, count] = ""; - - // objectiveInit has to take place after setupTeams -- objective HUD relies on flags - // having their team set - MissionGroup.objectiveInit(); - - //initialize the AI system - %game.aiInit(); - - //need to reset the teams if we switch from say, CTF to Bounty... - // assign the bots team - if ($currentMissionType !$= $previousMissionType) - { - $previousMissionType = $currentMissionType; - for(%i = 0; %i < ClientGroup.getCount(); %i++) - { - %cl = ClientGroup.getObject(%i); - if (%cl.isAIControlled()) - %game.assignClientTeam(%cl); - } - } - - //Save off respawn or Siege Team switch information... - if(%game.class !$= "SiegeGame") - MissionGroup.setupPositionMarkers(true); - echo("Default game mission load done."); -} - -function DefaultGame::onClientLeaveGame(%game, %client) -{ - // if there is a player attached to this client, kill it - if( isObject(%client.player)) - %client.player.scriptKill(0); - - //cancel a scheduled call... - cancel(%client.respawnTimer); - %client.respawnTimer = ""; - - //remove them from the team rank arrays - %game.removeFromTeamRankArray(%client); - logEcho(%client.nameBase@" (cl "@%client@") dropped"); -} - -function DefaultGame::clientMissionDropReady(%game, %client) -{ - //synchronize the clock HUD - messageClient(%client, 'MsgSystemClock', "", 0, 0); - - - %game.sendClientTeamList( %client ); - %game.setupClientHuds( %client ); - - if($CurrentMissionType $= "SinglePlayer") - { - //CommandToClient( %client, 'setPlayContent'); - return; - } - - %observer = false; - if( !$Host::TournamentMode ) - { - if( %client.camera.mode $= "observerFly" || %client.camera.mode $= "justJoined") - { - %observer = true; - %client.observerStartTime = getSimTime(); - commandToClient(%client, 'setHudMode', 'Observer'); - %client.setControlObject( %client.camera ); - //displayObserverHud( %client, 0 ); - updateObserverFlyHud(%client); - } - - if( !%observer ) - { - if(!$MatchStarted && !$CountdownStarted) // server has not started anything yet - { - %client.setControlObject( %client.camera ); - commandToClient(%client, 'setHudMode', 'Observer'); - } - else if(!$MatchStarted && $CountdownStarted) // server has started the countdown - { - commandToClient(%client, 'setHudMode', 'Observer'); - %client.setControlObject( %client.camera ); - } - else - { - commandToClient(%client, 'setHudMode', 'Standard'); // the game has already started - %client.setControlObject( %client.player ); - } - } - } - else - { - // set all players into obs mode. setting the control object will handle further procedures... - %client.camera.getDataBlock().setMode( %client.camera, "ObserverFly" ); - commandToClient(%client, 'setHudMode', 'Observer'); - %client.setControlObject( %client.camera ); - messageAll( 'MsgClientJoinTeam', "",%client.name, $teamName[0], %client, 0 ); - %client.team = 0; - - if( !$MatchStarted && !$CountdownStarted) - { - if($TeamDamage) - %damMess = "ENABLED"; - else - %damMess = "DISABLED"; - - if(%game.numTeams > 1) - BottomPrint(%client, "Server is Running in Tournament Mode.\nPick a Team\nTeam Damage is " @ %damMess, 0, 3 ); - } - else - { - BottomPrint( %client, "\nServer is Running in Tournament Mode", 0, 3 ); - } - } - - //make sure the objective HUD indicates your team on top and in green... - if (%client.team > 0) - messageClient(%client, 'MsgCheckTeamLines', "", %client.team); - - // were ready to go. - %client.matchStartReady = true; - echo("Client" SPC %client SPC "is ready."); - - if (!%client.isValid && !$RequiresClient[$CurrentMissionType]) //Ok, if we're joined and the client doesn't have the mod, tell em - commandToClient(%client,'CenterPrint',"You do not have the T2Bol client installed. For a better experience, please download the client from: www.blah.com",2,0); - - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here -} - -function DefaultGame::sendClientTeamList(%game, %client) -{ - // Send the client the current team list: - %teamCount = %game.numTeams; - for ( %i = 0; %i < %teamCount; %i++ ) - { - if ( %i > 0 ) - %teamList = %teamList @ "\n"; - - %teamList = %teamList @ detag( getTaggedString( %game.getTeamName(%i + 1) ) ); - } - messageClient( %client, 'MsgTeamList', "", %teamCount, %teamList ); -} - -function DefaultGame::setupClientHuds(%game, %client) -{ - // tell the client to setup the huds... - for(%i =0; %i<$WeaponsHudCount; %i++) - %client.setWeaponsHudBitmap(%i, $WeaponsHudData[%i, itemDataName], $WeaponsHudData[%i, bitmapName]); - for(%i =0; %i<$InventoryHudCount; %i++) - { - if ( $InventoryHudData[%i, slot] != 0 ) - %client.setInventoryHudBitmap($InventoryHudData[%i, slot], $InventoryHudData[%i, itemDataName], $InventoryHudData[%i, bitmapName]); - } - %client.setInventoryHudBitmap( 0, "", "gui/hud_handgren" ); - - %client.setWeaponsHudBackGroundBmp("gui/hud_new_panel"); - %client.setWeaponsHudHighLightBmp("gui/hud_new_weaponselect"); - %client.setWeaponsHudInfiniteAmmoBmp("gui/hud_infinity"); - %client.setInventoryHudBackGroundBmp("gui/hud_new_panel"); - - // tell the client if we are protecting statics (so no health bar will be displayed) - commandToClient(%client, 'protectingStaticObjects', %game.allowsProtectedStatics()); - commandToClient(%client, 'setPowerAudioProfiles', sPowerUp.getId(), sPowerDown.getId()); -} - -function DefaultGame::testDrop( %game, %client ) -{ - %game.clientJoinTeam( %client, 1, false ); - %client.camera.getDataBlock().setMode( %client.camera, "pre-game", %client.player ); - %client.setControlObject( %client.camera ); - CommandToClient( %client, 'setPlayContent' ); -} - -function DefaultGame::onClientEnterObserverMode( %game, %client ) -{ - // Default game doesn't care... -} - -// from 'item.cs' -function DefaultGame::playerTouchFlag(%game, %player, %flag) -{ - messageAll('MsgPlayerTouchFlag', 'Player %1 touched flag %2', %player, %flag); -} - -// from 'item.cs' -function DefaultGame::playerDroppedFlag(%game, %player, %flag) -{ - messageAll('MsgPlayerDroppedFlag', 'Player %1 dropped flag %2', %player, %flag); -} - -// from 'staticShape.cs' -function DefaultGame::flagStandCollision(%game, %dataBlock, %obj, %colObj) -{ - // for retreiveGame -} - -function DefaultGame::notifyMineDeployed(%game, %mine) -{ - //do nothign in the default game... -} - -// from 'staticshape.cs' -function DefaultGame::findProjector(%game, %flipflop) -{ - // search the flipflop's folder for a holo projector - // if one exists, associate it with the flipflop - %flipflop.projector = 0; - %folder = %flipflop.getGroup(); - for(%i = 0; %i < %folder.getCount(); %i++) - { - %proj = %folder.getObject(%i); - if(%proj.getDatablock().getName() $= "LogoProjector") - { - %flipflop.projector = %proj; - %flipflop.projector.holo = 0; - break; - } - } -} - -//****************************************************************************** -//* DefaultGame Trigger - Functions * -//****************************************************************************** - -/// -Trigger- ////////////////////////////////////////////////////////////////// -//Function -- onEnterTrigger (%game, %name, %data, %obj, %colObj) -// %game = Current game type object -// %name = Trigger name - defined when trigger is created -// %data = Trigger Data Block -// %obj = Trigger Object -// %colObj = Object that collided with the trigger -//Decription -- Called when trigger has been triggered -//////////////////////////////////////////////////////////////////////////////// -// from 'trigger.cs' -function DefaultGame::onEnterTrigger(%game, %triggerName, %data, %obj, %colobj) -{ - //Do Nothing -} - -/// -Trigger- ////////////////////////////////////////////////////////////////// -//Function -- onLeaveTrigger (%game, %name, %data, %obj, %colObj) -// %game = Current game type object -// %name = Trigger name - defined when trigger is created -// %data = Trigger Data Block -// %obj = Trigger Object -// %colObj = Object that collided with the trigger -//Decription -- Called when trigger has been untriggered -//////////////////////////////////////////////////////////////////////////////// -// from 'trigger.cs' -function DefaultGame::onLeaveTrigger(%game, %triggerName, %data, %obj, %colobj) -{ - //Do Nothing -} - -/// -Trigger- ////////////////////////////////////////////////////////////////// -//Function -- onTickTrigger(%game, %name, %data, %obj) -// %game = Current game type object -// %name = Trigger name - defined when trigger is created -// %data = Trigger Data Block -// %obj = Trigger Object -//Decription -- Called every tick if triggered -//////////////////////////////////////////////////////////////////////////////// -// from 'trigger.cs' -function DefaultGame::onTickTrigger(%game, %triggerName, %data, %obj) -{ - //Do Nothing -} - - -function DefaultGame::setUpTeams(%game) -{ - %group = nameToID("MissionGroup/Teams"); - if(%group == -1) - return; - - // create a team0 if it does not exist - %team = nameToID("MissionGroup/Teams/team0"); - if(%team == -1) - { - %team = new SimGroup("team0"); - %group.add(%team); - } - - // 'team0' is not counted as a team here - %game.numTeams = 0; - while(%team != -1) - { - // create drop set and add all spawnsphere objects into it - %dropSet = new SimSet("TeamDrops" @ %game.numTeams); - MissionCleanup.add(%dropSet); - - %spawns = nameToID("MissionGroup/Teams/team" @ %game.numTeams @ "/SpawnSpheres"); - if(%spawns != -1) - { - %count = %spawns.getCount(); - for(%i = 0; %i < %count; %i++) - %dropSet.add(%spawns.getObject(%i)); - } - - // set the 'team' field for all the objects in this team - %team.setTeam(%game.numTeams); - - clearVehicleCount(%team+1); - // get next group - %team = nameToID("MissionGroup/Teams/team" @ %game.numTeams + 1); - if (%team != -1) - %game.numTeams++; - } - - // set the number of sensor groups (including team0) that are processed - setSensorGroupCount(%game.numTeams + 1); -} - -function SimGroup::setTeam(%this, %team) -{ - for (%i = 0; %i < %this.getCount(); %i++) - { - %obj = %this.getObject(%i); - switch$ (%obj.getClassName()) - { - case SpawnSphere : - if($MatchStarted) - { - // find out what team the spawnsphere used to belong to - %found = false; - for(%l = 1; %l <= Game.numTeams; %l++) - { - %drops = nameToId("MissionCleanup/TeamDrops" @ %l); - for(%j = 0; %j < %drops.getCount(); %j++) - { - %current = %drops.getObject(%j); - if(%current == %obj) - %found = %l; - } - } - if(%team != %found) - Game.claimSpawn(%obj, %team, %found); - else - error("spawn "@%obj@" is already on team "@%team@"!"); - } - else - Game.claimSpawn(%obj, %team, ""); - case SimGroup : %obj.setTeam(%team); - default : %obj.team = %team; - } - - if(%obj.getType() & $TypeMasks::GameBaseObjectType) - { - // eeck.. please go away when scripts get cleaned... -// if(%obj.getDataBlock().getName() $= "StationVehiclePad") -// { - // z0dd - ZOD, 4/24/02. Rewrite for bug fix and MPB teleporter -// %team = %obj.team; -// %obj = %obj.station; -// %obj.team = %team; -// setTargetSensorGroup(%obj.getTarget(), %team); -// if(%obj.teleporter !$= "") -// { -// %obj = %obj.teleporter; -// %obj.team = %team; -// } -// } - %target = %obj.getTarget(); - if(%target != -1) - setTargetSensorGroup(%target, %team); - } - } -} - -function DefaultGame::claimSpawn(%game, %obj, %newTeam, %oldTeam) -{ - if(%newTeam == %oldTeam) - return; - - %newSpawnGroup = nameToId("MissionCleanup/TeamDrops" @ %newTeam); - if(%oldTeam !$= "") - { - %oldSpawnGroup = nameToId("MissionCleanup/TeamDrops" @ %oldTeam); - %oldSpawnGroup.remove(%obj); - } - %newSpawnGroup.add(%obj); -} - -// recursive function to assign teams to all mission objects - -function SimGroup::swapTeams(%this) -{ - // used in Siege only - Game.groupSwapTeams(%this); -} - -function ShapeBase::swapTeams(%this) -{ - // used in Siege only - Game.objectSwapTeams(%this); -} - -function GameBase::swapTeams(%this) -{ - // used in Siege only - Game.objectSwapTeams(%this); -} - -function TSStatic::swapTeams(%this) -{ - // used in Siege only - // do nothing -} - -function InteriorInstance::swapTeams(%this) -{ - // used in Siege only - // do nothing -- interiors don't switch teams -} - -function SimGroup::swapVehiclePads(%this) -{ - // used in Siege only - Game.groupSwapVehiclePads(%this); -} - -function ShapeBase::swapVehiclePads(%this) -{ - // used in Siege only - Game.objectSwapVehiclePads(%this); -} - -function GameBase::swapVehiclePads(%this) -{ - // used in Siege only - // do nothing -- only searching for vehicle pads -} - -function InteriorInstance::swapVehiclePads(%this) -{ - // used in Siege only - // do nothing -- only searching for vehicle pads -} - -function SimSet::swapVehiclePads(%this) -{ - // used in Siege only - // do nothing -- only searching for vehicle pads -} - -function PhysicalZone::swapVehiclePads(%this) -{ - // used in Siege only - // do nothing -- only searching for vehicle pads -} - -function SimGroup::objectRestore(%this) -{ - // used in Siege only - Game.groupObjectRestore(%this); -} - -function ShapeBase::objectRestore(%object) -{ - // only used for Siege - Game.shapeObjectRestore(%object); -} - -function Turret::objectRestore(%object) -{ - // only used for Siege - Game.shapeObjectRestore(%object); -} - -function AIObjective::objectRestore(%object) -{ - // only used for Siege - // don't do anything for AI Objectives -} - -function DefaultGame::checkObjectives(%game) -{ - //any special objectives that can be met by gametype - //none for default game -} - -//--------------------------------------------------- - -function DefaultGame::checkTimeLimit(%game, %forced) -{ - // Don't add extra checks: - if ( %forced ) - cancel( %game.timeCheck ); - - // if there is no time limit, check back in a minute to see if it's been set - if(($Host::TimeLimit $= "") || $Host::TimeLimit == 0) - { - %game.timeCheck = %game.schedule(20000, "checkTimeLimit"); - return; - } - - %curTimeLeftMS = ($Host::TimeLimit * 60 * 1000) + $missionStartTime - getSimTime(); - - if (%curTimeLeftMS <= 0) - { - // time's up, put down your pencils - %game.timeLimitReached(); - } - else - { - if(%curTimeLeftMS >= 20000) - %game.timeCheck = %game.schedule(20000, "checkTimeLimit"); - else - %game.timeCheck = %game.schedule(%curTimeLeftMS + 1, "checkTimeLimit"); - - //now synchronize everyone's clock - messageAll('MsgSystemClock', "", $Host::TimeLimit, %curTimeLeftMS); - } -} - -function listplayers() -{ - for(%i = 0; %i < ClientGroup.getCount(); %i++) - { - %cl = ClientGroup.getObject(%i); - %status = ""; - if(%cl.isAiControlled()) - %status = "Bot "; - if(%cl.isSmurf) - %status = "Alias "; - if(%cl.isAdmin) - %status = %status @ "Admin "; - if(%cl.isSuperAdmin) - %status = %status @ "SuperAdmin "; - if(%status $= "") - %status = ""; - echo("client: " @ %cl @ " player: " @ %cl.player @ " name: " @ %cl.nameBase @ " team: " @ %cl.team @ " status: " @ %status); - } -} - -function DefaultGame::clearTeamRankArray(%game, %team) -{ - %count = $TeamRank[%team, count]; - for (%i = 0; %i < %count; %i++) - $TeamRank[%team, %i] = ""; - $TeamRank[%team, count] = 0; -} - -function DefaultGame::populateTeamRankArray(%game, %client) -{ - //this function should be called *after* the client has been added to a team... - if (%client <= 0 || %client.team <= 0) - return; - - //find the team - if (%game.numTeams == 1) - %team = 0; - else - %team = %client.team; - - //find the number of teammates already ranked... - %count = $TeamRank[%team, count]; - if (%count $= "") - { - $TeamRank[%team, count] = 0; - %count = 0; - } - - //make sure we're not already in the array - for (%i = 0; %i < %count; %i++) - { - if ($TeamRank[%team, %i] == %client) - return; - } - - //add the client in at the bottom of the list, and increment the count - $TeamRank[%team, %count] = %client; - $TeamRank[%team, count] = $TeamRank[%team, count] + 1; - - //now recalculate the team rank for this player - %game.recalcTeamRanks(%client); -} - -function DefaultGame::removeFromTeamRankArray(%game, %client) -{ - //note, this should be called *before* the client actually switches teams or drops... - if (%client <= 0 || %client.team <= 0) - return; - - //find the correct team - if (%game.numTeams == 1) - %team = 0; - else - %team = %client.team; - - //now search throught the team rank array, looking for this client - %count = $TeamRank[%team, count]; - for (%i = 0; %i < %count; %i++) - { - if ($TeamRank[%team, %i] == %client) - { - //we've found the client in the array, now loop through, and move everyone else up a rank - for (%j = %i + 1; %j < %count; %j++) - { - %cl = $TeamRank[%team, %j]; - $TeamRank[%team, %j - 1] = %cl; - messageClient(%cl, 'MsgYourRankIs', "", %j); - } - $TeamRank[%team, %count - 1] = ""; - - //now decrement the team rank array count, and break - $TeamRank[%team, count] = $TeamRank[%team, count] - 1; - break; - } - } -} - -function DefaultGame::recalcTeamRanks(%game, %client) -{ - if (%client <= 0 || %client.team <= 0) - return; - - // this is a little confusing -- someone's actual numerical rank is always - // one number higher than his index in the $TeamRank array - // (e.g. person ranked 1st has index of 0) - - // TINMAN: I'm going to remove the %client.teamRank field - the index in the - // $TeamRank array already contains their rank - safer to search the array than - // to maintiain the information in a separate variable... - - //find the team, the client in the team array - if (%game.numTeams == 1) - %team = 0; - else - %team = %client.team; - - %count = $TeamRank[%team, count]; - %index = -1; - for (%i = 0; %i < %count; %i++) - { - if ($TeamRank[%team, %i] == %client) - { - %index = %i; - break; - } - } - - //if they weren't found in the array, return - if (%index < 0) - return; - - //make sure far down the array as they should be... - %tempIndex = %index; - %swapped = false; - while (true) - { - if (%tempIndex <= 0) - break; - - %tempIndex--; - %tempClient = $TeamRank[%team, %tempIndex]; - - //see if we should swap the two - if (%client.score > %tempClient.score) - { - %swapped = true; - %index = %tempIndex; - $TeamRank[%team, %tempIndex] = %client; - $TeamRank[%team, %tempIndex + 1] = %tempClient; - messageClient(%tempClient, 'MsgYourRankIs', "", %tempIndex + 2); - } - } - - //if we've swapped up at least once, we obviously won't need to swap down as well... - if (%swapped) - { - messageClient(%client, 'MsgYourRankIs', "", %index + 1); - return; - } - - //since we didnt' swap up, see if we need to swap down... - %tempIndex = %index; - %swapped = false; - while (true) - { - if (%tempIndex >= %count - 1) - break; - - %tempIndex++; - %tempClient = $TeamRank[%team, %tempIndex]; - - //see if we should swap the two - if (%client.score < %tempClient.score) - { - %swapped = true; - %index = %tempIndex; - $TeamRank[%team, %tempIndex] = %client; - $TeamRank[%team, %tempIndex - 1] = %tempClient; - messageClient(%tempClient, 'MsgYourRankIs', "", %tempIndex); - } - } - - //send the message (regardless of whether a swap happened or not) - messageClient(%client, 'MsgYourRankIs', "", %index + 1); -} - -function DefaultGame::recalcScore(%game, %cl) -{ - %game.recalcTeamRanks(%cl); -} - -function DefaultGame::testKill(%game, %victimID, %killerID) -{ - return ((%killerID !=0) && (%victimID.team != %killerID.team)); -} - -function DefaultGame::testSuicide(%game, %victimID, %killerID, %damageType) -{ - return ((%victimID == %killerID) || (%damageType == $DamageType::Ground) || (%damageType == $DamageType::Suicide)); -} - -function DefaultGame::testTeamKill(%game, %victimID, %killerID) -{ - return (%killerID.team == %victimID.team); -} - -function DefaultGame::testTurretKill(%game, %implement) -{ - if(%implement == 0) - return false; - else - return (%implement.getClassName() $= "Turret"); -} - -// function DefaultGame::awardScoreFlagCap(%game, %cl) -// { -// %cl.flagCaps++; -// $TeamScore[%cl.team] += %game.SCORE_PER_TEAM_FLAG_CAP; -// messageAll('MsgCTFTeamScore', "", %cl.team, $TeamScore[%cl.team]); -// -// if (%game.SCORE_PER_PLYR_FLAG_CAP > 1) -// %plural = "s"; -// else -// %plural = ""; -// -// if (%game.SCORE_PER_PLYR_FLAG_CAP != 0) -// messageClient(%cl, 'scoreFlaCapMsg', 'You received %1 point%2 for capturing the flag.', %game.SCORE_PER_PLYR_FLAG_CAP, %plural); -// %game.recalcScore(%cl); -// } - - -function DefaultGame::testOOBDeath(%game, %damageType) -{ - return (%damageType == $DamageType::OutOfBounds); -} - -function DefaultGame::awardScoreTurretKill(%game, %victimID, %implement) -{ - if ((%killer = %implement.getControllingClient()) != 0) //award whoever might be controlling the turret - { - if (%killer == %victimID) - %game.awardScoreSuicide(%victimID); - else if (%killer.team == %victimID.team) //player controlling a turret killed a teammate - { - %killer.teamKills++; - %game.awardScoreTurretTeamKill(%victimID, %killer); - %game.awardScoreDeath(%victimID); - } - else - { - %killer.turretKills++; - %game.recalcScore(%killer); - %game.awardScoreDeath(%victimID); - } - } - else if ((%killer = %implement.owner) != 0) //if it isn't controlled, award score to whoever deployed it - { - if (%killer.team == %victimID.team) - { - %game.awardScoreDeath(%victimID); - } - else - { - %killer.turretKills++; - %game.recalcScore(%killer); - %game.awardScoreDeath(%victimID); - } - } - //default is, no one was controlling it, no one owned it. No score given. -} - -function DefaultGame::awardScoreDeath(%game, %victimID) -{ - %victimID.deaths++; - if ( %game.SCORE_PER_DEATH != 0 ) - { -// %plural = (abs(%game.SCORE_PER_DEATH) != 1 ? "s" : ""); -// messageClient(%victimID, 'MsgScoreDeath', '\c0You have been penalized %1 point%2 for dying.', abs(%game.SCORE_PER_DEATH), %plural); - %game.recalcScore(%victimID); - } -} - -function DefaultGame::awardScoreKill(%game, %killerID) -{ - %killerID.kills++; - %game.recalcScore(%killerID); -} - -function DefaultGame::awardScoreSuicide(%game, %victimID) -{ - %victimID.suicides++; -// if (%game.SCORE_PER_SUICIDE != 0) -// messageClient(%victimID, 'MsgScoreSuicide', '\c0You have been penalized for killing yourself.'); - %game.recalcScore(%victimID); -} - -function DefaultGame::awardScoreTeamkill(%game, %victimID, %killerID) -{ - %killerID.teamKills++; - if (%game.SCORE_PER_TEAMKILL != 0) - messageClient(%killerID, 'MsgScoreTeamkill', '\c0You have been penalized for killing teammate %1.', %victimID.name); - %game.recalcScore(%killerID); -} - -function DefaultGame::awardScoreTurretTeamKill(%game, %victimID, %killerID) -{ - %killerID.teamKills++; - if (%game.SCORE_PER_TEAMKILL != 0) - messageClient(%killerID, 'MsgScoreTeamkill', '\c0You have been penalized for killing your teammate %1, with a turret.', %victimID.name); - %game.recalcScore(%killerID); -} - - -function DefaultGame::objectRepaired(%game, %obj, %objName) -{ - %item = %obj.getDataBlock().getName(); - //echo("Item repaired is a " @ %item); - switch$ (%item) - { - case generatorLarge : - %game.genOnRepaired(%obj, %objName); - case stationInventory : - %game.stationOnRepaired(%obj, %objName); - case sensorMediumPulse : - %game.sensorOnRepaired(%obj, %objName); - case sensorLargePulse : - %game.sensorOnRepaired(%obj, %objName); - case turretBaseLarge : - %game.turretOnRepaired(%obj, %objName); - case stationVehicle : %game.vStationOnRepaired(%obj, %objName); - default: //unused by current gametypes. Add more checks here if desired - } -} - -function DefaultGame::allowsProtectedStatics(%game) -{ - return false; -} - -// jff: why is game object doing this? -//Return a simple string with no extras -function DefaultGame::cleanWord(%game, %this) -{ - %length = strlen(%this); - for(%i = 0; %i < %length; %i++) - { - %char = getSubStr(%this, %i, 1); - if(%char $= "_") - { - %next = getSubStr(%this, (%i+1), 1); - if(%next $= "_") - { - %char = "'"; //apostrophe (2 chars) - %i++; - } - else - %char = " "; //space - } - %clean = (%clean @ %char); - } -} - -function DefaultGame::stationOnEnterTrigger(%game, %data, %obj, %colObj) -{ - return true; -} - -function DefaultGame::WeaponOnUse(%game, %data, %obj) -{ - return true; -} - -function DefaultGame::HandInvOnUse(%game, %data, %obj) -{ - return true; -} - -function DefaultGame::WeaponOnInventory(%game, %this, %obj, %amount) -{ - return true; -} - -function DefaultGame::ObserverOnTrigger(%game, %data, %obj, %trigger, %state) -{ - return true; -} - -// jff: why is the game being notified that a weapon is being thrown? hot potato gametype? -function DefaultGame::ShapeThrowWeapon(%game, %this) -{ - return true; -} - -function DefaultGame::leaveMissionArea(%game, %playerData, %player) -{ - if(%player.getState() $= "Dead") - return; - - %player.client.outOfBounds = true; - messageClient(%player.client, 'LeaveMissionArea', '\c1You left the mission area.~wfx/misc/warning_beep.wav'); -} - -function DefaultGame::enterMissionArea(%game, %playerData, %player) -{ - if(%player.getState() $= "Dead") - return; - - %player.client.outOfBounds = false; - messageClient(%player.client, 'EnterMissionArea', '\c1You are back in the mission area.'); -} - -//------------------------------------------------------------------------------ -// AI stubs: -//------------------------------------------------------------------------------ - -function DefaultGame::onAIDamaged(%game, %clVictim, %clAttacker, %damageType, %sourceObject) -{ -} - -function DefaultGame::onAIFriendlyFire(%game, %clVictim, %clAttacker, %damageType, %sourceObject) -{ -} - -function DefaultGame::onAIKilled(%game, %clVictim, %clKiller, %damageType, %implement) -{ - //unassign the client from any objectives - AIUnassignClient(%clVictim); - - //break the link, if this ai is controlled - aiReleaseHumanControl(%clVictim.controlByHuman, %clVictim); - - //and schedule the respawn - %clVictim.respawnThread = schedule(5000, %clVictim, "onAIRespawn", %clVictim); -} - -function DefaultGame::onAIKilledClient(%game, %clVictim, %clAttacker, %damageType, %implement) -{ - %clAttacker.setVictim(%clVictim, %clVictim.player); -} - -//------------------------------------------------------------------------------ -// Voting stuff: -//------------------------------------------------------------------------------ -function DefaultGame::sendGamePlayerPopupMenu( %game, %client, %targetClient, %key ) -{ - if( !%targetClient.matchStartReady ) - return; - - %isAdmin = ( %client.isAdmin || %client.isSuperAdmin ); - %isTargetSelf = ( %client == %targetClient ); - %isTargetAdmin = ( %targetClient.isAdmin || %targetClient.isSuperAdmin ); - %isTargetBot = %targetClient.isAIControlled(); - %isTargetObserver = ( %targetClient.team == 0 ); - %outrankTarget = false; - - if ( %client.isSuperAdmin ) - %outrankTarget = !%targetClient.isSuperAdmin; - else if ( %client.isAdmin ) - %outrankTarget = !%targetClient.isAdmin; - - if( %client.isSuperAdmin && %targetClient.guid != 0 ) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - { - messageClient( %client, 'MsgPlayerPopupItem', "", %key, "addAdmin", "", 'Add to Server Admin List', 10); - messageClient( %client, 'MsgPlayerPopupItem', "", %key, "addSuperAdmin", "", 'Add to Server SuperAdmin List', 11); - } - - //mute options - if ( !%isTargetSelf ) - { - if ( %client.muted[%targetClient] ) - messageClient( %client, 'MsgPlayerPopupItem', "", %key, "MutePlayer", "", 'Unmute Text Chat', 1); - else - messageClient( %client, 'MsgPlayerPopupItem', "", %key, "MutePlayer", "", 'Mute Text Chat', 1); - - if ( !%isTargetBot && %client.canListenTo( %targetClient ) ) - { - if ( %client.getListenState( %targetClient ) ) - messageClient( %client, 'MsgPlayerPopupItem', "", %key, "ListenPlayer", "", 'Disable Voice Com', 9 ); - else - messageClient( %client, 'MsgPlayerPopupItem', "", %key, "ListenPlayer", "", 'Enable Voice Com', 9 ); - } - // ------------------------------------------ - // z0dd - ZOD 4/4/02. Observe a specific player - if (%client.team == 0 && !%isTargetObserver) - messageClient(%client, 'MsgPlayerPopupItem', "", %key, "ObservePlayer", "", 'Observe Player', 12); - } - if( !%client.canVote && !%isAdmin ) - return; - - // regular vote options on players - if ( %game.scheduleVote $= "" && !%isAdmin && !%isTargetAdmin ) - { - if ( $Host::allowAdminPlayerVotes && !%isTargetBot ) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - messageClient( %client, 'MsgPlayerPopupItem', "", %key, "AdminPlayer", "", 'Vote to Make Admin', 2 ); - - if ( !%isTargetSelf ) - { - messageClient( %client, 'MsgPlayerPopupItem', "", %key, "KickPlayer", "", 'Vote to Kick', 3 ); - } - } - - // Admin only options on players: - else if ( %isAdmin ) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - { - if ( !%isTargetBot && !%isTargetAdmin ) - messageClient( %client, 'MsgPlayerPopupItem', "", %key, "AdminPlayer", "", 'Make Admin', 2 ); - - if ( !%isTargetSelf && %outrankTarget ) - { - messageClient( %client, 'MsgPlayerPopupItem', "", %key, "KickPlayer", "", 'Kick', 3 ); - - if ( !%isTargetBot ) - { - // ------------------------------------------------------------------------------------------------------ - // z0dd - ZOD 4/4/02. Warn player, send private message and remove admin privledges - messageClient(%client, 'MsgPlayerPopupItem', "", %key, "Warn", "", 'Warn player', 13); - messageClient( %client, 'MsgPlayerPopupItem', "", %key, "SendMessage", "", 'Send Private Message', 15 ); - if(%isTargetAdmin) - messageClient( %client, 'MsgPlayerPopupItem', "", %key, "StripAdmin", "", 'Strip admin', 14 ); - - if( %client.isSuperAdmin ) - messageClient( %client, 'MsgPlayerPopupItem', "", %key, "BanPlayer", "", 'Ban', 4 ); - - if ($CurrentMissionType !$= "RPG") - return; - if ( !%isTargetObserver ) - { - messageClient( %client, 'MsgPlayerPopupItem', "", %key, "ToObserver", "", 'Force observer', 5 ); - } - } - } - if ( %isTargetSelf || %outrankTarget ) - { - if ( %game.numTeams > 1 ) - { - if ( %isTargetObserver ) - { - %action = %isTargetSelf ? "Join " : "Change to "; - %str1 = %action @ getTaggedString( %game.getTeamName(1) ); - %str2 = %action @ getTaggedString( %game.getTeamName(2) ); - - messageClient( %client, 'MsgPlayerPopupItem', "", %key, "ChangeTeam", "", %str1, 6 ); - messageClient( %client, 'MsgPlayerPopupItem', "", %key, "ChangeTeam", "", %str2, 7 ); - } - else - { - %changeTo = %targetClient.team == 1 ? 2 : 1; - %str = "Switch to " @ getTaggedString( %game.getTeamName(%changeTo) ); - %caseId = 5 + %changeTo; - - messageClient( %client, 'MsgPlayerPopupItem', "", %key, "ChangeTeam", "", %str, %caseId ); - } - } - else if ( %isTargetObserver ) - { - %str = %isTargetSelf ? 'Join the Game' : 'Add to Game'; - messageClient( %client, 'MsgPlayerPopupItem', "", %key, "JoinGame", "", %str, 8 ); - } - } - } -} - -//------------------------------------------------------------------------------ -function DefaultGame::sendGameVoteMenu( %game, %client, %key ) -{ - %isAdmin = ( %client.isAdmin || %client.isSuperAdmin ); - %multipleTeams = %game.numTeams > 1; - - // no one is going anywhere until this thing starts - if($MatchStarted) - { - // Client options: - if ( %client.team != 0 ) - { - if ($CurrentMissionType !$= "RPG") - { - if ( %multipleTeams ) - if( !$Host::TournamentMode ) - messageClient( %client, 'MsgVoteItem', "", %key, 'ChooseTeam', "", 'Change your Team' ); - messageClient( %client, 'MsgVoteItem', "", %key, 'MakeObserver', "", 'Become an Observer' ); - } - } - else - { - if(!%multipleTeams && !$Host::TournamentMode) - messageClient( %client, 'MsgVoteItem', "", %key, 'JoinGame', "", 'Join the Game' ); - } - - //%totalSlots = $Host::maxPlayers - ($HostGamePlayerCount + $HostGameBotCount); - // if( $HostGameBotCount > 0 && %totalSlots > 0 && %client.isAdmin) - //messageClient( %client, 'MsgVoteItem', "", %key, 'Addbot', "", 'Add a Bot' ); - } - - if( !%client.canVote && !%isAdmin ) - return; - - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - - if ( %game.scheduleVote $= "" ) - { - if(!%client.isAdmin) - { - // Actual vote options: - messageClient( %client, 'MsgVoteItem', "", %key, 'VoteChangeMission', 'change the mission to', 'Vote to Change the Mission' ); - - if( $Host::TournamentMode ) - { - messageClient( %client, 'MsgVoteItem', "", %key, 'VoteFFAMode', 'Change server to Free For All.', 'Vote Free For All Mode' ); - - if(!$MatchStarted && !$CountdownStarted) - messageClient( %client, 'MsgVoteItem', "", %key, 'VoteMatchStart', 'Start Match', 'Vote to Start the Match' ); - } - else - messageClient( %client, 'MsgVoteItem', "", %key, 'VoteTournamentMode', 'Change server to Tournament.', 'Vote Tournament Mode' ); - - if ($CurrentMissionType !$= "RPG" && $CurrentMissionType !$= "Survival") - if ( %multipleTeams ) - { - if(!$MatchStarted && !$Host::TournamentMode) - messageClient( %client, 'MsgVoteItem', "", %key, 'ChooseTeam', "", 'Change your Team' ); - - if ( $teamDamage ) - messageClient( %client, 'MsgVoteItem', "", %key, 'VoteTeamDamage', 'disable team damage', 'Vote to Disable Team Damage' ); - else - messageClient( %client, 'MsgVoteItem', "", %key, 'VoteTeamDamage', 'enable team damage', 'Vote to Enable Team Damage' ); - } - } - else - { - // Actual vote options: - messageClient( %client, 'MsgVoteItem', "", %key, 'VoteChangeMission', 'change the mission to', 'Change the Mission' ); - - if ($CurrentMissionType !$= "RPG") //Don't screw with the time limit in the actual gamemode. :) - if( $Host::TournamentMode ) - { - messageClient( %client, 'MsgVoteItem', "", %key, 'VoteFFAMode', 'Change server to Free For All.', 'Free For All Mode' ); - - if(!$MatchStarted && !$CountdownStarted) - messageClient( %client, 'MsgVoteItem', "", %key, 'VoteMatchStart', 'Start Match', 'Start Match' ); - } - else - messageClient( %client, 'MsgVoteItem', "", %key, 'VoteTournamentMode', 'Change server to Tournament.', 'Tournament Mode' ); - - if ($CurrentMissionType !$= "RPG" && $CurrentMissionType !$= "Survival") - if ( %multipleTeams ) - { - if(!$MatchStarted) - messageClient( %client, 'MsgVoteItem', "", %key, 'ChooseTeam', "", 'Choose Team' ); - - if ($CurrentMissionType !$= "RPG") - if ( $teamDamage ) - messageClient( %client, 'MsgVoteItem', "", %key, 'VoteTeamDamage', 'disable team damage', 'Disable Team Damage' ); - else - messageClient( %client, 'MsgVoteItem', "", %key, 'VoteTeamDamage', 'enable team damage', 'Enable Team Damage' ); - } - } - } - - // Admin only options: - if ( %client.isAdmin ) - { - if ($CurrentMissionType !$= "RPG") - messageClient( %client, 'MsgVoteItem', "", %key, 'VoteChangeTimeLimit', 'change the time limit', 'Change the Time Limit' ); - - messageClient( %client, 'MsgVoteItem', "", %key, 'VoteResetServer', 'reset server defaults', 'Reset the Server' ); - - if ($CurrentMissionType $= "SV" && !$Host::ProgressiveMode) //Holy fuck, BETA option! Good thing it's admin only. - messageClient( %client, 'MsgVoteItem', "", %key, 'voteProgressiveMode', '', 'Enable BETA Progressive Mode' ); - else if ($Host::ProgressiveMode) - messageClient( %client, 'MsgVoteItem', "", %key, 'voteProgressiveMode', '', 'Disable BETA Progressive Mode' ); - - // ----------------------------------------------------------------------------- - // z0dd - ZOD, 5/12/02. Add bot menu for admins - %totalSlots = $Host::maxPlayers - ($HostGamePlayerCount + $HostGameBotCount); - if( $HostGameBotCount > 0 && %totalSlots > 0 && $CurrentMissionType !$= "RPG") - messageClient( %client, 'MsgVoteItem', "", %key, 'Addbot', "", 'Add a Bot' ); - // ----------------------------------------------------------------------------- - } - - // Host only options: - if ( %client.getAddress() $= "local" ) - { - if (!$ServerLock) //Would be a saved server Pref but it doesn't really make sense to lock your server everytime you host - messageClient( %client, 'MsgVoteItem', "", %key, 'voteLockServer', "", 'Lock Server' ); - else - messageClient( %client, 'MsgVoteItem', "", %key, 'voteLockServer', "", 'Unlock Server' ); - } - - if ($CurrentMissionType $= "RPG" && %client.isAdmin) - { - if ($Host::GlobalChat) //Would be a saved server Pref but it doesn't really make sense to lock your server everytime you host - messageClient( %client, 'MsgVoteItem', "", %key, 'voteGlobal', "", 'Disable Global Chat' ); - else - messageClient( %client, 'MsgVoteItem', "", %key, 'voteGlobal', "", 'Enable Global Chat' ); - } - -} - -//------------------------------------------------------------------------------ -function DefaultGame::sendGameTeamList( %game, %client, %key ) -{ - %teamCount = %game.numTeams; - if ( %teamCount < 2 ) - { - warn( "Team menu requested for one-team game!" ); - return; - } - - for ( %team = 1; %team - 1 < %teamCount; %team++ ) - messageClient( %client, 'MsgVoteItem', "", %key, %team, "", detag( getTaggedString( %game.getTeamName(%team) ) ) ); -} - -//------------------------------------------------------------------------------ -function DefaultGame::sendTimeLimitList( %game, %client, %key ) -{ - messageClient( %client, 'MsgVoteItem', "", %key, 10, "", '10 minutes' ); - messageClient( %client, 'MsgVoteItem', "", %key, 15, "", '15 minutes' ); - messageClient( %client, 'MsgVoteItem', "", %key, 20, "", '20 minutes' ); - messageClient( %client, 'MsgVoteItem', "", %key, 25, "", '25 minutes' ); - messageClient( %client, 'MsgVoteItem', "", %key, 30, "", '30 minutes' ); - messageClient( %client, 'MsgVoteItem', "", %key, 45, "", '45 minutes' ); - messageClient( %client, 'MsgVoteItem', "", %key, 60, "", '60 minutes' ); - messageClient( %client, 'MsgVoteItem', "", %key, 200, "", 'No time limit' ); -} - -//------------------------------------------------------------------------------ -// all global votes here -// this function was created to remove the call to "eval", which is non-functional in PURE servers... -function DefaultGame::evalVote(%game, %typeName, %admin, %arg1, %arg2, %arg3, %arg4) -{ - switch$ (%typeName) - { - case "voteChangeMission": - %game.voteChangeMission(%admin, %arg1, %arg2, %arg3, %arg4); - - case "voteTeamDamage": - %game.voteTeamDamage(%admin, %arg1, %arg2, %arg3, %arg4); - - case "voteTournamentMode": - %game.voteTournamentMode(%admin, %arg1, %arg2, %arg3, %arg4); - - case "voteMatchStart": - %game.voteMatchStart(%admin, %arg1, %arg2, %arg3, %arg4); - - case "voteFFAMode": - %game.voteFFAMode(%admin, %arg1, %arg2, %arg3, %arg4); - - case "voteChangeTimeLimit": - %game.voteChangeTimeLimit(%admin, %arg1, %arg2, %arg3, %arg4); - - case "voteResetServer": - %game.voteResetServer(%admin, %arg1, %arg2, %arg3, %arg4); - - case "voteKickPlayer": - %game.voteKickPlayer(%admin, %arg1, %arg2, %arg3, %arg4); - - case "voteAdminPlayer": - %game.voteAdminPlayer(%admin, %arg1, %arg2, %arg3, %arg4); - - case "voteGreedMode": - %game.voteGreedMode(%admin, %arg1, %arg2, %arg3, %arg4); - - case "voteHoardMode": - %game.voteHoardMode(%admin, %arg1, %arg2, %arg3, %arg4); - - case "voteLockServer": - %game.voteLockServer(%admin, %arg1, %arg2, %arg3, %arg4); - - case "voteGlobal": - %game.voteGlobal(%admin, %arg1, %arg2, %arg3, %arg4); - - case "voteProgressiveMode": - %game.voteProgressiveMode(%admin, %arg1, %arg2, %arg3, %arg4); - } -} - -function DefaultGame::voteChangeMission(%game, %admin, %missionDisplayName, %typeDisplayName, %missionId, %missionTypeId) -{ - %mission = $HostMissionFile[%missionId]; - if ( %mission $= "" ) - { - error( "Invalid mission index passed to DefaultGame::voteChangeMission!" ); - return; - } - - %missionType = $HostTypeName[%missionTypeId]; - if ( %missionType $= "" ) - { - error( "Invalid mission type id passed to DefaultGame::voteChangeMission!" ); - return; - } - - if(%admin) - { - messageAll('MsgAdminChangeMission', '\c2The Admin has changed the mission to %1 (%2).', %missionDisplayName, %typeDisplayName ); - logEcho("mission changed to "@%missionDisplayName@"/"@%typeDisplayName@" (admin)"); - %game.gameOver(); - loadMission( %mission, %missionType, false ); - } - else - { - %totalVotes = %game.totalVotesFor + %game.totalVotesAgainst; - if(%totalVotes > 0 && (%game.totalVotesFor / (ClientGroup.getCount() - $HostGameBotCount)) > ($Host::VotePasspercent / 100)) - { - messageAll('MsgVotePassed', '\c2The mission was changed to %1 (%2) by vote.', %missionDisplayName, %typeDisplayName ); - logEcho("mission changed to "@%missionDisplayName@"/"@%typeDisplayName@" (vote)"); - %game.gameOver(); - loadMission( %mission, %missionType, false ); - } - else - messageAll('MsgVoteFailed', '\c2Change mission vote did not pass: %1 percent.', mFloor(%game.totalVotesFor/(ClientGroup.getCount() - $HostGameBotCount) * 100)); - } -} - -//------------------------------------------------------------------------------ -function DefaultGame::voteTeamDamage(%game, %admin) -{ - %setto = ""; - %cause = ""; - - if ($CurrentMissionType $= "RPG") - return; - - if(%admin) - { - if($teamDamage) - { - messageAll('MsgAdminForce', '\c2The Admin has disabled team damage.'); - $Host::TeamDamageOn = $TeamDamage = 0; - %setto = "disabled"; - } - else - { - messageAll('MsgAdminForce', '\c2The Admin has enabled team damage.'); - $Host::TeamDamageOn = $TeamDamage = 1; - %setto = "enabled"; - } - %cause = "(admin)"; - } - else - { - %totalVotes = %game.totalVotesFor + %game.totalVotesAgainst; - if(%totalVotes > 0 && (%game.totalVotesFor / (ClientGroup.getCount() - $HostGameBotCount)) > ($Host::VotePasspercent / 100)) - { - if($teamDamage) - { - messageAll('MsgVotePassed', '\c2Team damage was disabled by vote.'); - $Host::TeamDamageOn = $TeamDamage = 0; - %setto = "disabled"; - } - else - { - messageAll('MsgVotePassed', '\c2Team damage was enabled by vote.'); - $Host::TeamDamageOn = $TeamDamage = 1; - %setto = "enabled"; - } - %cause = "(vote)"; - } - else - { - if($teamDamage) - messageAll('MsgVoteFailed', '\c2Disable team damage vote did not pass: %1 percent.', mFloor(%game.totalVotesFor/(ClientGroup.getCount() - $HostGameBotCount) * 100)); - else - messageAll('MsgVoteFailed', '\c2Enable team damage vote did not pass: %1 percent.', mFloor(%game.totalVotesFor/(ClientGroup.getCount() - $HostGameBotCount) * 100)); - } - } - if(%setto !$= "") - logEcho("team damage "@%setto SPC %cause); -} - -//------------------------------------------------------------------------------ -function DefaultGame::voteTournamentMode( %game, %admin, %missionDisplayName, %typeDisplayName, %missionId, %missionTypeId ) -{ - %mission = $HostMissionFile[%missionId]; - - if ($CurrentMissionType $= "RPG") - return; - - if ( %mission $= "" ) - { - error( "Invalid mission index passed to DefaultGame::voteTournamentMode!" ); - return; - } - - %missionType = $HostTypeName[%missionTypeId]; - if ( %missionType $= "" ) - { - error( "Invalid mission type id passed to DefaultGame::voteTournamentMode!" ); - return; - } - - %cause = ""; - if (%admin) - { - messageAll( 'MsgAdminForce', '\c2The Admin has switched the server to Tournament mode (%1).', %missionDisplayName ); - setModeTournament( %mission, %missionType ); - %cause = "(admin)"; - } - else - { - %totalVotes = %game.totalVotesFor + %game.totalVotesAgainst; - if(%totalVotes > 0 && (%game.totalVotesFor / (ClientGroup.getCount() - $HostGameBotCount)) > ($Host::VotePasspercent / 100)) - { - messageAll('MsgVotePassed', '\c2Server switched to Tournament mode by vote (%1): %2 percent.', %missionDisplayName, mFloor(%game.totalVotesFor/(ClientGroup.getCount() - $HostGameBotCount) * 100)); - setModeTournament( %mission, %missionType ); - %cause = "(vote)"; - } - else - messageAll('MsgVoteFailed', '\c2Tournament mode vote did not pass: %1 percent.', mFloor(%game.totalVotesFor/(ClientGroup.getCount() - $HostGameBotCount) * 100)); - } - if(%cause !$= "") - logEcho("tournament mode set "@%cause); -} - -//------------------------------------------------------------------------------ -function DefaultGame::voteMatchStart( %game, %admin) -{ - %cause = ""; - %ready = forceTourneyMatchStart(); - - if(%admin) - { - if(!%ready) - { - messageClient( %client, 'msgClient', '\c2No players are ready yet.'); - return; - } - else - { - messageAll('msgMissionStart', '\c2The admin has forced the match to start.'); - %cause = "(admin)"; - startTourneyCountdown(); - } - } - else - { - if(!%ready) - { - messageAll( 'msgClient', '\c2Vote passed to start match, but no players are ready yet.'); - return; - } - else - { - %totalVotes = %game.totalVotesFor + %game.totalVotesAgainst; - if(%totalVotes > 0 && (%game.totalVotesFor / (ClientGroup.getCount() - $HostGameBotCount)) > ($Host::VotePasspercent / 100)) - { - messageAll('MsgVotePassed', '\c2The match has been started by vote: %1 percent.', mFloor(%game.totalVotesFor/(ClientGroup.getCount() - $HostGameBotCount) * 100)); - startTourneyCountdown(); - } - else - messageAll('MsgVoteFailed', '\c2Start Match vote did not pass: %1 percent.', mFloor(%game.totalVotesFor/(ClientGroup.getCount() - $HostGameBotCount) * 100)); - } - } - - if(%cause !$= "") - logEcho("start match "@%cause); -} - -//------------------------------------------------------------------------------ -function DefaultGame::voteFFAMode( %game, %admin, %client ) -{ - %cause = ""; - %name = getTaggedString(%client.name); - - if ($CurrentMissionType $= "RPG") - return; - - if (%admin) - { - messageAll('MsgAdminForce', '\c2The Admin has switched the server to Free For All mode.', %client); - setModeFFA($CurrentMission, $CurrentMissionType); - %cause = "(admin)"; - } - else - { - %totalVotes = %game.totalVotesFor + %game.totalVotesAgainst; - if(%totalVotes > 0 && (%game.totalVotesFor / (ClientGroup.getCount() - $HostGameBotCount)) > ($Host::VotePasspercent / 100)) - { - messageAll('MsgVotePassed', '\c2Server switched to Free For All mode by vote.', %client); - setModeFFA($CurrentMission, $CurrentMissionType); - %cause = "(vote)"; - } - else - messageAll('MsgVoteFailed', '\c2Free For All mode vote did not pass: %1 percent.', mFloor(%game.totalVotesFor/(ClientGroup.getCount() - $HostGameBotCount) * 100)); - } - if(%cause !$= "") - logEcho("free for all set "@%cause); -} - -//------------------------------------------------------------------------------ -function DefaultGame::voteChangeTimeLimit( %game, %admin, %newLimit ) -{ - if( %newLimit == 999 ) - %display = "unlimited"; - else - %display = %newLimit; - - if ($CurrentMissionType $= "RPG") - return; - - %cause = ""; - if ( %admin ) - { - messageAll( 'MsgAdminForce', '\c2The Admin changed the mission time limit to %1 minutes.', %display ); - $Host::TimeLimit = %newLimit; - %cause = "(admin)"; - } - else - { - %totalVotes = %game.totalVotesFor + %game.totalVotesAgainst; - if(%totalVotes > 0 && (%game.totalVotesFor / (ClientGroup.getCount() - $HostGameBotCount)) > ($Host::VotePasspercent / 100)) - { - messageAll('MsgVotePassed', '\c2The mission time limit was set to %1 minutes by vote.', %display); - $Host::TimeLimit = %newLimit; - %cause = "(vote)"; - } - else - messageAll('MsgVoteFailed', '\c2The vote to change the mission time limit did not pass: %1 percent.', mFloor(%game.totalVotesFor/(ClientGroup.getCount() - $HostGameBotCount) * 100)); - } - - //if the time limit was actually changed... - if(%cause !$= "") - { - logEcho("time limit set to "@%display SPC %cause); - - //if the match has been started, reset the end of match countdown - if ($matchStarted) - { - //schedule the end of match countdown - %elapsedTimeMS = getSimTime() - $missionStartTime; - %curTimeLeftMS = ($Host::TimeLimit * 60 * 1000) - %elapsedTimeMS; - error("time limit="@$Host::TimeLimit@", elapsed="@(%elapsedTimeMS / 60000)@", curtimeleftms="@%curTimeLeftMS); - CancelEndCountdown(); - EndCountdown(%curTimeLeftMS); - cancel(%game.timeSync); - %game.checkTimeLimit(true); - } - } -} - -//------------------------------------------------------------------------------ -function DefaultGame::voteResetServer( %game, %admin, %client ) -{ - %cause = ""; - if ( %admin ) - { - messageAll( 'AdminResetServer', '\c2The Admin has reset the server.' ); - resetServerDefaults(); - %cause = "(admin)"; - } - else - { - %totalVotes = %game.totalVotesFor + %game.totalVotesAgainst; - if(%totalVotes > 0 && (%game.totalVotesFor / (ClientGroup.getCount() - $HostGameBotCount)) > ($Host::VotePasspercent / 100)) - { - messageAll('MsgVotePassed', '\c2The Server has been reset by vote.' ); - resetServerDefaults(); - %cause = "(vote)"; - } - else - messageAll('MsgVoteFailed', '\c2The vote to reset Server to defaults did not pass: %1 percent.', mFloor(%game.totalVotesFor/(ClientGroup.getCount() - $HostGameBotCount) * 100)); - } - if(%cause !$= "") - logEcho("server reset "@%cause); -} - -//------------------------------------------------------------------------------ -// all team based votes here -function DefaultGame::voteKickPlayer(%game, %admin, %client) -{ - %cause = ""; - - if(%admin) - { - kick(%client, %admin, %client.guid ); - %cause = "(admin)"; - } - else - { - %team = %client.team; - %totalVotes = %game.votesFor[%game.kickTeam] + %game.votesAgainst[%game.kickTeam]; - if(%totalVotes > 0 && (%game.votesFor[%game.kickTeam] / %totalVotes) > ($Host::VotePasspercent / 100)) - { - kick(%client, %admin, %game.kickGuid); - %cause = "(vote)"; - } - else - { - for ( %idx = 0; %idx < ClientGroup.getCount(); %idx++ ) - { - %cl = ClientGroup.getObject( %idx ); - - if (%cl.team == %game.kickTeam && !%cl.isAIControlled()) - messageClient( %cl, 'MsgVoteFailed', '\c2Kick player vote did not pass' ); - } - } - } - - %game.kickTeam = ""; - %game.kickGuid = ""; - %game.kickClientName = ""; - - if(%cause !$= "") - logEcho(%name@" (cl " @ %game.kickClient @ ") kicked " @ %cause); -} - -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -function DefaultGame::voteLockServer(%game, %admin) -{ - %setto = ""; - %cause = ""; - - if(%admin) - { - if(!$ServerLock) - { - messageAll('MsgAdminForce', '\c2The Admin has locked the server.'); - allowConnections(false); - $ServerLock = true; - %setto = "no"; - } - else - { - messageAll('MsgAdminForce', '\c2The Admin has unlocked the server.'); - allowConnections(true); - $ServerLock = false; - %setto = "yes"; - } - %cause = "(admin)"; - - if(%setto !$= "") - logEcho("server allow connections "@%setto SPC %cause); -} -} - -//------------------------------------------------------------------------------ -function DefaultGame::voteGlobal(%game, %admin) -{ - %setto = ""; - %cause = ""; - - if(%admin) - { - if(!$Host::GlobalChat) - { - messageAll('MsgAdminForce', '\c2The Admin has enabled Global chat.'); - $Host::GlobalChat = true; - %setto = "yes"; - } - else - { - messageAll('MsgAdminForce', '\c2The Admin has disabled global chat.'); - $Host::GlobalChat = false; - %setto = "yes"; - } - %cause = "(admin)"; - - if(%setto !$= "") - logEcho("server allow global chatting "@%setto SPC %cause); -} -} -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -function DefaultGame::voteProgressiveMode(%game, %admin) -{ - %setto = ""; - %cause = ""; - - if(%admin) - { - if(!$Host::ProgressiveMode) - { - messageAll('MsgAdminForce', '\c2The Admin has enabled progressive mode.'); - $Host::ProgressiveMode = true; - $Game::BotWave = Game.schedule(120000,"SpawnAI",true); - %setto = "no"; - } - else - { - messageAll('MsgAdminForce', '\c2The Admin has disabled progressive mode.'); - cancel($Game::BotWave); - $Host::ProgressiveMode = false; - %setto = "yes"; - } - %cause = "(admin)"; - - if(%setto !$= "") - logEcho("progressive mode "@%setto SPC %cause); -} -} -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -function DefaultGame::banPlayer(%game, %admin, %client) -{ - %cause = ""; - %name = %client.nameBase; - if( %admin ) - { - ban( %client, %admin ); - %cause = "(admin)"; - } - - if(%cause !$= "") - logEcho(%name@" (cl "@%client@") banned "@%cause); -} - -//------------------------------------------------------------------------------ -function DefaultGame::voteAdminPlayer(%game, %admin, %client) -{ - %cause = ""; - - if (%admin) - { - messageAll('MsgAdminAdminPlayer', '\c2The Admin made %2 an admin.', %client, %client.name); - %client.isAdmin = 1; - %cause = "(admin)"; - } - else - { - %totalVotes = %game.totalVotesFor + %game.totalVotesAgainst; - if(%totalVotes > 0 && (%game.totalVotesFor / (ClientGroup.getCount() - $HostGameBotCount)) > ($Host::VotePasspercent / 100)) - { - messageAll('MsgAdminPlayer', '\c2%2 was made an admin by vote.', %client, %client.name); - %client.isAdmin = 1; - %cause = "(vote)"; - } - else - messageAll('MsgVoteFailed', '\c2Vote to make %1 an admin did not pass.', %client.name); - } - if(%cause !$= "") - logEcho(%client.nameBase@" (cl "@%client@") made admin "@%cause); -} - -//------------------------------------------------------------------------------ -function DefaultGame::processGameLink(%game, %client, %arg1, %arg2, %arg3, %arg4, %arg5) -{ - if (isObject(%arg1)) - { - if (%arg1.isAIControlled()) - return; //Don't do bots.. - - messageClient( %client, 'ClearHud', "", 'scoreScreen', 0 ); - - %tag = 'scoreScreen'; - %client.isViewingStatistics = true; - - messageClient( %client, 'SetScoreHudHeader', "", 'Player Information'); - messageClient( %client, 'SetScoreHudSubheader', "", "" @ %arg1.namebase); - - %index = 0; - messageClient( %client, 'SetLineHud', "", %tag, %index, "General---"); - %index++; - messageClient( %client, 'SetLineHud', "", %tag, %index, 'Race: %1 ', %client.race); - %index++; - if (%client.race $= "Draakan") - { - messageClient( %client, 'SetLineHud', "", %tag, %index, 'Type: %1', %client.sex); - %index++; - } - else - { - messageClient( %client, 'SetLineHud', "", %tag, %index, 'Sex: %1', %client.sex ); - %index++; - } - messageClient( %client, 'SetLineHud', "", %tag, %index, ""); - %index++; - messageClient( %client, 'SetLineHud', "", %tag, %index, ""); - %index++; - messageClient( %client, 'SetLineHud', "", %tag, %index, "Accuracy Quota---"); - %index++; - messageClient( %client, 'SetLineHud', "", %tag, %index, 'Shots Fired: %1 ', $Data::Shots[%arg1.guid]); - %index++; - messageClient( %client, 'SetLineHud', "", %tag, %index, 'Shots Landed: %1', $Data::Hits[%arg1.guid]); - %index++; - messageClient( %client, 'SetLineHud', "", %tag, %index, 'Head Shots: %1', $Data::Headshots[%arg1.guid]); - %index++; - messageClient( %client, 'SetLineHud', "", %tag, %index, "Percent: "@mfloor(($Data::Hits[%arg1.guid] / $Data::Shots[%arg1.guid])*100)@"%"); - %index++; - messageClient( %client, 'SetLineHud', "", %tag, %index, ""); - %index++; - messageClient( %client, 'SetLineHud', "", %tag, %index, ""); - %index++; - messageClient( %client, 'SetLineHud', "", %tag, %index, "Kill/Death Ratio---"); - %index++; - messageClient( %client, 'SetLineHud', "", %tag, %index, 'Kills: %1', $Data::Kills[%arg1.guid]); - %index++; - messageClient( %client, 'SetLineHud', "", %tag, %index, 'Deaths: %1', $Data::Deaths[%arg1.guid]); - %index++; - messageClient( %client, 'SetLineHud', "", %tag, %index, 'Suicides: %1', $Data::Suicides[%arg1.guid]); - %index++; - messageClient( %client, 'SetLineHud', "", %tag, %index, 'Ratio: %1',$Data::Deaths[%arg1.guid] / $Data::Kills[%arg1.guid]); - %index++; - messageClient( %client, 'SetLineHud', "", %tag, %index, ""); - %index++; - messageClient( %client, 'SetLineHud', "", %tag, %index, ""); - %index++; - messageClient( %client, 'SetLineHud', "", %tag, %index, 'Flag Running---'); - %index++; - messageClient( %client, 'SetLineHud', "", %tag, %index, 'Flags Captured: %1', $Data::Caps[%arg1.guid]); - %index++; - messageClient( %client, 'SetLineHud', "", %tag, %index, 'Flags Returned: %1', $Data::FlagReturns[%arg1.guid]); - %index++; - messageClient( %client, 'SetLineHud', "", %tag, %index, ""); - %index++; - messageClient( %client, 'SetLineHud', "", %tag, %index, ""); - %index++; - messageClient( %client, 'SetLineHud', "", %tag, %index, 'Win/Loss Ratio---'); - %index++; - messageClient( %client, 'SetLineHud', "", %tag, %index, 'Games Won: %1', $Data::Won[%arg1.guid]); - %index++; - messageClient( %client, 'SetLineHud', "", %tag, %index, 'Games Lost: %1', $Data::Lost[%arg1.guid]); - %index++; - messageClient( %client, 'SetLineHud', "", %tag, %index, "Back To Score Menu"); - } - else //Then we clicked 'back' or something else happened. - { - messageClient( %client, 'ClearHud', "", 'scoreScreen', 0 ); - %client.isViewingStatistics = false; - //CTFGame:updateScoreHud:(%game,%client,'scoreHud'); - Game.updateScoreHud(%game,%client,'scoreHud'); - } -} - -//------------------------------------------------------------------------------ -$ScoreHudMaxVisible = 19; -function DefaultGame::updateScoreHud(%game, %client, %tag) -{ - -if (%client.isViewingStatistics) -return; - - if (Game.numTeams > 1) - { - // Send header: - messageClient( %client, 'SetScoreHudHeader', "", '\t%1%2\t%3%4', - %game.getTeamName(1), $TeamScore[1], %game.getTeamName(2), $TeamScore[2] ); - - // Send subheader: - messageClient( %client, 'SetScoreHudSubheader', "", '\tPLAYERS (%1)SCORE\tPLAYERS (%2)SCORE', - $TeamRank[1, count], $TeamRank[2, count] ); - - %index = 0; - while ( true ) - { - if ( %index >= $TeamRank[1, count]+2 && %index >= $TeamRank[2, count]+2 ) - break; - - //get the team1 client info - %team1Client = ""; - %team1ClientScore = ""; - %col1Style = ""; - if ( %index < $TeamRank[1, count] ) - { - %team1Client = $TeamRank[1, %index]; - %team1ClientScore = %team1Client.score $= "" ? 0 : %team1Client.score; - %col1Style = %team1Client == %client ? "" : ""; - %team1playersTotalScore += %team1Client.score; - } - else if( %index == $teamRank[1, count] && $teamRank[1, count] != 0 && %game.class $= "CTFGame") // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - { - %team1ClientScore = "--------------"; - } - else if( %index == $teamRank[1, count]+1 && $teamRank[1, count] != 0 && %game.class $= "CTFGame") // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - { - %team1ClientScore = %team1playersTotalScore != 0 ? %team1playersTotalScore : 0; - } - //get the team2 client info - %team2Client = ""; - %team2ClientScore = ""; - %col2Style = ""; - if ( %index < $TeamRank[2, count] ) - { - %team2Client = $TeamRank[2, %index]; - %team2ClientScore = %team2Client.score $= "" ? 0 : %team2Client.score; - %col2Style = %team2Client == %client ? "" : ""; - %team2playersTotalScore += %team2Client.score; - } - else if( %index == $teamRank[2, count] && $teamRank[2, count] != 0 && %game.class $= "CTFGame") // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - { - %team2ClientScore = "--------------"; - } - else if( %index == $teamRank[2, count]+1 && $teamRank[2, count] != 0 && %game.class $= "CTFGame") // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - { - %team2ClientScore = %team2playersTotalScore != 0 ? %team2playersTotalScore : 0; - } - - //if the client is not an observer, send the message - if (%client.team != 0) - { - messageClient( %client, 'SetLineHud', "", %tag, %index, '\t%5%1%2\t%6%3%4', - %team1Client.name, %team1ClientScore, %team2Client.name, %team2ClientScore, %col1Style, %col2Style, %team1Client, %team2Client ); - } - //else for observers, create an anchor around the player name so they can be observed - else - { - messageClient( %client, 'SetLineHud', "", %tag, %index, '\t%5%1%2\t%6%3%4', - %team1Client.name, %team1ClientScore, %team2Client.name, %team2ClientScore, %col1Style, %col2Style, %team1Client, %team2Client ); - } - - %index++; - } - } - else - { - //tricky stuff here... use two columns if we have more than 15 clients... - %numClients = $TeamRank[0, count]; - if ( %numClients > $ScoreHudMaxVisible ) - %numColumns = 2; - - // Clear header: - messageClient( %client, 'SetScoreHudHeader', "", "" ); - - // Send header: - if (%numColumns == 2) - messageClient(%client, 'SetScoreHudSubheader', "", '\tPLAYERSCORE\tPLAYERSCORE'); - else - messageClient(%client, 'SetScoreHudSubheader', "", '\tPLAYERSCORE'); - - %countMax = %numClients; - if ( %countMax > ( 2 * $ScoreHudMaxVisible ) ) - { - if ( %countMax & 1 ) - %countMax++; - %countMax = %countMax / 2; - } - else if ( %countMax > $ScoreHudMaxVisible ) - %countMax = $ScoreHudMaxVisible; - - for ( %index = 0; %index < %countMax; %index++ ) - { - //get the client info - %col1Client = $TeamRank[0, %index]; - %col1ClientScore = %col1Client.score $= "" ? 0 : %col1Client.score; - %col1Style = %col1Client == %client ? "" : ""; - - //see if we have two columns - if ( %numColumns == 2 ) - { - %col2Client = ""; - %col2ClientScore = ""; - %col2Style = ""; - - //get the column 2 client info - %col2Index = %index + %countMax; - if ( %col2Index < %numClients ) - { - %col2Client = $TeamRank[0, %col2Index]; - %col2ClientScore = %col2Client.score $= "" ? 0 : %col2Client.score; - %col2Style = %col2Client == %client ? "" : ""; - } - } - - //if the client is not an observer, send the message - if (%client.team != 0) - { - messageClient( %client, 'SetLineHud', "", %tag, %index, '\t%5%1%2\t%6%3%4', - "" @ getTaggedString(%team1Client.name) @ "", %team1ClientScore, "" @ getTaggedString(%team2Client.name) @ "", %team2ClientScore, %col1Style, %col2Style ); - } - //else for observers, create an anchor around the player name so they can be observed - else - { - messageClient( %client, 'SetLineHud', "", %tag, %index, '\t%5%1%2\t%6%3%4', - %team1Client.name, %team1ClientScore, %team2Client.name, %team2ClientScore, %col1Style, %col2Style, %team1Client, %team2Client ); - } - - } - - } - - // Tack on the list of observers: - %observerCount = 0; - for (%i = 0; %i < ClientGroup.getCount(); %i++) - { - %cl = ClientGroup.getObject(%i); - if (%cl.team == 0) - %observerCount++; - } - - if (%observerCount > 0) - { - messageClient( %client, 'SetLineHud', "", %tag, %index, ""); - %index++; - messageClient(%client, 'SetLineHud', "", %tag, %index, '\tOBSERVERS (%1)TIME', %observerCount); - %index++; - for (%i = 0; %i < ClientGroup.getCount(); %i++) - { - %cl = ClientGroup.getObject(%i); - //if this is an observer - if (%cl.team == 0) - { - %obsTime = getSimTime() - %cl.observerStartTime; - %obsTimeStr = %game.formatTime(%obsTime, false); - messageClient( %client, 'SetLineHud', "", %tag, %index, '\t%1%2', - %cl.name, %obsTimeStr ); - %index++; - } - } - } - - //clear the rest of Hud so we don't get old lines hanging around... - messageClient( %client, 'ClearHud', "", %tag, %index ); -} - -//------------------------------------------------------------------------------ -function UpdateClientTimes(%time) -{ - %secondsLeft = %time / 1000; - messageAll('MsgSystemClock', "", (%secondsLeft / 60), %time); -} - -//------------------------------------------------------------------------------ -function notifyMatchStart(%time) -{ - %seconds = mFloor(%time / 1000); - if (%seconds > 2) - MessageAll('MsgMissionStart', '\c2Match starts in %1 seconds.~wfx/misc/hunters_%1.wav', %seconds); - else if (%seconds == 2) - MessageAll('MsgMissionStart', '\c2Match starts in 2 seconds.~wvoice/announcer/ann.match_begins.wav'); - else if (%seconds == 1) - MessageAll('MsgMissionStart', '\c2Match starts in 1 second.'); - UpdateClientTimes(%time); -} - -//------------------------------------------------------------------------------ -function notifyMatchEnd(%time) -{ - %seconds = mFloor(%time / 1000); - if (%seconds > 1) - MessageAll('MsgMissionEnd', '\c2Match ends in %1 seconds.~wfx/misc/hunters_%1.wav', %seconds); - else if (%seconds == 1) - MessageAll('MsgMissionEnd', '\c2Match ends in 1 second.~wfx/misc/hunters_1.wav'); - UpdateClientTimes(%time); -} - -function DefaultGame::formatTime(%game, %tStr, %includeHundredths) -{ - %timeInSeconds = %tStr / 1000; - %mins = mFloor(%timeInSeconds / 60); - if(%mins < 1) - %timeString = "00:"; - else if(%mins < 10) - %timeString = "0" @ %mins @ ":"; - else - %timeString = %mins @ ":"; - - %timeInSeconds -= (%mins * 60); - %secs = mFloor(%timeInSeconds); - if(%secs < 1) - %timeString = %timeString @ "00"; - else if(%secs < 10) - %timeString = %timeString @ "0" @ %secs; - else - %timeString = %timeString @ %secs; - - if (%includeHundredths) - { - %timeString = %timeString @ "."; - %timeInSeconds -= %secs; - %hSecs = mFloor(%timeInSeconds * 100); // will be between 0 and 999 - if(%hSecs < 1) - %timeString = %timeString @ "00"; - else if(%hSecs < 10) - %timeString = %timeString @ "0" @ %hSecs; - else - %timeString = %timeString @ %hSecs; - } - - return %timeString; -} - -//------------------------------------------------------------------------------ -//AI FUNCTIONS -function DefaultGame::AIChooseGameObjective(%game, %client) -{ - AIChooseObjective(%client); -} - -//------------------------------------------------------------------------------ -function DefaultGame::getServerStatusString(%game) -{ - %status = %game.numTeams; - for ( %team = 1; %team - 1 < %game.numTeams; %team++ ) - { - %score = isObject( $teamScore[%team] ) ? $teamScore[%team] : 0; - %teamStr = getTaggedString( %game.getTeamName(%team) ) TAB %score; - %status = %status NL %teamStr; - } - - %status = %status NL ClientGroup.getCount(); - for ( %i = 0; %i < ClientGroup.getCount(); %i++ ) - { - %cl = ClientGroup.getObject( %i ); - %score = %cl.score $= "" ? 0 : %cl.score; - %playerStr = getTaggedString( %cl.name ) TAB getTaggedString( %game.getTeamName(%cl.team) ) TAB %score; - %status = %status NL %playerStr; - } - return( %status ); -} - -//------------------------------------------------------------------------------ -function DefaultGame::OptionsDlgSleep( %game ) -{ - // ignore in the default game... -} - -//------------------------------------------------------------------------------ -function DefaultGame::endMission( %game ) -{ -} - -//------------------------------------------------------------------------------ -// z0dd - ZOD. Console spam fix -function DefaultGame::countFlips(%game) -{ - return false; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Random Teams code by Founder (founder@mechina.com) 6/22/02 /////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////// - -function DefaultGame::setupClientTeams(%game) -{ - if(!$Host::ClassicRandomizeTeams || %game.numTeams == 1) - { - %count = ClientGroup.getCount(); - for (%i = 0; %i < %count; %i++) - { - %client = ClientGroup.getObject(%i); - %client.lastTeam = %client.team; - %client.setupTeam = 0; - } - return; - } - else - { - %numTeamPlayers = 0; - %totalNumPlayers = ClientGroup.getCount(); - for(%i = 0; %i < %totalNumPlayers; %i++) - { - %cl = ClientGroup.getObject(%i); - if(%cl.team == 0) - %cl.lastTeam = %cl.team; - else - { - %teamPlayer[%numTeamPlayers] = %cl; - %numTeamPlayers++; - } - } - %numPlayersLeft = %numTeamPlayers - 1; - for(%j = 0; %j < %numTeamPlayers; %j++) - { - if(%numPlayersLeft > 0) - { - %r = 0; - %val = mFloor(getRandom(0, %numPlayersLeft)); - if(%val > %numPlayersLeft) - %val = %numPlayersLeft; - - %client = %teamPlayer[%val]; - %shuffledPlayersArray[%j] = %client; - for(%y = 0; %y <= %numPlayersLeft; %y++) - { - %clplyr = %teamPlayer[%y]; - if(%clplyr != %client) - { - %teamPlayer[%r] = %clplyr; - %r++; - } - } - %numPlayersLeft--; - } - else - %shuffledPlayersArray[%j] = %teamPlayer[%numPlayersLeft]; - } - %thisTeam = 1; - for(%k = 0; %k <= %numTeamPlayers; %k++) - { - if(%thisTeam == 1) - { - %shuffledPlayersArray[%k].lastTeam = 1; - %thisTeam = 0; - } - else - { - %shuffledPlayersArray[%k].lastTeam = 2; - %thisTeam = 1; - } - } - } -} +//$MissionName is the file name of the mission +//$MapName is the displayed name(no underscore,spaces) +//$GameType (CTF,Hunters) + + +function DefaultGame::activatePackages(%game) +{ + // activate the default package for the game type + activatePackage(DefaultGame); + if(isPackage(%game.class) && %game.class !$= DefaultGame) + activatePackage(%game.class); +} + +function DefaultGame::deactivatePackages(%game) +{ + deactivatePackage(DefaultGame); + if(isPackage(%game.class) && %game.class !$= DefaultGame) + deactivatePackage(%game.class); +} + +package DefaultGame { + +function FlipFlop::objectiveInit(%data, %flipflop) +{ + // add this flipflop to missioncleanup + %flipflopSet = nameToID("MissionCleanup/FlipFlops"); + if(%flipflopSet <= 0) { + %flipflopSet = new SimSet("FlipFlops"); + MissionCleanup.add(%flipflopSet); + } + %flipflopSet.add(%flipflop); + + // see if there's a holo projector associated with this flipflop + // search the flipflop's folder for a holo projector + // if one exists, associate it with the flipflop + + %flipflop.projector = 0; + %folder = %flipflop.getGroup(); + for(%i = 0; %i < %folder.getCount(); %i++) + { + %proj = %folder.getObject(%i); + // weird, but line below prevents console error + if(%proj.getClassName() !$= "SimGroup" && %proj.getClassName() !$= "InteriorInstance") + if(%proj.getDatablock().getName() $= "LogoProjector") + { + %flipflop.projector = %proj; + %flipflop.projector.holo = 0; + break; + } + } + + // may have been hidden + %target = %flipFlop.getTarget(); + if(%target != -1) + { + // set flipflop to base skin + setTargetSkin(%target, $teamSkin[0]); + + // make this always visible in the commander map + setTargetAlwaysVisMask(%target, 0xffffffff); + + // make this always visible in the commander list + setTargetRenderMask(%target, getTargetRenderMask(%target) | $TargetInfo::CommanderListRender); + } +} + +function FlipFlop::playerTouch(%data, %flipflop, %player) +{ + %client = %player.client; + %flipTeam = %flipflop.team; + + if(%flipTeam == %client.team) + return false; + + %teamName = game.getTeamName(%client.team); + // Let the observers know: + messageTeam( 0, 'MsgClaimFlipFlop', '\c2%1 claimed %2 for %3.~wfx/misc/flipflop_taken.wav', %client.name, Game.cleanWord( %flipflop.name ), %teamName ); + // Let the teammates know: + messageTeam( %client.team, 'MsgClaimFlipFlop', '\c2%1 claimed %2 for %3.~wfx/misc/flipflop_taken.wav', %client.name, Game.cleanWord( %flipflop.name ), %teamName ); + // Let the other team know: + %losers = %client.team == 1 ? 2 : 1; + messageTeam( %losers, 'MsgClaimFlipFlop', '\c2%1 claimed %2 for %3.~wfx/packs/shield_hit.wav', %client.name, Game.cleanWord( %flipflop.name ), %teamName ); // z0dd - ZOD, 10/30/02. Change flipflop lost sound + + logEcho(%client.nameBase@" (pl "@%player@"/cl "@%client@") claimed flipflop "@%flipflop@" for team "@%client.team); + + //change the skin on the switch to claiming team's logo + setTargetSkin(%flipflop.getTarget(), game.getTeamSkin(%player.team)); + setTargetSensorGroup(%flipflop.getTarget(), %player.team); + + // if there is a "projector" associated with this flipflop, put the claiming team's logo there + if(%flipflop.projector > 0) + { + %projector = %flipflop.projector; + // axe the old projected holo, if one exists + if(%projector.holo > 0) + %projector.holo.delete(); + + %newHolo = getTaggedString(game.getTeamSkin(%client.team)) @ "Logo"; + + %projTransform = %projector.getTransform(); + // below two functions are from deployables.cs + %projRot = rotFromTransform(%projTransform); + %projPos = posFromTransform(%projTransform); + // place the holo above the projector (default 10 meters) + %hHeight = %projector.holoHeight; + if(%hHeight $= "") + %hHeight = 10; + %holoZ = getWord(%projPos, 2) + %hHeight; + %holoPos = firstWord(%projPos) SPC getWord(%projPos,1) SPC %holoZ; + + %holo = new StaticShape() + { + rotation = %projRot; + position = %holoPos; + dataBlock = %newHolo; + }; + // dump the hologram into MissionCleanup + MissionCleanup.add(%holo); + // associate the holo with the projector + %projector.holo = %holo; + } + + // convert the resources associated with the flipflop + Game.claimFlipflopResources(%flipflop, %client.team); + + if(Game.countFlips()) + for(%i = 1; %i <= Game.numTeams; %i++) + { + %teamHeld = Game.countFlipsHeld(%i); + messageAll('MsgFlipFlopsHeld', "", %i, %teamHeld); + } + + //call the ai function + Game.AIplayerCaptureFlipFlop(%player, %flipflop); + return true; +} + +}; + +//--------- DEFAULT SCORING, SUPERCEDE IN GAMETYPE FILE ------------------ + +function DefaultGame::initGameVars(%game) +{ + %game.SCORE_PER_SUICIDE = 0; + %game.SCORE_PER_TEAMKILL = 0; + %game.SCORE_PER_DEATH = 0; + + %game.SCORE_PER_KILL = 0; + + %game.SCORE_PER_TURRET_KILL = 0; +} + +//-- tracking --- +// .deaths .kills .suicides .teamKills .turretKills + +function DefaultGame::claimFlipflopResources(%game, %flipflop, %team) +{ + %group = %flipflop.getGroup(); + %group.setTeam(%team); + + // make this always visible in the commander map (gets reset when sensor group gets changed) + setTargetAlwaysVisMask(%flipflop.getTarget(), 0xffffffff); +} + +//------------------------------------------------------------------------------ +function DefaultGame::selectSpawnSphere(%game, %team) +{ + // - walks the objects in the 'teamdrops' group for this team + // - find a random spawn point which has a running sum less more than + // 0->total sphere weight + + %teamDropsGroup = "MissionCleanup/TeamDrops" @ %team; + + %group = nameToID(%teamDropsGroup); + if (%group != -1) + { + %count = %group.getCount(); + if (%count != 0) + { + // Get total weight of those spheres not filtered by mission types list- + %overallWeight = 0; + for (%i = 0; %i < %count; %i++) + { + %sphereObj = %group.getObject(%i); + if ( ! %sphereObj.isHidden() ) + %overallWeight += %sphereObj.sphereWeight; + } + + if (%overallWeight > 0) + { + // Subtract a little from this as hedge against any rounding offness- + %randSum = getRandom(%overallWeight) - 0.05; + // echo("randSum = " @ %randSum); + + for (%i = 0; %i < %count; %i++) + { + %sphereObj = %group.getObject(%i); + if (! %sphereObj.isHidden()) + { + %randSum -= %sphereObj.sphereWeight; + if (%randSum <= 0) + { + // echo("Chose sphere " @ %i); + return %group.getObject(%i); // Found our sphere + } + } + } + error("Random spawn sphere selection didn't work"); + } + else + error("No non-hidden spawnspheres were found in " @ %teamDropsGroup); + } + else + error("No spawnspheres found in " @ %teamDropsGroup); + } + else + error(%teamDropsGroup @ " not found in selectSpawnSphere()."); + + return -1; +} + +function DefaultGame::selectSpawnZone(%game, %sphere) +{ + // determines if this should spawn inside or outside + %overallWeight = %sphere.indoorWeight + %sphere.outdoorWeight; + %index = mFloor(getRandom() * (%overallWeight - 0.1)) + 1; + if ((%index - %sphere.indoorWeight) > 0) + return false; //do not pick an indoor spawn + else + return true; //pick an indoor spawn +} + +function DefaultGame::selectSpawnFacing(%game, %src, %target, %zone) +{ + //this used only when spawn loc is not on an interior. This points spawning player to the ctr of spawnshpere + %target = setWord(%target, 2, 0); + %src = setWord(%src, 2, 0); + + if(VectorDist(%target, %src) == 0) + return " 0 0 1 0 "; + %vec = VectorNormalize(VectorSub(%target, %src)); + %angle = mAcos(getWord(%vec, 1)); + + if(%src < %target) + return(" 0 0 1 " @ %angle); + else + return(" 0 0 1 " @ -%angle); +} + +function DefaultGame::pickTeamSpawn(%game, %team) +{ + // early exit if no nav graph + if (!navGraphExists()) + { + echo("No navigation graph is present. Build one."); + return -1; + } + + for (%attempt = 0; %attempt < 20; %attempt++) + { + // finds a random spawn sphere + // selects inside/outside on this random sphere + // if the navgraph exists, then uses it to grab a random node as spawn + // location/rotation + %sphere = %game.selectSpawnSphere(%team); + if (%sphere == -1) + { + echo("No spawn spheres found for team " @ %team); + return -1; + } + + %zone = %game.selectSpawnZone(%sphere); + %useIndoor = %zone; + %useOutdoor = !%zone; + if (%zone) + %area = "indoor"; + else + %area = "outdoor"; + + %radius = %sphere.radius; + %sphereTrans = %sphere.getTransform(); + %sphereCtr = getWord(%sphereTrans, 0) @ " " @ getWord(%sphereTrans, 1) @ " " @ getWord(%sphereTrans, 2); //don't need full transform here, just x, y, z + //echo("Selected Sphere is " @ %sphereCtr @ " with a radius of " @ %radius @ " meters. Selecting from " @ %area @ " zone."); + + %avoidThese = $TypeMasks::VehicleObjectType | $TypeMasks::MoveableObjectType | + $TypeMasks::PlayerObjectType | $TypeMasks::TurretObjectType; + + for (%tries = 0; %tries < 10; %tries++) + { + %nodeIndex = navGraph.randNode(%sphereCtr, %radius, %useIndoor, %useOutdoor); + if (%nodeIndex >= 0) + { + %loc = navGraph.randNodeLoc(%nodeIndex); + %adjUp = VectorAdd(%loc, "0 0 1.0"); // don't go much below + + if (ContainerBoxEmpty( %avoidThese, %adjUp, 2.0)) + break; + } + } + + if (%nodeIndex >= 0) + { + %loc = navGraph.randNodeLoc(%nodeIndex); + if (%zone) + { + %trns = %loc @ " 0 0 1 0"; + %spawnLoc = whereToLook(%trns); + } + else + { + %rot = %game.selectSpawnFacing(%loc, %sphereCtr, %zone); + %spawnLoc = %loc @ %rot; + } + return %spawnLoc; + } + } +} + +//------------------------------------------------------------ + +function DefaultGame::pickObserverSpawn(%game, %client, %next) +{ + %group = nameToID("MissionGroup/ObserverDropPoints"); + %count = %group.getCount(); + + if(!%count || %group == -1) + { + echo("no observer spawn points found"); + return -1; + } + + if(%client.lastObserverSpawn == -1) + { + %client.lastObserverSpawn = 0; + return(%group.getObject(%client.lastObserverSpawn)); + } + + if(%next == true) + %spawnIdx = %client.lastObserverSpawn + 1; + else + %spawnIdx = %client.lastObserverSpawn - 1; + + if(%spawnIdx < 0) + %spawnIdx = %count - 1; + else if(%spawnIdx >= %count) + %spawnIdx = 0; + + %client.lastObserverSpawn = %spawnIdx; + //echo("Observer spawn point found"); + return %group.getObject(%spawnIdx); +} + +//------------------------------------------------------------ +function DefaultGame::spawnPlayer( %game, %client, %respawn ) +{ + %client.lastSpawnPoint = %game.pickPlayerSpawn( %client, false ); + %client.suicidePickRespawnTime = getSimTime() + 20000; + %game.createPlayer( %client, %client.lastSpawnPoint, %respawn ); +} + +//------------------------------------------------------------ +function DefaultGame::playerSpawned(%game, %player) +{ + if( %player.client.respawnTimer ) + cancel(%player.client.respawnTimer); + + %player.client.observerStartTime = ""; + %game.equip(%player); + + //set the spawn time (for use by the AI system) + %player.client.spawnTime = getSimTime(); + +// jff: this should probably be checking the team of the client + //update anyone observing this client + %count = ClientGroup.getCount(); + for (%i = 0; %i < %count; %i++) + { + %cl = ClientGroup.getObject(%i); + if (%cl.camera.mode $= "observerFollow" && %cl.observeClient == %player.client) + { + %transform = %player.getTransform(); + %cl.camera.setOrbitMode(%player, %transform, 0.5, 4.5, 4.5); + %cl.camera.targetObj = %player; + } + } +} + +function DefaultGame::equip(%game, %player) +{ + for(%i =0; %i<$InventoryHudCount; %i++) + %player.client.setInventoryHudItem($InventoryHudData[%i, itemDataName], 0, 1); + %player.client.clearBackpackIcon(); + + //%player.setArmor("Light"); + %player.setInventory(RepairKit,1); + %player.setInventory(Grenade,6); + %player.setInventory(Blaster,1); + %player.setInventory(Disc,1); + %player.setInventory(Chaingun, 1); + %player.setInventory(ChaingunAmmo, 100); + %player.setInventory(DiscAmmo, 20); + %player.setInventory(Beacon, 3); + %player.setInventory(TargetingLaser, 1); + %player.weaponCount = 3; + + if (%player.client.race $= "Draakan") + %player.setInventory(Flamer,1); + + %player.use("Blaster"); +} + +//------------------------------------------------------------ +function DefaultGame::pickPlayerSpawn(%game, %client, %respawn) +{ + // place this client on his own team, '%respawn' does not ever seem to be used + //we no longer care whether it is a respawn since all spawns use same points. + return %game.pickTeamSpawn(%client.team); +} + +//------------------------------------------------------------ +function DefaultGame::createPlayer(%game, %client, %spawnLoc, %respawn) +{ + // do not allow a new player if there is one (not destroyed) on this client + if(isObject(%client.player) && (%client.player.getState() !$= "Dead")) + return; + + // clients and cameras can exist in team 0, but players should not + if(%client.team == 0) + error("Players should not be added to team0!"); + + // defaultplayerarmor is in 'players.cs' + if(%spawnLoc == -1) + %spawnLoc = "0 0 300 1 0 0 0"; + //else + // echo("Spawning player at " @ %spawnLoc); + + //Apparent game errors for bots spawned manually. + if (%client.race $= "") + %client.race = "Human"; + if (%client.sex $= "") + %client.sex = "Male"; + + // copied from player.cs + if (%client.race $= "Bioderm") + // Only have male bioderms. + %armor = $DefaultPlayerArmor @ "Male" @ %client.race @ Armor; + else + %armor = $DefaultPlayerArmor @ %client.sex @ %client.race @ Armor; + %client.armor = $DefaultPlayerArmor; + + + %player = new Player() { + //dataBlock = $DefaultPlayerArmor; + dataBlock = %armor; + shouldBurn = true; //So the Draakans can burn meh. + }; + + + if(%respawn) + { + %player.setInvincible(true); + //%player.setCloaked(true); // z0dd - ZOD, 8/6/02. Don't spawn players cloaked + %player.setInvincibleMode($InvincibleTime,0.02); + //%player.respawnCloakThread = %player.schedule($InvincibleTime * 1000, "setRespawnCloakOff"); // z0dd - ZOD, 8/6/02. Don't spawn players cloaked + %player.schedule($InvincibleTime * 1000, "setInvincible", false); + } + + %player.setTransform( %spawnLoc ); + MissionCleanup.add(%player); + + // setup some info + %player.setOwnerClient(%client); + %player.team = %client.team; + %client.outOfBounds = false; + %player.setEnergyLevel(60); + %client.player = %player; + + // updates client's target info for this player + %player.setTarget(%client.target); + setTargetDataBlock(%client.target, %player.getDatablock()); + setTargetSensorData(%client.target, PlayerSensor); + setTargetSensorGroup(%client.target, %client.team); + %client.setSensorGroup(%client.team); + + //make sure the player has been added to the team rank array... + %game.populateTeamRankArray(%client); + + %game.playerSpawned(%client.player); +} + +function Player::setRespawnCloakOff(%player) +{ + %player.setCloaked(false); + %player.respawnCloakThread = ""; +} + +//------------------------------------------------------------ + +function DefaultGame::startMatch(%game) +{ + echo("START MATCH"); + MessageAll('MsgMissionStart', "\c2Match started!"); + + //the match has been started, clear the team rank array, and repopulate it... + for (%i = 0; %i < 32; %i++) + %game.clearTeamRankArray(%i); + + //used in BountyGame, prolly in a few others as well... + $matchStarted = true; + + %game.clearDeployableMaxes(); + + $missionStartTime = getSimTime(); + %curTimeLeftMS = ($Host::TimeLimit * 60 * 1000); + + // schedule first timeLimit check for 20 seconds + if(%game.class !$= "SiegeGame") + { + %game.timeCheck = %game.schedule(20000, "checkTimeLimit"); + } + + //schedule the end of match countdown + EndCountdown($Host::TimeLimit * 60 * 1000); + + //reset everyone's score and add them to the team rank array + for (%i = 0; %i < ClientGroup.getCount(); %i++) + { + %cl = ClientGroup.getObject(%i); + %game.resetScore(%cl); + %game.populateTeamRankArray(%cl); + } + + // set all clients control to their player + %count = ClientGroup.getCount(); + for( %i = 0; %i < %count; %i++ ) + { + %cl = ClientGroup.getObject(%i); + + // Siege game will set the clock differently + if(%game.class !$= "SiegeGame") + messageClient(%cl, 'MsgSystemClock', "", $Host::TimeLimit, %curTimeLeftMS); + + if( !$Host::TournamentMode && %cl.matchStartReady && %cl.camera.mode $= "pre-game") + { + commandToClient(%cl, 'setHudMode', 'Standard'); + %cl.setControlObject( %cl.player ); + } + else + { + if( %cl.matchStartReady ) + { + if(%cl.camera.mode $= "pre-game") + { + %cl.observerMode = ""; + commandToClient(%cl, 'setHudMode', 'Standard'); + + if(isObject(%cl.player)) + %cl.setControlObject( %cl.player ); + else + echo("can't set control for client: " @ %cl @ ", no player object found!"); + } + else + %cl.observerMode = "observerFly"; + } + } + } + + // on with the show this is it! + AISystemEnabled( true ); +} + +function DefaultGame::gameOver( %game ) +{ + //set the bool + $missionRunning = false; + + //Since gameOver can't be called for RPG, tell the game to save any vars in memory + saveGame(); + + CancelCountdown(); + CancelEndCountdown(); + + //loop through all the clients, and do any cleanup... + %count = ClientGroup.getCount(); + for (%i = 0; %i < %count; %i++) + { + %client = ClientGroup.getObject(%i); + %player = %client.player; + + // z0dd - ZOD, 6/13/02. Need to remove this for random teams by Founder (founder@mechina.com). + if($CurrentMissionType $= TR2) // z0dd - ZOD, 9/17/02. Check for Team Rabbit 2 + %client.lastTeam = %client.team; + + if ( !%client.isAiControlled() ) + { + %client.endMission(); + messageClient( %client, 'MsgClearDebrief', "" ); + %game.sendDebriefing( %client ); + + if(%client.player.isBomber) + commandToClient(%client, 'endBomberSight'); + + //clear the score hud... + messageClient( %client, 'SetScoreHudHeader', "", "" ); + messageClient( %client, 'SetScoreHudSubheader', "", ""); + messageClient( %client, 'ClearHud', "", 'scoreScreen', 0 ); + + // clean up the players' HUDs: + %client.setWeaponsHudClearAll(); + %client.setInventoryHudClearAll(); + } + } + // z0dd - ZOD, 6/22/02. Setup random teams by Founder (founder@mechina.com). + if($CurrentMissionType !$= TR2) // z0dd - ZOD, 9/17/02. Check for Team Rabbit 2 + %game.setupClientTeams(); + + // Default game does nothing... except lets the AI know the mission is over + AIMissionEnd(); +} + +//------------------------------------------------------------------------------ +function DefaultGame::sendDebriefing( %game, %client ) +{ + if ( %game.numTeams == 1 ) + { + // Mission result: + %winner = $TeamRank[0, 0]; + if ( %winner.score > 0 ) + messageClient( %client, 'MsgDebriefResult', "", '%1 wins!', $TeamRank[0, 0].name ); + else + messageClient( %client, 'MsgDebriefResult', "", 'Nobody wins.' ); + + // Player scores: + %count = $TeamRank[0, count]; + messageClient( %client, 'MsgDebriefAddLine', "", 'PLAYERSCOREKILLS' ); + for ( %i = 0; %i < %count; %i++ ) + { + %cl = $TeamRank[0, %i]; + if ( %cl.score $= "" ) + %score = 0; + else + %score = %cl.score; + if ( %cl.kills $= "" ) + %kills = 0; + else + %kills = %cl.kills; + messageClient( %client, 'MsgDebriefAddLine', "", ' %1 %2 %3', %cl.name, %score, %kills ); + } + } + else + { + %topScore = ""; + %topCount = 0; + for ( %team = 1; %team <= %game.numTeams; %team++ ) + { + if ( %topScore $= "" || $TeamScore[%team] > %topScore ) + { + %topScore = $TeamScore[%team]; + %firstTeam = %team; + %topCount = 1; + } + else if ( $TeamScore[%team] == %topScore ) + { + %secondTeam = %team; + %topCount++; + } + } + + // Mission result: + if ( %topCount == 1 ) + messageClient( %client, 'MsgDebriefResult', "", 'Team %1 wins!', %game.getTeamName(%firstTeam) ); + else if ( %topCount == 2 ) + messageClient( %client, 'MsgDebriefResult', "", 'Team %1 and Team %2 tie!', %game.getTeamName(%firstTeam), %game.getTeamName(%secondTeam) ); + else + messageClient( %client, 'MsgDebriefResult', "", 'The mission ended in a tie.' ); + + // Team scores: + messageClient( %client, 'MsgDebriefAddLine', "", 'TEAMSCORE' ); + for ( %team = 1; %team - 1 < %game.numTeams; %team++ ) + { + if ( $TeamScore[%team] $= "" ) + %score = 0; + else + %score = $TeamScore[%team]; + messageClient( %client, 'MsgDebriefAddLine', "", ' %1 %2', %game.getTeamName(%team), %score ); + } + + // Player scores: + messageClient( %client, 'MsgDebriefAddLine', "", '\nPLAYERTEAMSCOREKILLS' ); + for ( %team = 1; %team - 1 < %game.numTeams; %team++ ) + %count[%team] = 0; + + %notDone = true; + while ( %notDone ) + { + // Get the highest remaining score: + %highScore = ""; + for ( %team = 1; %team <= %game.numTeams; %team++ ) + { + if ( %count[%team] < $TeamRank[%team, count] && ( %highScore $= "" || $TeamRank[%team, %count[%team]].score > %highScore ) ) + { + %highScore = $TeamRank[%team, %count[%team]].score; + %highTeam = %team; + } + } + + // Send the debrief line: + %cl = $TeamRank[%highTeam, %count[%highTeam]]; + %score = %cl.score $= "" ? 0 : %cl.score; + %kills = %cl.kills $= "" ? 0 : %cl.kills; + messageClient( %client, 'MsgDebriefAddLine', "", ' %1 %2 %3 %4', %cl.name, %game.getTeamName(%cl.team), %score, %kills ); + + %count[%highTeam]++; + %notDone = false; + for ( %team = 1; %team - 1 < %game.numTeams; %team++ ) + { + if ( %count[%team] < $TeamRank[%team, count] ) + { + %notDone = true; + break; + } + } + } + } + + //now go through an list all the observers: + %count = ClientGroup.getCount(); + %printedHeader = false; + for (%i = 0; %i < %count; %i++) + { + %cl = ClientGroup.getObject(%i); + if (%cl.team <= 0) + { + //print the header only if we actually find an observer + if (!%printedHeader) + { + %printedHeader = true; + messageClient(%client, 'MsgDebriefAddLine', "", '\nOBSERVERSSCORE'); + } + + //print out the client + %score = %cl.score $= "" ? 0 : %cl.score; + messageClient( %client, 'MsgDebriefAddLine', "", ' %1 %2', %cl.name, %score); + } + } +} + +//------------------------------------------------------------ +function DefaultGame::clearDeployableMaxes(%game) +{ + for(%i = 0; %i <= %game.numTeams; %i++) + { + $TeamDeployedCount[%i, TurretIndoorDeployable] = 0; + $TeamDeployedCount[%i, TurretOutdoorDeployable] = 0; + $TeamDeployedCount[%i, PulseSensorDeployable] = 0; + $TeamDeployedCount[%i, MotionSensorDeployable] = 0; + $TeamDeployedCount[%i, InventoryDeployable] = 0; + $TeamDeployedCount[%i, DeployedCamera] = 0; + $TeamDeployedCount[%i, MineDeployed] = 0; + $TeamDeployedCount[%i, TargetBeacon] = 0; + $TeamDeployedCount[%i, MarkerBeacon] = 0; + } +} + +// called from player scripts +function DefaultGame::onClientDamaged(%game, %clVictim, %clAttacker, %damageType, %sourceObject) +{ + //set the vars if it was a turret + if (isObject(%sourceObject)) + { + %sourceClassType = %sourceObject.getDataBlock().getClassName(); + %sourceType = %sourceObject.getDataBlock().getName(); + } + + if (%sourceClassType $= "TurretData") + { + // jff: are there special turret types which makes this needed? + // tinman: yes, we don't want bots stopping to fire on the big outdoor turrets, which they + // will just get mowed down. deployables only. + if (%sourceType $= "TurretDeployedFloorIndoor" || %sourceType $= "TurretDeployedWallIndoor" || + %sourceType $= "TurretDeployedCeilingIndoor" || %sourceType $= "TurretDeployedOutdoor") + { + %clVictim.lastDamageTurretTime = getSimTime(); + %clVictim.lastDamageTurret = %sourceObject; + } + + %turretAttacker = %sourceObject.getControllingClient(); + + //------------------------------------------------------------------- + // z0dd - ZOD, 5/29/02. Play a sound to client when they hit a player + if(%turretAttacker) + { + %client = %turretAttacker; + } + //------------------------------------------------------------------- + + // should get a damagae message from friendly fire turrets also + if(%turretAttacker && %turretAttacker != %clVictim && %turretAttacker.team == %clVictim.team) + { + if (%game.numTeams > 1 && %turretAttacker.player.causedRecentDamage != %clVictim.player) //is a teamgame & player just damaged a teammate + { + %turretAttacker.player.causedRecentDamage = %clVictim.player; + %turretAttacker.player.schedule(1000, "causedRecentDamage", ""); //allow friendly fire message every x ms + %game.friendlyFireMessage(%clVictim, %turretAttacker); + } + } + } + else if (%sourceClassType $= "PlayerData") + { + %client = %clAttacker; // z0dd - ZOD, 5/29/02. Play a sound to client when they hit a player + //now see if both were on the same team + if(%clAttacker && %clAttacker != %clVictim && %clVictim.team == %clAttacker.team) + { + if (%game.numTeams > 1 && %clAttacker.player.causedRecentDamage != %clVictim.player) //is a teamgame & player just damaged a teammate + { + %clAttacker.player.causedRecentDamage = %clVictim.player; + %clAttacker.player.schedule(1000, "causedRecentDamage", ""); //allow friendly fire message every x ms + %game.friendlyFireMessage(%clVictim, %clAttacker); + } + } + if (%clAttacker && %clAttacker != %clVictim) + { + %clVictim.lastDamageTime = getSimTime(); + %clVictim.lastDamageClient = %clAttacker; + if (%clVictim.isAIControlled()) + %clVictim.clientDetected(%clAttacker); + } + } + // ------------------------------------------------------------------ + // z0dd - ZOD, 5/29/02. Play a sound to client when they hit a player + else if( %sourceClassType $= "WheeledVehicleData" || + %sourceClassType $= "FlyingVehicleData" || + %sourceClassType $= "HoverVehicleData" ) + { + if (%sourceObject.getControllingClient()) + { + %client = %sourceObject.getControllingClient(); + } + } + + if ( %client && %client.playerHitSound && ($CurrentMissionType !$= TR2)) + { + // 1) Blaster + // 2) Plasma Gun + // 3) Chaingun + // 4) Disc + // 5) Grenades (GL and hand) + // 6) Laser + // 8) Mortar + // 9) Missile + // 10) ShockLance + + // 13) Impact (object to object) + + // 16) Plasma Turret + // 17) AA Turret + // 18) ELF Turret + // 19) Mortar Turret + // 20) Missile Turret + // 21) Indoor Deployable Turret + // 22) Outdoor Deployable Turret + // 23) Sentry Turret + + // 26) Shrike Blaster + // 27) Bobmer Plasma + // 28) Bomber Bomb + // 29) Tank Chaingun + // 30) Tank Mortar + // 31) Satchel + if (%client.team != %clVictim.team) + { + if ((%damageType > 0 && %damageType < 11) || + (%damageType == 13) || + (%damageType > 15 && %damageType < 24) || + (%damageType > 25 && %damageType < 32)) + { + messageClient(%client, 'MsgClientHit', %client.playerHitWav); + } + } + } + // ------------------------------------------------------------------ + + //call the game specific AI routines... + if (isObject(%clVictim) && %clVictim.isAIControlled()) + %game.onAIDamaged(%clVictim, %clAttacker, %damageType, %sourceObject); + if (isObject(%clAttacker) && %clAttacker.isAIControlled()) + %game.onAIFriendlyFire(%clVictim, %clAttacker, %damageType, %sourceObject); +} + +function DefaultGame::friendlyFireMessage(%game, %damaged, %damager) +{ + messageClient(%damaged, 'MsgDamagedByTeam', '\c1You were harmed by teammate %1', %damager.name); + messageClient(%damager, 'MsgDamagedTeam', '\c1You just harmed teammate %1.', %damaged.name); +} + +function DefaultGame::clearWaitRespawn(%game, %client) +{ + %client.waitRespawn = 0; +} + +// called from player scripts +function DefaultGame::onClientKilled(%game, %clVictim, %clKiller, %damageType, %implement, %damageLocation) +{ + +if ($CurrentMissionType !$= "RPG") +{ + if (%clVictim == %clKiller) //We suicided. + $Data::Suicides[%clVictim.guid]++; + + //Increment killer's kill count and victim's death count + if (%clKiller != %clVictim && isObject(%clKiller)) + { + $Data::Kills[%clKiller.guid]++; + $Data::Deaths[%clVictim.guid]++; + } +} + + %plVictim = %clVictim.player; + %plKiller = %clKiller.player; + %clVictim.plyrPointOfDeath = %plVictim.position; + %clVictim.plyrDiedHoldingFlag = %plVictim.holdingFlag; + %clVictim.waitRespawn = 1; + + cancel(%obj.reloadSchedule); // z0dd - ZOD, 9/3/02. Cancel rapid wpn fire fix scheduler + cancel( %plVictim.reCloak ); + cancel(%clVictim.respawnTimer); + %clVictim.respawnTimer = %game.schedule(($Host::PlayerRespawnTimeout * 1000), "forceObserver", %clVictim, "spawnTimeout" ); + + // reset the alarm for out of bounds + if(%clVictim.outOfBounds) + messageClient(%clVictim, 'EnterMissionArea', ""); + + if (%damageType == $DamageType::suicide) + %respawnDelay = 2; // z0dd - ZOD, 4/24/02. Was 10 + else + %respawnDelay = 2; + + %game.schedule(%respawnDelay*1000, "clearWaitRespawn", %clVictim); + // if victim had an undetonated satchel charge pack, get rid of it + if(%plVictim.thrownChargeId != 0) + if(!%plVictim.thrownChargeId.kaboom) + %plVictim.thrownChargeId.delete(); + + if(%plVictim.lastVehicle !$= "") + { + schedule(15000, %plVictim.lastVehicle,"vehicleAbandonTimeOut", %plVictim.lastVehicle); + %plVictim.lastVehicle.lastPilot = ""; + } + + // unmount pilot or remove sight from bomber + if(%plVictim.isMounted()) + { + if(%plVictim.vehicleTurret) + %plVictim.vehicleTurret.getDataBlock().playerDismount(%plVictim.vehicleTurret); + else + { + %plVictim.getDataBlock().doDismount(%plVictim, true); + %plVictim.mountVehicle = false; + } + } + + if(%plVictim.inStation) + commandToClient(%plVictim.client,'setStationKeys', false); + %clVictim.camera.mode = "playerDeath"; + + // reset who triggered this station and cancel outstanding armor switch thread + if(%plVictim.station) + { + %plVictim.station.triggeredBy = ""; + %plVictim.station.getDataBlock().stationTriggered(%plVictim.station,0); + if(%plVictim.armorSwitchSchedule) + cancel(%plVictim.armorSwitchSchedule); + } + + //Close huds if player dies... + messageClient(%clVictim, 'CloseHud', "", 'inventoryScreen'); + messageClient(%clVictim, 'CloseHud', "", 'vehicleHud'); + commandToClient(%clVictim, 'setHudMode', 'Standard', "", 0); + + // $weaponslot from item.cs + %plVictim.setRepairRate(0); + %plVictim.setImageTrigger($WeaponSlot, false); + + playDeathAnimation(%plVictim, %damageLocation, %damageType); + playDeathCry(%plVictim); + + %victimName = %clVictim.name; + + %game.displayDeathMessages(%clVictim, %clKiller, %damageType, %implement); + %game.updateKillScores(%clVictim, %clKiller, %damageType, %implement); + + // toss whatever is being carried, '$flagslot' from item.cs + // MES - had to move this to after death message display because of Rabbit game type + for(%index = 0 ; %index < 8; %index++) + { + %image = %plVictim.getMountedImage(%index); + if(%image) + { + if(%index == $FlagSlot) + %plVictim.throwObject(%plVictim.holdingFlag); + else + %plVictim.throw(%image.item); + } + } + + // target manager update + setTargetDataBlock(%clVictim.target, 0); + setTargetSensorData(%clVictim.target, 0); + + // clear the hud + %clVictim.SetWeaponsHudClearAll(); + %clVictim.SetInventoryHudClearAll(); + %clVictim.setAmmoHudCount(-1); + + // clear out weapons, inventory and pack huds + messageClient(%clVictim, 'msgDeploySensorOff', ""); //make sure the deploy hud gets shut off + messageClient(%clVictim, 'msgPackIconOff', ""); // clear the pack icon + + //clear the deployable HUD + %plVictim.client.deployPack = false; + cancel(%plVictim.deployCheckThread); + deactivateDeploySensor(%plVictim); + + //if the killer was an AI... + if (isObject(%clKiller) && %clKiller.isAIControlled()) + %game.onAIKilledClient(%clVictim, %clKiller, %damageType, %implement); + + + // reset control object on this player: also sets 'playgui' as content + serverCmdResetControlObject(%clVictim); + + // set control object to the camera + %clVictim.player = 0; + %transform = %plVictim.getTransform(); + + //note, AI's don't have a camera... + if (isObject(%clVictim.camera)) + { + %clVictim.camera.setTransform(%transform); + %clVictim.camera.setOrbitMode(%plVictim, %plVictim.getTransform(), 0.5, 4.5, 4.5); + %clVictim.setControlObject(%clVictim.camera); + } + + //hook in the AI specific code for when a client dies + if (%clVictim.isAIControlled()) + { + aiReleaseHumanControl(%clVictim.controlByHuman, %clVictim); + %game.onAIKilled(%clVictim, %clKiller, %damageType, %implement); + } + else + aiReleaseHumanControl(%clVictim, %clVictim.controlAI); + + //used to track corpses so the AI can get ammo, etc... + AICorpseAdded(%plVictim); + + //if the death was a suicide, prevent respawning for 5 seconds... + %clVictim.lastDeathSuicide = false; + if (%damageType == $DamageType::Suicide) + { + %clVictim.lastDeathSuicide = true; + %clVictim.suicideRespawnTime = getSimTime() + 1000; // z0dd - ZOD, 4/24/02. Was 5000 + } +} + +function DefaultGame::forceObserver( %game, %client, %reason ) +{ + //make sure we have a valid client... + if (%client <= 0) + return; + + // first kill this player + if(%client.player) + %client.player.scriptKill(0); + + if( %client.respawnTimer ) + cancel(%client.respawnTimer); + + %client.respawnTimer = ""; + + // remove them from the team rank array + %game.removeFromTeamRankArray(%client); + + // place them in observer mode + %client.lastObserverSpawn = -1; + %client.observerStartTime = getSimTime(); + %adminForce = 0; + + switch$ ( %reason ) + { + case "playerChoose": + %client.camera.getDataBlock().setMode( %client.camera, "observerFly" ); + messageClient(%client, 'MsgClientJoinTeam', '\c2You have become an observer.', %client.name, %game.getTeamName(0), %client, 0 ); + logEcho(%client.nameBase@" (cl "@%client@") entered observer mode"); + %client.lastTeam = %client.team; + + case "AdminForce": + %client.camera.getDataBlock().setMode( %client.camera, "observerFly" ); + messageClient(%client, 'MsgClientJoinTeam', '\c2You have been forced into observer mode by the admin.', %client.name, %game.getTeamName(0), %client, 0 ); + logEcho(%client.nameBase@" (cl "@%client@") was forced into observer mode by admin"); + %client.lastTeam = %client.team; + %adminForce = 1; + + if($Host::TournamentMode) + { + if(!$matchStarted) + { + if(%client.camera.Mode $= "pickingTeam") + { + commandToClient( %client, 'processPickTeam'); + clearBottomPrint( %client ); + } + else + { + clearCenterPrint(%client); + %client.notReady = true; + } + } + } + + case "spawnTimeout": + // DDDX: Fix for AI's derping this up + if (!IsObject(%client)) + return; + %client.camera.getDataBlock().setMode( %client.camera, "observerTimeout" ); + messageClient(%client, 'MsgClientJoinTeam', '\c2You have been placed in observer mode due to delay in respawning.', %client.name, %game.getTeamName(0), %client, 0 ); + logEcho(%client.nameBase@" (cl "@%client@") was placed in observer mode due to spawn delay"); + // save the team the player was on - only if this was a delay in respawning + %client.lastTeam = %client.team; + } + + // switch client to team 0 (observer) + %client.team = 0; + %client.player.team = 0; + setTargetSensorGroup( %client.target, %client.team ); + %client.setSensorGroup( %client.team ); + + // set their control to the obs. cam + %client.setControlObject( %client.camera ); + commandToClient(%client, 'setHudMode', 'Observer'); + + // display the hud + //displayObserverHud(%client, 0); + updateObserverFlyHud(%client); + + + // message everyone about this event + if( !%adminForce ) + messageAllExcept(%client, -1, 'MsgClientJoinTeam', '\c2%1 has become an observer.', %client.name, %game.getTeamName(0), %client, 0 ); + else + messageAllExcept(%client, -1, 'MsgClientJoinTeam', '\c2The admin has forced %1 to become an observer.', %client.name, %game.getTeamName(0), %client, 0 ); + + updateCanListenState( %client ); + + // call the onEvent for this game type + %game.onClientEnterObserverMode(%client); //Bounty uses this to remove this client from others' hit lists +} + +function DefaultGame::displayDeathMessages(%game, %clVictim, %clKiller, %damageType, %implement) +{ + // ---------------------------------------------------------------------------------- + // z0dd - ZOD, 6/18/02. From Panama Jack, send the damageTypeText as the last varible + // in each death message so client knows what weapon it was that killed them. + + // Handle Draakan genders + %victimSex = %clVictim.sex; + if (%victimSex $= "A" || %victimSex $= "B" || %victimSex $= "C") + %victimSex = "Male"; + %victimGender = (%victimSex $= "Male" ? 'him' : 'her'); + %victimPoss = (%victimSex $= "Male" ? 'his' : 'her'); + + %killerGender = (%clKiller.sex $= "Male" ? 'him' : 'her'); + %killerPoss = (%clKiller.sex $= "Male" ? 'his' : 'her'); + %victimGenderPoss = (%clVictim.sex $= "Male" ? 'he' : 'she'); + %killerGenderPoss = (%clKiller.sex $= "Male" ? 'he' : 'she'); + %victimName = %clVictim.name; + %killerName = %clKiller.name; + + //error("DamageType = " @ %damageType @ ", implement = " @ %implement @ ", implement class = " @ %implement.getClassName() @ ", is controlled = " @ %implement.getControllingClient()); + + if(%damageType == $DamageType::Explosion) + { + messageAll('msgExplosionKill', $DeathMessageExplosion[mFloor(getRandom() * $DeathMessageExplosionCount)], %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); + logEcho(%clVictim.nameBase@" (pl "@%clVictim.player@"/cl "@%clVictim@") killed by a nearby explosion."); + } + else if(%damageType == $DamageType::Suicide) //player presses cntrl-k + { + messageAll('msgSuicide', $DeathMessageSuicide[mFloor(getRandom() * $DeathMessageSuicideCount)], %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); + logEcho(%clVictim.nameBase@" (pl "@%clVictim.player@"/cl "@%clVictim@") committed suicide (CTRL-K)"); + } + else if(%damageType == $DamageType::VehicleSpawn) + { + messageAll('msgVehicleSpawnKill', $DeathMessageVehPad[mFloor(getRandom() * $DeathMessageVehPadCount)], %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); + logEcho(%clVictim.nameBase@" (pl "@%clVictim.player@"/cl "@%clVictim@") killed by vehicle spawn"); + } + else if(%damageType == $DamageType::ForceFieldPowerup) + { + messageAll('msgVehicleSpawnKill', $DeathMessageFFPowerup[mFloor(getRandom() * $DeathMessageFFPowerupCount)], %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); + logEcho(%clVictim.nameBase@" (pl "@%clVictim.player@"/cl "@%clVictim@") killed by Force Field Powerup"); + } + else if(%damageType == $DamageType::Crash) + { + messageAll('msgVehicleCrash', $DeathMessageVehicleCrash[%damageType, mFloor(getRandom() * $DeathMessageVehicleCrashCount)], %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); + logEcho(%clVictim.nameBase@" (pl "@%clVictim.player@"/cl "@%clVictim@") crashes a vehicle."); + } + else if(%damageType == $DamageType::Impact) // run down by vehicle + { + if( ( %controller = %implement.getControllingClient() ) > 0) + { + %killerGender = (%controller.sex $= "Male" ? 'him' : 'her'); + %killerPoss = (%controller.sex $= "Male" ? 'his' : 'her'); + %killerName = %controller.name; + messageAll('msgVehicleKill', $DeathMessageVehicle[mFloor(getRandom() * $DeathMessageVehicleCount)], %victimName, %victimGender, %victimPoss, %killerName ,%killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); + logEcho(%clVictim.nameBase@" (pl "@%clVictim.player@"/cl "@%clVictim@") killed by a vehicle controlled by "@%controller); + } + else + { + messageAll('msgVehicleKill', $DeathMessageVehicleUnmanned[mFloor(getRandom() * $DeathMessageVehicleUnmannedCount)], %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); + logEcho(%clVictim.nameBase@" (pl "@%clVictim.player@"/cl "@%clVictim@") killed by a vehicle (unmanned)"); + } + } + // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + // z0dd - ZOD, 5/15/02. Added Hover Vehicle so we get proper + // death messages when killed with Wildcat chaingun + //else if (isObject(%implement) && (%implement.getClassName() $= "Turret" || %implement.getClassName() $= "VehicleTurret" || %implement.getClassName() $= "FlyingVehicle")) //player killed by a turret + else if (isObject(%implement) && (%implement.getClassName() $= "Turret" || %implement.getClassName() $= "VehicleTurret" || %implement.getClassName() $= "FlyingVehicle" || %implement.getClassName() $= "HoverVehicle")) + { + if (%implement.getControllingClient() != 0) //is turret being controlled? + { + %controller = %implement.getControllingClient(); + %killerGender = (%controller.sex $= "Male" ? 'him' : 'her'); + %killerPoss = (%controller.sex $= "Male" ? 'his' : 'her'); + %killerName = %controller.name; + + if (%controller == %clVictim) + messageAll('msgTurretSelfKill', $DeathMessageTurretSelfKill[mFloor(getRandom() * $DeathMessageTurretSelfKillCount)],%victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); + else if (%controller.team == %clVictim.team) //controller TK'd a friendly + messageAll('msgCTurretKill', $DeathMessageCTurretTeamKill[%damageType, mFloor(getRandom() * $DeathMessageCTurretTeamKillCount)],%victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); + else //controller killed an enemy + messageAll('msgCTurretKill', $DeathMessageCTurretKill[%damageType, mFloor(getRandom() * $DeathMessageCTurretKillCount)],%victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); + logEcho(%clVictim.nameBase@" (pl "@%clVictim.player@"/cl "@%clVictim@") killed by a turret controlled by "@%controller); + } + // use the handle associated with the deployed object to verify valid owner + else if (isObject(%implement.owner)) + { + %owner = %implement.owner; + //error("Owner is " @ %owner @ " Handle is " @ %implement.ownerHandle); + //error("Turret is still owned"); + //turret is uncontrolled, but is owned - treat the same as controlled. + %killerGender = (%owner.sex $= "Male" ? 'him' : 'her'); + %killerPoss = (%owner.sex $= "Male" ? 'his' : 'her'); + %killerName = %owner.name; + + if (%owner.team == %clVictim.team) //player got in the way of a teammates deployed but uncontrolled turret. + messageAll('msgCTurretKill', $DeathMessageCTurretAccdtlKill[%damageType,mFloor(getRandom() * $DeathMessageCTurretAccdtlKillCount)],%victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); + else //deployed, uncontrolled turret killed an enemy + messageAll('msgCTurretKill', $DeathMessageCTurretKill[%damageType,mFloor(getRandom() * $DeathMessageCTurretKillCount)],%victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); + logEcho(%clVictim.nameBase@" (pl "@%clVictim.player@"/cl "@%clVictim@") was killed by turret (automated)"); + } + else //turret is not a placed (owned) turret (or owner is no longer on it's team), and is not being controlled + { + messageAll('msgTurretKill', $DeathMessageTurretKill[%damageType,mFloor(getRandom() * $DeathMessageTurretKillCount)],%victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); + logEcho(%clVictim.nameBase@" (pl "@%clVictim.player@"/cl "@%clVictim@") killed by turret"); + } + } + else if((%clKiller == %clVictim) || (%damageType == $DamageType::Ground)) //player killed himself or fell to death + { + messageAll('msgSelfKill', $DeathMessageSelfKill[%damageType,mFloor(getRandom() * $DeathMessageSelfKillCount)], %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); + logEcho(%clVictim.nameBase @ "(pl " @ %clVictim.player @ "/cl " @ %clVictim @ ") killed self (" @ getTaggedString($DamageTypeText[%damageType]) @ ")"); + } + + else if (%damageType == $DamageType::OutOfBounds) //killer died due to Out-of-Bounds damage + { + messageAll('msgOOBKill', $DeathMessageOOB[mFloor(getRandom() * $DeathMessageOOBCount)], %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); + logEcho(%clVictim.nameBase@" (pl "@%clVictim.player@"/cl "@%clVictim@") killed by out-of-bounds damage"); + } + + else if (%damageType == $DamageType::NexusCamping) //Victim died from camping near the nexus... + { + messageAll('msgCampKill', $DeathMessageCamping[mFloor(getRandom() * $DeathMessageCampingCount)], %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); + logEcho(%clVictim.nameBase@" (pl "@%clVictim.player@"/cl "@%clVictim@") killed for nexus camping"); + } + + else if(%clKiller.team == %clVictim.team) //was a TK + { + messageAll('msgTeamKill', $DeathMessageTeamKill[%damageType, mFloor(getRandom() * $DeathMessageTeamKillCount)], %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); + logEcho(%clVictim.nameBase@" (pl "@%clVictim.player@"/cl "@%clVictim@") teamkilled by "@%clKiller.nameBase@" (pl "@%clKiller.player@"/cl "@%clKiller@")"); + } + + else if (%damageType == $DamageType::Lava) //player died by falling in lava + { + messageAll('msgLavaKill', $DeathMessageLava[mFloor(getRandom() * $DeathMessageLavaCount)], %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); + logEcho(%clVictim.nameBase@" (pl "@%clVictim.player@"/cl "@%clVictim@") killed by lava"); + } + else if ( %damageType == $DamageType::Lightning ) // player was struck by lightning + { + messageAll('msgLightningKill', $DeathMessageLightning[mFloor(getRandom() * $DeathMessageLightningCount)], %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); + logEcho(%clVictim.nameBase@" (pl "@%clVictim.player@"/cl "@%clVictim@") killed by lightning"); + } + else if ( %damageType == $DamageType::Mine && !isObject(%clKiller) ) + { + error("Mine kill w/o source"); + messageAll('MsgRogueMineKill', $DeathMessageRogueMine[%damageType, mFloor(getRandom() * $DeathMessageRogueMineCount)], %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); + } + else //was a legitimate enemy kill + { + if(%damageType == 6 && (%clVictim.headShot)) + { + // laser headshot just occurred + messageAll('MsgHeadshotKill', $DeathMessageHeadshot[%damageType, mFloor(getRandom() * $DeathMessageHeadshotCount)], %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); + } + // ---------------------------------------------------- + // z0dd - ZOD, 8/25/02. Rear Lance hits + else if (%damageType == 10 && (%clVictim.rearshot)) + { + // shocklance rearshot just occurred + messageAll('MsgRearshotKill', $DeathMessageRearshot[%damageType, mFloor(getRandom() * $DeathMessageRearshotCount)], %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); + } + // ---------------------------------------------------- + else + messageAll('MsgLegitKill', $DeathMessage[%damageType, mFloor(getRandom() * $DeathMessageCount)], %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType, $DamageTypeText[%damageType], %victimGenderPoss, %killerGenderPoss); + logEcho(%clVictim.nameBase @ " (pl " @ %clVictim.player @ "/cl " @ %clVictim @ ") killed by " @ %clKiller.nameBase @ " (pl " @ %clKiller.player @ "/cl " @%clKiller @ ") using " @ getTaggedString($DamageTypeText[%damageType])); + } +} + +function DefaultGame::assignClientTeam(%game, %client, %respawn ) +{ +//error("DefaultGame::assignClientTeam"); + // this function is overwritten in non-team mission types (e.g. DM) + // so these lines won't do anything + //if(!%game.numTeams) + //{ + // setTargetSkin(%client.target, %client.skin); + // return; + //} + + // camera is responsible for creating a player + // - counts the number of players per team + // - puts this player on the least player count team + // - sets the client's skin to the servers default + + %numPlayers = ClientGroup.getCount(); + for(%i = 0; %i <= %game.numTeams; %i++) + %numTeamPlayers[%i] = 0; + + for(%i = 0; %i < %numPlayers; %i = %i + 1) + { + %cl = ClientGroup.getObject(%i); + if(%cl != %client) + %numTeamPlayers[%cl.team]++; + } + %leastPlayers = %numTeamPlayers[1]; + %leastTeam = 1; + for(%i = 2; %i <= %game.numTeams; %i++) + { + if( (%numTeamPlayers[%i] < %leastPlayers) || + ( (%numTeamPlayers[%i] == %leastPlayers) && + ($teamScore[%i] < $teamScore[%leastTeam] ) )) + { + %leastTeam = %i; + %leastPlayers = %numTeamPlayers[%i]; + } + } + + %client.team = %leastTeam; + %client.lastTeam = %team; + + // Assign the team skin: + if ( %client.isAIControlled() ) + { + if ( %leastTeam & 1 ) + { + %client.skin = addTaggedString( "basebot" ); + setTargetSkin( %client.target, 'basebot' ); + } + else + { + %client.skin = addTaggedString( "basebbot" ); + setTargetSkin( %client.target, 'basebbot' ); + } + } + else + setTargetSkin( %client.target, %game.getTeamSkin(%client.team) ); + //setTargetSkin( %client.target, %client.skin ); + + // might as well standardize the messages + //messageAllExcept( %client, -1, 'MsgClientJoinTeam', '\c1%1 joined %2.', %client.name, $teamName[%leastTeam], %client, %leastTeam ); + //messageClient( %client, 'MsgClientJoinTeam', '\c1You joined the %2 team.', $client.name, $teamName[%client.team], %client, %client.team ); + messageAllExcept( %client, -1, 'MsgClientJoinTeam', '\c1%1 joined %2.', %client.name, %game.getTeamName(%client.team), %client, %client.team ); + messageClient( %client, 'MsgClientJoinTeam', '\c1You joined the %2 team.', %client.name, %game.getTeamName(%client.team), %client, %client.team ); + + updateCanListenState( %client ); + + logEcho(%client.nameBase@" (cl "@%client@") joined team "@%client.team); +} + +function DefaultGame::getTeamSkin(%game, %team) +{ + //error("DefaultGame::getTeamSkin"); + %skin = $teamSkin[%team]; + //error("%skin = " SPC getTaggedString(%skin)); + return %skin; +} + +function DefaultGame::getTeamName(%game, %team) +{ + //error("DefaultGame::getTeamName"); + %name = $teamName[%team]; + //error("name = " SPC getTaggedString(%name)); + return %name; +} + +function DefaultGame::clientJoinTeam( %game, %client, %team, %respawn ) +{ +//error("DefaultGame::clientJoinTeam"); + if ( %team < 1 || %team > %game.numTeams ) + return; + + if( %respawn $= "" ) + %respawn = 1; + + %client.team = %team; + %client.lastTeam = %team; + setTargetSkin( %client.target, %game.getTeamSkin(%team) ); + setTargetSensorGroup( %client.target, %team ); + %client.setSensorGroup( %team ); + + // Spawn the player: + %game.spawnPlayer( %client, %respawn ); + + messageAllExcept( %client, -1, 'MsgClientJoinTeam', '\c1%1 joined %2.', %client.name, %game.getTeamName(%team), %client, %team ); + messageClient( %client, 'MsgClientJoinTeam', '\c1You joined the %2 team.', $client.name, %game.getTeamName(%client.team), %client, %client.team ); + + updateCanListenState( %client ); + + logEcho(%client.nameBase@" (cl "@%client@") joined team "@%client.team); +} + +function DefaultGame::AIHasJoined(%game, %client) +{ + //defined to prevent console spam +} + +function DefaultGame::AIChangeTeam(%game, %client, %newTeam) +{ + //make sure we're trying to drop an AI + if (!isObject(%client) || !%client.isAIControlled()) + return; + + //clear the ai from any objectives, etc... + AIUnassignClient(%client); + %client.stop(); + %client.clearTasks(); + %client.clearStep(); + %client.lastDamageClient = -1; + %client.lastDamageTurret = -1; + %client.shouldEngage = -1; + %client.setEngageTarget(-1); + %client.setTargetObject(-1); + %client.pilotVehicle = false; + %client.defaultTasksAdded = false; + + //kill the player, which should cause the Game object to perform whatever cleanup is required. + if (isObject(%client.player)) + %client.player.scriptKill(0); + + //clean up the team rank array + %game.removeFromTeamRankArray(%client); + + //assign the new team + %client.team = %newTeam; + if (%newTeam < 0) + Game.assignClientTeam(%client); + else + { + if ( %client.team & 1 ) + { + %client.skin = addTaggedString( "basebot" ); + setTargetSkin( %client.target, 'basebot' ); + } + else + { + %client.skin = addTaggedString( "basebbot" ); + setTargetSkin( %client.target, 'basebbot' ); + } + } + + messageAllExcept( %client, -1, 'MsgClientJoinTeam', '\c1bot %1 has switched to team %2.', %client.name, %game.getTeamName(%client.team), %client, %client.team ); +} + +function DefaultGame::clientChangeTeam(%game, %client, %team, %fromObs, %respawned) // z0dd - ZOD, 6/06/02. Don't send a message if player used respawn feature. Added %respawned +{ +//error("DefaultGame::clientChangeTeam"); + //first, remove the client from the team rank array + //the player will be added to the new team array as soon as he respawns... + %game.removeFromTeamRankArray(%client); + + %pl = %client.player; + if(isObject(%pl)) + { + if(%pl.isMounted()) + %pl.getDataBlock().doDismount(%pl); + %pl.scriptKill(0); + } + + // reset the client's targets and tasks only + clientResetTargets(%client, true); + + // give this client a new handle to disassociate ownership of deployed objects + if( %team $= "" && (%team > 0 && %team <= %game.numTeams)) + { + if( %client.team == 1 ) + %client.team = 2; + else + %client.team = 1; + } + else + %client.team = %team; + + // Set the client's skin: + if (!%client.isAIControlled()) + setTargetSkin( %client.target, %game.getTeamSkin(%client.team) ); + setTargetSensorGroup( %client.target, %client.team ); + %client.setSensorGroup( %client.team ); + + // Spawn the player: + %client.lastSpawnPoint = %game.pickPlayerSpawn( %client ); + + %game.createPlayer( %client, %client.lastSpawnPoint, $MatchStarted ); + + if($MatchStarted) + %client.setControlObject(%client.player); + else + { + %client.camera.getDataBlock().setMode(%client.camera, "pre-game", %client.player); + %client.setControlObject(%client.camera); + } + + // call the onEvent for this game type + %game.onClientEnterObserverMode(%client); //Bounty uses this to remove this client from others' hit lists + + if(%fromObs $= "" || !%fromObs) + { + //------------------------------------------------------------------------- + // z0dd - ZOD, 6/06/02. Don't send a message if player used respawn feature + if(!%respawned) + { + messageAllExcept( %client, -1, 'MsgClientJoinTeam', '\c1%1 switched to team %2.', %client.name, %game.getTeamName(%client.team), %client, %client.team ); + messageClient( %client, 'MsgClientJoinTeam', '\c1You switched to team %2.', $client.name, %game.getTeamName(%client.team), %client, %client.team ); + } + //------------------------------------------------------------------------- + } + else + { + messageAllExcept( %client, -1, 'MsgClientJoinTeam', '\c1%1 joined team %2.', %client.name, %game.getTeamName(%client.team), %client, %team ); + messageClient( %client, 'MsgClientJoinTeam', '\c1You joined team %2.', $client.name, %game.getTeamName(%client.team), %client, %client.team ); + } + + updateCanListenState( %client ); + + // MES - switch objective hud lines when client switches teams + messageClient(%client, 'MsgCheckTeamLines', "", %client.team); + logEcho(%client.nameBase@" (cl "@%client@") switched to team "@%client.team); +} + +// missioncleanup and missiongroup are checked prior to entering game code +function DefaultGame::missionLoadDone(%game) +{ + // walks through the mission group and sets the power stuff up + // - groups get initialized with power count 0 then iterated to + // increment powercount if an object within is powered + // - powers objects up/down + //MissionGroup.objectiveInit(); + MissionGroup.clearPower(); + MissionGroup.powerInit(0); + + %game.initGameVars(); //set up scoring variables and other game specific globals + + // make team0 visible/friendly to all + setSensorGroupAlwaysVisMask(0, 0xffffffff); + setSensorGroupFriendlyMask(0, 0xffffffff); + + // update colors: + // - enemy teams are red + // - same team is green + // - team 0 is white + for(%i = 0; %i < 32; %i++) + { + %team = (1 << %i); + setSensorGroupColor(%i, %team, "0 255 0 255"); + setSensorGroupColor(%i, ~%team, "255 0 0 255"); + setSensorGroupColor(%i, 1, "255 255 255 255"); + + // setup the team targets (alwyas friendly and visible to same team) + setTargetAlwaysVisMask(%i, %team); + setTargetFriendlyMask(%i, %team); + } + + //set up the teams + %game.setUpTeams(); + + //clear out the team rank array... + for (%i = 0; %i < 32; %i++) + $TeamRank[%i, count] = ""; + + // objectiveInit has to take place after setupTeams -- objective HUD relies on flags + // having their team set + MissionGroup.objectiveInit(); + + //initialize the AI system + %game.aiInit(); + + //need to reset the teams if we switch from say, CTF to Bounty... + // assign the bots team + if ($currentMissionType !$= $previousMissionType) + { + $previousMissionType = $currentMissionType; + for(%i = 0; %i < ClientGroup.getCount(); %i++) + { + %cl = ClientGroup.getObject(%i); + if (%cl.isAIControlled()) + %game.assignClientTeam(%cl); + } + } + + //Save off respawn or Siege Team switch information... + if(%game.class !$= "SiegeGame") + MissionGroup.setupPositionMarkers(true); + echo("Default game mission load done."); +} + +function DefaultGame::onClientLeaveGame(%game, %client) +{ + // if there is a player attached to this client, kill it + if( isObject(%client.player)) + %client.player.scriptKill(0); + + //cancel a scheduled call... + cancel(%client.respawnTimer); + %client.respawnTimer = ""; + + //remove them from the team rank arrays + %game.removeFromTeamRankArray(%client); + logEcho(%client.nameBase@" (cl "@%client@") dropped"); +} + +function DefaultGame::clientMissionDropReady(%game, %client) +{ + //synchronize the clock HUD + messageClient(%client, 'MsgSystemClock', "", 0, 0); + + + %game.sendClientTeamList( %client ); + %game.setupClientHuds( %client ); + + if($CurrentMissionType $= "SinglePlayer") + { + //CommandToClient( %client, 'setPlayContent'); + return; + } + + %observer = false; + if( !$Host::TournamentMode ) + { + if( %client.camera.mode $= "observerFly" || %client.camera.mode $= "justJoined") + { + %observer = true; + %client.observerStartTime = getSimTime(); + commandToClient(%client, 'setHudMode', 'Observer'); + %client.setControlObject( %client.camera ); + //displayObserverHud( %client, 0 ); + updateObserverFlyHud(%client); + } + + if( !%observer ) + { + if(!$MatchStarted && !$CountdownStarted) // server has not started anything yet + { + %client.setControlObject( %client.camera ); + commandToClient(%client, 'setHudMode', 'Observer'); + } + else if(!$MatchStarted && $CountdownStarted) // server has started the countdown + { + commandToClient(%client, 'setHudMode', 'Observer'); + %client.setControlObject( %client.camera ); + } + else + { + commandToClient(%client, 'setHudMode', 'Standard'); // the game has already started + %client.setControlObject( %client.player ); + } + } + } + else + { + // set all players into obs mode. setting the control object will handle further procedures... + %client.camera.getDataBlock().setMode( %client.camera, "ObserverFly" ); + commandToClient(%client, 'setHudMode', 'Observer'); + %client.setControlObject( %client.camera ); + messageAll( 'MsgClientJoinTeam', "",%client.name, $teamName[0], %client, 0 ); + %client.team = 0; + + if( !$MatchStarted && !$CountdownStarted) + { + if($TeamDamage) + %damMess = "ENABLED"; + else + %damMess = "DISABLED"; + + if(%game.numTeams > 1) + BottomPrint(%client, "Server is Running in Tournament Mode.\nPick a Team\nTeam Damage is " @ %damMess, 0, 3 ); + } + else + { + BottomPrint( %client, "\nServer is Running in Tournament Mode", 0, 3 ); + } + } + + //make sure the objective HUD indicates your team on top and in green... + if (%client.team > 0) + messageClient(%client, 'MsgCheckTeamLines', "", %client.team); + + // were ready to go. + %client.matchStartReady = true; + echo("Client" SPC %client SPC "is ready."); + + if (!%client.isValid && !$RequiresClient[$CurrentMissionType]) //Ok, if we're joined and the client doesn't have the mod, tell em + commandToClient(%client,'CenterPrint',"You do not have the T2Bol client installed. For a better experience, please download the client from: www.blah.com",2,0); + + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here +} + +function DefaultGame::sendClientTeamList(%game, %client) +{ + // Send the client the current team list: + %teamCount = %game.numTeams; + for ( %i = 0; %i < %teamCount; %i++ ) + { + if ( %i > 0 ) + %teamList = %teamList @ "\n"; + + %teamList = %teamList @ detag( getTaggedString( %game.getTeamName(%i + 1) ) ); + } + messageClient( %client, 'MsgTeamList', "", %teamCount, %teamList ); +} + +function DefaultGame::setupClientHuds(%game, %client) +{ + // tell the client to setup the huds... + for(%i =0; %i<$WeaponsHudCount; %i++) + %client.setWeaponsHudBitmap(%i, $WeaponsHudData[%i, itemDataName], $WeaponsHudData[%i, bitmapName]); + for(%i =0; %i<$InventoryHudCount; %i++) + { + if ( $InventoryHudData[%i, slot] != 0 ) + %client.setInventoryHudBitmap($InventoryHudData[%i, slot], $InventoryHudData[%i, itemDataName], $InventoryHudData[%i, bitmapName]); + } + %client.setInventoryHudBitmap( 0, "", "gui/hud_handgren" ); + + %client.setWeaponsHudBackGroundBmp("gui/hud_new_panel"); + %client.setWeaponsHudHighLightBmp("gui/hud_new_weaponselect"); + %client.setWeaponsHudInfiniteAmmoBmp("gui/hud_infinity"); + %client.setInventoryHudBackGroundBmp("gui/hud_new_panel"); + + // tell the client if we are protecting statics (so no health bar will be displayed) + commandToClient(%client, 'protectingStaticObjects', %game.allowsProtectedStatics()); + commandToClient(%client, 'setPowerAudioProfiles', sPowerUp.getId(), sPowerDown.getId()); +} + +function DefaultGame::testDrop( %game, %client ) +{ + %game.clientJoinTeam( %client, 1, false ); + %client.camera.getDataBlock().setMode( %client.camera, "pre-game", %client.player ); + %client.setControlObject( %client.camera ); + CommandToClient( %client, 'setPlayContent' ); +} + +function DefaultGame::onClientEnterObserverMode( %game, %client ) +{ + // Default game doesn't care... +} + +// from 'item.cs' +function DefaultGame::playerTouchFlag(%game, %player, %flag) +{ + messageAll('MsgPlayerTouchFlag', 'Player %1 touched flag %2', %player, %flag); +} + +// from 'item.cs' +function DefaultGame::playerDroppedFlag(%game, %player, %flag) +{ + messageAll('MsgPlayerDroppedFlag', 'Player %1 dropped flag %2', %player, %flag); +} + +// from 'staticShape.cs' +function DefaultGame::flagStandCollision(%game, %dataBlock, %obj, %colObj) +{ + // for retreiveGame +} + +function DefaultGame::notifyMineDeployed(%game, %mine) +{ + //do nothign in the default game... +} + +// from 'staticshape.cs' +function DefaultGame::findProjector(%game, %flipflop) +{ + // search the flipflop's folder for a holo projector + // if one exists, associate it with the flipflop + %flipflop.projector = 0; + %folder = %flipflop.getGroup(); + for(%i = 0; %i < %folder.getCount(); %i++) + { + %proj = %folder.getObject(%i); + if(%proj.getDatablock().getName() $= "LogoProjector") + { + %flipflop.projector = %proj; + %flipflop.projector.holo = 0; + break; + } + } +} + +//****************************************************************************** +//* DefaultGame Trigger - Functions * +//****************************************************************************** + +/// -Trigger- ////////////////////////////////////////////////////////////////// +//Function -- onEnterTrigger (%game, %name, %data, %obj, %colObj) +// %game = Current game type object +// %name = Trigger name - defined when trigger is created +// %data = Trigger Data Block +// %obj = Trigger Object +// %colObj = Object that collided with the trigger +//Decription -- Called when trigger has been triggered +//////////////////////////////////////////////////////////////////////////////// +// from 'trigger.cs' +function DefaultGame::onEnterTrigger(%game, %triggerName, %data, %obj, %colobj) +{ + //Do Nothing +} + +/// -Trigger- ////////////////////////////////////////////////////////////////// +//Function -- onLeaveTrigger (%game, %name, %data, %obj, %colObj) +// %game = Current game type object +// %name = Trigger name - defined when trigger is created +// %data = Trigger Data Block +// %obj = Trigger Object +// %colObj = Object that collided with the trigger +//Decription -- Called when trigger has been untriggered +//////////////////////////////////////////////////////////////////////////////// +// from 'trigger.cs' +function DefaultGame::onLeaveTrigger(%game, %triggerName, %data, %obj, %colobj) +{ + //Do Nothing +} + +/// -Trigger- ////////////////////////////////////////////////////////////////// +//Function -- onTickTrigger(%game, %name, %data, %obj) +// %game = Current game type object +// %name = Trigger name - defined when trigger is created +// %data = Trigger Data Block +// %obj = Trigger Object +//Decription -- Called every tick if triggered +//////////////////////////////////////////////////////////////////////////////// +// from 'trigger.cs' +function DefaultGame::onTickTrigger(%game, %triggerName, %data, %obj) +{ + //Do Nothing +} + + +function DefaultGame::setUpTeams(%game) +{ + %group = nameToID("MissionGroup/Teams"); + if(%group == -1) + return; + + // create a team0 if it does not exist + %team = nameToID("MissionGroup/Teams/team0"); + if(%team == -1) + { + %team = new SimGroup("team0"); + %group.add(%team); + } + + // 'team0' is not counted as a team here + %game.numTeams = 0; + while(%team != -1) + { + // create drop set and add all spawnsphere objects into it + %dropSet = new SimSet("TeamDrops" @ %game.numTeams); + MissionCleanup.add(%dropSet); + + %spawns = nameToID("MissionGroup/Teams/team" @ %game.numTeams @ "/SpawnSpheres"); + if(%spawns != -1) + { + %count = %spawns.getCount(); + for(%i = 0; %i < %count; %i++) + %dropSet.add(%spawns.getObject(%i)); + } + + // set the 'team' field for all the objects in this team + %team.setTeam(%game.numTeams); + + clearVehicleCount(%team+1); + // get next group + %team = nameToID("MissionGroup/Teams/team" @ %game.numTeams + 1); + if (%team != -1) + %game.numTeams++; + } + + // set the number of sensor groups (including team0) that are processed + setSensorGroupCount(%game.numTeams + 1); +} + +function SimGroup::setTeam(%this, %team) +{ + for (%i = 0; %i < %this.getCount(); %i++) + { + %obj = %this.getObject(%i); + switch$ (%obj.getClassName()) + { + case SpawnSphere : + if($MatchStarted) + { + // find out what team the spawnsphere used to belong to + %found = false; + for(%l = 1; %l <= Game.numTeams; %l++) + { + %drops = nameToId("MissionCleanup/TeamDrops" @ %l); + for(%j = 0; %j < %drops.getCount(); %j++) + { + %current = %drops.getObject(%j); + if(%current == %obj) + %found = %l; + } + } + if(%team != %found) + Game.claimSpawn(%obj, %team, %found); + else + error("spawn "@%obj@" is already on team "@%team@"!"); + } + else + Game.claimSpawn(%obj, %team, ""); + case SimGroup : %obj.setTeam(%team); + default : %obj.team = %team; + } + + if(%obj.getType() & $TypeMasks::GameBaseObjectType) + { + // eeck.. please go away when scripts get cleaned... +// if(%obj.getDataBlock().getName() $= "StationVehiclePad") +// { + // z0dd - ZOD, 4/24/02. Rewrite for bug fix and MPB teleporter +// %team = %obj.team; +// %obj = %obj.station; +// %obj.team = %team; +// setTargetSensorGroup(%obj.getTarget(), %team); +// if(%obj.teleporter !$= "") +// { +// %obj = %obj.teleporter; +// %obj.team = %team; +// } +// } + %target = %obj.getTarget(); + if(%target != -1) + setTargetSensorGroup(%target, %team); + } + } +} + +function DefaultGame::claimSpawn(%game, %obj, %newTeam, %oldTeam) +{ + if(%newTeam == %oldTeam) + return; + + %newSpawnGroup = nameToId("MissionCleanup/TeamDrops" @ %newTeam); + if(%oldTeam !$= "") + { + %oldSpawnGroup = nameToId("MissionCleanup/TeamDrops" @ %oldTeam); + %oldSpawnGroup.remove(%obj); + } + %newSpawnGroup.add(%obj); +} + +// recursive function to assign teams to all mission objects + +function SimGroup::swapTeams(%this) +{ + // used in Siege only + Game.groupSwapTeams(%this); +} + +function ShapeBase::swapTeams(%this) +{ + // used in Siege only + Game.objectSwapTeams(%this); +} + +function GameBase::swapTeams(%this) +{ + // used in Siege only + Game.objectSwapTeams(%this); +} + +function TSStatic::swapTeams(%this) +{ + // used in Siege only + // do nothing +} + +function InteriorInstance::swapTeams(%this) +{ + // used in Siege only + // do nothing -- interiors don't switch teams +} + +function SimGroup::swapVehiclePads(%this) +{ + // used in Siege only + Game.groupSwapVehiclePads(%this); +} + +function ShapeBase::swapVehiclePads(%this) +{ + // used in Siege only + Game.objectSwapVehiclePads(%this); +} + +function GameBase::swapVehiclePads(%this) +{ + // used in Siege only + // do nothing -- only searching for vehicle pads +} + +function InteriorInstance::swapVehiclePads(%this) +{ + // used in Siege only + // do nothing -- only searching for vehicle pads +} + +function SimSet::swapVehiclePads(%this) +{ + // used in Siege only + // do nothing -- only searching for vehicle pads +} + +function PhysicalZone::swapVehiclePads(%this) +{ + // used in Siege only + // do nothing -- only searching for vehicle pads +} + +function SimGroup::objectRestore(%this) +{ + // used in Siege only + Game.groupObjectRestore(%this); +} + +function ShapeBase::objectRestore(%object) +{ + // only used for Siege + Game.shapeObjectRestore(%object); +} + +function Turret::objectRestore(%object) +{ + // only used for Siege + Game.shapeObjectRestore(%object); +} + +function AIObjective::objectRestore(%object) +{ + // only used for Siege + // don't do anything for AI Objectives +} + +function DefaultGame::checkObjectives(%game) +{ + //any special objectives that can be met by gametype + //none for default game +} + +//--------------------------------------------------- + +function DefaultGame::checkTimeLimit(%game, %forced) +{ + // Don't add extra checks: + if ( %forced ) + cancel( %game.timeCheck ); + + // if there is no time limit, check back in a minute to see if it's been set + if(($Host::TimeLimit $= "") || $Host::TimeLimit == 0) + { + %game.timeCheck = %game.schedule(20000, "checkTimeLimit"); + return; + } + + %curTimeLeftMS = ($Host::TimeLimit * 60 * 1000) + $missionStartTime - getSimTime(); + + if (%curTimeLeftMS <= 0) + { + // time's up, put down your pencils + %game.timeLimitReached(); + } + else + { + if(%curTimeLeftMS >= 20000) + %game.timeCheck = %game.schedule(20000, "checkTimeLimit"); + else + %game.timeCheck = %game.schedule(%curTimeLeftMS + 1, "checkTimeLimit"); + + //now synchronize everyone's clock + messageAll('MsgSystemClock', "", $Host::TimeLimit, %curTimeLeftMS); + } +} + +function listplayers() +{ + for(%i = 0; %i < ClientGroup.getCount(); %i++) + { + %cl = ClientGroup.getObject(%i); + %status = ""; + if(%cl.isAiControlled()) + %status = "Bot "; + if(%cl.isSmurf) + %status = "Alias "; + if(%cl.isAdmin) + %status = %status @ "Admin "; + if(%cl.isSuperAdmin) + %status = %status @ "SuperAdmin "; + if(%status $= "") + %status = ""; + echo("client: " @ %cl @ " player: " @ %cl.player @ " name: " @ %cl.nameBase @ " team: " @ %cl.team @ " status: " @ %status); + } +} + +function DefaultGame::clearTeamRankArray(%game, %team) +{ + %count = $TeamRank[%team, count]; + for (%i = 0; %i < %count; %i++) + $TeamRank[%team, %i] = ""; + $TeamRank[%team, count] = 0; +} + +function DefaultGame::populateTeamRankArray(%game, %client) +{ + //this function should be called *after* the client has been added to a team... + if (%client <= 0 || %client.team <= 0) + return; + + //find the team + if (%game.numTeams == 1) + %team = 0; + else + %team = %client.team; + + //find the number of teammates already ranked... + %count = $TeamRank[%team, count]; + if (%count $= "") + { + $TeamRank[%team, count] = 0; + %count = 0; + } + + //make sure we're not already in the array + for (%i = 0; %i < %count; %i++) + { + if ($TeamRank[%team, %i] == %client) + return; + } + + //add the client in at the bottom of the list, and increment the count + $TeamRank[%team, %count] = %client; + $TeamRank[%team, count] = $TeamRank[%team, count] + 1; + + //now recalculate the team rank for this player + %game.recalcTeamRanks(%client); +} + +function DefaultGame::removeFromTeamRankArray(%game, %client) +{ + //note, this should be called *before* the client actually switches teams or drops... + if (%client <= 0 || %client.team <= 0) + return; + + //find the correct team + if (%game.numTeams == 1) + %team = 0; + else + %team = %client.team; + + //now search throught the team rank array, looking for this client + %count = $TeamRank[%team, count]; + for (%i = 0; %i < %count; %i++) + { + if ($TeamRank[%team, %i] == %client) + { + //we've found the client in the array, now loop through, and move everyone else up a rank + for (%j = %i + 1; %j < %count; %j++) + { + %cl = $TeamRank[%team, %j]; + $TeamRank[%team, %j - 1] = %cl; + messageClient(%cl, 'MsgYourRankIs', "", %j); + } + $TeamRank[%team, %count - 1] = ""; + + //now decrement the team rank array count, and break + $TeamRank[%team, count] = $TeamRank[%team, count] - 1; + break; + } + } +} + +function DefaultGame::recalcTeamRanks(%game, %client) +{ + if (%client <= 0 || %client.team <= 0) + return; + + // this is a little confusing -- someone's actual numerical rank is always + // one number higher than his index in the $TeamRank array + // (e.g. person ranked 1st has index of 0) + + // TINMAN: I'm going to remove the %client.teamRank field - the index in the + // $TeamRank array already contains their rank - safer to search the array than + // to maintiain the information in a separate variable... + + //find the team, the client in the team array + if (%game.numTeams == 1) + %team = 0; + else + %team = %client.team; + + %count = $TeamRank[%team, count]; + %index = -1; + for (%i = 0; %i < %count; %i++) + { + if ($TeamRank[%team, %i] == %client) + { + %index = %i; + break; + } + } + + //if they weren't found in the array, return + if (%index < 0) + return; + + //make sure far down the array as they should be... + %tempIndex = %index; + %swapped = false; + while (true) + { + if (%tempIndex <= 0) + break; + + %tempIndex--; + %tempClient = $TeamRank[%team, %tempIndex]; + + //see if we should swap the two + if (%client.score > %tempClient.score) + { + %swapped = true; + %index = %tempIndex; + $TeamRank[%team, %tempIndex] = %client; + $TeamRank[%team, %tempIndex + 1] = %tempClient; + messageClient(%tempClient, 'MsgYourRankIs', "", %tempIndex + 2); + } + } + + //if we've swapped up at least once, we obviously won't need to swap down as well... + if (%swapped) + { + messageClient(%client, 'MsgYourRankIs', "", %index + 1); + return; + } + + //since we didnt' swap up, see if we need to swap down... + %tempIndex = %index; + %swapped = false; + while (true) + { + if (%tempIndex >= %count - 1) + break; + + %tempIndex++; + %tempClient = $TeamRank[%team, %tempIndex]; + + //see if we should swap the two + if (%client.score < %tempClient.score) + { + %swapped = true; + %index = %tempIndex; + $TeamRank[%team, %tempIndex] = %client; + $TeamRank[%team, %tempIndex - 1] = %tempClient; + messageClient(%tempClient, 'MsgYourRankIs', "", %tempIndex); + } + } + + //send the message (regardless of whether a swap happened or not) + messageClient(%client, 'MsgYourRankIs', "", %index + 1); +} + +function DefaultGame::recalcScore(%game, %cl) +{ + %game.recalcTeamRanks(%cl); +} + +function DefaultGame::testKill(%game, %victimID, %killerID) +{ + return ((%killerID !=0) && (%victimID.team != %killerID.team)); +} + +function DefaultGame::testSuicide(%game, %victimID, %killerID, %damageType) +{ + return ((%victimID == %killerID) || (%damageType == $DamageType::Ground) || (%damageType == $DamageType::Suicide)); +} + +function DefaultGame::testTeamKill(%game, %victimID, %killerID) +{ + return (%killerID.team == %victimID.team); +} + +function DefaultGame::testTurretKill(%game, %implement) +{ + if(%implement == 0) + return false; + else + return (%implement.getClassName() $= "Turret"); +} + +// function DefaultGame::awardScoreFlagCap(%game, %cl) +// { +// %cl.flagCaps++; +// $TeamScore[%cl.team] += %game.SCORE_PER_TEAM_FLAG_CAP; +// messageAll('MsgCTFTeamScore', "", %cl.team, $TeamScore[%cl.team]); +// +// if (%game.SCORE_PER_PLYR_FLAG_CAP > 1) +// %plural = "s"; +// else +// %plural = ""; +// +// if (%game.SCORE_PER_PLYR_FLAG_CAP != 0) +// messageClient(%cl, 'scoreFlaCapMsg', 'You received %1 point%2 for capturing the flag.', %game.SCORE_PER_PLYR_FLAG_CAP, %plural); +// %game.recalcScore(%cl); +// } + + +function DefaultGame::testOOBDeath(%game, %damageType) +{ + return (%damageType == $DamageType::OutOfBounds); +} + +function DefaultGame::awardScoreTurretKill(%game, %victimID, %implement) +{ + if ((%killer = %implement.getControllingClient()) != 0) //award whoever might be controlling the turret + { + if (%killer == %victimID) + %game.awardScoreSuicide(%victimID); + else if (%killer.team == %victimID.team) //player controlling a turret killed a teammate + { + %killer.teamKills++; + %game.awardScoreTurretTeamKill(%victimID, %killer); + %game.awardScoreDeath(%victimID); + } + else + { + %killer.turretKills++; + %game.recalcScore(%killer); + %game.awardScoreDeath(%victimID); + } + } + else if ((%killer = %implement.owner) != 0) //if it isn't controlled, award score to whoever deployed it + { + if (%killer.team == %victimID.team) + { + %game.awardScoreDeath(%victimID); + } + else + { + %killer.turretKills++; + %game.recalcScore(%killer); + %game.awardScoreDeath(%victimID); + } + } + //default is, no one was controlling it, no one owned it. No score given. +} + +function DefaultGame::awardScoreDeath(%game, %victimID) +{ + %victimID.deaths++; + if ( %game.SCORE_PER_DEATH != 0 ) + { +// %plural = (abs(%game.SCORE_PER_DEATH) != 1 ? "s" : ""); +// messageClient(%victimID, 'MsgScoreDeath', '\c0You have been penalized %1 point%2 for dying.', abs(%game.SCORE_PER_DEATH), %plural); + %game.recalcScore(%victimID); + } +} + +function DefaultGame::awardScoreKill(%game, %killerID) +{ + %killerID.kills++; + %game.recalcScore(%killerID); +} + +function DefaultGame::awardScoreSuicide(%game, %victimID) +{ + %victimID.suicides++; +// if (%game.SCORE_PER_SUICIDE != 0) +// messageClient(%victimID, 'MsgScoreSuicide', '\c0You have been penalized for killing yourself.'); + %game.recalcScore(%victimID); +} + +function DefaultGame::awardScoreTeamkill(%game, %victimID, %killerID) +{ + %killerID.teamKills++; + if (%game.SCORE_PER_TEAMKILL != 0) + messageClient(%killerID, 'MsgScoreTeamkill', '\c0You have been penalized for killing teammate %1.', %victimID.name); + %game.recalcScore(%killerID); +} + +function DefaultGame::awardScoreTurretTeamKill(%game, %victimID, %killerID) +{ + %killerID.teamKills++; + if (%game.SCORE_PER_TEAMKILL != 0) + messageClient(%killerID, 'MsgScoreTeamkill', '\c0You have been penalized for killing your teammate %1, with a turret.', %victimID.name); + %game.recalcScore(%killerID); +} + + +function DefaultGame::objectRepaired(%game, %obj, %objName) +{ + %item = %obj.getDataBlock().getName(); + //echo("Item repaired is a " @ %item); + switch$ (%item) + { + case generatorLarge : + %game.genOnRepaired(%obj, %objName); + case stationInventory : + %game.stationOnRepaired(%obj, %objName); + case sensorMediumPulse : + %game.sensorOnRepaired(%obj, %objName); + case sensorLargePulse : + %game.sensorOnRepaired(%obj, %objName); + case turretBaseLarge : + %game.turretOnRepaired(%obj, %objName); + case stationVehicle : %game.vStationOnRepaired(%obj, %objName); + default: //unused by current gametypes. Add more checks here if desired + } +} + +function DefaultGame::allowsProtectedStatics(%game) +{ + return false; +} + +// jff: why is game object doing this? +//Return a simple string with no extras +function DefaultGame::cleanWord(%game, %this) +{ + %length = strlen(%this); + for(%i = 0; %i < %length; %i++) + { + %char = getSubStr(%this, %i, 1); + if(%char $= "_") + { + %next = getSubStr(%this, (%i+1), 1); + if(%next $= "_") + { + %char = "'"; //apostrophe (2 chars) + %i++; + } + else + %char = " "; //space + } + %clean = (%clean @ %char); + } +} + +function DefaultGame::stationOnEnterTrigger(%game, %data, %obj, %colObj) +{ + return true; +} + +function DefaultGame::WeaponOnUse(%game, %data, %obj) +{ + return true; +} + +function DefaultGame::HandInvOnUse(%game, %data, %obj) +{ + return true; +} + +function DefaultGame::WeaponOnInventory(%game, %this, %obj, %amount) +{ + return true; +} + +function DefaultGame::ObserverOnTrigger(%game, %data, %obj, %trigger, %state) +{ + return true; +} + +// jff: why is the game being notified that a weapon is being thrown? hot potato gametype? +function DefaultGame::ShapeThrowWeapon(%game, %this) +{ + return true; +} + +function DefaultGame::leaveMissionArea(%game, %playerData, %player) +{ + if(%player.getState() $= "Dead") + return; + + %player.client.outOfBounds = true; + messageClient(%player.client, 'LeaveMissionArea', '\c1You left the mission area.~wfx/misc/warning_beep.wav'); +} + +function DefaultGame::enterMissionArea(%game, %playerData, %player) +{ + if(%player.getState() $= "Dead") + return; + + %player.client.outOfBounds = false; + messageClient(%player.client, 'EnterMissionArea', '\c1You are back in the mission area.'); +} + +//------------------------------------------------------------------------------ +// AI stubs: +//------------------------------------------------------------------------------ + +function DefaultGame::onAIDamaged(%game, %clVictim, %clAttacker, %damageType, %sourceObject) +{ +} + +function DefaultGame::onAIFriendlyFire(%game, %clVictim, %clAttacker, %damageType, %sourceObject) +{ +} + +function DefaultGame::onAIKilled(%game, %clVictim, %clKiller, %damageType, %implement) +{ + //unassign the client from any objectives + AIUnassignClient(%clVictim); + + //break the link, if this ai is controlled + aiReleaseHumanControl(%clVictim.controlByHuman, %clVictim); + + //and schedule the respawn + %clVictim.respawnThread = schedule(5000, %clVictim, "onAIRespawn", %clVictim); +} + +function DefaultGame::onAIKilledClient(%game, %clVictim, %clAttacker, %damageType, %implement) +{ + %clAttacker.setVictim(%clVictim, %clVictim.player); +} + +//------------------------------------------------------------------------------ +// Voting stuff: +//------------------------------------------------------------------------------ +function DefaultGame::sendGamePlayerPopupMenu( %game, %client, %targetClient, %key ) +{ + if( !%targetClient.matchStartReady ) + return; + + %isAdmin = ( %client.isAdmin || %client.isSuperAdmin ); + %isTargetSelf = ( %client == %targetClient ); + %isTargetAdmin = ( %targetClient.isAdmin || %targetClient.isSuperAdmin ); + %isTargetBot = %targetClient.isAIControlled(); + %isTargetObserver = ( %targetClient.team == 0 ); + %outrankTarget = false; + + if ( %client.isSuperAdmin ) + %outrankTarget = !%targetClient.isSuperAdmin; + else if ( %client.isAdmin ) + %outrankTarget = !%targetClient.isAdmin; + + if( %client.isSuperAdmin && %targetClient.guid != 0 ) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + { + messageClient( %client, 'MsgPlayerPopupItem', "", %key, "addAdmin", "", 'Add to Server Admin List', 10); + messageClient( %client, 'MsgPlayerPopupItem', "", %key, "addSuperAdmin", "", 'Add to Server SuperAdmin List', 11); + } + + //mute options + if ( !%isTargetSelf ) + { + if ( %client.muted[%targetClient] ) + messageClient( %client, 'MsgPlayerPopupItem', "", %key, "MutePlayer", "", 'Unmute Text Chat', 1); + else + messageClient( %client, 'MsgPlayerPopupItem', "", %key, "MutePlayer", "", 'Mute Text Chat', 1); + + if ( !%isTargetBot && %client.canListenTo( %targetClient ) ) + { + if ( %client.getListenState( %targetClient ) ) + messageClient( %client, 'MsgPlayerPopupItem', "", %key, "ListenPlayer", "", 'Disable Voice Com', 9 ); + else + messageClient( %client, 'MsgPlayerPopupItem', "", %key, "ListenPlayer", "", 'Enable Voice Com', 9 ); + } + // ------------------------------------------ + // z0dd - ZOD 4/4/02. Observe a specific player + if (%client.team == 0 && !%isTargetObserver) + messageClient(%client, 'MsgPlayerPopupItem', "", %key, "ObservePlayer", "", 'Observe Player', 12); + } + if( !%client.canVote && !%isAdmin ) + return; + + // regular vote options on players + if ( %game.scheduleVote $= "" && !%isAdmin && !%isTargetAdmin ) + { + if ( $Host::allowAdminPlayerVotes && !%isTargetBot ) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + messageClient( %client, 'MsgPlayerPopupItem', "", %key, "AdminPlayer", "", 'Vote to Make Admin', 2 ); + + if ( !%isTargetSelf ) + { + messageClient( %client, 'MsgPlayerPopupItem', "", %key, "KickPlayer", "", 'Vote to Kick', 3 ); + } + } + + // Admin only options on players: + else if ( %isAdmin ) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + { + if ( !%isTargetBot && !%isTargetAdmin ) + messageClient( %client, 'MsgPlayerPopupItem', "", %key, "AdminPlayer", "", 'Make Admin', 2 ); + + if ( !%isTargetSelf && %outrankTarget ) + { + messageClient( %client, 'MsgPlayerPopupItem', "", %key, "KickPlayer", "", 'Kick', 3 ); + + if ( !%isTargetBot ) + { + // ------------------------------------------------------------------------------------------------------ + // z0dd - ZOD 4/4/02. Warn player, send private message and remove admin privledges + messageClient(%client, 'MsgPlayerPopupItem', "", %key, "Warn", "", 'Warn player', 13); + messageClient( %client, 'MsgPlayerPopupItem', "", %key, "SendMessage", "", 'Send Private Message', 15 ); + if(%isTargetAdmin) + messageClient( %client, 'MsgPlayerPopupItem', "", %key, "StripAdmin", "", 'Strip admin', 14 ); + + if( %client.isSuperAdmin ) + messageClient( %client, 'MsgPlayerPopupItem', "", %key, "BanPlayer", "", 'Ban', 4 ); + + if ($CurrentMissionType !$= "RPG") + return; + if ( !%isTargetObserver ) + { + messageClient( %client, 'MsgPlayerPopupItem', "", %key, "ToObserver", "", 'Force observer', 5 ); + } + } + } + if ( %isTargetSelf || %outrankTarget ) + { + if ( %game.numTeams > 1 ) + { + if ( %isTargetObserver ) + { + %action = %isTargetSelf ? "Join " : "Change to "; + %str1 = %action @ getTaggedString( %game.getTeamName(1) ); + %str2 = %action @ getTaggedString( %game.getTeamName(2) ); + + messageClient( %client, 'MsgPlayerPopupItem', "", %key, "ChangeTeam", "", %str1, 6 ); + messageClient( %client, 'MsgPlayerPopupItem', "", %key, "ChangeTeam", "", %str2, 7 ); + } + else + { + %changeTo = %targetClient.team == 1 ? 2 : 1; + %str = "Switch to " @ getTaggedString( %game.getTeamName(%changeTo) ); + %caseId = 5 + %changeTo; + + messageClient( %client, 'MsgPlayerPopupItem', "", %key, "ChangeTeam", "", %str, %caseId ); + } + } + else if ( %isTargetObserver ) + { + %str = %isTargetSelf ? 'Join the Game' : 'Add to Game'; + messageClient( %client, 'MsgPlayerPopupItem', "", %key, "JoinGame", "", %str, 8 ); + } + } + } +} + +//------------------------------------------------------------------------------ +function DefaultGame::sendGameVoteMenu( %game, %client, %key ) +{ + %isAdmin = ( %client.isAdmin || %client.isSuperAdmin ); + %multipleTeams = %game.numTeams > 1; + + // no one is going anywhere until this thing starts + if($MatchStarted) + { + // Client options: + if ( %client.team != 0 ) + { + if ($CurrentMissionType !$= "RPG") + { + if ( %multipleTeams ) + if( !$Host::TournamentMode ) + messageClient( %client, 'MsgVoteItem', "", %key, 'ChooseTeam', "", 'Change your Team' ); + messageClient( %client, 'MsgVoteItem', "", %key, 'MakeObserver', "", 'Become an Observer' ); + } + } + else + { + if(!%multipleTeams && !$Host::TournamentMode) + messageClient( %client, 'MsgVoteItem', "", %key, 'JoinGame', "", 'Join the Game' ); + } + + //%totalSlots = $Host::maxPlayers - ($HostGamePlayerCount + $HostGameBotCount); + // if( $HostGameBotCount > 0 && %totalSlots > 0 && %client.isAdmin) + //messageClient( %client, 'MsgVoteItem', "", %key, 'Addbot', "", 'Add a Bot' ); + } + + if( !%client.canVote && !%isAdmin ) + return; + + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + + if ( %game.scheduleVote $= "" ) + { + if(!%client.isAdmin) + { + // Actual vote options: + messageClient( %client, 'MsgVoteItem', "", %key, 'VoteChangeMission', 'change the mission to', 'Vote to Change the Mission' ); + + if( $Host::TournamentMode ) + { + messageClient( %client, 'MsgVoteItem', "", %key, 'VoteFFAMode', 'Change server to Free For All.', 'Vote Free For All Mode' ); + + if(!$MatchStarted && !$CountdownStarted) + messageClient( %client, 'MsgVoteItem', "", %key, 'VoteMatchStart', 'Start Match', 'Vote to Start the Match' ); + } + else + messageClient( %client, 'MsgVoteItem', "", %key, 'VoteTournamentMode', 'Change server to Tournament.', 'Vote Tournament Mode' ); + + if ($CurrentMissionType !$= "RPG" && $CurrentMissionType !$= "Survival") + if ( %multipleTeams ) + { + if(!$MatchStarted && !$Host::TournamentMode) + messageClient( %client, 'MsgVoteItem', "", %key, 'ChooseTeam', "", 'Change your Team' ); + + if ( $teamDamage ) + messageClient( %client, 'MsgVoteItem', "", %key, 'VoteTeamDamage', 'disable team damage', 'Vote to Disable Team Damage' ); + else + messageClient( %client, 'MsgVoteItem', "", %key, 'VoteTeamDamage', 'enable team damage', 'Vote to Enable Team Damage' ); + } + } + else + { + // Actual vote options: + messageClient( %client, 'MsgVoteItem', "", %key, 'VoteChangeMission', 'change the mission to', 'Change the Mission' ); + + if ($CurrentMissionType !$= "RPG") //Don't screw with the time limit in the actual gamemode. :) + if( $Host::TournamentMode ) + { + messageClient( %client, 'MsgVoteItem', "", %key, 'VoteFFAMode', 'Change server to Free For All.', 'Free For All Mode' ); + + if(!$MatchStarted && !$CountdownStarted) + messageClient( %client, 'MsgVoteItem', "", %key, 'VoteMatchStart', 'Start Match', 'Start Match' ); + } + else + messageClient( %client, 'MsgVoteItem', "", %key, 'VoteTournamentMode', 'Change server to Tournament.', 'Tournament Mode' ); + + if ($CurrentMissionType !$= "RPG" && $CurrentMissionType !$= "Survival") + if ( %multipleTeams ) + { + if(!$MatchStarted) + messageClient( %client, 'MsgVoteItem', "", %key, 'ChooseTeam', "", 'Choose Team' ); + + if ($CurrentMissionType !$= "RPG") + if ( $teamDamage ) + messageClient( %client, 'MsgVoteItem', "", %key, 'VoteTeamDamage', 'disable team damage', 'Disable Team Damage' ); + else + messageClient( %client, 'MsgVoteItem', "", %key, 'VoteTeamDamage', 'enable team damage', 'Enable Team Damage' ); + } + } + } + + // Admin only options: + if ( %client.isAdmin ) + { + if ($CurrentMissionType !$= "RPG") + messageClient( %client, 'MsgVoteItem', "", %key, 'VoteChangeTimeLimit', 'change the time limit', 'Change the Time Limit' ); + + messageClient( %client, 'MsgVoteItem', "", %key, 'VoteResetServer', 'reset server defaults', 'Reset the Server' ); + + if ($CurrentMissionType $= "SV" && !$Host::ProgressiveMode) //Holy fuck, BETA option! Good thing it's admin only. + messageClient( %client, 'MsgVoteItem', "", %key, 'voteProgressiveMode', '', 'Enable BETA Progressive Mode' ); + else if ($Host::ProgressiveMode) + messageClient( %client, 'MsgVoteItem', "", %key, 'voteProgressiveMode', '', 'Disable BETA Progressive Mode' ); + + // ----------------------------------------------------------------------------- + // z0dd - ZOD, 5/12/02. Add bot menu for admins + %totalSlots = $Host::maxPlayers - ($HostGamePlayerCount + $HostGameBotCount); + if( $HostGameBotCount > 0 && %totalSlots > 0 && $CurrentMissionType !$= "RPG") + messageClient( %client, 'MsgVoteItem', "", %key, 'Addbot', "", 'Add a Bot' ); + // ----------------------------------------------------------------------------- + } + + // Host only options: + if ( %client.getAddress() $= "local" ) + { + if (!$ServerLock) //Would be a saved server Pref but it doesn't really make sense to lock your server everytime you host + messageClient( %client, 'MsgVoteItem', "", %key, 'voteLockServer', "", 'Lock Server' ); + else + messageClient( %client, 'MsgVoteItem', "", %key, 'voteLockServer', "", 'Unlock Server' ); + } + + if ($CurrentMissionType $= "RPG" && %client.isAdmin) + { + if ($Host::GlobalChat) //Would be a saved server Pref but it doesn't really make sense to lock your server everytime you host + messageClient( %client, 'MsgVoteItem', "", %key, 'voteGlobal', "", 'Disable Global Chat' ); + else + messageClient( %client, 'MsgVoteItem', "", %key, 'voteGlobal', "", 'Enable Global Chat' ); + } + +} + +//------------------------------------------------------------------------------ +function DefaultGame::sendGameTeamList( %game, %client, %key ) +{ + %teamCount = %game.numTeams; + if ( %teamCount < 2 ) + { + warn( "Team menu requested for one-team game!" ); + return; + } + + for ( %team = 1; %team - 1 < %teamCount; %team++ ) + messageClient( %client, 'MsgVoteItem', "", %key, %team, "", detag( getTaggedString( %game.getTeamName(%team) ) ) ); +} + +//------------------------------------------------------------------------------ +function DefaultGame::sendTimeLimitList( %game, %client, %key ) +{ + messageClient( %client, 'MsgVoteItem', "", %key, 10, "", '10 minutes' ); + messageClient( %client, 'MsgVoteItem', "", %key, 15, "", '15 minutes' ); + messageClient( %client, 'MsgVoteItem', "", %key, 20, "", '20 minutes' ); + messageClient( %client, 'MsgVoteItem', "", %key, 25, "", '25 minutes' ); + messageClient( %client, 'MsgVoteItem', "", %key, 30, "", '30 minutes' ); + messageClient( %client, 'MsgVoteItem', "", %key, 45, "", '45 minutes' ); + messageClient( %client, 'MsgVoteItem', "", %key, 60, "", '60 minutes' ); + messageClient( %client, 'MsgVoteItem', "", %key, 200, "", 'No time limit' ); +} + +//------------------------------------------------------------------------------ +// all global votes here +// this function was created to remove the call to "eval", which is non-functional in PURE servers... +function DefaultGame::evalVote(%game, %typeName, %admin, %arg1, %arg2, %arg3, %arg4) +{ + switch$ (%typeName) + { + case "voteChangeMission": + %game.voteChangeMission(%admin, %arg1, %arg2, %arg3, %arg4); + + case "voteTeamDamage": + %game.voteTeamDamage(%admin, %arg1, %arg2, %arg3, %arg4); + + case "voteTournamentMode": + %game.voteTournamentMode(%admin, %arg1, %arg2, %arg3, %arg4); + + case "voteMatchStart": + %game.voteMatchStart(%admin, %arg1, %arg2, %arg3, %arg4); + + case "voteFFAMode": + %game.voteFFAMode(%admin, %arg1, %arg2, %arg3, %arg4); + + case "voteChangeTimeLimit": + %game.voteChangeTimeLimit(%admin, %arg1, %arg2, %arg3, %arg4); + + case "voteResetServer": + %game.voteResetServer(%admin, %arg1, %arg2, %arg3, %arg4); + + case "voteKickPlayer": + %game.voteKickPlayer(%admin, %arg1, %arg2, %arg3, %arg4); + + case "voteAdminPlayer": + %game.voteAdminPlayer(%admin, %arg1, %arg2, %arg3, %arg4); + + case "voteGreedMode": + %game.voteGreedMode(%admin, %arg1, %arg2, %arg3, %arg4); + + case "voteHoardMode": + %game.voteHoardMode(%admin, %arg1, %arg2, %arg3, %arg4); + + case "voteLockServer": + %game.voteLockServer(%admin, %arg1, %arg2, %arg3, %arg4); + + case "voteGlobal": + %game.voteGlobal(%admin, %arg1, %arg2, %arg3, %arg4); + + case "voteProgressiveMode": + %game.voteProgressiveMode(%admin, %arg1, %arg2, %arg3, %arg4); + } +} + +function DefaultGame::voteChangeMission(%game, %admin, %missionDisplayName, %typeDisplayName, %missionId, %missionTypeId) +{ + %mission = $HostMissionFile[%missionId]; + if ( %mission $= "" ) + { + error( "Invalid mission index passed to DefaultGame::voteChangeMission!" ); + return; + } + + %missionType = $HostTypeName[%missionTypeId]; + if ( %missionType $= "" ) + { + error( "Invalid mission type id passed to DefaultGame::voteChangeMission!" ); + return; + } + + if(%admin) + { + messageAll('MsgAdminChangeMission', '\c2The Admin has changed the mission to %1 (%2).', %missionDisplayName, %typeDisplayName ); + logEcho("mission changed to "@%missionDisplayName@"/"@%typeDisplayName@" (admin)"); + %game.gameOver(); + loadMission( %mission, %missionType, false ); + } + else + { + %totalVotes = %game.totalVotesFor + %game.totalVotesAgainst; + if(%totalVotes > 0 && (%game.totalVotesFor / (ClientGroup.getCount() - $HostGameBotCount)) > ($Host::VotePasspercent / 100)) + { + messageAll('MsgVotePassed', '\c2The mission was changed to %1 (%2) by vote.', %missionDisplayName, %typeDisplayName ); + logEcho("mission changed to "@%missionDisplayName@"/"@%typeDisplayName@" (vote)"); + %game.gameOver(); + loadMission( %mission, %missionType, false ); + } + else + messageAll('MsgVoteFailed', '\c2Change mission vote did not pass: %1 percent.', mFloor(%game.totalVotesFor/(ClientGroup.getCount() - $HostGameBotCount) * 100)); + } +} + +//------------------------------------------------------------------------------ +function DefaultGame::voteTeamDamage(%game, %admin) +{ + %setto = ""; + %cause = ""; + + if ($CurrentMissionType $= "RPG") + return; + + if(%admin) + { + if($teamDamage) + { + messageAll('MsgAdminForce', '\c2The Admin has disabled team damage.'); + $Host::TeamDamageOn = $TeamDamage = 0; + %setto = "disabled"; + } + else + { + messageAll('MsgAdminForce', '\c2The Admin has enabled team damage.'); + $Host::TeamDamageOn = $TeamDamage = 1; + %setto = "enabled"; + } + %cause = "(admin)"; + } + else + { + %totalVotes = %game.totalVotesFor + %game.totalVotesAgainst; + if(%totalVotes > 0 && (%game.totalVotesFor / (ClientGroup.getCount() - $HostGameBotCount)) > ($Host::VotePasspercent / 100)) + { + if($teamDamage) + { + messageAll('MsgVotePassed', '\c2Team damage was disabled by vote.'); + $Host::TeamDamageOn = $TeamDamage = 0; + %setto = "disabled"; + } + else + { + messageAll('MsgVotePassed', '\c2Team damage was enabled by vote.'); + $Host::TeamDamageOn = $TeamDamage = 1; + %setto = "enabled"; + } + %cause = "(vote)"; + } + else + { + if($teamDamage) + messageAll('MsgVoteFailed', '\c2Disable team damage vote did not pass: %1 percent.', mFloor(%game.totalVotesFor/(ClientGroup.getCount() - $HostGameBotCount) * 100)); + else + messageAll('MsgVoteFailed', '\c2Enable team damage vote did not pass: %1 percent.', mFloor(%game.totalVotesFor/(ClientGroup.getCount() - $HostGameBotCount) * 100)); + } + } + if(%setto !$= "") + logEcho("team damage "@%setto SPC %cause); +} + +//------------------------------------------------------------------------------ +function DefaultGame::voteTournamentMode( %game, %admin, %missionDisplayName, %typeDisplayName, %missionId, %missionTypeId ) +{ + %mission = $HostMissionFile[%missionId]; + + if ($CurrentMissionType $= "RPG") + return; + + if ( %mission $= "" ) + { + error( "Invalid mission index passed to DefaultGame::voteTournamentMode!" ); + return; + } + + %missionType = $HostTypeName[%missionTypeId]; + if ( %missionType $= "" ) + { + error( "Invalid mission type id passed to DefaultGame::voteTournamentMode!" ); + return; + } + + %cause = ""; + if (%admin) + { + messageAll( 'MsgAdminForce', '\c2The Admin has switched the server to Tournament mode (%1).', %missionDisplayName ); + setModeTournament( %mission, %missionType ); + %cause = "(admin)"; + } + else + { + %totalVotes = %game.totalVotesFor + %game.totalVotesAgainst; + if(%totalVotes > 0 && (%game.totalVotesFor / (ClientGroup.getCount() - $HostGameBotCount)) > ($Host::VotePasspercent / 100)) + { + messageAll('MsgVotePassed', '\c2Server switched to Tournament mode by vote (%1): %2 percent.', %missionDisplayName, mFloor(%game.totalVotesFor/(ClientGroup.getCount() - $HostGameBotCount) * 100)); + setModeTournament( %mission, %missionType ); + %cause = "(vote)"; + } + else + messageAll('MsgVoteFailed', '\c2Tournament mode vote did not pass: %1 percent.', mFloor(%game.totalVotesFor/(ClientGroup.getCount() - $HostGameBotCount) * 100)); + } + if(%cause !$= "") + logEcho("tournament mode set "@%cause); +} + +//------------------------------------------------------------------------------ +function DefaultGame::voteMatchStart( %game, %admin) +{ + %cause = ""; + %ready = forceTourneyMatchStart(); + + if(%admin) + { + if(!%ready) + { + messageClient( %client, 'msgClient', '\c2No players are ready yet.'); + return; + } + else + { + messageAll('msgMissionStart', '\c2The admin has forced the match to start.'); + %cause = "(admin)"; + startTourneyCountdown(); + } + } + else + { + if(!%ready) + { + messageAll( 'msgClient', '\c2Vote passed to start match, but no players are ready yet.'); + return; + } + else + { + %totalVotes = %game.totalVotesFor + %game.totalVotesAgainst; + if(%totalVotes > 0 && (%game.totalVotesFor / (ClientGroup.getCount() - $HostGameBotCount)) > ($Host::VotePasspercent / 100)) + { + messageAll('MsgVotePassed', '\c2The match has been started by vote: %1 percent.', mFloor(%game.totalVotesFor/(ClientGroup.getCount() - $HostGameBotCount) * 100)); + startTourneyCountdown(); + } + else + messageAll('MsgVoteFailed', '\c2Start Match vote did not pass: %1 percent.', mFloor(%game.totalVotesFor/(ClientGroup.getCount() - $HostGameBotCount) * 100)); + } + } + + if(%cause !$= "") + logEcho("start match "@%cause); +} + +//------------------------------------------------------------------------------ +function DefaultGame::voteFFAMode( %game, %admin, %client ) +{ + %cause = ""; + %name = getTaggedString(%client.name); + + if ($CurrentMissionType $= "RPG") + return; + + if (%admin) + { + messageAll('MsgAdminForce', '\c2The Admin has switched the server to Free For All mode.', %client); + setModeFFA($CurrentMission, $CurrentMissionType); + %cause = "(admin)"; + } + else + { + %totalVotes = %game.totalVotesFor + %game.totalVotesAgainst; + if(%totalVotes > 0 && (%game.totalVotesFor / (ClientGroup.getCount() - $HostGameBotCount)) > ($Host::VotePasspercent / 100)) + { + messageAll('MsgVotePassed', '\c2Server switched to Free For All mode by vote.', %client); + setModeFFA($CurrentMission, $CurrentMissionType); + %cause = "(vote)"; + } + else + messageAll('MsgVoteFailed', '\c2Free For All mode vote did not pass: %1 percent.', mFloor(%game.totalVotesFor/(ClientGroup.getCount() - $HostGameBotCount) * 100)); + } + if(%cause !$= "") + logEcho("free for all set "@%cause); +} + +//------------------------------------------------------------------------------ +function DefaultGame::voteChangeTimeLimit( %game, %admin, %newLimit ) +{ + if( %newLimit == 999 ) + %display = "unlimited"; + else + %display = %newLimit; + + if ($CurrentMissionType $= "RPG") + return; + + %cause = ""; + if ( %admin ) + { + messageAll( 'MsgAdminForce', '\c2The Admin changed the mission time limit to %1 minutes.', %display ); + $Host::TimeLimit = %newLimit; + %cause = "(admin)"; + } + else + { + %totalVotes = %game.totalVotesFor + %game.totalVotesAgainst; + if(%totalVotes > 0 && (%game.totalVotesFor / (ClientGroup.getCount() - $HostGameBotCount)) > ($Host::VotePasspercent / 100)) + { + messageAll('MsgVotePassed', '\c2The mission time limit was set to %1 minutes by vote.', %display); + $Host::TimeLimit = %newLimit; + %cause = "(vote)"; + } + else + messageAll('MsgVoteFailed', '\c2The vote to change the mission time limit did not pass: %1 percent.', mFloor(%game.totalVotesFor/(ClientGroup.getCount() - $HostGameBotCount) * 100)); + } + + //if the time limit was actually changed... + if(%cause !$= "") + { + logEcho("time limit set to "@%display SPC %cause); + + //if the match has been started, reset the end of match countdown + if ($matchStarted) + { + //schedule the end of match countdown + %elapsedTimeMS = getSimTime() - $missionStartTime; + %curTimeLeftMS = ($Host::TimeLimit * 60 * 1000) - %elapsedTimeMS; + error("time limit="@$Host::TimeLimit@", elapsed="@(%elapsedTimeMS / 60000)@", curtimeleftms="@%curTimeLeftMS); + CancelEndCountdown(); + EndCountdown(%curTimeLeftMS); + cancel(%game.timeSync); + %game.checkTimeLimit(true); + } + } +} + +//------------------------------------------------------------------------------ +function DefaultGame::voteResetServer( %game, %admin, %client ) +{ + %cause = ""; + if ( %admin ) + { + messageAll( 'AdminResetServer', '\c2The Admin has reset the server.' ); + resetServerDefaults(); + %cause = "(admin)"; + } + else + { + %totalVotes = %game.totalVotesFor + %game.totalVotesAgainst; + if(%totalVotes > 0 && (%game.totalVotesFor / (ClientGroup.getCount() - $HostGameBotCount)) > ($Host::VotePasspercent / 100)) + { + messageAll('MsgVotePassed', '\c2The Server has been reset by vote.' ); + resetServerDefaults(); + %cause = "(vote)"; + } + else + messageAll('MsgVoteFailed', '\c2The vote to reset Server to defaults did not pass: %1 percent.', mFloor(%game.totalVotesFor/(ClientGroup.getCount() - $HostGameBotCount) * 100)); + } + if(%cause !$= "") + logEcho("server reset "@%cause); +} + +//------------------------------------------------------------------------------ +// all team based votes here +function DefaultGame::voteKickPlayer(%game, %admin, %client) +{ + %cause = ""; + + if(%admin) + { + kick(%client, %admin, %client.guid ); + %cause = "(admin)"; + } + else + { + %team = %client.team; + %totalVotes = %game.votesFor[%game.kickTeam] + %game.votesAgainst[%game.kickTeam]; + if(%totalVotes > 0 && (%game.votesFor[%game.kickTeam] / %totalVotes) > ($Host::VotePasspercent / 100)) + { + kick(%client, %admin, %game.kickGuid); + %cause = "(vote)"; + } + else + { + for ( %idx = 0; %idx < ClientGroup.getCount(); %idx++ ) + { + %cl = ClientGroup.getObject( %idx ); + + if (%cl.team == %game.kickTeam && !%cl.isAIControlled()) + messageClient( %cl, 'MsgVoteFailed', '\c2Kick player vote did not pass' ); + } + } + } + + %game.kickTeam = ""; + %game.kickGuid = ""; + %game.kickClientName = ""; + + if(%cause !$= "") + logEcho(%name@" (cl " @ %game.kickClient @ ") kicked " @ %cause); +} + +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +function DefaultGame::voteLockServer(%game, %admin) +{ + %setto = ""; + %cause = ""; + + if(%admin) + { + if(!$ServerLock) + { + messageAll('MsgAdminForce', '\c2The Admin has locked the server.'); + allowConnections(false); + $ServerLock = true; + %setto = "no"; + } + else + { + messageAll('MsgAdminForce', '\c2The Admin has unlocked the server.'); + allowConnections(true); + $ServerLock = false; + %setto = "yes"; + } + %cause = "(admin)"; + + if(%setto !$= "") + logEcho("server allow connections "@%setto SPC %cause); +} +} + +//------------------------------------------------------------------------------ +function DefaultGame::voteGlobal(%game, %admin) +{ + %setto = ""; + %cause = ""; + + if(%admin) + { + if(!$Host::GlobalChat) + { + messageAll('MsgAdminForce', '\c2The Admin has enabled Global chat.'); + $Host::GlobalChat = true; + %setto = "yes"; + } + else + { + messageAll('MsgAdminForce', '\c2The Admin has disabled global chat.'); + $Host::GlobalChat = false; + %setto = "yes"; + } + %cause = "(admin)"; + + if(%setto !$= "") + logEcho("server allow global chatting "@%setto SPC %cause); +} +} +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +function DefaultGame::voteProgressiveMode(%game, %admin) +{ + %setto = ""; + %cause = ""; + + if(%admin) + { + if(!$Host::ProgressiveMode) + { + messageAll('MsgAdminForce', '\c2The Admin has enabled progressive mode.'); + $Host::ProgressiveMode = true; + $Game::BotWave = Game.schedule(120000,"SpawnAI",true); + %setto = "no"; + } + else + { + messageAll('MsgAdminForce', '\c2The Admin has disabled progressive mode.'); + cancel($Game::BotWave); + $Host::ProgressiveMode = false; + %setto = "yes"; + } + %cause = "(admin)"; + + if(%setto !$= "") + logEcho("progressive mode "@%setto SPC %cause); +} +} +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +function DefaultGame::banPlayer(%game, %admin, %client) +{ + %cause = ""; + %name = %client.nameBase; + if( %admin ) + { + ban( %client, %admin ); + %cause = "(admin)"; + } + + if(%cause !$= "") + logEcho(%name@" (cl "@%client@") banned "@%cause); +} + +//------------------------------------------------------------------------------ +function DefaultGame::voteAdminPlayer(%game, %admin, %client) +{ + %cause = ""; + + if (%admin) + { + messageAll('MsgAdminAdminPlayer', '\c2The Admin made %2 an admin.', %client, %client.name); + %client.isAdmin = 1; + %cause = "(admin)"; + } + else + { + %totalVotes = %game.totalVotesFor + %game.totalVotesAgainst; + if(%totalVotes > 0 && (%game.totalVotesFor / (ClientGroup.getCount() - $HostGameBotCount)) > ($Host::VotePasspercent / 100)) + { + messageAll('MsgAdminPlayer', '\c2%2 was made an admin by vote.', %client, %client.name); + %client.isAdmin = 1; + %cause = "(vote)"; + } + else + messageAll('MsgVoteFailed', '\c2Vote to make %1 an admin did not pass.', %client.name); + } + if(%cause !$= "") + logEcho(%client.nameBase@" (cl "@%client@") made admin "@%cause); +} + +//------------------------------------------------------------------------------ +function DefaultGame::processGameLink(%game, %client, %arg1, %arg2, %arg3, %arg4, %arg5) +{ + if (isObject(%arg1)) + { + if (%arg1.isAIControlled()) + return; //Don't do bots.. + + messageClient( %client, 'ClearHud', "", 'scoreScreen', 0 ); + + %tag = 'scoreScreen'; + %client.isViewingStatistics = true; + + messageClient( %client, 'SetScoreHudHeader', "", 'Player Information'); + messageClient( %client, 'SetScoreHudSubheader', "", "" @ %arg1.namebase); + + %index = 0; + messageClient( %client, 'SetLineHud', "", %tag, %index, "General---"); + %index++; + messageClient( %client, 'SetLineHud', "", %tag, %index, 'Race: %1 ', %client.race); + %index++; + if (%client.race $= "Draakan") + { + messageClient( %client, 'SetLineHud', "", %tag, %index, 'Type: %1', %client.sex); + %index++; + } + else + { + messageClient( %client, 'SetLineHud', "", %tag, %index, 'Sex: %1', %client.sex ); + %index++; + } + messageClient( %client, 'SetLineHud', "", %tag, %index, ""); + %index++; + messageClient( %client, 'SetLineHud', "", %tag, %index, ""); + %index++; + messageClient( %client, 'SetLineHud', "", %tag, %index, "Accuracy Quota---"); + %index++; + messageClient( %client, 'SetLineHud', "", %tag, %index, 'Shots Fired: %1 ', $Data::Shots[%arg1.guid]); + %index++; + messageClient( %client, 'SetLineHud', "", %tag, %index, 'Shots Landed: %1', $Data::Hits[%arg1.guid]); + %index++; + messageClient( %client, 'SetLineHud', "", %tag, %index, 'Head Shots: %1', $Data::Headshots[%arg1.guid]); + %index++; + messageClient( %client, 'SetLineHud', "", %tag, %index, "Percent: "@mfloor(($Data::Hits[%arg1.guid] / $Data::Shots[%arg1.guid])*100)@"%"); + %index++; + messageClient( %client, 'SetLineHud', "", %tag, %index, ""); + %index++; + messageClient( %client, 'SetLineHud', "", %tag, %index, ""); + %index++; + messageClient( %client, 'SetLineHud', "", %tag, %index, "Kill/Death Ratio---"); + %index++; + messageClient( %client, 'SetLineHud', "", %tag, %index, 'Kills: %1', $Data::Kills[%arg1.guid]); + %index++; + messageClient( %client, 'SetLineHud', "", %tag, %index, 'Deaths: %1', $Data::Deaths[%arg1.guid]); + %index++; + messageClient( %client, 'SetLineHud', "", %tag, %index, 'Suicides: %1', $Data::Suicides[%arg1.guid]); + %index++; + messageClient( %client, 'SetLineHud', "", %tag, %index, 'Ratio: %1',$Data::Deaths[%arg1.guid] / $Data::Kills[%arg1.guid]); + %index++; + messageClient( %client, 'SetLineHud', "", %tag, %index, ""); + %index++; + messageClient( %client, 'SetLineHud', "", %tag, %index, ""); + %index++; + messageClient( %client, 'SetLineHud', "", %tag, %index, 'Flag Running---'); + %index++; + messageClient( %client, 'SetLineHud', "", %tag, %index, 'Flags Captured: %1', $Data::Caps[%arg1.guid]); + %index++; + messageClient( %client, 'SetLineHud', "", %tag, %index, 'Flags Returned: %1', $Data::FlagReturns[%arg1.guid]); + %index++; + messageClient( %client, 'SetLineHud', "", %tag, %index, ""); + %index++; + messageClient( %client, 'SetLineHud', "", %tag, %index, ""); + %index++; + messageClient( %client, 'SetLineHud', "", %tag, %index, 'Win/Loss Ratio---'); + %index++; + messageClient( %client, 'SetLineHud', "", %tag, %index, 'Games Won: %1', $Data::Won[%arg1.guid]); + %index++; + messageClient( %client, 'SetLineHud', "", %tag, %index, 'Games Lost: %1', $Data::Lost[%arg1.guid]); + %index++; + messageClient( %client, 'SetLineHud', "", %tag, %index, "Back To Score Menu"); + } + else //Then we clicked 'back' or something else happened. + { + messageClient( %client, 'ClearHud', "", 'scoreScreen', 0 ); + %client.isViewingStatistics = false; + //CTFGame:updateScoreHud:(%game,%client,'scoreHud'); + Game.updateScoreHud(%game,%client,'scoreHud'); + } +} + +//------------------------------------------------------------------------------ +$ScoreHudMaxVisible = 19; +function DefaultGame::updateScoreHud(%game, %client, %tag) +{ + +if (%client.isViewingStatistics) +return; + + if (Game.numTeams > 1) + { + // Send header: + messageClient( %client, 'SetScoreHudHeader', "", '\t%1%2\t%3%4', + %game.getTeamName(1), $TeamScore[1], %game.getTeamName(2), $TeamScore[2] ); + + // Send subheader: + messageClient( %client, 'SetScoreHudSubheader', "", '\tPLAYERS (%1)SCORE\tPLAYERS (%2)SCORE', + $TeamRank[1, count], $TeamRank[2, count] ); + + %index = 0; + while ( true ) + { + if ( %index >= $TeamRank[1, count]+2 && %index >= $TeamRank[2, count]+2 ) + break; + + //get the team1 client info + %team1Client = ""; + %team1ClientScore = ""; + %col1Style = ""; + if ( %index < $TeamRank[1, count] ) + { + %team1Client = $TeamRank[1, %index]; + %team1ClientScore = %team1Client.score $= "" ? 0 : %team1Client.score; + %col1Style = %team1Client == %client ? "" : ""; + %team1playersTotalScore += %team1Client.score; + } + else if( %index == $teamRank[1, count] && $teamRank[1, count] != 0 && %game.class $= "CTFGame") // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + { + %team1ClientScore = "--------------"; + } + else if( %index == $teamRank[1, count]+1 && $teamRank[1, count] != 0 && %game.class $= "CTFGame") // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + { + %team1ClientScore = %team1playersTotalScore != 0 ? %team1playersTotalScore : 0; + } + //get the team2 client info + %team2Client = ""; + %team2ClientScore = ""; + %col2Style = ""; + if ( %index < $TeamRank[2, count] ) + { + %team2Client = $TeamRank[2, %index]; + %team2ClientScore = %team2Client.score $= "" ? 0 : %team2Client.score; + %col2Style = %team2Client == %client ? "" : ""; + %team2playersTotalScore += %team2Client.score; + } + else if( %index == $teamRank[2, count] && $teamRank[2, count] != 0 && %game.class $= "CTFGame") // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + { + %team2ClientScore = "--------------"; + } + else if( %index == $teamRank[2, count]+1 && $teamRank[2, count] != 0 && %game.class $= "CTFGame") // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + { + %team2ClientScore = %team2playersTotalScore != 0 ? %team2playersTotalScore : 0; + } + + //if the client is not an observer, send the message + if (%client.team != 0) + { + messageClient( %client, 'SetLineHud', "", %tag, %index, '\t%5%1%2\t%6%3%4', + %team1Client.name, %team1ClientScore, %team2Client.name, %team2ClientScore, %col1Style, %col2Style, %team1Client, %team2Client ); + } + //else for observers, create an anchor around the player name so they can be observed + else + { + messageClient( %client, 'SetLineHud', "", %tag, %index, '\t%5%1%2\t%6%3%4', + %team1Client.name, %team1ClientScore, %team2Client.name, %team2ClientScore, %col1Style, %col2Style, %team1Client, %team2Client ); + } + + %index++; + } + } + else + { + //tricky stuff here... use two columns if we have more than 15 clients... + %numClients = $TeamRank[0, count]; + if ( %numClients > $ScoreHudMaxVisible ) + %numColumns = 2; + + // Clear header: + messageClient( %client, 'SetScoreHudHeader', "", "" ); + + // Send header: + if (%numColumns == 2) + messageClient(%client, 'SetScoreHudSubheader', "", '\tPLAYERSCORE\tPLAYERSCORE'); + else + messageClient(%client, 'SetScoreHudSubheader', "", '\tPLAYERSCORE'); + + %countMax = %numClients; + if ( %countMax > ( 2 * $ScoreHudMaxVisible ) ) + { + if ( %countMax & 1 ) + %countMax++; + %countMax = %countMax / 2; + } + else if ( %countMax > $ScoreHudMaxVisible ) + %countMax = $ScoreHudMaxVisible; + + for ( %index = 0; %index < %countMax; %index++ ) + { + //get the client info + %col1Client = $TeamRank[0, %index]; + %col1ClientScore = %col1Client.score $= "" ? 0 : %col1Client.score; + %col1Style = %col1Client == %client ? "" : ""; + + //see if we have two columns + if ( %numColumns == 2 ) + { + %col2Client = ""; + %col2ClientScore = ""; + %col2Style = ""; + + //get the column 2 client info + %col2Index = %index + %countMax; + if ( %col2Index < %numClients ) + { + %col2Client = $TeamRank[0, %col2Index]; + %col2ClientScore = %col2Client.score $= "" ? 0 : %col2Client.score; + %col2Style = %col2Client == %client ? "" : ""; + } + } + + //if the client is not an observer, send the message + if (%client.team != 0) + { + messageClient( %client, 'SetLineHud', "", %tag, %index, '\t%5%1%2\t%6%3%4', + "" @ getTaggedString(%team1Client.name) @ "", %team1ClientScore, "" @ getTaggedString(%team2Client.name) @ "", %team2ClientScore, %col1Style, %col2Style ); + } + //else for observers, create an anchor around the player name so they can be observed + else + { + messageClient( %client, 'SetLineHud', "", %tag, %index, '\t%5%1%2\t%6%3%4', + %team1Client.name, %team1ClientScore, %team2Client.name, %team2ClientScore, %col1Style, %col2Style, %team1Client, %team2Client ); + } + + } + + } + + // Tack on the list of observers: + %observerCount = 0; + for (%i = 0; %i < ClientGroup.getCount(); %i++) + { + %cl = ClientGroup.getObject(%i); + if (%cl.team == 0) + %observerCount++; + } + + if (%observerCount > 0) + { + messageClient( %client, 'SetLineHud', "", %tag, %index, ""); + %index++; + messageClient(%client, 'SetLineHud', "", %tag, %index, '\tOBSERVERS (%1)TIME', %observerCount); + %index++; + for (%i = 0; %i < ClientGroup.getCount(); %i++) + { + %cl = ClientGroup.getObject(%i); + //if this is an observer + if (%cl.team == 0) + { + %obsTime = getSimTime() - %cl.observerStartTime; + %obsTimeStr = %game.formatTime(%obsTime, false); + messageClient( %client, 'SetLineHud', "", %tag, %index, '\t%1%2', + %cl.name, %obsTimeStr ); + %index++; + } + } + } + + //clear the rest of Hud so we don't get old lines hanging around... + messageClient( %client, 'ClearHud', "", %tag, %index ); +} + +//------------------------------------------------------------------------------ +function UpdateClientTimes(%time) +{ + %secondsLeft = %time / 1000; + messageAll('MsgSystemClock', "", (%secondsLeft / 60), %time); +} + +//------------------------------------------------------------------------------ +function notifyMatchStart(%time) +{ + %seconds = mFloor(%time / 1000); + if (%seconds > 2) + MessageAll('MsgMissionStart', '\c2Match starts in %1 seconds.~wfx/misc/hunters_%1.wav', %seconds); + else if (%seconds == 2) + MessageAll('MsgMissionStart', '\c2Match starts in 2 seconds.~wvoice/announcer/ann.match_begins.wav'); + else if (%seconds == 1) + MessageAll('MsgMissionStart', '\c2Match starts in 1 second.'); + UpdateClientTimes(%time); +} + +//------------------------------------------------------------------------------ +function notifyMatchEnd(%time) +{ + %seconds = mFloor(%time / 1000); + if (%seconds > 1) + MessageAll('MsgMissionEnd', '\c2Match ends in %1 seconds.~wfx/misc/hunters_%1.wav', %seconds); + else if (%seconds == 1) + MessageAll('MsgMissionEnd', '\c2Match ends in 1 second.~wfx/misc/hunters_1.wav'); + UpdateClientTimes(%time); +} + +function DefaultGame::formatTime(%game, %tStr, %includeHundredths) +{ + %timeInSeconds = %tStr / 1000; + %mins = mFloor(%timeInSeconds / 60); + if(%mins < 1) + %timeString = "00:"; + else if(%mins < 10) + %timeString = "0" @ %mins @ ":"; + else + %timeString = %mins @ ":"; + + %timeInSeconds -= (%mins * 60); + %secs = mFloor(%timeInSeconds); + if(%secs < 1) + %timeString = %timeString @ "00"; + else if(%secs < 10) + %timeString = %timeString @ "0" @ %secs; + else + %timeString = %timeString @ %secs; + + if (%includeHundredths) + { + %timeString = %timeString @ "."; + %timeInSeconds -= %secs; + %hSecs = mFloor(%timeInSeconds * 100); // will be between 0 and 999 + if(%hSecs < 1) + %timeString = %timeString @ "00"; + else if(%hSecs < 10) + %timeString = %timeString @ "0" @ %hSecs; + else + %timeString = %timeString @ %hSecs; + } + + return %timeString; +} + +//------------------------------------------------------------------------------ +//AI FUNCTIONS +function DefaultGame::AIChooseGameObjective(%game, %client) +{ + AIChooseObjective(%client); +} + +//------------------------------------------------------------------------------ +function DefaultGame::getServerStatusString(%game) +{ + %status = %game.numTeams; + for ( %team = 1; %team - 1 < %game.numTeams; %team++ ) + { + %score = isObject( $teamScore[%team] ) ? $teamScore[%team] : 0; + %teamStr = getTaggedString( %game.getTeamName(%team) ) TAB %score; + %status = %status NL %teamStr; + } + + %status = %status NL ClientGroup.getCount(); + for ( %i = 0; %i < ClientGroup.getCount(); %i++ ) + { + %cl = ClientGroup.getObject( %i ); + %score = %cl.score $= "" ? 0 : %cl.score; + %playerStr = getTaggedString( %cl.name ) TAB getTaggedString( %game.getTeamName(%cl.team) ) TAB %score; + %status = %status NL %playerStr; + } + return( %status ); +} + +//------------------------------------------------------------------------------ +function DefaultGame::OptionsDlgSleep( %game ) +{ + // ignore in the default game... +} + +//------------------------------------------------------------------------------ +function DefaultGame::endMission( %game ) +{ +} + +//------------------------------------------------------------------------------ +// z0dd - ZOD. Console spam fix +function DefaultGame::countFlips(%game) +{ + return false; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Random Teams code by Founder (founder@mechina.com) 6/22/02 /////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// + +function DefaultGame::setupClientTeams(%game) +{ + if(!$Host::ClassicRandomizeTeams || %game.numTeams == 1) + { + %count = ClientGroup.getCount(); + for (%i = 0; %i < %count; %i++) + { + %client = ClientGroup.getObject(%i); + %client.lastTeam = %client.team; + %client.setupTeam = 0; + } + return; + } + else + { + %numTeamPlayers = 0; + %totalNumPlayers = ClientGroup.getCount(); + for(%i = 0; %i < %totalNumPlayers; %i++) + { + %cl = ClientGroup.getObject(%i); + if(%cl.team == 0) + %cl.lastTeam = %cl.team; + else + { + %teamPlayer[%numTeamPlayers] = %cl; + %numTeamPlayers++; + } + } + %numPlayersLeft = %numTeamPlayers - 1; + for(%j = 0; %j < %numTeamPlayers; %j++) + { + if(%numPlayersLeft > 0) + { + %r = 0; + %val = mFloor(getRandom(0, %numPlayersLeft)); + if(%val > %numPlayersLeft) + %val = %numPlayersLeft; + + %client = %teamPlayer[%val]; + %shuffledPlayersArray[%j] = %client; + for(%y = 0; %y <= %numPlayersLeft; %y++) + { + %clplyr = %teamPlayer[%y]; + if(%clplyr != %client) + { + %teamPlayer[%r] = %clplyr; + %r++; + } + } + %numPlayersLeft--; + } + else + %shuffledPlayersArray[%j] = %teamPlayer[%numPlayersLeft]; + } + %thisTeam = 1; + for(%k = 0; %k <= %numTeamPlayers; %k++) + { + if(%thisTeam == 1) + { + %shuffledPlayersArray[%k].lastTeam = 1; + %thisTeam = 0; + } + else + { + %shuffledPlayersArray[%k].lastTeam = 2; + %thisTeam = 1; + } + } + } +} diff --git a/scripts/deployables.cs b/scripts/deployables.cs index 05dd689..5d912a3 100644 --- a/scripts/deployables.cs +++ b/scripts/deployables.cs @@ -1,1440 +1,1440 @@ -// deployable objects script -// -// remote pulse sensor, remote motion sensor, remote turrets (indoor -// and outdoor), remote inventory station, remote ammo station -// Note: cameras are treated as grenades, not "regular" deployables - -$TurretIndoorSpaceRadius = 18; // deployed turrets must be this many meters apart // z0dd - ZOD, 8/14/02. Was 20 -$InventorySpaceRadius = 10; // deployed inventory must be this many meters apart // z0dd - ZOD, 8/14/02. Was 20 -$TurretIndoorSphereRadius = 50; // radius for turret frequency check -$TurretIndoorMaxPerSphere = 5; // # of turrets allowed in above radius // z0dd - ZOD, 8/14/02. Was 4 - -$TurretOutdoorSpaceRadius = 20; // deployed turrets must be this many meters apart // z0dd - ZOD, 8/14/02. Was 25 -$TurretOutdoorSphereRadius = 60; // radius for turret frequency check -$TurretOutdoorMaxPerSphere = 5; // # of turrets allowed in above radius // z0dd - ZOD, 8/14/02. Was 4 - -$TeamDeployableMax[InventoryDeployable] = 5; -$TeamDeployableMax[TurretIndoorDeployable] = 10; -$TeamDeployableMax[TurretOutdoorDeployable] = 10; -$TeamDeployableMax[PulseSensorDeployable] = 15; -$TeamDeployableMax[MotionSensorDeployable] = 15; - -$TeamDeployableMin[TurretIndoorDeployable] = 4; -$TeamDeployableMin[TurretOutdoorDeployable] = 4; - -$NotDeployableReason::None = 0; -$NotDeployableReason::MaxDeployed = 1; -$NotDeployableReason::NoSurfaceFound = 2; -$NotDeployableReason::SlopeTooGreat = 3; -$NotDeployableReason::SelfTooClose = 4; -$NotDeployableReason::ObjectTooClose = 5; -$NotDeployableReason::NoTerrainFound = 6; -$NotDeployableReason::NoInteriorFound = 7; -$NotDeployableReason::TurretTooClose = 8; -$NotDeployableReason::TurretSaturation = 9; -$NotDeployableReason::SurfaceTooNarrow = 10; -$NotDeployableReason::InventoryTooClose = 11; -//$NotDeployableReason::OrganicTooClose = 12; // z0dd - ZOD, 4/18/02. Address deploy of objects inside other objects. - -$MinDeployableDistance = 2.5; -$MaxDeployableDistance = 5.0; //meters from body - -// -------------------------------------------- -// effect datablocks -// -------------------------------------------- - -datablock EffectProfile(TurretDeployEffect) -{ - effectname = "packs/generic_deploy"; - minDistance = 2.5; - maxDistance = 5.0; -}; - -datablock EffectProfile(SensorDeployEffect) -{ - effectname = "powered/sensor_activate"; - minDistance = 2.5; - maxDistance = 5.0; -}; - -datablock EffectProfile(MotionSensorDeployEffect) -{ - effectname = "powered/motion_sensor_activate"; - minDistance = 2.5; - maxDistance = 5.0; -}; - -datablock EffectProfile(StationDeployEffect) -{ - effectname = "packs/inventory_deploy"; - minDistance = 2.5; - maxDistance = 5.0; -}; - -// -------------------------------------------- -// sound datablocks -// -------------------------------------------- - -datablock AudioProfile(TurretDeploySound) -{ - fileName = "fx/packs/turret_place.wav"; - description = AudioClose3d; - preload = true; - effect = TurretDeployEffect; -}; - -datablock AudioProfile(SensorDeploySound) -{ - fileName = "fx/powered/sensor_activate.wav"; - description = AudioClose3d; - preload = true; - effect = SensorDeployEffect; - //effect = MotionSensorDeployEffect; // z0dd - ZOD 6/21/02. From Durt, wrong place -}; - -datablock AudioProfile(MotionSensorDeploySound) -{ - fileName = "fx/powered/motion_sensor_activate.wav"; - description = AudioClose3d; - preload = true; - effect = MotionSensorDeployEffect; // z0dd - ZOD 6/21/02. Was in wrong place -}; - -datablock AudioProfile(StationDeploySound) -{ - fileName = "fx/packs/inventory_deploy.wav"; - description = AudioClose3d; - preload = true; - effect = StationDeployEffect; -}; - -// -------------------------------------------- -// deployable debris definition - -datablock DebrisData( DeployableDebris ) -{ - explodeOnMaxBounce = false; - - elasticity = 0.40; - friction = 0.5; - - lifetime = 17.0; - lifetimeVariance = 0.0; - - minSpinSpeed = 60; - maxSpinSpeed = 600; - - numBounces = 10; - bounceVariance = 0; - - staticOnMaxBounce = true; - - useRadiusMass = true; - baseRadius = 0.2; - - velocity = 5.0; - velocityVariance = 2.5; - -}; - - -// -------------------------------------------- -// deployable inventory station - -datablock StaticShapeData(DeployedStationInventory) : StaticShapeDamageProfile -{ - className = Station; - shapeFile = "deploy_inventory.dts"; - maxDamage = 0.70; - destroyedLevel = 0.70; - disabledLevel = 0.42; - explosion = DeployablesExplosion; - expDmgRadius = 8.0; - expDamage = 0.35; - expImpulse = 500.0; - - dynamicType = $TypeMasks::StationObjectType; - isShielded = true; - energyPerDamagePoint = 110; - maxEnergy = 50; - rechargeRate = 0.20; - renderWhenDestroyed = false; - doesRepair = true; - - deployedObject = true; - - cmdCategory = "DSupport"; - cmdIcon = CMDStationIcon; - cmdMiniIconName = "commander/MiniIcons/com_inventory_grey"; - targetNameTag = 'Deployable'; - targetTypeTag = 'Station'; - - debrisShapeName = "debris_generic_small.dts"; - debris = DeployableDebris; - heatSignature = 0; -}; - -datablock ShapeBaseImageData(InventoryDeployableImage) -{ - mass = 12; // z0dd - ZOD, 7/17/02. large packs are too heavy enough with new physics. was 15 - emap = true; - - shapeFile = "pack_deploy_inventory.dts"; - item = InventoryDeployable; - mountPoint = 1; - offset = "0 0 0"; - deployed = DeployedStationInventory; - heatSignature = 0; - - stateName[0] = "Idle"; - stateTransitionOnTriggerDown[0] = "Activate"; - - stateName[1] = "Activate"; - stateScript[1] = "onActivate"; - stateTransitionOnTriggerUp[1] = "Idle"; - - isLarge = true; - maxDepSlope = 30; - deploySound = StationDeploySound; - - flatMinDeployDis = 1.0; - flatMaxDeployDis = 5.0; - - minDeployDis = 2.5; - maxDeployDis = 5.0; -}; - -datablock ItemData(InventoryDeployable) -{ - className = Pack; - catagory = "Deployables"; - shapeFile = "pack_deploy_inventory.dts"; - mass = 3.0; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 1; - rotate = false; - image = "InventoryDeployableImage"; - pickUpName = "an inventory pack"; - heatSignature = 0; - - computeCRC = true; - emap = true; - -}; - -// -------------------------------------------- -// deployable motion sensor - -datablock SensorData(DeployMotionSensorObj) -{ - detects = true; - detectsUsingLOS = true; - detectsActiveJammed = false; - detectsPassiveJammed = true; - detectsCloaked = true; - detectionPings = false; - detectMinVelocity = 2; - detectRadius = 60; -}; - -datablock StaticShapeData(DeployedMotionSensor) : StaticShapeDamageProfile -{ - className = Sensor; - shapeFile = "deploy_sensor_motion.dts"; - maxDamage = 0.6; - destroyedLevel = 0.6; - disabledLevel = 0.4; - explosion = DeployablesExplosion; - dynamicType = $TypeMasks::SensorObjectType; - - deployedObject = true; - - cmdCategory = "DSupport"; - cmdIcon = CMDSensorIcon; - cmdMiniIconName = "commander/MiniIcons/com_deploymotionsensor"; - targetNameTag = 'Deployable Motion'; - targetTypeTag = 'Sensor'; - sensorData = DeployMotionSensorObj; - sensorRadius = DeployMotionSensorObj.detectRadius; - sensorColor = "9 136 255"; - deployAmbientThread = true; - - debrisShapeName = "debris_generic_small.dts"; - debris = DeployableDebris; - heatSignature = 0; -}; - -datablock ShapeBaseImageData(MotionSensorDeployableImage) -{ - shapeFile = "pack_deploy_sensor_motion.dts"; - item = MotionSensorDeployable; - mountPoint = 1; - offset = "0 0 0"; - deployed = DeployedMotionSensor; - - stateName[0] = "Idle"; - stateTransitionOnTriggerDown[0] = "Activate"; - - stateName[1] = "Activate"; - stateScript[1] = "onActivate"; - stateTransitionOnTriggerUp[1] = "Idle"; - - maxDepSlope = 360; - deploySound = MotionSensorDeploySound; - emap = true; - heatSignature = 1; - - minDeployDis = 0.5; - maxDeployDis = 5.0; //meters from body -}; - -datablock ItemData(MotionSensorDeployable) -{ - className = Pack; - catagory = "Deployables"; - shapeFile = "pack_deploy_sensor_motion.dts"; - mass = 2.0; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 1; - rotate = false; - image = "MotionSensorDeployableImage"; - pickUpName = "a motion sensor pack"; - - computeCRC = true; - emap = true; - heatSignature = 0; - - //maxSensors = 3; - maxSensors = 2; -}; - -// -------------------------------------------- -// deployable pulse sensor - -datablock SensorData(DeployPulseSensorObj) -{ - detects = true; - detectsUsingLOS = true; - detectsPassiveJammed = false; - detectsCloaked = false; - detectionPings = true; - detectRadius = 175; // z0dd - ZOD, 8/15/02. Was 150 -}; - -datablock StaticShapeData(DeployedPulseSensor) : StaticShapeDamageProfile -{ - className = Sensor; - shapeFile = "deploy_sensor_pulse.dts"; - maxDamage = 0.6; - destroyedLevel = 0.6; - disabledLevel = 0.4; - explosion = DeployablesExplosion; - dynamicType = $TypeMasks::SensorObjectType; - - deployedObject = true; - - cmdCategory = "DSupport"; - cmdIcon = CMDSensorIcon; - cmdMiniIconName = "commander/MiniIcons/com_deploypulsesensor"; - targetNameTag = 'Deployable'; - targetTypeTag = 'Pulse Sensor'; - sensorData = DeployPulseSensorObj; - sensorRadius = DeployPulseSensorObj.detectRadius; - sensorColor = "255 194 9"; - deployAmbientThread = true; - - debrisShapeName = "debris_generic_small.dts"; - debris = DeployableDebris; - heatSignature = 0; -}; - -datablock ShapeBaseImageData(PulseSensorDeployableImage) -{ - shapeFile = "pack_deploy_sensor_pulse.dts"; - item = PulseSensorDeployable; - mountPoint = 1; - offset = "0 0 0"; - deployed = DeployedPulseSensor; - - stateName[0] = "Idle"; - stateTransitionOnTriggerDown[0] = "Activate"; - - stateName[1] = "Activate"; - stateScript[1] = "onActivate"; - stateTransitionOnTriggerUp[1] = "Idle"; - deploySound = SensorDeploySound; - - maxDepSlope = 40; - emap = true; - heatSignature = 0; - - minDeployDis = 0.5; - maxDeployDis = 5.0; //meters from body -}; - -datablock ItemData(PulseSensorDeployable) -{ - className = Pack; - catagory = "Deployables"; - shapeFile = "pack_deploy_sensor_pulse.dts"; - mass = 2.0; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 1; - rotate = false; - image = "PulseSensorDeployableImage"; - pickUpName = "a pulse sensor pack"; - - computeCRC = true; - emap = true; - - maxSensors = 2; -}; - -// -------------------------------------------- -// deployable outdoor turret - -datablock ShapeBaseImageData(TurretOutdoorDeployableImage) -{ - mass = 10; - - shapeFile = "pack_deploy_turreto.dts"; - item = TurretOutdoorDeployable; - mountPoint = 1; - offset = "0 0 0"; - deployed = TurretDeployedOutdoor; - - stateName[0] = "Idle"; - stateTransitionOnTriggerDown[0] = "Activate"; - - stateName[1] = "Activate"; - stateScript[1] = "onActivate"; - stateTransitionOnTriggerUp[1] = "Idle"; - - maxDamage = 4.5; - destroyedLevel = 4.5; - disabledLevel = 4.0; - - isLarge = true; - emap = true; - - maxDepSlope = 40; - deploySound = TurretDeploySound; - - minDeployDis = 0.5; - maxDeployDis = 5.0; //meters from body -}; - -datablock ItemData(TurretOutdoorDeployable) -{ - className = Pack; - catagory = "Deployables"; - shapeFile = "pack_deploy_turreto.dts"; - mass = 3.0; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 1; - rotate = false; - image = "TurretOutdoorDeployableImage"; - pickUpName = "a landspike turret pack"; - - computeCRC = true; - emap = true; - -}; - -// -------------------------------------------- -// deployable indoor turret (3 varieties -- floor, wall and ceiling) - -datablock ShapeBaseImageData(TurretIndoorDeployableImage) -{ - mass = 10; - - shapeFile = "pack_deploy_turreti.dts"; - item = TurretIndoorDeployable; - mountPoint = 1; - offset = "0 0 0"; - - stateName[0] = "Idle"; - stateTransitionOnTriggerDown[0] = "Activate"; - - stateName[1] = "Activate"; - stateScript[1] = "onActivate"; - stateTransitionOnTriggerUp[1] = "Idle"; - - isLarge = true; - emap = true; - - maxDepSlope = 360; - deploySound = TurretDeploySound; - - minDeployDis = 0.5; - maxDeployDis = 5.0; //meters from body -}; - -datablock ItemData(TurretIndoorDeployable) -{ - className = Pack; - catagory = "Deployables"; - shapeFile = "pack_deploy_turreti.dts"; - mass = 3.0; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 1; - rotate = false; - image = "TurretIndoorDeployableImage"; - pickUpName = "a spider clamp turret pack"; - - computeCRC = true; - emap = true; - -}; - -// -------------------------------------------- -// miscellaneous yet handy functions - -function posFromTransform(%transform) -{ - // the first three words of an object's transform are the object's position - %position = getWord(%transform, 0) @ " " @ getWord(%transform, 1) @ " " @ getWord(%transform, 2); - return %position; -} - -function rotFromTransform(%transform) -{ - // the last four words of an object's transform are the object's rotation - %rotation = getWord(%transform, 3) @ " " @ getWord(%transform, 4) @ " " @ getWord(%transform, 5) @ " " @ getWord(%transform, 6); - return %rotation; -} - -function posFromRaycast(%transform) -{ - // the 2nd, 3rd, and 4th words returned from a successful raycast call are the position of the point - %position = getWord(%transform, 1) @ " " @ getWord(%transform, 2) @ " " @ getWord(%transform, 3); - return %position; -} - -function normalFromRaycast(%transform) -{ - // the 5th, 6th and 7th words returned from a successful raycast call are the normal of the surface - %norm = getWord(%transform, 4) @ " " @ getWord(%transform, 5) @ " " @ getWord(%transform, 6); - return %norm; -} - -function addToDeployGroup(%object) -{ - // all deployables should go into a special group for AI purposes - %depGroup = nameToID("MissionCleanup/Deployables"); - if(%depGroup <= 0) { - %depGroup = new SimGroup("Deployables"); - MissionCleanup.add(%depGroup); - } - %depGroup.add(%object); -} - -function Deployables::searchView(%obj, %searchRange, %mask) -{ - // get the eye vector and eye transform of the player - %eyeVec = %obj.getEyeVector(); - %eyeTrans = %obj.getEyeTransform(); - - // extract the position of the player's camera from the eye transform (first 3 words) - %eyePos = posFromTransform(%eyeTrans); - - // normalize the eye vector - %nEyeVec = VectorNormalize(%eyeVec); - - // scale (lengthen) the normalized eye vector according to the search range - %scEyeVec = VectorScale(%nEyeVec, %searchRange); - - // 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, 0); - - return %searchResult; -} - -//-----------------------// -// Deployable Procedures // -//-----------------------// - -//------------------------------------------------- -function ShapeBaseImageData::testMaxDeployed(%item, %plyr) -{ - if(%item.item $= TurretOutdoorDeployable || %item.item $= TurretIndoorDeployable) - %itemCount = countTurretsAllowed(%item.item); - else - %itemCount = $TeamDeployableMax[%item.item]; - - return $TeamDeployedCount[%plyr.team, %item.item] >= %itemCount; -} - -//------------------------------------------------- -function ShapeBaseImageData::testNoSurfaceInRange(%item, %plyr) -{ - return ! Deployables::searchView(%plyr, $MaxDeployDistance, $TypeMasks::TerrainObjectType | $TypeMasks::InteriorObjectType); -} - -//------------------------------------------------- -function ShapeBaseImageData::testSlopeTooGreat(%item) -{ - if (%item.surface) - { - return getTerrainAngle(%item.surfaceNrm) > %item.maxDepSlope; - } -} - -//------------------------------------------------- -function ShapeBaseImageData::testSelfTooClose(%item, %plyr) -{ - InitContainerRadiusSearch(%item.surfacePt, $MinDeployDistance, $TypeMasks::PlayerObjectType); - - return containerSearchNext() == %plyr; -} - -//------------------------------------------------------------------------------------ -// z0dd - ZOD - BadShot - Founder, 6/24/02. Address deploying of objects inside other -// objects. New function. -//function ShapeBaseImageData::testOrganicTooClose(%item, %plyr) -//{ -// InitContainerRadiusSearch( %item.surfacePt, $MaxDeployableDistance, $TypeMasks::StaticTSObjectType ); -// %test = containerSearchNext(); -// if(%test) -// { -// for (%i = 0; %i < $NumStaticTSObjects; %i++) -// { -// if(getWord($StaticTSObjects[%i], 2) $= %test.shapeName) -// { -// %organicIndex = %i; -// break; -// } -// } -// if(getWord($StaticTSObjects[%organicIndex], 0) $= Organics) -// { -// %scale1 = getWord(%test.scale, 1); -// %scale2 = getWord(%test.scale, 2); -// %maxDist1 = %scale1 > 1 ? 3.2 * %scale1 : ""; -// %maxDist2 = %scale2 > 1 ? 3.2 * %scale2 : ""; -// %maxDist = %maxDist1 >= %maxDist2 ? %maxDist1 : %maxDist2; -// %maxDist = %maxDist $= "" ? 3.2 : %maxDist; -// %distance = VectorDist(getWords(%item.surfacePt, 0, 1) SPC 0, getWords(%test.getWorldBoxCenter(), 0, 1) SPC 0); -// if (%distance <= %maxDist) -// return %test; -// else -// return false; -// } -// else -// return false; -// } -// else -// return false; -//} -//------------------------------------------------------------------------------------ - -function ShapeBaseImageData::testObjectTooClose(%item) -{ - %mask = ($TypeMasks::VehicleObjectType | $TypeMasks::MoveableObjectType | - $TypeMasks::StaticShapeObjectType | - $TypeMasks::ForceFieldObjectType | $TypeMasks::ItemObjectType | - $TypeMasks::PlayerObjectType | $TypeMasks::TurretObjectType); - - InitContainerRadiusSearch( %item.surfacePt, $MinDeployDistance, %mask ); - - %test = containerSearchNext(); - return %test; -} - - -//------------------------------------------------- -function TurretOutdoorDeployableImage::testNoTerrainFound(%item) -{ - return %item.surface.getClassName() !$= TerrainBlock; -} - -function ShapeBaseImageData::testNoTerrainFound(%item, %surface) -{ - //don't check this for non-Landspike turret deployables -} - -//------------------------------------------------- -function TurretIndoorDeployableImage::testNoInteriorFound(%item) -{ - return %item.surface.getClassName() !$= InteriorInstance; -} - -function ShapeBaseImageData::testNoInteriorFound(%item, %surface) -{ - //don't check this for non-Clasping turret deployables -} - -//------------------------------------------------- -function TurretIndoorDeployableImage::testHavePurchase(%item, %xform) -{ - %footprintRadius = 0.34; - %collMask = $TypeMasks::InteriorObjectType; - return %item.deployed.checkDeployPurchase(%xform, %footprintRadius, %collMask); -} - -function ShapeBaseImageData::testHavePurchase(%item, %xform) -{ - //don't check this for non-Clasping turret deployables - return true; -} - -//------------------------------------------------- -function ShapeBaseImageData::testInventoryTooClose(%item, %plyr) -{ - return false; -} - -function InventoryDeployableImage::testInventoryTooClose(%item, %plyr) -{ - InitContainerRadiusSearch(%item.surfacePt, $InventorySpaceRadius, $TypeMasks::StaticShapeObjectType); - - // old function was only checking whether the first object found was a turret -- also wasn't checking - // which team the object was on - %turretInRange = false; - while((%found = containerSearchNext()) != 0) - { - %foundName = %found.getDataBlock().getName(); - if( (%foundName $= DeployedStationInventory) ) - if (%found.team == %plyr.team) - { - %turretInRange = true; - break; - } - } - return %turretInRange; -} - -function TurretIndoorDeployableImage::testTurretTooClose(%item, %plyr) -{ - InitContainerRadiusSearch(%item.surfacePt, $TurretIndoorSpaceRadius, $TypeMasks::StaticShapeObjectType); - - // old function was only checking whether the first object found was a turret -- also wasn't checking - // which team the object was on - %turretInRange = false; - while((%found = containerSearchNext()) != 0) - { - %foundName = %found.getDataBlock().getName(); - if((%foundname $= TurretDeployedFloorIndoor) || (%foundName $= TurretDeployedWallIndoor) || (%foundName $= TurretDeployedCeilingIndoor) || (%foundName $= TurretDeployedOutdoor) ) - if (%found.team == %plyr.team) - { - %turretInRange = true; - break; - } - } - return %turretInRange; -} - -function TurretOutdoorDeployableImage::testTurretTooClose(%item, %plyr) -{ - InitContainerRadiusSearch(%item.surfacePt, $TurretOutdoorSpaceRadius, $TypeMasks::StaticShapeObjectType); - - // old function was only checking whether the first object found was a turret -- also wasn't checking - // which team the object was on - %turretInRange = false; - while((%found = containerSearchNext()) != 0) - { - %foundName = %found.getDataBlock().getName(); - if((%foundname $= TurretDeployedFloorIndoor) || (%foundName $= TurretDeployedWallIndoor) || (%foundName $= TurretDeployedCeilingIndoor) || (%foundName $= TurretDeployedOutdoor) ) - if (%found.team == %plyr.team) - { - %turretInRange = true; - break; - } - } - return %turretInRange; -} - -function ShapeBaseImageData::testTurretTooClose(%item, %plyr) -{ - //don't check this for non-turret deployables -} - -//------------------------------------------------- -function TurretIndoorDeployableImage::testTurretSaturation(%item) -{ - %highestDensity = 0; - InitContainerRadiusSearch(%item.surfacePt, $TurretIndoorSphereRadius, $TypeMasks::StaticShapeObjectType); - %found = containerSearchNext(); - while(%found) - { - %foundName = %found.getDataBlock().getName(); - if((%foundname $= TurretDeployedFloorIndoor) || (%foundName $= TurretDeployedWallIndoor) || (%foundName $= TurretDeployedCeilingIndoor) || (%foundName $= TurretDeployedOutdoor) ) - { - //found one - %numTurretsNearby++; - - %nearbyDensity = testNearbyDensity(%found, $TurretIndoorSphereRadius); - if (%nearbyDensity > %highestDensity) - %highestDensity = %nearbyDensity; - } - %found = containerSearchNext(); - } - - if (%numTurretsNearby > %highestDensity) - %highestDensity = %numTurretsNearby; - return %highestDensity > $TurretIndoorMaxPerSphere; -} - -function TurretOutdoorDeployableImage::testTurretSaturation(%item) -{ - %highestDensity = 0; - InitContainerRadiusSearch(%item.surfacePt, $TurretOutdoorSphereRadius, $TypeMasks::StaticShapeObjectType); - %found = containerSearchNext(); - while(%found) - { - %foundName = %found.getDataBlock().getName(); - if((%foundname $= TurretDeployedFloorIndoor) || (%foundName $= TurretDeployedWallIndoor) || (%foundName $= TurretDeployedCeilingIndoor) || (%foundName $= TurretDeployedOutdoor) ) - { - //found one - %numTurretsNearby++; - - %nearbyDensity = testNearbyDensity(%found, $TurretOutdoorSphereRadius); - if (%nearbyDensity > %highestDensity) - %highestDensity = %nearbyDensity; - } - %found = containerSearchNext(); - } - - if (%numTurretsNearby > %highestDensity) - %highestDensity = %numTurretsNearby; - return %highestDensity > $TurretOutdoorMaxPerSphere; -} - -function ShapeBaseImageData::testTurretSaturation(%item, %surfacePt) -{ - //don't check this for non-turret deployables -} - -function testNearbyDensity(%item, %radius) -{ - //this checks how many turrets are in adjacent spheres in case placing a new one overloads them. - %surfacePt = posFromTransform(%item.getTransform()); - %turretCount = 0; - - InitContainerRadiusSearch(%surfacePt, %radius, $TypeMasks::StaticShapeObjectType); - %found = containerSearchNext(); - while(%found) - { - %foundName = %found.getDataBlock().getName(); - if((%foundname $= TurretDeployedFloorIndoor) || (%foundName $= TurretDeployedWallIndoor) || (%foundName $= TurretDeployedCeilingIndoor) || (%foundName $= TurretDeployedOutdoor) ) - %turretCount++; - %found = containerSearchNext(); - } - return %turretCount; -} - -//------------------------------------------------- -//if this function, or any of the included tests are changed, those changes need to be reflected in function: -//AIODeployEquipment::weight(%this, %client, %level), found in aiObjectives.cs --tinman -function ShapeBaseImageData::testInvalidDeployConditions(%item, %plyr, %slot) -{ - cancel(%plyr.deployCheckThread); - %disqualified = $NotDeployableReason::None; //default - $MaxDeployDistance = %item.maxDeployDis; - $MinDeployDistance = %item.minDeployDis; - - %surface = Deployables::searchView(%plyr, - $MaxDeployDistance, - ($TypeMasks::TerrainObjectType | - $TypeMasks::InteriorObjectType)); - if (%surface) - { - %surfacePt = posFromRaycast(%surface); - %surfaceNrm = normalFromRaycast(%surface); - - // Check that point to see if anything is objstructing it... - %eyeTrans = %plyr.getEyeTransform(); - %eyePos = posFromTransform(%eyeTrans); - - %searchResult = containerRayCast(%eyePos, %surfacePt, -1, %plyr); - if (!%searchResult) - { - %item.surface = %surface; - %item.surfacePt = %surfacePt; - %item.surfaceNrm = %surfaceNrm; - } - else - { - if(checkPositions(%surfacePT, posFromRaycast(%searchResult))) - { - %item.surface = %surface; - %item.surfacePt = %surfacePt; - %item.surfaceNrm = %surfaceNrm; - } - else - { - // Don't set the item - %disqualified = $NotDeployableReason::ObjectTooClose; - } - } - if(!getTerrainAngle(%surfaceNrm) && %item.flatMaxDeployDis !$= "") - { - $MaxDeployDistance = %item.flatMaxDeployDis; - $MinDeployDistance = %item.flatMinDeployDis; - } - } - - if (%item.testMaxDeployed(%plyr)) - { - %disqualified = $NotDeployableReason::MaxDeployed; - } - else if (%item.testNoSurfaceInRange(%plyr)) - { - %disqualified = $NotDeployableReason::NoSurfaceFound; - } - else if (%item.testNoTerrainFound(%surface)) - { - %disqualified = $NotDeployableReason::NoTerrainFound; - } - else if (%item.testNoInteriorFound()) - { - %disqualified = $NotDeployableReason::NoInteriorFound; - } - else if (%item.testSlopeTooGreat(%surface, %surfaceNrm)) - { - %disqualified = $NotDeployableReason::SlopeTooGreat; - } - else if (%item.testSelfTooClose(%plyr, %surfacePt)) - { - %disqualified = $NotDeployableReason::SelfTooClose; - } - else if (%item.testObjectTooClose(%surfacePt)) - { - %disqualified = $NotDeployableReason::ObjectTooClose; - } - else if (%item.testTurretTooClose(%plyr)) - { - %disqualified = $NotDeployableReason::TurretTooClose; - } - else if (%item.testInventoryTooClose(%plyr)) - { - %disqualified = $NotDeployableReason::InventoryTooClose; - } - else if (%item.testTurretSaturation()) - { - %disqualified = $NotDeployableReason::TurretSaturation; - } - //--------------------------------------------------------------------------------------- - // z0dd - ZOD, 4/18/02. Addresses the exploit of deploying objects inside other objects. -// else if (%item.testOrganicTooClose(%plyr)) -// { -// %disqualified = $NotDeployableReason::OrganicTooClose; -// } - //--------------------------------------------------------------------------------------- - else if (%disqualified == $NotDeployableReason::None) - { - // Test that there are no objstructing objects that this object - // will intersect with - // - %rot = %item.getInitialRotation(%plyr); - if(%item.deployed.className $= "DeployedTurret") - { - %xform = %item.deployed.getDeployTransform(%item.surfacePt, %item.surfaceNrm); - } - else - { - %xform = %surfacePt SPC %rot; - } - - if (!%item.deployed.checkDeployPos(%xform)) - { - %disqualified = $NotDeployableReason::ObjectTooClose; - } - else if (!%item.testHavePurchase(%xform)) - { - %disqualified = $NotDeployableReason::SurfaceTooNarrow; - } - } - - if (%plyr.getMountedImage($BackpackSlot) == %item) //player still have the item? - { - if (%disqualified) - activateDeploySensorRed(%plyr); - else - activateDeploySensorGrn(%plyr); - - if (%plyr.client.deployPack == true) - %item.attemptDeploy(%plyr, %slot, %disqualified); - else - { - %plyr.deployCheckThread = %item.schedule(25, "testInvalidDeployConditions", %plyr, %slot); //update checks every 50 milliseconds - } - } - else - deactivateDeploySensor(%plyr); -} - -function checkPositions(%pos1, %pos2) -{ - %passed = true; - if((mFloor(getWord(%pos1, 0)) - mFloor(getWord(%pos2,0)))) - %passed = false; - if((mFloor(getWord(%pos1, 1)) - mFloor(getWord(%pos2,1)))) - %passed = false; - if((mFloor(getWord(%pos1, 2)) - mFloor(getWord(%pos2,2)))) - %passed = false; - return %passed; -} - -function ShapeBaseImageData::attemptDeploy(%item, %plyr, %slot, %disqualified) -{ - deactivateDeploySensor(%plyr); - Deployables::displayErrorMsg(%item, %plyr, %slot, %disqualified); -} - -function activateDeploySensorRed(%pl) -{ - if(%pl.deploySensor !$= "red") - { - messageClient(%pl.client, 'msgDeploySensorRed', ""); - %pl.deploySensor = "red"; - } -} - -function activateDeploySensorGrn(%pl) -{ - if(%pl.deploySensor !$= "green") - { - messageClient(%pl.client, 'msgDeploySensorGrn', ""); - %pl.deploySensor = "green"; - } -} - -function deactivateDeploySensor(%pl) -{ - if (%pl.deploySensor !$= "") - { - messageClient(%pl.client, 'msgDeploySensorOff', ""); - %pl.deploySensor = ""; - } -} - -function Deployables::displayErrorMsg(%item, %plyr, %slot, %error) -{ - deactivateDeploySensor(%plyr); - - %errorSnd = '~wfx/misc/misc.error.wav'; - switch (%error) - { - case $NotDeployableReason::None: - %item.onDeploy(%plyr, %slot); - messageClient(%plyr.client, 'MsgTeamDeploySuccess', ""); - return; - - case $NotDeployableReason::NoSurfaceFound: - %msg = '\c2Item must be placed within reach.%1'; - - case $NotDeployableReason::MaxDeployed: - %msg = '\c2Your team\'s control network has reached its capacity for this item.%1'; - - case $NotDeployableReason::SlopeTooGreat: - %msg = '\c2Surface is too steep to place this item on.%1'; - - case $NotDeployableReason::SelfTooClose: - %msg = '\c2You are too close to the surface you are trying to place the item on.%1'; - - case $NotDeployableReason::ObjectTooClose: - %msg = '\c2You cannot place this item so close to another object.%1'; - - case $NotDeployableReason::NoTerrainFound: - %msg = '\c2You must place this on outdoor terrain.%1'; - - case $NotDeployableReason::NoInteriorFound: - %msg = '\c2You must place this on a solid surface.%1'; - - case $NotDeployableReason::TurretTooClose: - %msg = '\c2Interference from a nearby turret prevents placement here.%1'; - - case $NotDeployableReason::TurretSaturation: - %msg = '\c2There are too many turrets nearby.%1'; - - case $NotDeployableReason::SurfaceTooNarrow: - %msg = '\c2There is not adequate surface to clamp to here.%1'; - - case $NotDeployableReason::InventoryTooClose: - %msg = '\c2Interference from a nearby inventory prevents placement here.%1'; - - // -------------------------------------------------------------------------------------- - // z0dd - ZOD, 4/18/02. Addresses the exploit of deploying objects inside other objects. -// case $NotDeployableReason::OrganicTooClose: -// %msg = '\c2You cannot place this item so close to an organic object.%1'; - // -------------------------------------------------------------------------------------- - - default: - %msg = '\c2Deploy failed.'; - } - messageClient(%plyr.client, 'MsgDeployFailed', %msg, %errorSnd); -} - -function ShapeBaseImageData::onActivate(%data, %obj, %slot) -{ - //Tinman - apparently, anything that uses the generic onActivate() method is a deployable. - //repair packs, cloak packs, shield, etc... all overload this method... - %data.testInvalidDeployConditions(%obj, %slot); - - //whether the test passed or not, reset the image trigger (deployables don't have an on/off toggleable state) - %obj.setImageTrigger(%slot, false); -} - -function ShapeBaseImageData::onDeploy(%item, %plyr, %slot) -{ - if(%item.item $= "MotionSensorDeployable" || %item.item $= "PulseSensorDeployable") - { - %plyr.deploySensors--; - %plyr.client.updateSensorPackText(%plyr.deploySensors); - if(%plyr.deploySensors <= 0) - { - // take the deployable off the player's back and out of inventory - %plyr.unmountImage(%slot); - %plyr.decInventory(%item.item, 1); - } - } - else - { - // take the deployable off the player's back and out of inventory - %plyr.unmountImage(%slot); - %plyr.decInventory(%item.item, 1); - } - - // create the actual deployable - %rot = %item.getInitialRotation(%plyr); - if(%item.deployed.className $= "DeployedTurret") - %className = "Turret"; - else - %className = "StaticShape"; - - %deplObj = new (%className)() { - dataBlock = %item.deployed; - }; - - - // set orientation - if(%className $= "Turret") - %deplObj.setDeployRotation(%item.surfacePt, %item.surfaceNrm); - else - %deplObj.setTransform(%item.surfacePt SPC %rot); - - // set the recharge rate right away - if(%deplObj.getDatablock().rechargeRate) - %deplObj.setRechargeRate(%deplObj.getDatablock().rechargeRate); - - // set team, owner, and handle - %deplObj.team = %plyr.client.Team; - %deplObj.owner = %plyr.client; - - // set the sensor group if it needs one - if(%deplObj.getTarget() != -1) - setTargetSensorGroup(%deplObj.getTarget(), %plyr.client.team); - - // place the deployable in the MissionCleanup/Deployables group (AI reasons) - addToDeployGroup(%deplObj); - - //let the AI know as well... - AIDeployObject(%plyr.client, %deplObj); - - // play the deploy sound - serverPlay3D(%item.deploySound, %deplObj.getTransform()); - - // increment the team count for this deployed object - - $TeamDeployedCount[%plyr.team, %item.item]++; - %deplObj.deploy(); - return %deplObj; -} - -function ShapeBaseImageData::getInitialRotation(%item, %plyr) -{ - return rotFromTransform(%plyr.getTransform()); -} - -function MotionSensorDeployableImage::getInitialRotation(%item, %plyr) -{ - %rotAxis = vectorNormalize(vectorCross(%item.surfaceNrm, "0 0 1")); - if (getWord(%item.surfaceNrm, 2) == 1 || getWord(%item.surfaceNrm, 2) == -1) - %rotAxis = vectorNormalize(vectorCross(%item.surfaceNrm, "0 1 0")); - return %rotAxis SPC mACos(vectorDot(%item.surfaceNrm, "0 0 1")); -} - -function MotionSensorDeployable::onPickup(%this, %pack, %player, %amount) -{ - // %this = Sensor pack datablock - // %pack = Sensor pack object number - // %player = player - // %amount = amount picked up (1) - - if(%pack.sensors $= "") - { - // assume that this is a pack that has been placed in a mission - // this case was handled in ::onInventory below (max sensors); - } - else - { - // find out how many sensor were in the pack - %player.deploySensors = %pack.sensors; - %player.client.updateSensorPackText(%player.deploySensors); - } -} - -function MotionSensorDeployable::onThrow(%this,%pack,%player) -{ - // %this = Sensor pack datablock - // %pack = Sensor pack object number - // %player = player - - %player.throwSensorPack = 1; - %pack.sensors = %player.deploySensors; - %player.deploySensors = 0; - %player.client.updateSensorPackText(%player.deploySensors); - // do the normal ItemData::onThrow stuff -- sound and schedule deletion - serverPlay3D(ItemThrowSound, %player.getTransform()); - %pack.schedulePop(); -} - -function MotionSensorDeployable::onInventory(%this,%player,%value) -{ - // %this = Sensor pack datablock - // %player = player - // %value = 1 if gaining a pack, 0 if losing a pack - - if(%player.getClassName() $= "Player") - { - if(%value) - { - // player picked up or bought a motion sensor pack - %player.deploySensors = %this.maxSensors; - %player.client.updateSensorPackText(%player.deploySensors); - } - else - { - // player dropped or sold a motion sensor pack - if(%player.throwSensorPack) - { - // player threw the pack - %player.throwSensorPack = 0; - // everything handled in ::onThrow above - } - else - { - //the pack was sold at an inventory station, or unmounted because the player - // used all the sensors - %player.deploySensors = 0; - %player.client.updateSensorPackText(%player.deploySensors); - } - } - } - Pack::onInventory(%this,%player,%value); -} - -function PulseSensorDeployable::onPickup(%this, %pack, %player, %amount) -{ - // %this = Sensor pack datablock - // %pack = Sensor pack object number - // %player = player - // %amount = amount picked up (1) - - if(%pack.sensors $= "") - { - // assume that this is a pack that has been placed in a mission - // this case was handled in ::onInventory below (max sensors); - } - else - { - // find out how many sensor were in the pack - %player.deploySensors = %pack.sensors; - %player.client.updateSensorPackText(%player.deploySensors); - } -} - -function PulseSensorDeployable::onThrow(%this,%pack,%player) -{ - // %this = Sensor pack datablock - // %pack = Sensor pack object number - // %player = player - - %player.throwSensorPack = 1; - %pack.sensors = %player.deploySensors; - %player.deploySensors = 0; - %player.client.updateSensorPackText(%player.deploySensors); - // do the normal ItemData::onThrow stuff -- sound and schedule deletion - serverPlay3D(ItemThrowSound, %player.getTransform()); - %pack.schedulePop(); -} - -function PulseSensorDeployable::onInventory(%this,%player,%value) -{ - // %this = Sensor pack datablock - // %player = player - // %value = 1 if gaining a pack, 0 if losing a pack - - if(%player.getClassName() $= "Player") - { - if(%value) - { - // player picked up or bought a motion sensor pack - %player.deploySensors = %this.maxSensors; - %player.client.updateSensorPackText(%player.deploySensors); - } - else - { - // player dropped or sold a motion sensor pack - if(%player.throwSensorPack) - { - // player threw the pack - %player.throwSensorPack = 0; - // everything handled in ::onThrow above - } - else - { - //the pack was sold at an inventory station, or unmounted because the player - // used all the sensors - %player.deploySensors = 0; - %player.client.updateSensorPackText(%player.deploySensors); - } - } - } - Pack::onInventory(%this,%player,%value); -} - -function TurretIndoorDeployableImage::getInitialRotation(%item, %plyr) -{ - %surfaceAngle = getTerrainAngle(%item.surfaceNrm); - if(%surfaceAngle > 155) - %item.deployed = TurretDeployedCeilingIndoor; - else if(%surfaceAngle > 45) - %item.deployed = TurretDeployedWallIndoor; - else - %item.deployed = TurretDeployedFloorIndoor; -} - -function TurretIndoorDeployable::onPickup(%this, %obj, %shape, %amount) -{ - // created to prevent console errors -} - -function TurretOutdoorDeployable::onPickup(%this, %obj, %shape, %amount) -{ - // created to prevent console errors -} - -function InventoryDeployable::onPickup(%this, %obj, %shape, %amount) -{ - // created to prevent console errors -} - -// --------------------------------------------------------------------------------------- -// deployed station functions -function DeployedStationInventory::onEndSequence(%data, %obj, %thread) -{ - Parent::onEndSequence(%data, %obj, %thread); - if(%thread == $DeployThread) - { - %trigger = new Trigger() - { - dataBlock = stationTrigger; - polyhedron = "-0.125 0.0 0.1 0.25 0.0 0.0 0.0 -0.7 0.0 0.0 0.0 1.0"; - }; - MissionCleanup.add(%trigger); - - %trans = %obj.getTransform(); - %vSPos = getWords(%trans,0,2); - %vRot = getWords(%trans,3,5); - %vAngle = getWord(%trans,6); - %matrix = VectorOrthoBasis(%vRot @ " " @ %vAngle + 0.0); - %yRot = getWords(%matrix, 3, 5); - %pos = vectorAdd(%vSPos, vectorScale(%yRot, -0.1)); - - %trigger.setTransform(%pos @ " " @ %vRot @ " " @ %vAngle); - - // associate the trigger with the station - %trigger.station = %obj; - %trigger.mainObj = %obj; - %trigger.disableObj = %obj; - %obj.trigger = %trigger; - } -} - -//-------------------------------------------------------------------------- -//DeployedMotionSensor: -//-------------------------------------------------------------------------- - -function DeployedMotionSensor::onDestroyed(%this, %obj, %prevState) -{ - //%obj.hide(true); - Parent::onDestroyed(%this, %obj, %prevState); - $TeamDeployedCount[%obj.team, MotionSensorDeployable]--; - %obj.schedule(500, "delete"); -} - -//-------------------------------------------------------------------------- -//DeployedPulseSensor: -//-------------------------------------------------------------------------- -function PulseSensorDeployableImage::onActivate(%data, %obj, %slot) -{ - Parent::onActivate( %data, %obj, %slot ); - //%data.testInvalidDeployConditions(%obj, %slot); -} - -function DeployedPulseSensor::onDestroyed(%this, %obj, %prevState) -{ - Parent::onDestroyed(%this, %obj, %prevState); - $TeamDeployedCount[%obj.team, PulseSensorDeployable]--; - %obj.schedule(300, "delete"); -} - -// --------------------------------------------------------------------------------------- -// deployed turret functions - -function DeployedTurret::onAdd(%data, %obj) -{ - Parent::onAdd(%data, %obj); - // auto-mount the barrel - %obj.mountImage(%data.barrel, 0, false); -} - -function DeployedTurret::onDestroyed(%this, %obj, %prevState) -{ - Parent::onDestroyed(%this, %obj, %prevState); - %turType = %this.getName(); - // either it'll be an outdoor turret, or one of the three types of indoor turret - // (floor, ceiling, wall) - if(%turType $= "TurretDeployedOutdoor") - %turType = "TurretOutdoorDeployable"; - else - %turType = "TurretIndoorDeployable"; - - // decrement team count - $TeamDeployedCount[%obj.team, %turType]--; - - %obj.schedule(700, "delete"); -} - -function countTurretsAllowed(%type) -{ - for(%j = 1; %j < Game.numTeams; %j++) - %teamPlayerCount[%j] = 0; - %numClients = ClientGroup.getCount(); - for(%i = 0; %i < %numClients; %i++) - { - %cl = ClientGroup.getObject(%i); - if(%cl.team > 0) - %teamPlayerCount[%cl.team]++; - } - // the bigger team determines the number of turrets allowed - %maxPlayers = %teamPlayerCount[1] > %teamPlayerCount[2] ? %teamPlayerCount[1] : %teamPlayerCount[2]; - // each team can have 1 turret of each type (indoor/outdoor) for every 2 players - // minimum and maximums are defined in deployables.cs - %teamTurretMax = mFloor(%maxPlayers / 2); - if(%teamTurretMax < $TeamDeployableMin[%type]) - %teamTurretMax = $TeamDeployableMin[%type]; - else if(%teamTurretMax > $TeamDeployableMax[%type]) - %teamTurretMax = $TeamDeployableMax[%type]; - - return %teamTurretMax; -} +// deployable objects script +// +// remote pulse sensor, remote motion sensor, remote turrets (indoor +// and outdoor), remote inventory station, remote ammo station +// Note: cameras are treated as grenades, not "regular" deployables + +$TurretIndoorSpaceRadius = 18; // deployed turrets must be this many meters apart // z0dd - ZOD, 8/14/02. Was 20 +$InventorySpaceRadius = 10; // deployed inventory must be this many meters apart // z0dd - ZOD, 8/14/02. Was 20 +$TurretIndoorSphereRadius = 50; // radius for turret frequency check +$TurretIndoorMaxPerSphere = 5; // # of turrets allowed in above radius // z0dd - ZOD, 8/14/02. Was 4 + +$TurretOutdoorSpaceRadius = 20; // deployed turrets must be this many meters apart // z0dd - ZOD, 8/14/02. Was 25 +$TurretOutdoorSphereRadius = 60; // radius for turret frequency check +$TurretOutdoorMaxPerSphere = 5; // # of turrets allowed in above radius // z0dd - ZOD, 8/14/02. Was 4 + +$TeamDeployableMax[InventoryDeployable] = 5; +$TeamDeployableMax[TurretIndoorDeployable] = 10; +$TeamDeployableMax[TurretOutdoorDeployable] = 10; +$TeamDeployableMax[PulseSensorDeployable] = 15; +$TeamDeployableMax[MotionSensorDeployable] = 15; + +$TeamDeployableMin[TurretIndoorDeployable] = 4; +$TeamDeployableMin[TurretOutdoorDeployable] = 4; + +$NotDeployableReason::None = 0; +$NotDeployableReason::MaxDeployed = 1; +$NotDeployableReason::NoSurfaceFound = 2; +$NotDeployableReason::SlopeTooGreat = 3; +$NotDeployableReason::SelfTooClose = 4; +$NotDeployableReason::ObjectTooClose = 5; +$NotDeployableReason::NoTerrainFound = 6; +$NotDeployableReason::NoInteriorFound = 7; +$NotDeployableReason::TurretTooClose = 8; +$NotDeployableReason::TurretSaturation = 9; +$NotDeployableReason::SurfaceTooNarrow = 10; +$NotDeployableReason::InventoryTooClose = 11; +//$NotDeployableReason::OrganicTooClose = 12; // z0dd - ZOD, 4/18/02. Address deploy of objects inside other objects. + +$MinDeployableDistance = 2.5; +$MaxDeployableDistance = 5.0; //meters from body + +// -------------------------------------------- +// effect datablocks +// -------------------------------------------- + +datablock EffectProfile(TurretDeployEffect) +{ + effectname = "packs/generic_deploy"; + minDistance = 2.5; + maxDistance = 5.0; +}; + +datablock EffectProfile(SensorDeployEffect) +{ + effectname = "powered/sensor_activate"; + minDistance = 2.5; + maxDistance = 5.0; +}; + +datablock EffectProfile(MotionSensorDeployEffect) +{ + effectname = "powered/motion_sensor_activate"; + minDistance = 2.5; + maxDistance = 5.0; +}; + +datablock EffectProfile(StationDeployEffect) +{ + effectname = "packs/inventory_deploy"; + minDistance = 2.5; + maxDistance = 5.0; +}; + +// -------------------------------------------- +// sound datablocks +// -------------------------------------------- + +datablock AudioProfile(TurretDeploySound) +{ + fileName = "fx/packs/turret_place.wav"; + description = AudioClose3d; + preload = true; + effect = TurretDeployEffect; +}; + +datablock AudioProfile(SensorDeploySound) +{ + fileName = "fx/powered/sensor_activate.wav"; + description = AudioClose3d; + preload = true; + effect = SensorDeployEffect; + //effect = MotionSensorDeployEffect; // z0dd - ZOD 6/21/02. From Durt, wrong place +}; + +datablock AudioProfile(MotionSensorDeploySound) +{ + fileName = "fx/powered/motion_sensor_activate.wav"; + description = AudioClose3d; + preload = true; + effect = MotionSensorDeployEffect; // z0dd - ZOD 6/21/02. Was in wrong place +}; + +datablock AudioProfile(StationDeploySound) +{ + fileName = "fx/packs/inventory_deploy.wav"; + description = AudioClose3d; + preload = true; + effect = StationDeployEffect; +}; + +// -------------------------------------------- +// deployable debris definition + +datablock DebrisData( DeployableDebris ) +{ + explodeOnMaxBounce = false; + + elasticity = 0.40; + friction = 0.5; + + lifetime = 17.0; + lifetimeVariance = 0.0; + + minSpinSpeed = 60; + maxSpinSpeed = 600; + + numBounces = 10; + bounceVariance = 0; + + staticOnMaxBounce = true; + + useRadiusMass = true; + baseRadius = 0.2; + + velocity = 5.0; + velocityVariance = 2.5; + +}; + + +// -------------------------------------------- +// deployable inventory station + +datablock StaticShapeData(DeployedStationInventory) : StaticShapeDamageProfile +{ + className = Station; + shapeFile = "deploy_inventory.dts"; + maxDamage = 0.70; + destroyedLevel = 0.70; + disabledLevel = 0.42; + explosion = DeployablesExplosion; + expDmgRadius = 8.0; + expDamage = 0.35; + expImpulse = 500.0; + + dynamicType = $TypeMasks::StationObjectType; + isShielded = true; + energyPerDamagePoint = 110; + maxEnergy = 50; + rechargeRate = 0.20; + renderWhenDestroyed = false; + doesRepair = true; + + deployedObject = true; + + cmdCategory = "DSupport"; + cmdIcon = CMDStationIcon; + cmdMiniIconName = "commander/MiniIcons/com_inventory_grey"; + targetNameTag = 'Deployable'; + targetTypeTag = 'Station'; + + debrisShapeName = "debris_generic_small.dts"; + debris = DeployableDebris; + heatSignature = 0; +}; + +datablock ShapeBaseImageData(InventoryDeployableImage) +{ + mass = 12; // z0dd - ZOD, 7/17/02. large packs are too heavy enough with new physics. was 15 + emap = true; + + shapeFile = "pack_deploy_inventory.dts"; + item = InventoryDeployable; + mountPoint = 1; + offset = "0 0 0"; + deployed = DeployedStationInventory; + heatSignature = 0; + + stateName[0] = "Idle"; + stateTransitionOnTriggerDown[0] = "Activate"; + + stateName[1] = "Activate"; + stateScript[1] = "onActivate"; + stateTransitionOnTriggerUp[1] = "Idle"; + + isLarge = true; + maxDepSlope = 30; + deploySound = StationDeploySound; + + flatMinDeployDis = 1.0; + flatMaxDeployDis = 5.0; + + minDeployDis = 2.5; + maxDeployDis = 5.0; +}; + +datablock ItemData(InventoryDeployable) +{ + className = Pack; + catagory = "Deployables"; + shapeFile = "pack_deploy_inventory.dts"; + mass = 3.0; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 1; + rotate = false; + image = "InventoryDeployableImage"; + pickUpName = "an inventory pack"; + heatSignature = 0; + + computeCRC = true; + emap = true; + +}; + +// -------------------------------------------- +// deployable motion sensor + +datablock SensorData(DeployMotionSensorObj) +{ + detects = true; + detectsUsingLOS = true; + detectsActiveJammed = false; + detectsPassiveJammed = true; + detectsCloaked = true; + detectionPings = false; + detectMinVelocity = 2; + detectRadius = 60; +}; + +datablock StaticShapeData(DeployedMotionSensor) : StaticShapeDamageProfile +{ + className = Sensor; + shapeFile = "deploy_sensor_motion.dts"; + maxDamage = 0.6; + destroyedLevel = 0.6; + disabledLevel = 0.4; + explosion = DeployablesExplosion; + dynamicType = $TypeMasks::SensorObjectType; + + deployedObject = true; + + cmdCategory = "DSupport"; + cmdIcon = CMDSensorIcon; + cmdMiniIconName = "commander/MiniIcons/com_deploymotionsensor"; + targetNameTag = 'Deployable Motion'; + targetTypeTag = 'Sensor'; + sensorData = DeployMotionSensorObj; + sensorRadius = DeployMotionSensorObj.detectRadius; + sensorColor = "9 136 255"; + deployAmbientThread = true; + + debrisShapeName = "debris_generic_small.dts"; + debris = DeployableDebris; + heatSignature = 0; +}; + +datablock ShapeBaseImageData(MotionSensorDeployableImage) +{ + shapeFile = "pack_deploy_sensor_motion.dts"; + item = MotionSensorDeployable; + mountPoint = 1; + offset = "0 0 0"; + deployed = DeployedMotionSensor; + + stateName[0] = "Idle"; + stateTransitionOnTriggerDown[0] = "Activate"; + + stateName[1] = "Activate"; + stateScript[1] = "onActivate"; + stateTransitionOnTriggerUp[1] = "Idle"; + + maxDepSlope = 360; + deploySound = MotionSensorDeploySound; + emap = true; + heatSignature = 1; + + minDeployDis = 0.5; + maxDeployDis = 5.0; //meters from body +}; + +datablock ItemData(MotionSensorDeployable) +{ + className = Pack; + catagory = "Deployables"; + shapeFile = "pack_deploy_sensor_motion.dts"; + mass = 2.0; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 1; + rotate = false; + image = "MotionSensorDeployableImage"; + pickUpName = "a motion sensor pack"; + + computeCRC = true; + emap = true; + heatSignature = 0; + + //maxSensors = 3; + maxSensors = 2; +}; + +// -------------------------------------------- +// deployable pulse sensor + +datablock SensorData(DeployPulseSensorObj) +{ + detects = true; + detectsUsingLOS = true; + detectsPassiveJammed = false; + detectsCloaked = false; + detectionPings = true; + detectRadius = 175; // z0dd - ZOD, 8/15/02. Was 150 +}; + +datablock StaticShapeData(DeployedPulseSensor) : StaticShapeDamageProfile +{ + className = Sensor; + shapeFile = "deploy_sensor_pulse.dts"; + maxDamage = 0.6; + destroyedLevel = 0.6; + disabledLevel = 0.4; + explosion = DeployablesExplosion; + dynamicType = $TypeMasks::SensorObjectType; + + deployedObject = true; + + cmdCategory = "DSupport"; + cmdIcon = CMDSensorIcon; + cmdMiniIconName = "commander/MiniIcons/com_deploypulsesensor"; + targetNameTag = 'Deployable'; + targetTypeTag = 'Pulse Sensor'; + sensorData = DeployPulseSensorObj; + sensorRadius = DeployPulseSensorObj.detectRadius; + sensorColor = "255 194 9"; + deployAmbientThread = true; + + debrisShapeName = "debris_generic_small.dts"; + debris = DeployableDebris; + heatSignature = 0; +}; + +datablock ShapeBaseImageData(PulseSensorDeployableImage) +{ + shapeFile = "pack_deploy_sensor_pulse.dts"; + item = PulseSensorDeployable; + mountPoint = 1; + offset = "0 0 0"; + deployed = DeployedPulseSensor; + + stateName[0] = "Idle"; + stateTransitionOnTriggerDown[0] = "Activate"; + + stateName[1] = "Activate"; + stateScript[1] = "onActivate"; + stateTransitionOnTriggerUp[1] = "Idle"; + deploySound = SensorDeploySound; + + maxDepSlope = 40; + emap = true; + heatSignature = 0; + + minDeployDis = 0.5; + maxDeployDis = 5.0; //meters from body +}; + +datablock ItemData(PulseSensorDeployable) +{ + className = Pack; + catagory = "Deployables"; + shapeFile = "pack_deploy_sensor_pulse.dts"; + mass = 2.0; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 1; + rotate = false; + image = "PulseSensorDeployableImage"; + pickUpName = "a pulse sensor pack"; + + computeCRC = true; + emap = true; + + maxSensors = 2; +}; + +// -------------------------------------------- +// deployable outdoor turret + +datablock ShapeBaseImageData(TurretOutdoorDeployableImage) +{ + mass = 10; + + shapeFile = "pack_deploy_turreto.dts"; + item = TurretOutdoorDeployable; + mountPoint = 1; + offset = "0 0 0"; + deployed = TurretDeployedOutdoor; + + stateName[0] = "Idle"; + stateTransitionOnTriggerDown[0] = "Activate"; + + stateName[1] = "Activate"; + stateScript[1] = "onActivate"; + stateTransitionOnTriggerUp[1] = "Idle"; + + maxDamage = 4.5; + destroyedLevel = 4.5; + disabledLevel = 4.0; + + isLarge = true; + emap = true; + + maxDepSlope = 40; + deploySound = TurretDeploySound; + + minDeployDis = 0.5; + maxDeployDis = 5.0; //meters from body +}; + +datablock ItemData(TurretOutdoorDeployable) +{ + className = Pack; + catagory = "Deployables"; + shapeFile = "pack_deploy_turreto.dts"; + mass = 3.0; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 1; + rotate = false; + image = "TurretOutdoorDeployableImage"; + pickUpName = "a landspike turret pack"; + + computeCRC = true; + emap = true; + +}; + +// -------------------------------------------- +// deployable indoor turret (3 varieties -- floor, wall and ceiling) + +datablock ShapeBaseImageData(TurretIndoorDeployableImage) +{ + mass = 10; + + shapeFile = "pack_deploy_turreti.dts"; + item = TurretIndoorDeployable; + mountPoint = 1; + offset = "0 0 0"; + + stateName[0] = "Idle"; + stateTransitionOnTriggerDown[0] = "Activate"; + + stateName[1] = "Activate"; + stateScript[1] = "onActivate"; + stateTransitionOnTriggerUp[1] = "Idle"; + + isLarge = true; + emap = true; + + maxDepSlope = 360; + deploySound = TurretDeploySound; + + minDeployDis = 0.5; + maxDeployDis = 5.0; //meters from body +}; + +datablock ItemData(TurretIndoorDeployable) +{ + className = Pack; + catagory = "Deployables"; + shapeFile = "pack_deploy_turreti.dts"; + mass = 3.0; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 1; + rotate = false; + image = "TurretIndoorDeployableImage"; + pickUpName = "a spider clamp turret pack"; + + computeCRC = true; + emap = true; + +}; + +// -------------------------------------------- +// miscellaneous yet handy functions + +function posFromTransform(%transform) +{ + // the first three words of an object's transform are the object's position + %position = getWord(%transform, 0) @ " " @ getWord(%transform, 1) @ " " @ getWord(%transform, 2); + return %position; +} + +function rotFromTransform(%transform) +{ + // the last four words of an object's transform are the object's rotation + %rotation = getWord(%transform, 3) @ " " @ getWord(%transform, 4) @ " " @ getWord(%transform, 5) @ " " @ getWord(%transform, 6); + return %rotation; +} + +function posFromRaycast(%transform) +{ + // the 2nd, 3rd, and 4th words returned from a successful raycast call are the position of the point + %position = getWord(%transform, 1) @ " " @ getWord(%transform, 2) @ " " @ getWord(%transform, 3); + return %position; +} + +function normalFromRaycast(%transform) +{ + // the 5th, 6th and 7th words returned from a successful raycast call are the normal of the surface + %norm = getWord(%transform, 4) @ " " @ getWord(%transform, 5) @ " " @ getWord(%transform, 6); + return %norm; +} + +function addToDeployGroup(%object) +{ + // all deployables should go into a special group for AI purposes + %depGroup = nameToID("MissionCleanup/Deployables"); + if(%depGroup <= 0) { + %depGroup = new SimGroup("Deployables"); + MissionCleanup.add(%depGroup); + } + %depGroup.add(%object); +} + +function Deployables::searchView(%obj, %searchRange, %mask) +{ + // get the eye vector and eye transform of the player + %eyeVec = %obj.getEyeVector(); + %eyeTrans = %obj.getEyeTransform(); + + // extract the position of the player's camera from the eye transform (first 3 words) + %eyePos = posFromTransform(%eyeTrans); + + // normalize the eye vector + %nEyeVec = VectorNormalize(%eyeVec); + + // scale (lengthen) the normalized eye vector according to the search range + %scEyeVec = VectorScale(%nEyeVec, %searchRange); + + // 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, 0); + + return %searchResult; +} + +//-----------------------// +// Deployable Procedures // +//-----------------------// + +//------------------------------------------------- +function ShapeBaseImageData::testMaxDeployed(%item, %plyr) +{ + if(%item.item $= TurretOutdoorDeployable || %item.item $= TurretIndoorDeployable) + %itemCount = countTurretsAllowed(%item.item); + else + %itemCount = $TeamDeployableMax[%item.item]; + + return $TeamDeployedCount[%plyr.team, %item.item] >= %itemCount; +} + +//------------------------------------------------- +function ShapeBaseImageData::testNoSurfaceInRange(%item, %plyr) +{ + return ! Deployables::searchView(%plyr, $MaxDeployDistance, $TypeMasks::TerrainObjectType | $TypeMasks::InteriorObjectType); +} + +//------------------------------------------------- +function ShapeBaseImageData::testSlopeTooGreat(%item) +{ + if (%item.surface) + { + return getTerrainAngle(%item.surfaceNrm) > %item.maxDepSlope; + } +} + +//------------------------------------------------- +function ShapeBaseImageData::testSelfTooClose(%item, %plyr) +{ + InitContainerRadiusSearch(%item.surfacePt, $MinDeployDistance, $TypeMasks::PlayerObjectType); + + return containerSearchNext() == %plyr; +} + +//------------------------------------------------------------------------------------ +// z0dd - ZOD - BadShot - Founder, 6/24/02. Address deploying of objects inside other +// objects. New function. +//function ShapeBaseImageData::testOrganicTooClose(%item, %plyr) +//{ +// InitContainerRadiusSearch( %item.surfacePt, $MaxDeployableDistance, $TypeMasks::StaticTSObjectType ); +// %test = containerSearchNext(); +// if(%test) +// { +// for (%i = 0; %i < $NumStaticTSObjects; %i++) +// { +// if(getWord($StaticTSObjects[%i], 2) $= %test.shapeName) +// { +// %organicIndex = %i; +// break; +// } +// } +// if(getWord($StaticTSObjects[%organicIndex], 0) $= Organics) +// { +// %scale1 = getWord(%test.scale, 1); +// %scale2 = getWord(%test.scale, 2); +// %maxDist1 = %scale1 > 1 ? 3.2 * %scale1 : ""; +// %maxDist2 = %scale2 > 1 ? 3.2 * %scale2 : ""; +// %maxDist = %maxDist1 >= %maxDist2 ? %maxDist1 : %maxDist2; +// %maxDist = %maxDist $= "" ? 3.2 : %maxDist; +// %distance = VectorDist(getWords(%item.surfacePt, 0, 1) SPC 0, getWords(%test.getWorldBoxCenter(), 0, 1) SPC 0); +// if (%distance <= %maxDist) +// return %test; +// else +// return false; +// } +// else +// return false; +// } +// else +// return false; +//} +//------------------------------------------------------------------------------------ + +function ShapeBaseImageData::testObjectTooClose(%item) +{ + %mask = ($TypeMasks::VehicleObjectType | $TypeMasks::MoveableObjectType | + $TypeMasks::StaticShapeObjectType | + $TypeMasks::ForceFieldObjectType | $TypeMasks::ItemObjectType | + $TypeMasks::PlayerObjectType | $TypeMasks::TurretObjectType); + + InitContainerRadiusSearch( %item.surfacePt, $MinDeployDistance, %mask ); + + %test = containerSearchNext(); + return %test; +} + + +//------------------------------------------------- +function TurretOutdoorDeployableImage::testNoTerrainFound(%item) +{ + return %item.surface.getClassName() !$= TerrainBlock; +} + +function ShapeBaseImageData::testNoTerrainFound(%item, %surface) +{ + //don't check this for non-Landspike turret deployables +} + +//------------------------------------------------- +function TurretIndoorDeployableImage::testNoInteriorFound(%item) +{ + return %item.surface.getClassName() !$= InteriorInstance; +} + +function ShapeBaseImageData::testNoInteriorFound(%item, %surface) +{ + //don't check this for non-Clasping turret deployables +} + +//------------------------------------------------- +function TurretIndoorDeployableImage::testHavePurchase(%item, %xform) +{ + %footprintRadius = 0.34; + %collMask = $TypeMasks::InteriorObjectType; + return %item.deployed.checkDeployPurchase(%xform, %footprintRadius, %collMask); +} + +function ShapeBaseImageData::testHavePurchase(%item, %xform) +{ + //don't check this for non-Clasping turret deployables + return true; +} + +//------------------------------------------------- +function ShapeBaseImageData::testInventoryTooClose(%item, %plyr) +{ + return false; +} + +function InventoryDeployableImage::testInventoryTooClose(%item, %plyr) +{ + InitContainerRadiusSearch(%item.surfacePt, $InventorySpaceRadius, $TypeMasks::StaticShapeObjectType); + + // old function was only checking whether the first object found was a turret -- also wasn't checking + // which team the object was on + %turretInRange = false; + while((%found = containerSearchNext()) != 0) + { + %foundName = %found.getDataBlock().getName(); + if( (%foundName $= DeployedStationInventory) ) + if (%found.team == %plyr.team) + { + %turretInRange = true; + break; + } + } + return %turretInRange; +} + +function TurretIndoorDeployableImage::testTurretTooClose(%item, %plyr) +{ + InitContainerRadiusSearch(%item.surfacePt, $TurretIndoorSpaceRadius, $TypeMasks::StaticShapeObjectType); + + // old function was only checking whether the first object found was a turret -- also wasn't checking + // which team the object was on + %turretInRange = false; + while((%found = containerSearchNext()) != 0) + { + %foundName = %found.getDataBlock().getName(); + if((%foundname $= TurretDeployedFloorIndoor) || (%foundName $= TurretDeployedWallIndoor) || (%foundName $= TurretDeployedCeilingIndoor) || (%foundName $= TurretDeployedOutdoor) ) + if (%found.team == %plyr.team) + { + %turretInRange = true; + break; + } + } + return %turretInRange; +} + +function TurretOutdoorDeployableImage::testTurretTooClose(%item, %plyr) +{ + InitContainerRadiusSearch(%item.surfacePt, $TurretOutdoorSpaceRadius, $TypeMasks::StaticShapeObjectType); + + // old function was only checking whether the first object found was a turret -- also wasn't checking + // which team the object was on + %turretInRange = false; + while((%found = containerSearchNext()) != 0) + { + %foundName = %found.getDataBlock().getName(); + if((%foundname $= TurretDeployedFloorIndoor) || (%foundName $= TurretDeployedWallIndoor) || (%foundName $= TurretDeployedCeilingIndoor) || (%foundName $= TurretDeployedOutdoor) ) + if (%found.team == %plyr.team) + { + %turretInRange = true; + break; + } + } + return %turretInRange; +} + +function ShapeBaseImageData::testTurretTooClose(%item, %plyr) +{ + //don't check this for non-turret deployables +} + +//------------------------------------------------- +function TurretIndoorDeployableImage::testTurretSaturation(%item) +{ + %highestDensity = 0; + InitContainerRadiusSearch(%item.surfacePt, $TurretIndoorSphereRadius, $TypeMasks::StaticShapeObjectType); + %found = containerSearchNext(); + while(%found) + { + %foundName = %found.getDataBlock().getName(); + if((%foundname $= TurretDeployedFloorIndoor) || (%foundName $= TurretDeployedWallIndoor) || (%foundName $= TurretDeployedCeilingIndoor) || (%foundName $= TurretDeployedOutdoor) ) + { + //found one + %numTurretsNearby++; + + %nearbyDensity = testNearbyDensity(%found, $TurretIndoorSphereRadius); + if (%nearbyDensity > %highestDensity) + %highestDensity = %nearbyDensity; + } + %found = containerSearchNext(); + } + + if (%numTurretsNearby > %highestDensity) + %highestDensity = %numTurretsNearby; + return %highestDensity > $TurretIndoorMaxPerSphere; +} + +function TurretOutdoorDeployableImage::testTurretSaturation(%item) +{ + %highestDensity = 0; + InitContainerRadiusSearch(%item.surfacePt, $TurretOutdoorSphereRadius, $TypeMasks::StaticShapeObjectType); + %found = containerSearchNext(); + while(%found) + { + %foundName = %found.getDataBlock().getName(); + if((%foundname $= TurretDeployedFloorIndoor) || (%foundName $= TurretDeployedWallIndoor) || (%foundName $= TurretDeployedCeilingIndoor) || (%foundName $= TurretDeployedOutdoor) ) + { + //found one + %numTurretsNearby++; + + %nearbyDensity = testNearbyDensity(%found, $TurretOutdoorSphereRadius); + if (%nearbyDensity > %highestDensity) + %highestDensity = %nearbyDensity; + } + %found = containerSearchNext(); + } + + if (%numTurretsNearby > %highestDensity) + %highestDensity = %numTurretsNearby; + return %highestDensity > $TurretOutdoorMaxPerSphere; +} + +function ShapeBaseImageData::testTurretSaturation(%item, %surfacePt) +{ + //don't check this for non-turret deployables +} + +function testNearbyDensity(%item, %radius) +{ + //this checks how many turrets are in adjacent spheres in case placing a new one overloads them. + %surfacePt = posFromTransform(%item.getTransform()); + %turretCount = 0; + + InitContainerRadiusSearch(%surfacePt, %radius, $TypeMasks::StaticShapeObjectType); + %found = containerSearchNext(); + while(%found) + { + %foundName = %found.getDataBlock().getName(); + if((%foundname $= TurretDeployedFloorIndoor) || (%foundName $= TurretDeployedWallIndoor) || (%foundName $= TurretDeployedCeilingIndoor) || (%foundName $= TurretDeployedOutdoor) ) + %turretCount++; + %found = containerSearchNext(); + } + return %turretCount; +} + +//------------------------------------------------- +//if this function, or any of the included tests are changed, those changes need to be reflected in function: +//AIODeployEquipment::weight(%this, %client, %level), found in aiObjectives.cs --tinman +function ShapeBaseImageData::testInvalidDeployConditions(%item, %plyr, %slot) +{ + cancel(%plyr.deployCheckThread); + %disqualified = $NotDeployableReason::None; //default + $MaxDeployDistance = %item.maxDeployDis; + $MinDeployDistance = %item.minDeployDis; + + %surface = Deployables::searchView(%plyr, + $MaxDeployDistance, + ($TypeMasks::TerrainObjectType | + $TypeMasks::InteriorObjectType)); + if (%surface) + { + %surfacePt = posFromRaycast(%surface); + %surfaceNrm = normalFromRaycast(%surface); + + // Check that point to see if anything is objstructing it... + %eyeTrans = %plyr.getEyeTransform(); + %eyePos = posFromTransform(%eyeTrans); + + %searchResult = containerRayCast(%eyePos, %surfacePt, -1, %plyr); + if (!%searchResult) + { + %item.surface = %surface; + %item.surfacePt = %surfacePt; + %item.surfaceNrm = %surfaceNrm; + } + else + { + if(checkPositions(%surfacePT, posFromRaycast(%searchResult))) + { + %item.surface = %surface; + %item.surfacePt = %surfacePt; + %item.surfaceNrm = %surfaceNrm; + } + else + { + // Don't set the item + %disqualified = $NotDeployableReason::ObjectTooClose; + } + } + if(!getTerrainAngle(%surfaceNrm) && %item.flatMaxDeployDis !$= "") + { + $MaxDeployDistance = %item.flatMaxDeployDis; + $MinDeployDistance = %item.flatMinDeployDis; + } + } + + if (%item.testMaxDeployed(%plyr)) + { + %disqualified = $NotDeployableReason::MaxDeployed; + } + else if (%item.testNoSurfaceInRange(%plyr)) + { + %disqualified = $NotDeployableReason::NoSurfaceFound; + } + else if (%item.testNoTerrainFound(%surface)) + { + %disqualified = $NotDeployableReason::NoTerrainFound; + } + else if (%item.testNoInteriorFound()) + { + %disqualified = $NotDeployableReason::NoInteriorFound; + } + else if (%item.testSlopeTooGreat(%surface, %surfaceNrm)) + { + %disqualified = $NotDeployableReason::SlopeTooGreat; + } + else if (%item.testSelfTooClose(%plyr, %surfacePt)) + { + %disqualified = $NotDeployableReason::SelfTooClose; + } + else if (%item.testObjectTooClose(%surfacePt)) + { + %disqualified = $NotDeployableReason::ObjectTooClose; + } + else if (%item.testTurretTooClose(%plyr)) + { + %disqualified = $NotDeployableReason::TurretTooClose; + } + else if (%item.testInventoryTooClose(%plyr)) + { + %disqualified = $NotDeployableReason::InventoryTooClose; + } + else if (%item.testTurretSaturation()) + { + %disqualified = $NotDeployableReason::TurretSaturation; + } + //--------------------------------------------------------------------------------------- + // z0dd - ZOD, 4/18/02. Addresses the exploit of deploying objects inside other objects. +// else if (%item.testOrganicTooClose(%plyr)) +// { +// %disqualified = $NotDeployableReason::OrganicTooClose; +// } + //--------------------------------------------------------------------------------------- + else if (%disqualified == $NotDeployableReason::None) + { + // Test that there are no objstructing objects that this object + // will intersect with + // + %rot = %item.getInitialRotation(%plyr); + if(%item.deployed.className $= "DeployedTurret") + { + %xform = %item.deployed.getDeployTransform(%item.surfacePt, %item.surfaceNrm); + } + else + { + %xform = %surfacePt SPC %rot; + } + + if (!%item.deployed.checkDeployPos(%xform)) + { + %disqualified = $NotDeployableReason::ObjectTooClose; + } + else if (!%item.testHavePurchase(%xform)) + { + %disqualified = $NotDeployableReason::SurfaceTooNarrow; + } + } + + if (%plyr.getMountedImage($BackpackSlot) == %item) //player still have the item? + { + if (%disqualified) + activateDeploySensorRed(%plyr); + else + activateDeploySensorGrn(%plyr); + + if (%plyr.client.deployPack == true) + %item.attemptDeploy(%plyr, %slot, %disqualified); + else + { + %plyr.deployCheckThread = %item.schedule(25, "testInvalidDeployConditions", %plyr, %slot); //update checks every 50 milliseconds + } + } + else + deactivateDeploySensor(%plyr); +} + +function checkPositions(%pos1, %pos2) +{ + %passed = true; + if((mFloor(getWord(%pos1, 0)) - mFloor(getWord(%pos2,0)))) + %passed = false; + if((mFloor(getWord(%pos1, 1)) - mFloor(getWord(%pos2,1)))) + %passed = false; + if((mFloor(getWord(%pos1, 2)) - mFloor(getWord(%pos2,2)))) + %passed = false; + return %passed; +} + +function ShapeBaseImageData::attemptDeploy(%item, %plyr, %slot, %disqualified) +{ + deactivateDeploySensor(%plyr); + Deployables::displayErrorMsg(%item, %plyr, %slot, %disqualified); +} + +function activateDeploySensorRed(%pl) +{ + if(%pl.deploySensor !$= "red") + { + messageClient(%pl.client, 'msgDeploySensorRed', ""); + %pl.deploySensor = "red"; + } +} + +function activateDeploySensorGrn(%pl) +{ + if(%pl.deploySensor !$= "green") + { + messageClient(%pl.client, 'msgDeploySensorGrn', ""); + %pl.deploySensor = "green"; + } +} + +function deactivateDeploySensor(%pl) +{ + if (%pl.deploySensor !$= "") + { + messageClient(%pl.client, 'msgDeploySensorOff', ""); + %pl.deploySensor = ""; + } +} + +function Deployables::displayErrorMsg(%item, %plyr, %slot, %error) +{ + deactivateDeploySensor(%plyr); + + %errorSnd = '~wfx/misc/misc.error.wav'; + switch (%error) + { + case $NotDeployableReason::None: + %item.onDeploy(%plyr, %slot); + messageClient(%plyr.client, 'MsgTeamDeploySuccess', ""); + return; + + case $NotDeployableReason::NoSurfaceFound: + %msg = '\c2Item must be placed within reach.%1'; + + case $NotDeployableReason::MaxDeployed: + %msg = '\c2Your team\'s control network has reached its capacity for this item.%1'; + + case $NotDeployableReason::SlopeTooGreat: + %msg = '\c2Surface is too steep to place this item on.%1'; + + case $NotDeployableReason::SelfTooClose: + %msg = '\c2You are too close to the surface you are trying to place the item on.%1'; + + case $NotDeployableReason::ObjectTooClose: + %msg = '\c2You cannot place this item so close to another object.%1'; + + case $NotDeployableReason::NoTerrainFound: + %msg = '\c2You must place this on outdoor terrain.%1'; + + case $NotDeployableReason::NoInteriorFound: + %msg = '\c2You must place this on a solid surface.%1'; + + case $NotDeployableReason::TurretTooClose: + %msg = '\c2Interference from a nearby turret prevents placement here.%1'; + + case $NotDeployableReason::TurretSaturation: + %msg = '\c2There are too many turrets nearby.%1'; + + case $NotDeployableReason::SurfaceTooNarrow: + %msg = '\c2There is not adequate surface to clamp to here.%1'; + + case $NotDeployableReason::InventoryTooClose: + %msg = '\c2Interference from a nearby inventory prevents placement here.%1'; + + // -------------------------------------------------------------------------------------- + // z0dd - ZOD, 4/18/02. Addresses the exploit of deploying objects inside other objects. +// case $NotDeployableReason::OrganicTooClose: +// %msg = '\c2You cannot place this item so close to an organic object.%1'; + // -------------------------------------------------------------------------------------- + + default: + %msg = '\c2Deploy failed.'; + } + messageClient(%plyr.client, 'MsgDeployFailed', %msg, %errorSnd); +} + +function ShapeBaseImageData::onActivate(%data, %obj, %slot) +{ + //Tinman - apparently, anything that uses the generic onActivate() method is a deployable. + //repair packs, cloak packs, shield, etc... all overload this method... + %data.testInvalidDeployConditions(%obj, %slot); + + //whether the test passed or not, reset the image trigger (deployables don't have an on/off toggleable state) + %obj.setImageTrigger(%slot, false); +} + +function ShapeBaseImageData::onDeploy(%item, %plyr, %slot) +{ + if(%item.item $= "MotionSensorDeployable" || %item.item $= "PulseSensorDeployable") + { + %plyr.deploySensors--; + %plyr.client.updateSensorPackText(%plyr.deploySensors); + if(%plyr.deploySensors <= 0) + { + // take the deployable off the player's back and out of inventory + %plyr.unmountImage(%slot); + %plyr.decInventory(%item.item, 1); + } + } + else + { + // take the deployable off the player's back and out of inventory + %plyr.unmountImage(%slot); + %plyr.decInventory(%item.item, 1); + } + + // create the actual deployable + %rot = %item.getInitialRotation(%plyr); + if(%item.deployed.className $= "DeployedTurret") + %className = "Turret"; + else + %className = "StaticShape"; + + %deplObj = new (%className)() { + dataBlock = %item.deployed; + }; + + + // set orientation + if(%className $= "Turret") + %deplObj.setDeployRotation(%item.surfacePt, %item.surfaceNrm); + else + %deplObj.setTransform(%item.surfacePt SPC %rot); + + // set the recharge rate right away + if(%deplObj.getDatablock().rechargeRate) + %deplObj.setRechargeRate(%deplObj.getDatablock().rechargeRate); + + // set team, owner, and handle + %deplObj.team = %plyr.client.Team; + %deplObj.owner = %plyr.client; + + // set the sensor group if it needs one + if(%deplObj.getTarget() != -1) + setTargetSensorGroup(%deplObj.getTarget(), %plyr.client.team); + + // place the deployable in the MissionCleanup/Deployables group (AI reasons) + addToDeployGroup(%deplObj); + + //let the AI know as well... + AIDeployObject(%plyr.client, %deplObj); + + // play the deploy sound + serverPlay3D(%item.deploySound, %deplObj.getTransform()); + + // increment the team count for this deployed object + + $TeamDeployedCount[%plyr.team, %item.item]++; + %deplObj.deploy(); + return %deplObj; +} + +function ShapeBaseImageData::getInitialRotation(%item, %plyr) +{ + return rotFromTransform(%plyr.getTransform()); +} + +function MotionSensorDeployableImage::getInitialRotation(%item, %plyr) +{ + %rotAxis = vectorNormalize(vectorCross(%item.surfaceNrm, "0 0 1")); + if (getWord(%item.surfaceNrm, 2) == 1 || getWord(%item.surfaceNrm, 2) == -1) + %rotAxis = vectorNormalize(vectorCross(%item.surfaceNrm, "0 1 0")); + return %rotAxis SPC mACos(vectorDot(%item.surfaceNrm, "0 0 1")); +} + +function MotionSensorDeployable::onPickup(%this, %pack, %player, %amount) +{ + // %this = Sensor pack datablock + // %pack = Sensor pack object number + // %player = player + // %amount = amount picked up (1) + + if(%pack.sensors $= "") + { + // assume that this is a pack that has been placed in a mission + // this case was handled in ::onInventory below (max sensors); + } + else + { + // find out how many sensor were in the pack + %player.deploySensors = %pack.sensors; + %player.client.updateSensorPackText(%player.deploySensors); + } +} + +function MotionSensorDeployable::onThrow(%this,%pack,%player) +{ + // %this = Sensor pack datablock + // %pack = Sensor pack object number + // %player = player + + %player.throwSensorPack = 1; + %pack.sensors = %player.deploySensors; + %player.deploySensors = 0; + %player.client.updateSensorPackText(%player.deploySensors); + // do the normal ItemData::onThrow stuff -- sound and schedule deletion + serverPlay3D(ItemThrowSound, %player.getTransform()); + %pack.schedulePop(); +} + +function MotionSensorDeployable::onInventory(%this,%player,%value) +{ + // %this = Sensor pack datablock + // %player = player + // %value = 1 if gaining a pack, 0 if losing a pack + + if(%player.getClassName() $= "Player") + { + if(%value) + { + // player picked up or bought a motion sensor pack + %player.deploySensors = %this.maxSensors; + %player.client.updateSensorPackText(%player.deploySensors); + } + else + { + // player dropped or sold a motion sensor pack + if(%player.throwSensorPack) + { + // player threw the pack + %player.throwSensorPack = 0; + // everything handled in ::onThrow above + } + else + { + //the pack was sold at an inventory station, or unmounted because the player + // used all the sensors + %player.deploySensors = 0; + %player.client.updateSensorPackText(%player.deploySensors); + } + } + } + Pack::onInventory(%this,%player,%value); +} + +function PulseSensorDeployable::onPickup(%this, %pack, %player, %amount) +{ + // %this = Sensor pack datablock + // %pack = Sensor pack object number + // %player = player + // %amount = amount picked up (1) + + if(%pack.sensors $= "") + { + // assume that this is a pack that has been placed in a mission + // this case was handled in ::onInventory below (max sensors); + } + else + { + // find out how many sensor were in the pack + %player.deploySensors = %pack.sensors; + %player.client.updateSensorPackText(%player.deploySensors); + } +} + +function PulseSensorDeployable::onThrow(%this,%pack,%player) +{ + // %this = Sensor pack datablock + // %pack = Sensor pack object number + // %player = player + + %player.throwSensorPack = 1; + %pack.sensors = %player.deploySensors; + %player.deploySensors = 0; + %player.client.updateSensorPackText(%player.deploySensors); + // do the normal ItemData::onThrow stuff -- sound and schedule deletion + serverPlay3D(ItemThrowSound, %player.getTransform()); + %pack.schedulePop(); +} + +function PulseSensorDeployable::onInventory(%this,%player,%value) +{ + // %this = Sensor pack datablock + // %player = player + // %value = 1 if gaining a pack, 0 if losing a pack + + if(%player.getClassName() $= "Player") + { + if(%value) + { + // player picked up or bought a motion sensor pack + %player.deploySensors = %this.maxSensors; + %player.client.updateSensorPackText(%player.deploySensors); + } + else + { + // player dropped or sold a motion sensor pack + if(%player.throwSensorPack) + { + // player threw the pack + %player.throwSensorPack = 0; + // everything handled in ::onThrow above + } + else + { + //the pack was sold at an inventory station, or unmounted because the player + // used all the sensors + %player.deploySensors = 0; + %player.client.updateSensorPackText(%player.deploySensors); + } + } + } + Pack::onInventory(%this,%player,%value); +} + +function TurretIndoorDeployableImage::getInitialRotation(%item, %plyr) +{ + %surfaceAngle = getTerrainAngle(%item.surfaceNrm); + if(%surfaceAngle > 155) + %item.deployed = TurretDeployedCeilingIndoor; + else if(%surfaceAngle > 45) + %item.deployed = TurretDeployedWallIndoor; + else + %item.deployed = TurretDeployedFloorIndoor; +} + +function TurretIndoorDeployable::onPickup(%this, %obj, %shape, %amount) +{ + // created to prevent console errors +} + +function TurretOutdoorDeployable::onPickup(%this, %obj, %shape, %amount) +{ + // created to prevent console errors +} + +function InventoryDeployable::onPickup(%this, %obj, %shape, %amount) +{ + // created to prevent console errors +} + +// --------------------------------------------------------------------------------------- +// deployed station functions +function DeployedStationInventory::onEndSequence(%data, %obj, %thread) +{ + Parent::onEndSequence(%data, %obj, %thread); + if(%thread == $DeployThread) + { + %trigger = new Trigger() + { + dataBlock = stationTrigger; + polyhedron = "-0.125 0.0 0.1 0.25 0.0 0.0 0.0 -0.7 0.0 0.0 0.0 1.0"; + }; + MissionCleanup.add(%trigger); + + %trans = %obj.getTransform(); + %vSPos = getWords(%trans,0,2); + %vRot = getWords(%trans,3,5); + %vAngle = getWord(%trans,6); + %matrix = VectorOrthoBasis(%vRot @ " " @ %vAngle + 0.0); + %yRot = getWords(%matrix, 3, 5); + %pos = vectorAdd(%vSPos, vectorScale(%yRot, -0.1)); + + %trigger.setTransform(%pos @ " " @ %vRot @ " " @ %vAngle); + + // associate the trigger with the station + %trigger.station = %obj; + %trigger.mainObj = %obj; + %trigger.disableObj = %obj; + %obj.trigger = %trigger; + } +} + +//-------------------------------------------------------------------------- +//DeployedMotionSensor: +//-------------------------------------------------------------------------- + +function DeployedMotionSensor::onDestroyed(%this, %obj, %prevState) +{ + //%obj.hide(true); + Parent::onDestroyed(%this, %obj, %prevState); + $TeamDeployedCount[%obj.team, MotionSensorDeployable]--; + %obj.schedule(500, "delete"); +} + +//-------------------------------------------------------------------------- +//DeployedPulseSensor: +//-------------------------------------------------------------------------- +function PulseSensorDeployableImage::onActivate(%data, %obj, %slot) +{ + Parent::onActivate( %data, %obj, %slot ); + //%data.testInvalidDeployConditions(%obj, %slot); +} + +function DeployedPulseSensor::onDestroyed(%this, %obj, %prevState) +{ + Parent::onDestroyed(%this, %obj, %prevState); + $TeamDeployedCount[%obj.team, PulseSensorDeployable]--; + %obj.schedule(300, "delete"); +} + +// --------------------------------------------------------------------------------------- +// deployed turret functions + +function DeployedTurret::onAdd(%data, %obj) +{ + Parent::onAdd(%data, %obj); + // auto-mount the barrel + %obj.mountImage(%data.barrel, 0, false); +} + +function DeployedTurret::onDestroyed(%this, %obj, %prevState) +{ + Parent::onDestroyed(%this, %obj, %prevState); + %turType = %this.getName(); + // either it'll be an outdoor turret, or one of the three types of indoor turret + // (floor, ceiling, wall) + if(%turType $= "TurretDeployedOutdoor") + %turType = "TurretOutdoorDeployable"; + else + %turType = "TurretIndoorDeployable"; + + // decrement team count + $TeamDeployedCount[%obj.team, %turType]--; + + %obj.schedule(700, "delete"); +} + +function countTurretsAllowed(%type) +{ + for(%j = 1; %j < Game.numTeams; %j++) + %teamPlayerCount[%j] = 0; + %numClients = ClientGroup.getCount(); + for(%i = 0; %i < %numClients; %i++) + { + %cl = ClientGroup.getObject(%i); + if(%cl.team > 0) + %teamPlayerCount[%cl.team]++; + } + // the bigger team determines the number of turrets allowed + %maxPlayers = %teamPlayerCount[1] > %teamPlayerCount[2] ? %teamPlayerCount[1] : %teamPlayerCount[2]; + // each team can have 1 turret of each type (indoor/outdoor) for every 2 players + // minimum and maximums are defined in deployables.cs + %teamTurretMax = mFloor(%maxPlayers / 2); + if(%teamTurretMax < $TeamDeployableMin[%type]) + %teamTurretMax = $TeamDeployableMin[%type]; + else if(%teamTurretMax > $TeamDeployableMax[%type]) + %teamTurretMax = $TeamDeployableMax[%type]; + + return %teamTurretMax; +} diff --git a/scripts/hud.cs b/scripts/hud.cs index b08789b..8224607 100644 --- a/scripts/hud.cs +++ b/scripts/hud.cs @@ -1,1848 +1,1852 @@ -//-------------------------------------------------------------------------- -function GameConnection::sensorPing(%this, %ping) -{ - sensorHud.ping = %ping; - sensorHud.update(); -} - -function GameConnection::sensorJammed(%this, %jam) -{ - sensorHud.jam = %jam; - sensorHud.update(); -} - -function SensorHud::update(%this) -{ - if(!%this.ping && !%this.jam) - { - %this.setVisible(false); - sensorHudBack.setVisible(true); - return; - } - - %this.setVisible(true); - sensorHudBack.setVisible(false); - - if(%this.jam) - %this.color = %this.jamColor; - else - %this.color = %this.pingColor; -} - -// - anything which should be reset on new server/mission -function clientCmdResetHud() -{ - deploySensor.setVisible(false); - controlObjectText.setVisible(false); - - sensorHud.jam = false; - sensorHud.ping = false; - sensorHud.update(); -} - -//-------------------------------------------------------------------------- -$vehicleReticle[AssaultVehicle, 1, bitmap] = "gui/hud_ret_tankchaingun"; -$vehicleReticle[AssaultVehicle, 1, frame] = true; -$vehicleReticle[AssaultVehicle, 2, bitmap] = "gui/hud_ret_tankmortar"; -$vehicleReticle[AssaultVehicle, 2, frame] = true; - -$vehicleReticle[BomberFlyer, 1, bitmap] = "gui/hud_ret_shrike"; -$vehicleReticle[BomberFlyer, 1, frame] = false; -$vehicleReticle[BomberFlyer, 2, bitmap] = ""; -$vehicleReticle[BomberFlyer, 2, frame] = false; -$vehicleReticle[BomberFlyer, 3, bitmap] = "gui/hud_ret_targlaser"; -$vehicleReticle[BomberFlyer, 3, frame] = false; - -function GameConnection::setVWeaponsHudActive(%client, %slot) -{ - %veh = %client.player.getObjectMount(); - %vehType = %veh.getDatablock().getName(); - commandToClient(%client, 'setVWeaponsHudActive', %slot, %vehType); -} - -function clientCmdSetVWeaponsHudActive(%num, %vType) -{ - //vWeaponsBox.setActiveWeapon(%num); - if(%num > $numVWeapons) - %num = $numVWeapons; - - for(%i = 1; %i <= $numVWeapons; %i++) - { - %oldHilite = "vWeap" @ %i @ "Hilite"; - %oldHilite.setVisible(false); - } - %newHilite = "vWeap" @ %num @ "Hilite"; - %newHilite.setVisible(true); - - // set the bitmap and frame for the reticle - reticleHud.setBitmap($vehicleReticle[%vType, %num, bitmap]); - reticleFrameHud.setVisible($vehicleReticle[%vType, %num, frame]); -} - -function GameConnection::setVWeaponsHudClearAll(%client) -{ - commandToClient(%client, 'setVWeaponsHudClearAll'); -} - -function clientCmdSetVWeaponsHudClearAll() -{ - //vWeaponsBox.clearAll(); -} - -//---------------------------------------------------------------------------- -//---------------------------------------------------------------------------- -function GameConnection::setWeaponsHudBitmap(%client, %slot, %name, %bitmap) -{ - commandToClient(%client, 'setWeaponsHudBitmap',%slot,%name,%bitmap); -} - -//---------------------------------------------------------------------------- -function clientCmdSetWeaponsHudBitmap(%slot, %name, %bitmap) -{ - $WeaponNames[%slot] = %name; - weaponsHud.setWeaponBitmap(%slot,%bitmap); -} - -//---------------------------------------------------------------------------- -function GameConnection::setWeaponsHudItem(%client, %name, %ammoAmount, %addItem) -{ - //error("GC:SWHI name="@%name@",ammoAmount="@%ammoAmount@",addItem="@%addItem); -// for(%i = 0; %i < $WeaponsHudCount; %i++) -// if($WeaponsHudData[%i, itemDataName] $= %name) -// { -// if($WeaponsHudData[%i, ammoDataName] !$= "") { -// %ammoInv = %client.player.inv[$WeaponsHudData[%i, ammoDataName]]; -// //error(" ----- player has " @ %ammoInv SPC $WeaponsHudData[%i, ammoDataName]); -// //error("SWHI:Setting weapon "@%name@" ("@%i@") ammo to " @ %ammoInv); -// commandToClient(%client, 'setWeaponsHudItem',%i,%ammoInv, %addItem); -// } -// else { -// //error("SWHI:Setting weapon "@%name@" ("@%i@") ammo to infinite"); -// commandToClient(%client, 'setWeaponsHudItem',%i,-1, %addItem); -// } -// break; -// } - - - // My try... - for(%i = 0; %i < $WeaponsHudCount; %i++) - if($WeaponsHudData[%i, itemDataName] $= %name) - { - if($WeaponsHudData[%i, ammoDataName] !$= "") { - %ammoInv = %client.player.inv[$WeaponsHudData[%i, ammoDataName]]; - //error(" ----- player has " @ %ammoInv SPC $WeaponsHudData[%i, ammoDataName]); - //error("SWHI:Setting weapon "@%name@" ("@%i@") ammo to " @ %ammoInv); - commandToClient(%client, 'setWeaponsHudItem',%i,%ammoInv, %addItem); - } - else { - //error("SWHI:Setting weapon "@%name@" ("@%i@") ammo to infinite"); - commandToClient(%client, 'setWeaponsHudItem',%i,-1, %addItem); - } - break; - } -} - -//---------------------------------------------------------------------------- -function clientCmdSetWeaponsHudItem(%slot, %ammoAmount, %addItem) -{ - if(%addItem) { - //error("adding weapon to hud in slot " @ %slot @ " with ammo " @ %ammoAmount); - weaponsHud.addWeapon(%slot, %ammoAmount); - } - else { - //error("removing weapon from hud"); - weaponsHud.removeWeapon(%slot); - } -} - -//---------------------------------------------------------------------------- -function GameConnection::setWeaponsHudAmmo(%client, %name, %ammoAmount) -{ - for(%i = 0; %i < $WeaponsHudCount; %i++) - if($WeaponsHudData[%i, ammoDataName] $= %name) - { - //error("SWHA:Setting ammo "@%name@" for weapon "@%i@" to " @ %ammoAmount); - commandToClient(%client, 'setWeaponsHudAmmo',%i, %ammoAmount); - break; - } -} - -//---------------------------------------------------------------------------- -function clientCmdSetWeaponsHudAmmo(%slot, %ammoAmount) -{ - weaponsHud.setAmmo(%slot, %ammoAmount); -} - -//---------------------------------------------------------------------------- -// z0dd - ZOD, 9/13/02. Serverside reticles, sever tells client what file to use. -function GameConnection::setWeaponsHudActive(%client, %name, %clearActive) -{ - if(%clearActive) - { - commandToClient(%client, 'setWeaponsHudActive', -1); - } - else - { - for(%i = 0; %i < $WeaponsHudCount; %i++) - { - if($WeaponsHudData[%i, itemDataName] $= %name) - { - commandToClient(%client, 'setWeaponsHudActive', %i, $WeaponsHudData[%i, reticle], $WeaponsHudData[%i, visible]); - break; - } - } - } -} -//---------------------------------------------------------------------------- - -//------------------------------------------------------------------------------ -// z0dd- ZOD, 9/13/02. Serverside reticles, sever tells client what file to use. -// Total Rewrite. -function clientCmdSetWeaponsHudActive(%slot, %ret, %vis) -{ - // z0dd - ZOD, 9/30/02. Changed for lazy scripter backward compatibility. - weaponsHud.setActiveWeapon(%slot); - switch$($WeaponNames[%slot]) - { - case "Blaster": - reticleHud.setBitmap("gui/ret_blaster"); - reticleFrameHud.setVisible(true); - case "Plasma": - reticleHud.setBitmap("gui/ret_plasma"); - reticleFrameHud.setVisible(true); - case "Chaingun": - reticleHud.setBitmap("gui/ret_chaingun"); - reticleFrameHud.setVisible(true); - case "Disc": - reticleHud.setBitmap("gui/ret_disc"); - reticleFrameHud.setVisible(true); - case "GrenadeLauncher": - reticleHud.setBitmap("gui/ret_grenade"); - reticleFrameHud.setVisible(true); - case "SniperRifle": - reticleHud.setBitmap("gui/hud_ret_sniper"); - reticleFrameHud.setVisible(false); - case "ELFGun": - reticleHud.setBitmap("gui/ret_elf"); - reticleFrameHud.setVisible(true); - case "Mortar": - reticleHud.setBitmap("gui/ret_mortor"); - reticleFrameHud.setVisible(true); - case "MissileLauncher": - reticleHud.setBitmap("gui/ret_missile"); - reticleFrameHud.setVisible(true); - case "ShockLance": - reticleHud.setBitmap("gui/hud_ret_shocklance"); - reticleFrameHud.setVisible(false); - case "TargetingLaser": - reticleHud.setBitmap("gui/hud_ret_targlaser"); - reticleFrameHud.setVisible(false); - default: - reticleHud.setBitmap(%ret); - reticleFrameHud.setVisible(%vis); - } -} - -//------------------------------------------------------------------------------ - -function clientCmdSetRepairReticle() -{ - reticleHud.setBitmap("gui/ret_chaingun"); - reticleFrameHud.setVisible(true); -} - -//---------------------------------------------------------------------------- -function GameConnection::setWeaponsHudBackGroundBmp(%client, %name) -{ - commandToClient(%client, 'setWeaponsHudBackGroundBmp',%name); -} - -//---------------------------------------------------------------------------- -function clientCmdSetWeaponsHudBackGroundBmp(%name) -{ - weaponsHud.setBackGroundBitmap(%name); -} - -//---------------------------------------------------------------------------- -function GameConnection::setWeaponsHudHighLightBmp(%client, %name) -{ - commandToClient(%client, 'setWeaponsHudHighLightBmp',%name); -} - -//---------------------------------------------------------------------------- -function clientCmdSetWeaponsHudHighLightBmp(%name) -{ - weaponsHud.setHighLightBitmap(%name); -} - -//---------------------------------------------------------------------------- -function GameConnection::setWeaponsHudInfiniteAmmoBmp(%client, %name) -{ - commandToClient(%client, 'setWeaponsHudInfiniteAmmoBmp',%name); -} - -//---------------------------------------------------------------------------- -function clientCmdSetWeaponsHudInfiniteAmmoBmp(%name) -{ - weaponsHud.setInfiniteAmmoBitmap(%name); -} -//---------------------------------------------------------------------------- -function GameConnection::setWeaponsHudClearAll(%client) -{ - commandToClient(%client, 'setWeaponsHudClearAll'); -} - -//---------------------------------------------------------------------------- -function clientCmdSetWeaponsHudClearAll() -{ - weaponsHud.clearAll(); -} - -//---------------------------------------------------------------------------- -// Ammo Hud -//---------------------------------------------------------------------------- -function GameConnection::setAmmoHudCount(%client, %amount) -{ - commandToClient(%client, 'setAmmoHudCount', %amount); -} - -//---------------------------------------------------------------------------- -function clientCmdSetAmmoHudCount(%amount) -{ - if(%amount == -1) - ammoHud.setValue(""); - else - ammoHud.setValue(%amount); -} - -//---------------------------------------------------------------------------- -// Backpack Hud -//---------------------------------------------------------------------------- - -$BackpackHudData[0, itemDataName] = "AmmoPack"; -$BackpackHudData[0, bitmapName] = "gui/hud_new_packammo"; -$BackpackHudData[1, itemDataName] = "CloakingPack"; -$BackpackHudData[1, bitmapName] = "gui/hud_new_packcloak"; -$BackpackHudData[2, itemDataName] = "EnergyPack"; -$BackpackHudData[2, bitmapName] = "gui/hud_new_packenergy"; -$BackpackHudData[3, itemDataName] = "RepairPack"; -$BackpackHudData[3, bitmapName] = "gui/hud_new_packrepair"; -$BackpackHudData[4, itemDataName] = "SatchelCharge"; -$BackpackHudData[4, bitmapName] = "gui/hud_new_packsatchel"; -$BackpackHudData[5, itemDataName] = "ShieldPack"; -$BackpackHudData[5, bitmapName] = "gui/hud_new_packshield"; -$BackpackHudData[6, itemDataName] = "InventoryDeployable"; -$BackpackHudData[6, bitmapName] = "gui/hud_new_packinventory"; -$BackpackHudData[7, itemDataName] = "MotionSensorDeployable"; -$BackpackHudData[7, bitmapName] = "gui/hud_new_packmotionsens"; -$BackpackHudData[8, itemDataName] = "PulseSensorDeployable"; -$BackpackHudData[8, bitmapName] = "gui/hud_new_packradar"; -$BackpackHudData[9, itemDataName] = "TurretOutdoorDeployable"; -$BackpackHudData[9, bitmapName] = "gui/hud_new_packturretout"; -$BackpackHudData[10, itemDataName] = "TurretIndoorDeployable"; -$BackpackHudData[10, bitmapName] = "gui/hud_new_packturretin"; -$BackpackHudData[11, itemDataName] = "SensorJammerPack"; -$BackpackHudData[11, bitmapName] = "gui/hud_new_packsensjam"; -$BackpackHudData[12, itemDataName] = "AABarrelPack"; -$BackpackHudData[12, bitmapName] = "gui/hud_new_packturret"; -$BackpackHudData[13, itemDataName] = "FusionBarrelPack"; -$BackpackHudData[13, bitmapName] = "gui/hud_new_packturret"; -$BackpackHudData[14, itemDataName] = "MissileBarrelPack"; -$BackpackHudData[14, bitmapName] = "gui/hud_new_packturret"; -$BackpackHudData[15, itemDataName] = "PlasmaBarrelPack"; -$BackpackHudData[15, bitmapName] = "gui/hud_new_packturret"; -$BackpackHudData[16, itemDataName] = "ELFBarrelPack"; -$BackpackHudData[16, bitmapName] = "gui/hud_new_packturret"; -$BackpackHudData[17, itemDataName] = "MortarBarrelPack"; -$BackpackHudData[17, bitmapName] = "gui/hud_new_packturret"; -$BackpackHudData[18, itemDataName] = "SatchelUnarmed"; -$BackpackHudData[18, bitmapName] = "gui/hud_satchel_unarmed"; - -// --------------------------------------------------------- -// z0dd - ZOD, 9/12/02. TR2 need -// TR2 -$BackpackHudData[19, itemDataName] = "TR2EnergyPack"; -$BackpackHudData[19, bitmapName] = "gui/hud_new_packenergy"; -// --------------------------------------------------------- - -$BackpackHudCount = 20; - -function GameConnection::clearBackpackIcon(%client) -{ - commandToClient(%client, 'setBackpackHudItem', 0, 0); -} - -function GameConnection::setBackpackHudItem(%client, %name, %addItem) -{ - for(%i = 0; %i < $BackpackHudCount; %i++) - if($BackpackHudData[%i, itemDataName] $= %name) - commandToClient(%client, 'setBackpackHudItem', %i, %addItem); -} - -function clientCmdSetBackpackHudItem(%num, %addItem) -{ - if(%addItem) - { - backpackIcon.setBitmap($BackpackHudData[%num, bitmapName]); - backpackFrame.setVisible(true); - backpackIcon.setVisible(true); - backpackFrame.pack = true; - } - else - { - backpackIcon.setBitmap(""); - backpackFrame.setVisible(false); - backpackText.setValue(""); - backpackText.setVisible(false); - backpackFrame.pack = false; - } -} - -function GameConnection::updateSensorPackText(%client, %num) -{ - commandToClient(%client, 'updatePackText', %num); -} - -function clientCmdUpdatePackText(%num) -{ - backpackText.setValue(%num); - if(%num == 0) - backpackText.setVisible(false); - else - backpackText.setVisible(true); -} - -// Pack Icons Activate / Deactivate -function clientCmdSetSatchelArmed() -{ - backpackIcon.setBitmap( "gui/hud_satchel_armed" ); -} - -function clientCmdsetCloakIconOn() -{ - backpackIcon.setBitmap( "gui/hud_new_packcloak_armed" ); -} - -function clientCmdsetCloakIconOff() -{ - backpackIcon.setBitmap( "gui/hud_new_packcloak" ); -} - -function clientCmdsetRepairPackIconOn() -{ - backpackIcon.setBitmap( "gui/hud_new_packrepair_armed" ); -} - -function clientCmdsetRepairPackIconOff() -{ - backpackIcon.setBitmap( "gui/hud_new_packrepair" ); -} - -function clientCmdsetShieldIconOn() -{ - backpackIcon.setBitmap( "gui/hud_new_packshield_armed" ); -} - -function clientCmdsetShieldIconOff() -{ - backpackIcon.setBitmap( "gui/hud_new_packshield" ); -} - -function clientCmdsetSenJamIconOn() -{ - backpackIcon.setBitmap( "gui/hud_new_packsensjam_armed" ); -} - -function clientCmdsetSenJamIconOff() -{ - backpackIcon.setBitmap( "gui/hud_new_packsensjam" ); -} - - -//---------------------------------------------------------------------------- -//---------------------------------------------------------------------------- -$InventoryHudData[0, bitmapName] = "gui/hud_handgren"; -$InventoryHudData[0, itemDataName] = Grenade; -$InventoryHudData[0, ammoDataName] = Grenade; -$InventoryHudData[0, slot] = 0; -$InventoryHudData[1, bitmapName] = "gui/hud_mine"; -$InventoryHudData[1, itemDataName] = Mine; -$InventoryHudData[1, ammoDataName] = Mine; -$InventoryHudData[1, slot] = 1; -$InventoryHudData[2, bitmapName] = "gui/hud_medpack"; -$InventoryHudData[2, itemDataName] = RepairKit; -$InventoryHudData[2, ammoDataName] = RepairKit; -$InventoryHudData[2, slot] = 3; -$InventoryHudData[3, bitmapName] = "gui/hud_whiteout_gren"; -$InventoryHudData[3, itemDataName] = FlashGrenade; -$InventoryHudData[3, ammoDataName] = FlashGrenade; -$InventoryHudData[3, slot] = 0; -$InventoryHudData[4, bitmapName] = "gui/hud_concuss_gren"; -$InventoryHudData[4, itemDataName] = ConcussionGrenade; -$InventoryHudData[4, ammoDataName] = ConcussionGrenade; -$InventoryHudData[4, slot] = 0; -$InventoryHudData[5, bitmapName] = "gui/hud_handgren"; -$InventoryHudData[5, itemDataName] = FlareGrenade; -$InventoryHudData[5, ammoDataName] = FlareGrenade; -$InventoryHudData[5, slot] = 0; -$InventoryHudData[6, bitmapName] = "gui/hud_handgren"; -$InventoryHudData[6, itemDataName] = CameraGrenade; -$InventoryHudData[6, ammoDataName] = CameraGrenade; -$InventoryHudData[6, slot] = 0; -$InventoryHudData[7, bitmapName] = "gui/hud_beacon"; -$InventoryHudData[7, itemDataName] = Beacon; -$InventoryHudData[7, ammoDataName] = Beacon; -$InventoryHudData[7, slot] = 2; - -// ----------------------------------------------------- -// z0dd - ZOD, 9/12/02. TR2 need -//$InventoryHudCount = 8; -$InventoryHudData[8, bitmapName] = "gui/hud_handgren"; -$InventoryHudData[8, itemDataName] = TR2Grenade; -$InventoryHudData[8, ammoDataName] = TR2Grenade; -$InventoryHudData[8, slot] = 0; -$InventoryHudCount = 9; -// ----------------------------------------------------- - - -//---------------------------------------------------------------------------- -// Inventory Hud -//---------------------------------------------------------------------------- -//------------------------------------------------------------------------- --- -function GameConnection::setInventoryHudBitmap(%client, %slot, %name, %bitmap) -{ - commandToClient(%client, 'setInventoryHudBitmap',%slot,%name,%bitmap); -} - -//---------------------------------------------------------------------------- -function clientCmdSetInventoryHudBitmap(%slot, %name, %bitmap) -{ - inventoryHud.setInventoryBitmap(%slot,%bitmap); -} - -//---------------------------------------------------------------------------- -function GameConnection::setInventoryHudItem(%client, %name, %amount, %addItem) -{ - for(%i = 0; %i < $InventoryHudCount; %i++) - if($InventoryHudData[%i, itemDataName] $= %name) - { - if($InventoryHudData[%i, ammoDataName] !$= "") - commandToClient(%client, 'setInventoryHudItem',$InventoryHudData[%i, slot],%amount, %addItem); - else - commandToClient(%client, 'setInventoryHudItem',$InventoryHudData[%i, slot],-1, %addItem); - break; - } -} - -//---------------------------------------------------------------------------- -function clientCmdSetInventoryHudItem(%slot, %amount, %addItem) -{ - if(%addItem) - inventoryHud.addInventory(%slot, %amount); - else - inventoryHud.removeInventory(%slot); -} - -//---------------------------------------------------------------------------- -function GameConnection::setInventoryHudAmount(%client, %name, %amount) -{ - for(%i = 0; %i < $InventoryHudCount; %i++) - if($InventoryHudData[%i, ammoDataName] $= %name) - { - commandToClient(%client, 'setInventoryHudAmount',$InventoryHudData[%i, slot], %amount); - break; - } -} - -//---------------------------------------------------------------------------- -function clientCmdSetInventoryHudAmount(%slot, %amount) -{ - inventoryHud.setAmount(%slot, %amount); -} - -//---------------------------------------------------------------------------- -function GameConnection::setInventoryHudBackGroundBmp(%client, %name) -{ - commandToClient(%client, 'setInventoryHudBackGroundBmp',%name); -} - -//---------------------------------------------------------------------------- -function clientCmdSetInventoryHudBackGroundBmp(%name) -{ - inventoryHud.setBackGroundBitmap(%name); -} - -//---------------------------------------------------------------------------- -function GameConnection::setInventoryHudClearAll(%client) -{ - commandToClient(%client, 'setInventoryHudClearAll'); -} - -//---------------------------------------------------------------------------- -function clientCmdSetInventoryHudClearAll() -{ - inventoryHud.clearAll(); - backpackIcon.setBitmap( "" ); - backpackFrame.setVisible( false ); - backpackText.setValue( "" ); - backpackText.setVisible(false); - backpackFrame.pack = false; -} - -//---------------------------------------------------------------------------- -// MessageHud -function MessageHud::open(%this) -{ - %offset = 6; - - if(%this.isVisible()) - return; - - if(%this.isTeamMsg) - %text = "TEAM:"; - else - %text = "GLOBAL:"; - - MessageHud_Text.setValue(%text); - - %windowPos = "8 " @ ( getWord( outerChatHud.position, 1 ) + getWord( outerChatHud.extent, 1 ) + 1 ); - %windowExt = getWord( OuterChatHud.extent, 0 ) @ " " @ getWord( MessageHud_Frame.extent, 1 ); - - if( MainVoteHud.isVisible() ) - { - %votePos = firstWord( MainVoteHud.position ) @ " " @ ( getWord( OuterChatHud.extent, 1 ) + getWord( messageHud_Frame.extent, 1 ) + 10 ); - MainVoteHud.position = %votePos; - } - - if( voiceCommHud.isVisible() ) - { - %vCommPos = firstWord( voiceCommHud.position ) SPC ( getWord( OuterChatHud.extent, 1 ) + getWord( messageHud_Frame.extent, 1 ) + 18 ); - voiceCommHud.position = %vCommPos; - } - - %textExtent = getWord(MessageHud_Text.extent, 0); - %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); - deactivateKeyboard(); - MessageHud_Edit.makeFirstResponder(true); -} - -//------------------------------------------------------------------------------ -function MessageHud::close(%this) -{ - if(!%this.isVisible()) - return; - - // readjust vote hud if open - if( MainVoteHud.isVisible() ) - { - %tempY = getWord(outerChatHud.position, 1) + getWord(outerChatHud.extent, 1) + 2; - %mainVoteX = firstWord(mainVoteHud.position); - %voteHudPos = %mainVoteX SPC %tempY; - mainVoteHud.position = %voteHudPos; - } - // put voice comm hud back where it was (if it moved) - %vTempY = getWord(outerChatHud.position, 1) + getWord(outerChatHud.extent, 1) + 12; - %mainCommX = firstWord(voiceCommHud.position); - %commHudPos = %mainCommX SPC %vTempY; - voiceCommHud.position = %commHudPos; - - Canvas.popDialog(%this); - %this.setVisible(false); - if ( $enableDirectInput ) - activateKeyboard(); - 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 = trim(%this.getValue()); - if(%text !$= "") - { - if(MessageHud.isTeamMsg) - commandToServer('teamMessageSent', %text); - else - commandToServer('messageSent', %text); - } - - MessageHud.close(); -} - -//------------------------------------------------------------------------------ -// main chat hud -function MainChatHud::onWake( %this ) -{ - // set the chat hud to the users pref - %this.setChatHudLength( $Pref::ChatHudLength ); -} - -// chat hud sizes -$outerChatLenY[1] = 72; -$outerChatLenY[2] = 140; -$outerChatLenY[3] = 200; - -// size for scroll -$chatScrollLenY[1] = 64; -$chatScrollLenY[2] = 128; -$chatScrollLenY[3] = 192; - -//------------------------------------------------------------------------------ -function MainChatHud::setChatHudLength( %this, %length ) -{ - %outerChatLenX = firstWord(outerChatHud.extent); - %chatScrollLenX = firstWord(chatScrollHud.extent); - %OCHextent = %outerChatLenX SPC $outerChatLenY[%length]; - %CSHextent = %chatScrollLenX SPC $chatScrollLenY[%length]; - - outerChatHud.extent = %OCHextent; - chatScrollHud.extent = %CSHextent; - - %totalLines = HudMessageVector.getNumLines(); - %posLines = %length * 4; - %linesOver = ( %totalLines - %posLines ) * 14; - ChatPageDown.position = ( firstWord( outerChatHud.extent ) - 20 ) @ " " @ ( $chatScrollLenY[%length] - 6 ); - - if( ( %linesOver > 0 ) && !%sizeIncrease ) - { - %linesOver = %totalLines - %posLines; - %posAdjust = %linesOver * ChatHud.profile.fontSize + 3; - - %newPos = "0" @ " " @ ( -1 * %posAdjust ); - ChatHud.position = %newPos; - } - else if( %sizeIncrease && ( %linesOver > 0 ) ) - { - %curPos = getWord( ChatHud.position, 1 ); - %newY = %curPos + ( 4 * 14 ); - %newPos = "0 " @ %newY; - ChatHud.position = %newPos; - } - else if( %linesOver <= 0 ) - { - ChatHud.position = "0 0"; - } - - // adjust votehud and voicecommhud to be just beneath chathud - %tempY = getWord(outerChatHud.position, 1) + getWord(outerChatHud.extent, 1) + 2; - %vTempY = %tempY + 10; - %mainVoteX = firstWord(mainVoteHud.position); - %vCommX = firstWord(voiceCommHud.position); - %voteHudPos = %mainVoteX SPC %tempY; - %vCommPos = %vCommX SPC %vTempY; - mainVoteHud.position = %voteHudPos; - voiceCommHud.position = %vCommPos; - ChatHud.resize(firstWord(ChatHud.position), getWord(ChatHud.position, 1), firstWord(ChatHud.extent), getWord(ChatHud.extent, 1)); -} - -//------------------------------------------------------------------------------ -function MainChatHud::nextChatHudLen( %this ) -{ - $pref::chatHudLength++; - if($pref::chatHudLength == 4) - { - $pref::chatHudLength = 1; - %sizeIncrease = false; - ChatPageDown.position = ( firstWord( outerChatHud.extent ) - 20 ) @ " 50"; - } - else - %sizeIncrease = true; - - %outerChatLenX = firstWord(outerChatHud.extent); - %chatScrollLenX = firstWord(chatScrollHud.extent); - %OCHextent = %outerChatLenX SPC $outerChatLenY[$pref::chatHudLength]; - %CSHextent = %chatScrollLenX SPC $chatScrollLenY[$pref::chatHudLength]; - - outerChatHud.extent = %OCHextent; - chatScrollHud.extent = %CSHextent; - - %totalLines = HudMessageVector.getNumLines(); - %posLines = $pref::chatHudLength * 4; - %linesOver = %totalLines - %posLines; - ChatPageDown.position = ( firstWord( outerChatHud.extent ) - 20 ) @ " " @ ( $chatScrollLenY[$pref::chatHudLength] - 6 ); - - if( ( %linesOver > 0 ) && !%sizeIncrease ) - { - %linesOver = %totalLines - %posLines; - %posAdjust = %linesOver * $ShellFontSize; - - %newPos = "0" @ " " @ ( -1 * %posAdjust ); - ChatHud.position = %newPos; - } - else if( %sizeIncrease && ( %linesOver > 0 ) ) - { - %curPos = getWord( ChatHud.position, 1 ); - %newY = %curPos + ( 4 * $ShellFontSize ); - %newPos = "0 " @ %newY; - ChatHud.position = %newPos; - } - else if( %linesOver <= 0 ) - { - ChatHud.position = "0 0"; - } - - // adjust votehud to be just beneath chathud - %tempY = getWord(outerChatHud.position, 1) + getWord(outerChatHud.extent, 1) + 2; - %vTempY = %tempY + 10; - %mainVoteX = firstWord(mainVoteHud.position); - %vCommX = firstWord(voiceCommHud.position); - %voteHudPos = %mainVoteX SPC %tempY; - %vCommPos = %vCommX SPC %vTempY; - mainVoteHud.position = %voteHudPos; - voiceCommHud.position = %vCommPos; - ChatHud.resize(firstWord(ChatHud.position), getWord(ChatHud.position, 1), firstWord(ChatHud.extent), getWord(ChatHud.extent, 1)); -} - -//---------------------------------------------------------------------------- -// MessageHud key handlers -function ToggleMessageHud(%make) -{ - if(%make) - { - MessageHud.isTeamMsg = false; - MessageHud.toggleState(); - } -} - -//------------------------------------------------------------------------------ -function TeamMessageHud(%make) -{ - if(%make) - { - MessageHud.isTeamMsg = true; - MessageHud.toggleState(); - } -} - -//---------------------------------------------------------------------------- -// MessageHud message handlers -function serverCmdTeamMessageSent(%client, %text) -{ - if(strlen(%text) >= $Host::MaxMessageLen) - %text = getSubStr(%text, 0, $Host::MaxMessageLen); - chatMessageTeam(%client, %client.team, '\c3%1: %2', %client.name, %text); -} - -//------------------------------------------------------------------------------ -function serverCmdMessageSent(%client, %text) -{ - if(strlen(%text) >= $Host::MaxMessageLen) - %text = getSubStr(%text, 0, $Host::MaxMessageLen); - chatMessageAll(%client, '\c4%1: %2', %client.name, %text); -} - -//-------------------------------------------------------------------------- -function toggleHuds(%tag) -{ - if($Hud[%tag] && $Hud[%tag].pushed) - hideHud(%tag); - else - showHud(%tag); -} - -//------------------------------------------------------------------------------ - -//modes are standard, pilot, passenger, object, observer -$HudMode = "Observer"; -$HudModeType = "HoverBike"; -$HudModeNode = 0; -function ClientCmdSetHudMode(%mode, %type, %node) -{ - $HudMode = detag(%mode); - $HudModeType = detag(%type); - $HudModeNode = %node; - - clientCmdDisplayHuds(); -} - -//------------------------------------------------------------------------------ -$ControlObjectReticle[AABarrelLarge, bitmap] = "ret_chaingun"; -$ControlObjectReticle[AABarrelLarge, frame] = true; -$ControlObjectReticle[ELFBarrelLarge, bitmap] = "ret_elf"; -$ControlObjectReticle[ELFBarrelLarge, frame] = true; -$ControlObjectReticle[DeployableIndoorBarrel, bitmap] = "ret_blaster"; -$ControlObjectReticle[DeployableIndoorBarrel, frame] = true; -$ControlObjectReticle[MissileBarrelLarge, bitmap] = "ret_missile"; -$ControlObjectReticle[MissileBarrelLarge, frame] = true; -$ControlObjectReticle[MortarBarrelLarge, bitmap] = "ret_mortor"; // mortor? hahaha -$ControlObjectReticle[MortarBarrelLarge, frame] = true; -$ControlObjectReticle[DeployableOutdoorBarrel, bitmap] = "ret_blaster"; -$ControlObjectReticle[DeployableOutdoorBarrel, frame] = true; -$ControlObjectReticle[PlasmaBarrelLarge, bitmap] = "ret_plasma"; -$ControlObjectReticle[PlasmaBarrelLarge, frame] = true; -$ControlObjectReticle[SentryTurretBarrel, bitmap] = "ret_blaster"; -$ControlObjectReticle[SentryTurretBarrel, frame] = true; - -function setControlObjectReticle(%type) -{ - if($ControlObjectReticle[%type, bitmap] !$= "") - { - reticleHud.setBitmap("gui/" @ $ControlObjectReticle[%type, bitmap]); - reticleFrameHud.setVisible($ControlObjectReticle[%type, frame]); - - retCenterHud.setVisible(true); - } - else - retCenterHud.setVisible(false); -} - -function updateActionMaps() -{ - //pop the action maps... - if ( isObject( moveMap ) ) - moveMap.pop(); - if ( isObject( passengerKeys ) ) - passengerKeys.pop(); - if ( isObject( observerBlockMap ) ) - observerBlockMap.pop(); - if ( isObject( observerMap ) ) - observerMap.pop(); - if ( isObject( pickTeamMap ) ) - pickTeamMap.pop(); - if ( isObject( halftimeMap ) ) - halftimeMap.delete(); - - //if (isObject(flyingCameraMove)) - // flyingCameraMove.pop(); - if (isObject(ControlActionMap)) - ControlActionMap.pop(); - - // push the proper map - switch$ ($HudMode) - { - case "Pilot": - passengerKeys.push(); - - case "Passenger": - moveMap.push(); - - case "Object": - moveMap.push(); - ControlActionMap.push(); - - case "Observer": - moveMap.push(); - if ( isObject( observerBlockMap ) ) - observerBlockMap.delete(); - // Create an action map just to block unwanted parts of the move map: - new ActionMap( observerBlockMap ); - observerBlockMap.blockBind( moveMap, jump ); - observerBlockMap.blockBind( moveMap, mouseFire ); - observerBlockMap.blockBind( moveMap, mouseJet ); - observerBlockMap.blockBind( moveMap, toggleZoom ); - observerBlockMap.blockBind( moveMap, setZoomFOV ); - observerBlockMap.push(); - observerMap.push(); - // Make sure that "Spawn" is bound: - if ( observerMap.getBinding( mouseFire ) $= "" ) - observerMap.copyBind( moveMap, mouseFire ); - - case "PickTeam": - //////////////////////// - // pickTeam Keys - ////////////////////// - if( !isObject( pickTeamMap ) ) - new ActionMap( pickTeamMap ); - pickTeamMap.copyBind( moveMap, toggleMessageHud ); - pickTeamMap.push(); - - case "SiegeHalftime": - new ActionMap( halftimeMap ); - halftimeMap.bindCmd( keyboard, escape, "", "escapeFromGame();" ); - halftimeMap.copyBind( moveMap, toggleMessageHud ); - halftimeMap.copyBind( moveMap, teamMessageHud ); - halftimeMap.copyBind( moveMap, activateChatMenuHud ); - halftimeMap.copyBind( moveMap, resizeChatHud ); - halftimeMap.copyBind( moveMap, pageMessageHudUp ); - halftimeMap.copyBind( moveMap, pageMessageHudDown ); - halftimeMap.copyBind( moveMap, voiceCapture ); - halftimeMap.push(); - - //case 'Standard': - default: - moveMap.push(); - } -} - -//------------------------------------------------------------------------------ -function ClientCmdDisplayHuds() -{ - if ( $LaunchMode $= "InteriorView" ) - return; - - // only update action maps if playGui is current content - %content = Canvas.getContent(); - %PlayGuiActive = isObject(%content) && ( %content.getName() $= "PlayGui" ); - if ( %PlayGuiActive ) - updateActionMaps(); - - ammoHud.setVisible(false); - objectiveHud.setVisible(false); - inventoryHud.setVisible(false); - backpackFrame.setVisible(false); - weaponsHud.setVisible(false); - retCenterHud.setVisible(false); - HudClusterBack.setVisible(false); - outerChatHud.setVisible(false); - clockHud.setVisible(false); - controlObjectText.setVisible(false); - siegeHalftimeHud.setVisible(false); - clientCmdToggleDashHud(false); - %hideCursor = true; - - switch$ ($HudMode) - { - case "Pilot": - clientCmdShowVehicleGauges($HudModeType, $HudModeNode); - clientCmdToggleDashHud(true); - objectiveHud.setVisible(true); - dashBoardHud.setposition(0, 0); - retCenterHud.setVisible(true); - HudClusterBack.setVisible(true); - outerChatHud.setVisible(true); - clockHud.setVisible(true); - - case "Passenger": - clientCmdShowVehicleGauges($HudModeType, $HudModeNode); - clientCmdToggleDashHud(true); - objectiveHud.setVisible(true); - dashBoardHud.setPosition(0, 0); - ammoHud.setVisible(true); - objectiveHud.setVisible(true); - inventoryHud.setVisible(true); - weaponsHud.setVisible(true); - if(backpackFrame.pack) - backpackFrame.setVisible(true); - retCenterHud.setVisible(true); - HudClusterBack.setVisible(true); - outerChatHud.setVisible(true); - clockHud.setVisible(true); - - case "Object": - ammoHud.setVisible(true); - HudClusterBack.setVisible(true); - outerChatHud.setVisible(true); - controlObjectText.setVisible(true); - clockHud.setVisible(true); - - setControlObjectReticle($HudModeType); - - case "Observer": - objectiveHud.setVisible(true); - HudClusterBack.setVisible(true); - outerChatHud.setVisible(true); - clockHud.setVisible(true); - - case "SiegeHalftime": - closeHud( "", "", 'scoreScreen' ); - closeHud( "", "", 'inventoryScreen' ); - closeHud( "", "", 'vehicleHud' ); - objectiveHud.setVisible(true); - outerChatHud.setVisible(true); - siegeHalftimeHud.setVisible(true); - %hideCursor = false; - - case "PickTeam": - ammoHud.setVisible(false); - objectiveHud.setVisible(false); - inventoryHud.setVisible(false); - backpackFrame.setVisible(false); - weaponsHud.setVisible(false); - retCenterHud.setVisible(false); - HudClusterBack.setVisible(false); - outerChatHud.setVisible(true); - controlObjectText.setVisible(false); - clockHud.setVisible(false); - - //case 'Standard': - default: - ammoHud.setVisible(true); - objectiveHud.setVisible(true); - inventoryHud.setVisible(true); - weaponsHud.setVisible(true); - if(backpackFrame.pack) - backpackFrame.setVisible(true); - retCenterHud.setVisible(true); - HudClusterBack.setVisible(true); - outerChatHud.setVisible(true); - clockHud.setVisible(true); - - if(voteHud.voting) - mainVoteHud.setVisible(1); - else - mainVoteHud.setVisible(0); - - } - - if ( PlayGui.hideCursor != %hideCursor ) - { - PlayGui.hideCursor = %hideCursor; - if ( %PlayGuiActive ) - Canvas.updateCursorState(); - } -} - -function dashboardHud::onResize(%this, %width, %height) -{ - %currentWidth = getWord(dashboardHud.getPosition(), 0); - %currentHeight = getWord(dashboardHud.getPosition(), 1); - - %screenWidth = getWord(getResolution(), 0); - %screenHeight = getWord(getResolution(), 1); - - switch$ ($HudMode) - { - case "Pilot": - if(%screenHeight <= 480) - { - if($HudModeNode == 0) - { %xVal = 0; %yVal = 339; } - else - { %xVal = 0; %yVal = 320; } - } - else if(%screenHeight <= 600) - { - if($HudModeNode == 0) - { %xVal = 80; %yVal = 455; } - else - { %xVal = 80; %yVal = 440; } - } - else - { - %xVal = (%screenWidth - 640) / 2; - %yVal = (%screenheight - 480) + 360; - } - - case "Passenger": - %xVal = (%screenWidth - 640) / 2; - %yVal = (%screenheight - 480) + 360; - } - - if(%currentWidth != %xVal || %currentHeight != %yVal) - dashBoardHud.setPosition(%xVal, %yVal); -} - -function clientcmdTogglePlayHuds(%val) -{ - ammoHud.setVisible(%val); - objectiveHud.setVisible(%val); - inventoryHud.setVisible(%val); - if(backpackFrame.pack) - backpackFrame.setVisible(%val); - weaponsHud.setVisible(%val); - retCenterHud.setVisible(%val); - HudClusterBack.setVisible(%val); - outerChatHud.setVisible(%val); - clockHud.setVisible(%val); - - if(%val) - { - if(voteHud.voting) - mainVoteHud.setVisible(1); - } - else - mainVoteHud.setVisible(0); -} - -//------------------------------------------------------------------------------ -function toggleCursorHuds(%tag) -{ - if($Hud[%tag] !$= "" && $Hud[%tag].pushed) - { - hideHud(%tag); - clientCmdTogglePlayHuds(true); - } - else - { - showHud(%tag); - clientCmdTogglePlayHuds(false); - } -} - -//------------------------------------------------------------------------------ -function showHud(%tag) -{ - commandToServer('ShowHud', %tag); -} - -//------------------------------------------------------------------------------ -function serverCmdShowHud(%client, %tag) -{ - %tagName = getWord(%tag, 1); - %tag = getWord(%tag, 0); - messageClient(%client, 'OpenHud', "", %tag); - switch$ (%tag) - { - case 'inventoryScreen': - %client.numFavsCount = 0; - inventoryScreen::updateHud(1,%client,%tag); - case 'vehicleHud': - vehicleHud::updateHud(1,%client,%tag); - case 'scoreScreen': - updateScoreHudThread(%client, %tag); - } -} - -//------------------------------------------------------------------------------ -function updateScoreHudThread(%client, %tag) -{ - // z0dd - ZOD, 6/13/02. Need to check for game object - // for Random Teams by Founder (founder@mechina.com). - if(isObject(Game)) - { - Game.updateScoreHud(%client, %tag); - cancel(%client.scoreHudThread); - %client.scoreHudThread = schedule(3000, %client, "updateScoreHudThread", %client, %tag); - } -} - -//------------------------------------------------------------------------------ -function hideHud(%tag) -{ - commandToServer('HideHud', %tag); -} - -//------------------------------------------------------------------------------ -function serverCmdHideHud(%client, %tag) -{ - %tag = getWord(%tag, 0); - messageClient(%client, 'CloseHud', "", %tag); - switch$ (%tag) - { - case 'scoreScreen': - cancel(%client.scoreHudThread); - %client.scoreHudThread = ""; - } -} - -//------------------------------------------------------------------------------ -addMessageCallback('OpenHud', openHud); -addMessageCallback('CloseHud', closeHud); -addMessageCallback('ClearHud', clearHud); -addMessageCallback('SetLineHud', setLineHud); -addMessageCallback('RemoveLineHud', removeLineHud); - -//------------------------------------------------------------------------------ -function openHud(%msgType, %msgString, %tag) -{ - // Vehicle hud can only be pushed on the PlayGui: - if ( %tag $= 'vehicleHud' && Canvas.getContent() != PlayGui.getId() ) - return; - - %tagName = getWord(%tag, 1); - %tag = getWord(%tag, 0); - if($Hud[%tag] $= "") - { - %tagName.loadHud(%tag); - %tagName.setupHud(%tag); - } - Canvas.pushDialog($Hud[%tag]); - $Hud[%tag].pushed = 1; -} - -//------------------------------------------------------------------------------ -function closeHud(%msgType, %msgString, %tag) -{ - %tag = getWord(%tag, 0); - if($Hud[%tag].pushed) - { - $Hud[%tag].setVisible(false); - Canvas.popDialog($Hud[%tag]); - $Hud[%tag].pushed = 0; - } -} - -//------------------------------------------------------------------------------ -function clearHud(%msgType, %msgString, %tag, %a0) -{ - %tag = getWord(%tag, 0); - %startingLine = detag(%a0); - - while ($Hud[%tag].data[%startingLine, 0] !$= "") - { - for(%i = 0; %i < $Hud[%tag].numCol; %i++) - { - //remove and delete the hud line - %obj = $Hud[%tag].data[%startingLine, %i]; - $Hud[%tag].childGui.remove(%obj); - $Hud[%tag].data[%startingLine, %i] = ""; - %obj.delete(); - } - - %startingLine++; - } - - //don't forget to adjust the size accordingly... - if (%tag $= 'scoreScreen') - { - %height = 0; - %guiCtrl = $Hud[%tag].childGui; - - if(isObject(%guiCtrl)) - { - //set the new extent to be the position + extent of the last element... - %height = 0; - if (%guiCtrl.getCount() > 0) - { - %lastCtrl = %guiCtrl.getObject(%guiCtrl.getCount() - 1); - %height = getWord(%lastCtrl.position, 1) + getWord(%lastCtrl.extent, 1); - } - - //now reset the extent - %guiCtrl.resize(getWord(%guiCtrl.position, 0), getWord(%guiCtrl.position, 1), getWord(%guiCtrl.extent, 0), %height); - } - } -} - -//------------------------------------------------------------------------------ -function removeLineHud(%msgType, %msgString, %hudName, %lineNumber, %a0, %a1, %a2, %a3) -{ - %tag = getWord(%hudName, 0); - %lineNum = detag(%lineNumber); - if($Hud[%tag].data[%lineNum,0] !$= "") - for(%i = 0; %i < $Hud[%tag].numCol; %i++) - { - $Hud[%tag].childGui.remove($Hud[%tag].data[%lineNum, %i]); - $Hud[%tag].data[%lineNum, %i] = ""; - } - - //don't forget to adjust the size accordingly... - if (%tag $= 'scoreScreen') - { - %height = 0; - %guiCtrl = $Hud[%tag].childGui; - - //set the new extent to be the position + extent of the last element... - %height = 0; - if (%guiCtrl.getCount() > 0) - { - %lastCtrl = %guiCtrl.getObject(%guiCtrl.getCount() - 1); - %height = getWord(%lastCtrl.position, 1) + getWord(%lastCtrl.extent, 1); - } - - //now reset the extent - %guiCtrl.resize(getWord(%guiCtrl.position, 0), getWord(%guiCtrl.position, 1), getWord(%guiCtrl.extent, 0), %height); - } -} - -//------------------------------------------------------------------------------ -function setLineHud(%msgType, %msgString, %hudName, %lineNumber, %a0, %a1, %a2, %a3, %a4) -{ - %tag = getWord(%hudName, 0); - %lineNum = detag(%lineNumber); - - if(!isObject($Hud[%tag].data[%lineNum, 0])) - { - $Hud[%tag].numCol = addLine(%tag, %lineNum, %a0, %a1, %a2, %a3); - for(%i = 0; %i < $Hud[%tag].numCol; %i++) - $Hud[%tag].childGui.add($Hud[%tag].data[%lineNum, %i]); - } - - for(%i = 0; %i < $Hud[%tag].numCol; %i++) - $Hud[%tag].data[%lineNum, %i].hudSetValue(detag(%a[%i]),detag(%a4)); - - //don't forget to adjust the size accordingly... - if (%tag $= 'scoreScreen') - { - %height = 0; - %guiCtrl = $Hud[%tag].childGui; - - //set the new extent to be the position + extent of the last element... - %height = 0; - if (%guiCtrl.getCount() > 0) - { - %lastCtrl = %guiCtrl.getObject(%guiCtrl.getCount() - 1); - %height = getWord(%lastCtrl.position, 1) + getWord(%lastCtrl.extent, 1); - } - - //now reset the extent - %guiCtrl.resize(getWord(%guiCtrl.position, 0), getWord(%guiCtrl.position, 1), getWord(%guiCtrl.extent, 0), %height); - } -} - -//------------------------------------------------------------------------------ -function GuiButtonCtrl::hudSetValue(%obj, %text) -{ - %obj.setValue(%text); -} - -//------------------------------------------------------------------------------ -function GuiTextCtrl::hudSetValue(%obj, %text) -{ - %obj.setValue(%text); -} - -//------------------------------------------------------------------------------ -function GuiMLTextCtrl::hudSetValue(%obj, %text) -{ - %obj.setValue(%text); -} - -//------------------------------------------------------------------------------ -function ShellTabGroupCtrl::hasTab(%obj, %text) -{ - %count = %obj.tabCount(); - for (%i = 0; %i < %count; %i++) - { - %textS = %obj.getTabText( %i ); - if (%textS $= %text) - return true; - } -return false; -} - -//------------------------------------------------------------------------------ -function GuiPopUpMenuCtrl::hudSetValue(%obj, %text, %textOverFlow) -{ - if(%textOverFlow !$= "") - %text = %text @ %textOverFlow; - %obj.clear(); - %value = getField(%text,0); - %startVal = 1; - if(%value $= "noSelect") - { - %obj.replaceText(false); - %value = getField(%text,1); - %startVal = 2; - } - else - %obj.replaceText(true); - - %obj.setValue(%value); - if(getFieldCount(%text) > 1) - { - %obj.setActive(true); - for(%i = %startVal; %i < getFieldCount(%text); %i++) - %obj.add(getField(%text, %i), %i); - } - else - %obj.setActive(false); -} - -//------------------------------------------------------------------------------ -function ShellTabButton::hudSetValue( %obj, %text ) -{ - %obj.setText( %text ); -} - -//------------------------------------------------------------------------------ -function addLine(%tag, %lineNum, %a0, %a1, %a2, %a3) -{ - %colNum = 0; - if(isObject($Hud[%tag])) - %colNum = $Hud[%tag].addLine(%tag, %lineNum, detag(%a2), detag(%a3)); - return %colNum; -} - -//------------------------------------------------------------------------------ -function INV_Menu::onSelect( %obj, %index, %text ) -{ - %favList = $Hud['inventoryScreen'].data[0, 1].type TAB $Hud['inventoryScreen'].data[0, 1].getValue(); - for ( %i = 1; %i < $Hud['inventoryScreen'].count; %i++ ) - %favList = %favList TAB $Hud['inventoryScreen'].data[%i, 1].type TAB $Hud['inventoryScreen'].data[%i, 1].getValue(); - commandToServer( 'setClientFav', %favList ); -} - -//------------------------------------------------------------------------------ -function INV_ListMenu::onSelect( %obj, %id, %text, %force ) -{ - // Deselect the current tab ( because it was on the OLD list ): - if ( InventoryScreen.selId !$= "" ) - { - $Hud['inventoryScreen'].staticData[0, InventoryScreen.selId].setValue( false ); - InventoryScreen.selId = ""; - } - - $pref::FavCurrentList = %id; - %favListStart = %id * 10; - - // Select the currently selected favorite if it is now visible: - %tab = $pref::FavCurrentSelect - ( $pref::FavCurrentList * 10 ) + 1; - if ( %tab > 0 && %tab < 11 ) - { - InventoryScreen.selId = %tab; - $Hud['inventoryScreen'].staticData[0, %tab].setValue( true ); - } - - %obj.clear(); - %obj.setValue( %text ); - %count = 10; - %list = 0; - for ( %index = 0; $pref::FavNames[%index] !$= ""; %index++ ) - { - if ( %index >= %count - 1 ) - { - if ( %count != %favListStart + 10 ) - %obj.add( "Favorites " @ %index - 8 @ " - " @ %index + 1, %list ); - - %count += 10; - %list++; - } - } - - for ( %i = 0; %i < 10; %i++ ) - { - $Hud['inventoryScreen'].staticData[0, %i + 1].command = "InventoryScreen.onTabSelect(" @ %favListStart + %i @ ");"; - $Hud['inventoryScreen'].staticData[0, %i + 1].setText( strupr( $pref::FavNames[%favListStart + %i] ) ); - } -} - -//------------------------------------------------------------------------------ -function serverCmdSetClientFav(%client, %text) -{ - if ( getWord( getField( %text, 0 ), 0 ) $= armor ) - { - %client.curFavList = %text; - %validList = checkInventory( %client, %text ); - %client.favorites[0] = getField( %text, 1 ); - %armor = getArmorDatablock( %client, $NameToInv[getField( %validList,1 )] ); - %weaponCount = 0; - %packCount = 0; - %grenadeCount = 0; - %mineCount = 0; - %count = 1; - %client.weaponIndex = ""; - %client.packIndex = ""; - %client.grenadeIndex = ""; - %client.mineIndex = ""; - - for(%i = 3; %i < getFieldCount(%validList); %i = %i + 2) - { - %setItem = false; - switch$ (getField(%validList,%i-1)) - { - case weapon: - if(%weaponCount < %armor.maxWeapons) - { - if(!%weaponCount) - %client.weaponIndex = %count; - else - %client.weaponIndex = %client.weaponIndex TAB %count; - %weaponCount++; - %setItem = true; - } - case pack: - if(%packCount < 1) - { - %client.packIndex = %count; - %packCount++; - %setItem = true; - } - case grenade: - if(%grenadeCount < %armor.maxGrenades) - { - if(!%grenadeCount) - %client.grenadeIndex = %count; - else - %client.grenadeIndex = %client.grenadeIndex TAB %count; - %grenadeCount++; - %setItem = true; - } - case mine: - if(%mineCount < %armor.maxMines) - { - if(!%mineCount) - %client.mineIndex = %count; - else - %client.mineIndex = %client.mineIndex TAB %count; - %mineCount++; - %setItem = true; - } - } - if(%setItem) - { - %client.favorites[%count] = getField(%validList, %i); - %count++; - } - } - %client.numFavs = %count; - %client.numFavsCount = 0; - inventoryScreen::updateHud(1, %client, 'inventoryScreen'); - } -} - -//------------------------------------------------------------------------------ -function getCenterPos(%tag) -{ - %TerExtDivX = getWord(PlayGui.extent, 0) / 2; - %TerExtDivY = getWord(PlayGui.extent, 1) / 2; - - %HudExtDivX = getWord($Hud[%tag].extent,0) / 2; - %HudExtDivY = getWord($Hud[%tag].extent,1) / 2; - - %pos = %TerExtDivX - %HudExtDivX @ " " @ %TerExtDivY - %HudExtDivY; - return %pos; -} - -//------------------------------------------------------------------------------ -function hideZoomHud() -{ - ZoomHud.setVisible(false); - ZoomHud.hideThread = 0; -} - -function calcZoomFOV() -{ - if($pref::player::currentFOV == $pref::player::defaultFov / 2) - $pref::player::currentFOV = $pref::player::defaultFov / 5; - else - $pref::player::currentFOV = $pref::player::currentFOV / 2; - - if($pref::player::currentFOV < 4) - $pref::player::currentFOV = $pref::player::defaultFov / 2; - - if(!$ZoomOn) - { - %pos = getZoomCenter($pref::player::defaultFov / $pref::player::currentFOV); - %extent = getZoomExtent($pref::player::defaultFov / $pref::player::currentFOV); - ZoomHud.resize(getWord(%pos, 0), getWord(%pos, 1), getWord(%extent, 0), getWord(%extent, 1)); - if(ZoomHud.hideThread != 0) - cancel(ZoomHud.hideThread); - ZoomHud.hideThread = schedule(5000, 0, hideZoomHud); - ZoomHud.setVisible(true); - } - else - setFov( $pref::player::currentFOV ); -} - -//------------------------------------------------------------------------------ -function getZoomCenter(%power) -{ - %power += (%power/4); - %TerExtDivX = mFloor(getWord(PlayGui.extent, 0) / 2); - %TerExtDivY = mFloor(getWord(PlayGui.extent, 1) / 2); - - %HudExtDivX = mFloor((getWord(PlayGui.extent, 0) / %power)/2); - %HudExtDivY = mFloor((getWord(PlayGui.extent, 1) / %power)/2); - - %pos = %TerExtDivX - %HudExtDivX @ " " @ %TerExtDivY - %HudExtDivY; - return %pos; -} - -//------------------------------------------------------------------------------ -function getZoomExtent(%power) -{ - %power += (%power/4); - %HudExtDivX = mFloor(getWord(PlayGui.extent, 0) / %power); - %HudExtDivY = mFloor(getWord(PlayGui.extent, 1) / %power); - - %val = %HudExtDivX @ " " @ %HudExtDivY; - - return %val; -} - -//------------------------------------------------------------------------------ -function hideAllHuds() -{ - objectiveHud.setVisible( false ); - outerChatHud.setVisible( false ); - energyHud.setVisible( false ); - damageHud.setVisible( false ); - sensorHudBack.setVisible( false ); - controlObjectText.setVisible( false ); -} - -//------------------------------------------------------------------------------ -function restoreAllHuds() -{ - objectiveHud.setVisible( true ); - outerChatHud.setVisible( true ); - energyHud.setVisible( true ); - damageHud.setVisible( true ); - sensorHudBack.setVisible( true ); -} - -//------------------------------------------------------------------------------ -//------------------------------------------------------------------------------ -// voting hud stuff -///////////////////////////////////////////////// -addMessageCallback('clearVoteHud', clearVoteHud); -addMessageCallback('addYesVote', addYesVote); -addMessageCallback('addNoVote', addNoVote); -addMessageCallback('openVoteHud', openVoteHud); -addMessageCallback('closeVoteHud', closeVoteHud); -addMessageCallback('VoteStarted', initVote); - -//------------------------------------------------------------------------------ -function initVote(%msgType, %msgString) -{ - if(!$BottomPrintActive) - { - %yBind = strUpr(getField(moveMap.getBinding(voteYes), 1)); - %nBind = strUpr(getField(moveMap.getBinding(voteNo), 1)); - - %message = detag(%msgString) @ "\nPress " @ %yBind @ " to vote YES or " @ %nBind @ " to vote NO."; - clientCmdBottomPrint(%message, 10, 2); - } -} - -function openVoteHud(%msgType, %msgString, %numClients, %passPercent) -{ - alxPlay(VoteInitiatedSound, 0, 0, 0); - voteHud.voting = true; - - voteHud.totalVotes = 0; - voteHud.size = %numClients; - voteHud.quorum = (%numClients / 2); - - if(voteHud.quorum < 1) - voteHud.quorum = 1; - - voteHud.pass = voteHud.quorum * %passPercent; - - voteHud.setPassValue(%passPercent); - passHash.position = firstWord( mainVoteHud.extent) * %passPercent + 1 @ " -1"; - - if( MessageHud.isVisible() ) - { - %votePos = firstWord( MainVoteHud.position ) @ " " @ ( getWord( OuterChatHud.extent, 1 ) + getWord( messageHud_Frame.extent, 1 ) + 12 ); - MainVoteHud.position = %votePos; - } - else - { - %tempY = getWord(outerChatHud.position, 1) + getWord(outerChatHud.extent, 1) + 2; - %mainVoteX = firstWord(mainVoteHud.position); - %voteHudPos = %mainVoteX SPC %tempY; - mainVoteHud.position = %voteHudPos; - } - - voteHud.setVisible(true); - mainVoteHud.setVisible(true); -} - -function stripBind(%string) -{ - return getSubstr(%string, 9, 90); -} - -//------------------------------------------------------------------------------ -function CloseVoteHud(%msgType, %msgString) -{ - voteHud.setVisible(false); - mainVoteHud.setVisible(false); - voteHud.yesCount = 0; - voteHud.noCount = 0; - voteHud.voting = false; -} - -//------------------------------------------------------------------------------ -function addYesVote(%msgType, %msgString) -{ - voteHud.yesCount++; - voteHud.totalVotes++; - - if(voteHud.isVisible()) - { - voteHud.setYesValue(voteHud.yesCount / voteHud.size); - } -} - -//------------------------------------------------------------------------------ -function addNoVote(%msgType, %msgString) -{ - voteHud.noCount++; - voteHud.totalVotes++; - - if(voteHud.isVisible()) - voteHud.setNoValue(voteHud.noCount / voteHud.size); -} - -//------------------------------------------------------------------------------ -function clearVoteHud(%msgType, %msgString) -{ - voteHud.setYesValue(0.0); - voteHud.setNoValue(0.0); -} - -//------------------------------------------------------------------------------ -function cleanUpHuds() -{ - if($Hud['inventoryScreen'] !$= "") - { - for(%lineNum = 0; $Hud['inventoryScreen'].data[%lineNum, 0] !$= ""; %lineNum++) - for(%i = 0; %i < $Hud['inventoryScreen'].numCol; %i++) - { - $Hud['inventoryScreen'].childGui.remove($Hud['inventoryScreen'].data[%lineNum, %i]); - $Hud['inventoryScreen'].data[%lineNum, %i] = ""; - } - } -} - -// z0dd - ZOD, 4/18/02. Total re-write to give players more information on who they are observing. -function displayObserverHud(%client, %targetClient, %potentialClient) -{ - %targName = getTaggedString(%targetClient.name); - %potName = getTaggedString(%potentialClient.name); - %targTeam = getTaggedString(Game.getTeamName(%targetClient.team)); - %potTeam = getTaggedString(Game.getTeamName(%potentialClient.team)); - - if (%targetClient > 0) - { - if(%targetClient.team == 1) - bottomPrint(%client, "You are now observing:\n" @ %targName @ "\nTeam: " @ %targTeam, 0, 3); - else - bottomPrint(%client, "You are now observing:\n" @ %targName @ "\nTeam: " @ %targTeam, 0, 3); - } - else if (%potentialClient > 0) - { - if(%potentialClient.team == 1) - bottomPrint(%client, "Observer Fly Mode\n" @ %potName @ "\nTeam: " @ %potTeam, 0, 3); - else - bottomPrint(%client, "Observer Fly Mode\n" @ %potName @ "\nTeam: " @ %potTeam, 0, 3); - } - else - bottomPrint(%client, "\nObserver Fly Mode", 0, 3); -} - -function hudFirstPersonToggled() -{ - ammoHud.setVisible($firstPerson); -} - -$testCount = 0; - -function testChatHud() -{ - $testCount++; - messageAll( '', "This is test number " @ $testCount ); - $tester = schedule( 50, 0, "testChatHud"); -} - -//------------------------------------------------------------------------- -function HudNetDisplay::getPrefs(%this) -{ - for(%i = 0; %i < 6; %i++) - %this.renderField[%i] = ($pref::Net::graphFields >> %i) & 1; -} - -function NetBarHud::infoUpdate(%this, %ping, %packetLoss, %sendPackets, %sendBytes, %receivePackets, %receiveBytes) -{ - NetBarHudPingText.setText(mFormatFloat(%ping, "%4.0f") @ "ms"); - NetBarHudPacketLossText.setText(mFormatFloat(%packetLoss, "%3.0f") @ "%"); - - NetBarHudSendBar.value = %sendPackets / $pref::Net::PacketRateToServer; - NetBarHudReceiveBar.value = %receivePackets / $pref::Net::PacketRateToClient; -} +//-------------------------------------------------------------------------- +function GameConnection::sensorPing(%this, %ping) +{ + sensorHud.ping = %ping; + sensorHud.update(); +} + +function GameConnection::sensorJammed(%this, %jam) +{ + sensorHud.jam = %jam; + sensorHud.update(); +} + +function SensorHud::update(%this) +{ + if(!%this.ping && !%this.jam) + { + %this.setVisible(false); + sensorHudBack.setVisible(true); + return; + } + + %this.setVisible(true); + sensorHudBack.setVisible(false); + + if(%this.jam) + %this.color = %this.jamColor; + else + %this.color = %this.pingColor; +} + +// - anything which should be reset on new server/mission +function clientCmdResetHud() +{ + deploySensor.setVisible(false); + controlObjectText.setVisible(false); + + sensorHud.jam = false; + sensorHud.ping = false; + sensorHud.update(); +} + +//-------------------------------------------------------------------------- +$vehicleReticle[AssaultVehicle, 1, bitmap] = "gui/hud_ret_tankchaingun"; +$vehicleReticle[AssaultVehicle, 1, frame] = true; +$vehicleReticle[AssaultVehicle, 2, bitmap] = "gui/hud_ret_tankmortar"; +$vehicleReticle[AssaultVehicle, 2, frame] = true; + +$vehicleReticle[BomberFlyer, 1, bitmap] = "gui/hud_ret_shrike"; +$vehicleReticle[BomberFlyer, 1, frame] = false; +$vehicleReticle[BomberFlyer, 2, bitmap] = ""; +$vehicleReticle[BomberFlyer, 2, frame] = false; +$vehicleReticle[BomberFlyer, 3, bitmap] = "gui/hud_ret_targlaser"; +$vehicleReticle[BomberFlyer, 3, frame] = false; + +function GameConnection::setVWeaponsHudActive(%client, %slot) +{ + %veh = %client.player.getObjectMount(); + %vehType = %veh.getDatablock().getName(); + commandToClient(%client, 'setVWeaponsHudActive', %slot, %vehType); +} + +function clientCmdSetVWeaponsHudActive(%num, %vType) +{ + //vWeaponsBox.setActiveWeapon(%num); + if(%num > $numVWeapons) + %num = $numVWeapons; + + for(%i = 1; %i <= $numVWeapons; %i++) + { + %oldHilite = "vWeap" @ %i @ "Hilite"; + %oldHilite.setVisible(false); + } + %newHilite = "vWeap" @ %num @ "Hilite"; + %newHilite.setVisible(true); + + // set the bitmap and frame for the reticle + reticleHud.setBitmap($vehicleReticle[%vType, %num, bitmap]); + reticleFrameHud.setVisible($vehicleReticle[%vType, %num, frame]); +} + +function GameConnection::setVWeaponsHudClearAll(%client) +{ + commandToClient(%client, 'setVWeaponsHudClearAll'); +} + +function clientCmdSetVWeaponsHudClearAll() +{ + //vWeaponsBox.clearAll(); +} + +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- +function GameConnection::setWeaponsHudBitmap(%client, %slot, %name, %bitmap) +{ + commandToClient(%client, 'setWeaponsHudBitmap',%slot,%name,%bitmap); +} + +//---------------------------------------------------------------------------- +function clientCmdSetWeaponsHudBitmap(%slot, %name, %bitmap) +{ + $WeaponNames[%slot] = %name; + weaponsHud.setWeaponBitmap(%slot,%bitmap); +} + +//---------------------------------------------------------------------------- +function GameConnection::setWeaponsHudItem(%client, %name, %ammoAmount, %addItem) +{ + //error("GC:SWHI name="@%name@",ammoAmount="@%ammoAmount@",addItem="@%addItem); +// for(%i = 0; %i < $WeaponsHudCount; %i++) +// if($WeaponsHudData[%i, itemDataName] $= %name) +// { +// if($WeaponsHudData[%i, ammoDataName] !$= "") { +// %ammoInv = %client.player.inv[$WeaponsHudData[%i, ammoDataName]]; +// //error(" ----- player has " @ %ammoInv SPC $WeaponsHudData[%i, ammoDataName]); +// //error("SWHI:Setting weapon "@%name@" ("@%i@") ammo to " @ %ammoInv); +// commandToClient(%client, 'setWeaponsHudItem',%i,%ammoInv, %addItem); +// } +// else { +// //error("SWHI:Setting weapon "@%name@" ("@%i@") ammo to infinite"); +// commandToClient(%client, 'setWeaponsHudItem',%i,-1, %addItem); +// } +// break; +// } + + + // My try... + for(%i = 0; %i < $WeaponsHudCount; %i++) + if($WeaponsHudData[%i, itemDataName] $= %name) + { + if($WeaponsHudData[%i, ammoDataName] !$= "") { + %ammoInv = %client.player.inv[$WeaponsHudData[%i, ammoDataName]]; + //error(" ----- player has " @ %ammoInv SPC $WeaponsHudData[%i, ammoDataName]); + //error("SWHI:Setting weapon "@%name@" ("@%i@") ammo to " @ %ammoInv); + commandToClient(%client, 'setWeaponsHudItem',%i,%ammoInv, %addItem); + } + else { + //error("SWHI:Setting weapon "@%name@" ("@%i@") ammo to infinite"); + commandToClient(%client, 'setWeaponsHudItem',%i,-1, %addItem); + } + break; + } +} + +//---------------------------------------------------------------------------- +function clientCmdSetWeaponsHudItem(%slot, %ammoAmount, %addItem) +{ + if(%addItem) { + //error("adding weapon to hud in slot " @ %slot @ " with ammo " @ %ammoAmount); + weaponsHud.addWeapon(%slot, %ammoAmount); + } + else { + //error("removing weapon from hud"); + weaponsHud.removeWeapon(%slot); + } +} + +//---------------------------------------------------------------------------- +function GameConnection::setWeaponsHudAmmo(%client, %name, %ammoAmount) +{ + for(%i = 0; %i < $WeaponsHudCount; %i++) + if($WeaponsHudData[%i, ammoDataName] $= %name) + { + //error("SWHA:Setting ammo "@%name@" for weapon "@%i@" to " @ %ammoAmount); + commandToClient(%client, 'setWeaponsHudAmmo',%i, %ammoAmount); + break; + } +} + +//---------------------------------------------------------------------------- +function clientCmdSetWeaponsHudAmmo(%slot, %ammoAmount) +{ + weaponsHud.setAmmo(%slot, %ammoAmount); +} + +//---------------------------------------------------------------------------- +// z0dd - ZOD, 9/13/02. Serverside reticles, sever tells client what file to use. +function GameConnection::setWeaponsHudActive(%client, %name, %clearActive) +{ + if(%clearActive) + { + commandToClient(%client, 'setWeaponsHudActive', -1); + } + else + { + for(%i = 0; %i < $WeaponsHudCount; %i++) + { + if($WeaponsHudData[%i, itemDataName] $= %name) + { + commandToClient(%client, 'setWeaponsHudActive', %i, $WeaponsHudData[%i, reticle], $WeaponsHudData[%i, visible]); + break; + } + } + } +} +//---------------------------------------------------------------------------- + +//------------------------------------------------------------------------------ +// z0dd- ZOD, 9/13/02. Serverside reticles, sever tells client what file to use. +// Total Rewrite. +function clientCmdSetWeaponsHudActive(%slot, %ret, %vis) +{ + // z0dd - ZOD, 9/30/02. Changed for lazy scripter backward compatibility. + weaponsHud.setActiveWeapon(%slot); + switch$($WeaponNames[%slot]) + { + case "Blaster": + reticleHud.setBitmap("gui/ret_blaster"); + reticleFrameHud.setVisible(true); + case "Plasma": + reticleHud.setBitmap("gui/ret_plasma"); + reticleFrameHud.setVisible(true); + case "Chaingun": + reticleHud.setBitmap("gui/ret_chaingun"); + reticleFrameHud.setVisible(true); + case "Disc": + reticleHud.setBitmap("gui/ret_disc"); + reticleFrameHud.setVisible(true); + case "GrenadeLauncher": + reticleHud.setBitmap("gui/ret_grenade"); + reticleFrameHud.setVisible(true); + case "SniperRifle": + reticleHud.setBitmap("gui/hud_ret_sniper"); + reticleFrameHud.setVisible(false); + case "ELFGun": + reticleHud.setBitmap("gui/ret_elf"); + reticleFrameHud.setVisible(true); + case "Mortar": + reticleHud.setBitmap("gui/ret_mortor"); + reticleFrameHud.setVisible(true); + case "MissileLauncher": + reticleHud.setBitmap("gui/ret_missile"); + reticleFrameHud.setVisible(true); + case "ShockLance": + reticleHud.setBitmap("gui/hud_ret_shocklance"); + reticleFrameHud.setVisible(false); + case "TargetingLaser": + reticleHud.setBitmap("gui/hud_ret_targlaser"); + reticleFrameHud.setVisible(false); + default: + reticleHud.setBitmap(%ret); + reticleFrameHud.setVisible(%vis); + } +} + +//------------------------------------------------------------------------------ + +function clientCmdSetRepairReticle() +{ + reticleHud.setBitmap("gui/ret_chaingun"); + reticleFrameHud.setVisible(true); +} + +//---------------------------------------------------------------------------- +function GameConnection::setWeaponsHudBackGroundBmp(%client, %name) +{ + commandToClient(%client, 'setWeaponsHudBackGroundBmp',%name); +} + +//---------------------------------------------------------------------------- +function clientCmdSetWeaponsHudBackGroundBmp(%name) +{ + weaponsHud.setBackGroundBitmap(%name); +} + +//---------------------------------------------------------------------------- +function GameConnection::setWeaponsHudHighLightBmp(%client, %name) +{ + commandToClient(%client, 'setWeaponsHudHighLightBmp',%name); +} + +//---------------------------------------------------------------------------- +function clientCmdSetWeaponsHudHighLightBmp(%name) +{ + weaponsHud.setHighLightBitmap(%name); +} + +//---------------------------------------------------------------------------- +function GameConnection::setWeaponsHudInfiniteAmmoBmp(%client, %name) +{ + commandToClient(%client, 'setWeaponsHudInfiniteAmmoBmp',%name); +} + +//---------------------------------------------------------------------------- +function clientCmdSetWeaponsHudInfiniteAmmoBmp(%name) +{ + weaponsHud.setInfiniteAmmoBitmap(%name); +} +//---------------------------------------------------------------------------- +function GameConnection::setWeaponsHudClearAll(%client) +{ + commandToClient(%client, 'setWeaponsHudClearAll'); +} + +//---------------------------------------------------------------------------- +function clientCmdSetWeaponsHudClearAll() +{ + weaponsHud.clearAll(); +} + +//---------------------------------------------------------------------------- +// Ammo Hud +//---------------------------------------------------------------------------- +function GameConnection::setAmmoHudCount(%client, %amount) +{ + commandToClient(%client, 'setAmmoHudCount', %amount); +} + +//---------------------------------------------------------------------------- +function clientCmdSetAmmoHudCount(%amount) +{ + if(%amount == -1) + ammoHud.setValue(""); + else + ammoHud.setValue(%amount); +} + +//---------------------------------------------------------------------------- +// Backpack Hud +//---------------------------------------------------------------------------- + +$BackpackHudData[0, itemDataName] = "AmmoPack"; +$BackpackHudData[0, bitmapName] = "gui/hud_new_packammo"; +$BackpackHudData[1, itemDataName] = "CloakingPack"; +$BackpackHudData[1, bitmapName] = "gui/hud_new_packcloak"; +$BackpackHudData[2, itemDataName] = "EnergyPack"; +$BackpackHudData[2, bitmapName] = "gui/hud_new_packenergy"; +$BackpackHudData[3, itemDataName] = "RepairPack"; +$BackpackHudData[3, bitmapName] = "gui/hud_new_packrepair"; +$BackpackHudData[4, itemDataName] = "SatchelCharge"; +$BackpackHudData[4, bitmapName] = "gui/hud_new_packsatchel"; +$BackpackHudData[5, itemDataName] = "ShieldPack"; +$BackpackHudData[5, bitmapName] = "gui/hud_new_packshield"; +$BackpackHudData[6, itemDataName] = "InventoryDeployable"; +$BackpackHudData[6, bitmapName] = "gui/hud_new_packinventory"; +$BackpackHudData[7, itemDataName] = "MotionSensorDeployable"; +$BackpackHudData[7, bitmapName] = "gui/hud_new_packmotionsens"; +$BackpackHudData[8, itemDataName] = "PulseSensorDeployable"; +$BackpackHudData[8, bitmapName] = "gui/hud_new_packradar"; +$BackpackHudData[9, itemDataName] = "TurretOutdoorDeployable"; +$BackpackHudData[9, bitmapName] = "gui/hud_new_packturretout"; +$BackpackHudData[10, itemDataName] = "TurretIndoorDeployable"; +$BackpackHudData[10, bitmapName] = "gui/hud_new_packturretin"; +$BackpackHudData[11, itemDataName] = "SensorJammerPack"; +$BackpackHudData[11, bitmapName] = "gui/hud_new_packsensjam"; +$BackpackHudData[12, itemDataName] = "AABarrelPack"; +$BackpackHudData[12, bitmapName] = "gui/hud_new_packturret"; +$BackpackHudData[13, itemDataName] = "FusionBarrelPack"; +$BackpackHudData[13, bitmapName] = "gui/hud_new_packturret"; +$BackpackHudData[14, itemDataName] = "MissileBarrelPack"; +$BackpackHudData[14, bitmapName] = "gui/hud_new_packturret"; +$BackpackHudData[15, itemDataName] = "PlasmaBarrelPack"; +$BackpackHudData[15, bitmapName] = "gui/hud_new_packturret"; +$BackpackHudData[16, itemDataName] = "ELFBarrelPack"; +$BackpackHudData[16, bitmapName] = "gui/hud_new_packturret"; +$BackpackHudData[17, itemDataName] = "MortarBarrelPack"; +$BackpackHudData[17, bitmapName] = "gui/hud_new_packturret"; +$BackpackHudData[18, itemDataName] = "SatchelUnarmed"; +$BackpackHudData[18, bitmapName] = "gui/hud_satchel_unarmed"; + +// --------------------------------------------------------- +// z0dd - ZOD, 9/12/02. TR2 need +// TR2 +$BackpackHudData[19, itemDataName] = "TR2EnergyPack"; +$BackpackHudData[19, bitmapName] = "gui/hud_new_packenergy"; +// --------------------------------------------------------- + +$BackpackHudCount = 20; + +function GameConnection::clearBackpackIcon(%client) +{ + commandToClient(%client, 'setBackpackHudItem', 0, 0); +} + +function GameConnection::setBackpackHudItem(%client, %name, %addItem) +{ + for(%i = 0; %i < $BackpackHudCount; %i++) + if($BackpackHudData[%i, itemDataName] $= %name) + commandToClient(%client, 'setBackpackHudItem', %i, %addItem); +} + +function clientCmdSetBackpackHudItem(%num, %addItem) +{ + if(%addItem) + { + backpackIcon.setBitmap($BackpackHudData[%num, bitmapName]); + backpackFrame.setVisible(true); + backpackIcon.setVisible(true); + backpackFrame.pack = true; + } + else + { + backpackIcon.setBitmap(""); + backpackFrame.setVisible(false); + backpackText.setValue(""); + backpackText.setVisible(false); + backpackFrame.pack = false; + } +} + +function GameConnection::updateSensorPackText(%client, %num) +{ + commandToClient(%client, 'updatePackText', %num); +} + +function clientCmdUpdatePackText(%num) +{ + backpackText.setValue(%num); + if(%num == 0) + backpackText.setVisible(false); + else + backpackText.setVisible(true); +} + +// Pack Icons Activate / Deactivate +function clientCmdSetSatchelArmed() +{ + backpackIcon.setBitmap( "gui/hud_satchel_armed" ); +} + +function clientCmdsetCloakIconOn() +{ + backpackIcon.setBitmap( "gui/hud_new_packcloak_armed" ); +} + +function clientCmdsetCloakIconOff() +{ + backpackIcon.setBitmap( "gui/hud_new_packcloak" ); +} + +function clientCmdsetRepairPackIconOn() +{ + backpackIcon.setBitmap( "gui/hud_new_packrepair_armed" ); +} + +function clientCmdsetRepairPackIconOff() +{ + backpackIcon.setBitmap( "gui/hud_new_packrepair" ); +} + +function clientCmdsetShieldIconOn() +{ + backpackIcon.setBitmap( "gui/hud_new_packshield_armed" ); +} + +function clientCmdsetShieldIconOff() +{ + backpackIcon.setBitmap( "gui/hud_new_packshield" ); +} + +function clientCmdsetSenJamIconOn() +{ + backpackIcon.setBitmap( "gui/hud_new_packsensjam_armed" ); +} + +function clientCmdsetSenJamIconOff() +{ + backpackIcon.setBitmap( "gui/hud_new_packsensjam" ); +} + + +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- +$InventoryHudData[0, bitmapName] = "gui/hud_handgren"; +$InventoryHudData[0, itemDataName] = Grenade; +$InventoryHudData[0, ammoDataName] = Grenade; +$InventoryHudData[0, slot] = 0; +$InventoryHudData[1, bitmapName] = "gui/hud_mine"; +$InventoryHudData[1, itemDataName] = Mine; +$InventoryHudData[1, ammoDataName] = Mine; +$InventoryHudData[1, slot] = 1; +$InventoryHudData[2, bitmapName] = "gui/hud_medpack"; +$InventoryHudData[2, itemDataName] = RepairKit; +$InventoryHudData[2, ammoDataName] = RepairKit; +$InventoryHudData[2, slot] = 3; +$InventoryHudData[3, bitmapName] = "gui/hud_whiteout_gren"; +$InventoryHudData[3, itemDataName] = FlashGrenade; +$InventoryHudData[3, ammoDataName] = FlashGrenade; +$InventoryHudData[3, slot] = 0; +$InventoryHudData[4, bitmapName] = "gui/hud_concuss_gren"; +$InventoryHudData[4, itemDataName] = ConcussionGrenade; +$InventoryHudData[4, ammoDataName] = ConcussionGrenade; +$InventoryHudData[4, slot] = 0; +$InventoryHudData[5, bitmapName] = "gui/hud_handgren"; +$InventoryHudData[5, itemDataName] = FlareGrenade; +$InventoryHudData[5, ammoDataName] = FlareGrenade; +$InventoryHudData[5, slot] = 0; +$InventoryHudData[6, bitmapName] = "gui/hud_handgren"; +$InventoryHudData[6, itemDataName] = CameraGrenade; +$InventoryHudData[6, ammoDataName] = CameraGrenade; +$InventoryHudData[6, slot] = 0; +$InventoryHudData[7, bitmapName] = "gui/hud_beacon"; +$InventoryHudData[7, itemDataName] = Beacon; +$InventoryHudData[7, ammoDataName] = Beacon; +$InventoryHudData[7, slot] = 2; + +// ----------------------------------------------------- +// z0dd - ZOD, 9/12/02. TR2 need +//$InventoryHudCount = 8; +$InventoryHudData[8, bitmapName] = "gui/hud_handgren"; +$InventoryHudData[8, itemDataName] = TR2Grenade; +$InventoryHudData[8, ammoDataName] = TR2Grenade; +$InventoryHudData[8, slot] = 0; +$InventoryHudCount = 9; +// ----------------------------------------------------- + + +//---------------------------------------------------------------------------- +// Inventory Hud +//---------------------------------------------------------------------------- +//------------------------------------------------------------------------- --- +function GameConnection::setInventoryHudBitmap(%client, %slot, %name, %bitmap) +{ + commandToClient(%client, 'setInventoryHudBitmap',%slot,%name,%bitmap); +} + +//---------------------------------------------------------------------------- +function clientCmdSetInventoryHudBitmap(%slot, %name, %bitmap) +{ + inventoryHud.setInventoryBitmap(%slot,%bitmap); +} + +//---------------------------------------------------------------------------- +function GameConnection::setInventoryHudItem(%client, %name, %amount, %addItem) +{ + for(%i = 0; %i < $InventoryHudCount; %i++) + if($InventoryHudData[%i, itemDataName] $= %name) + { + if($InventoryHudData[%i, ammoDataName] !$= "") + commandToClient(%client, 'setInventoryHudItem',$InventoryHudData[%i, slot],%amount, %addItem); + else + commandToClient(%client, 'setInventoryHudItem',$InventoryHudData[%i, slot],-1, %addItem); + break; + } +} + +//---------------------------------------------------------------------------- +function clientCmdSetInventoryHudItem(%slot, %amount, %addItem) +{ + if(%addItem) + inventoryHud.addInventory(%slot, %amount); + else + inventoryHud.removeInventory(%slot); +} + +//---------------------------------------------------------------------------- +function GameConnection::setInventoryHudAmount(%client, %name, %amount) +{ + for(%i = 0; %i < $InventoryHudCount; %i++) + if($InventoryHudData[%i, ammoDataName] $= %name) + { + commandToClient(%client, 'setInventoryHudAmount',$InventoryHudData[%i, slot], %amount); + break; + } +} + +//---------------------------------------------------------------------------- +function clientCmdSetInventoryHudAmount(%slot, %amount) +{ + inventoryHud.setAmount(%slot, %amount); +} + +//---------------------------------------------------------------------------- +function GameConnection::setInventoryHudBackGroundBmp(%client, %name) +{ + commandToClient(%client, 'setInventoryHudBackGroundBmp',%name); +} + +//---------------------------------------------------------------------------- +function clientCmdSetInventoryHudBackGroundBmp(%name) +{ + inventoryHud.setBackGroundBitmap(%name); +} + +//---------------------------------------------------------------------------- +function GameConnection::setInventoryHudClearAll(%client) +{ + commandToClient(%client, 'setInventoryHudClearAll'); +} + +//---------------------------------------------------------------------------- +function clientCmdSetInventoryHudClearAll() +{ + inventoryHud.clearAll(); + backpackIcon.setBitmap( "" ); + backpackFrame.setVisible( false ); + backpackText.setValue( "" ); + backpackText.setVisible(false); + backpackFrame.pack = false; +} + +//---------------------------------------------------------------------------- +// MessageHud +function MessageHud::open(%this) +{ + %offset = 6; + + if(%this.isVisible()) + return; + + if(%this.isTeamMsg) + %text = "TEAM:"; + else + %text = "GLOBAL:"; + + MessageHud_Text.setValue(%text); + + %windowPos = "8 " @ ( getWord( outerChatHud.position, 1 ) + getWord( outerChatHud.extent, 1 ) + 1 ); + %windowExt = getWord( OuterChatHud.extent, 0 ) @ " " @ getWord( MessageHud_Frame.extent, 1 ); + + if( MainVoteHud.isVisible() ) + { + %votePos = firstWord( MainVoteHud.position ) @ " " @ ( getWord( OuterChatHud.extent, 1 ) + getWord( messageHud_Frame.extent, 1 ) + 10 ); + MainVoteHud.position = %votePos; + } + + if( voiceCommHud.isVisible() ) + { + %vCommPos = firstWord( voiceCommHud.position ) SPC ( getWord( OuterChatHud.extent, 1 ) + getWord( messageHud_Frame.extent, 1 ) + 18 ); + voiceCommHud.position = %vCommPos; + } + + %textExtent = getWord(MessageHud_Text.extent, 0); + %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); + deactivateKeyboard(); + MessageHud_Edit.makeFirstResponder(true); +} + +//------------------------------------------------------------------------------ +function MessageHud::close(%this) +{ + if(!%this.isVisible()) + return; + + // readjust vote hud if open + if( MainVoteHud.isVisible() ) + { + %tempY = getWord(outerChatHud.position, 1) + getWord(outerChatHud.extent, 1) + 2; + %mainVoteX = firstWord(mainVoteHud.position); + %voteHudPos = %mainVoteX SPC %tempY; + mainVoteHud.position = %voteHudPos; + } + // put voice comm hud back where it was (if it moved) + %vTempY = getWord(outerChatHud.position, 1) + getWord(outerChatHud.extent, 1) + 12; + %mainCommX = firstWord(voiceCommHud.position); + %commHudPos = %mainCommX SPC %vTempY; + voiceCommHud.position = %commHudPos; + + Canvas.popDialog(%this); + %this.setVisible(false); + if ( $enableDirectInput ) + activateKeyboard(); + 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 = trim(%this.getValue()); + if(%text !$= "") + { + if(MessageHud.isTeamMsg) + commandToServer('teamMessageSent', %text); + else + commandToServer('messageSent', %text); + } + + MessageHud.close(); +} + +//------------------------------------------------------------------------------ +// main chat hud +function MainChatHud::onWake( %this ) +{ + // set the chat hud to the users pref + %this.setChatHudLength( $Pref::ChatHudLength ); +} + +// chat hud sizes +$outerChatLenY[1] = 72; +$outerChatLenY[2] = 140; +$outerChatLenY[3] = 200; + +// size for scroll +$chatScrollLenY[1] = 64; +$chatScrollLenY[2] = 128; +$chatScrollLenY[3] = 192; + +//------------------------------------------------------------------------------ +function MainChatHud::setChatHudLength( %this, %length ) +{ + %outerChatLenX = firstWord(outerChatHud.extent); + %chatScrollLenX = firstWord(chatScrollHud.extent); + %OCHextent = %outerChatLenX SPC $outerChatLenY[%length]; + %CSHextent = %chatScrollLenX SPC $chatScrollLenY[%length]; + + outerChatHud.extent = %OCHextent; + chatScrollHud.extent = %CSHextent; + + %totalLines = HudMessageVector.getNumLines(); + %posLines = %length * 4; + %linesOver = ( %totalLines - %posLines ) * 14; + ChatPageDown.position = ( firstWord( outerChatHud.extent ) - 20 ) @ " " @ ( $chatScrollLenY[%length] - 6 ); + + if( ( %linesOver > 0 ) && !%sizeIncrease ) + { + %linesOver = %totalLines - %posLines; + %posAdjust = %linesOver * ChatHud.profile.fontSize + 3; + + %newPos = "0" @ " " @ ( -1 * %posAdjust ); + ChatHud.position = %newPos; + } + else if( %sizeIncrease && ( %linesOver > 0 ) ) + { + %curPos = getWord( ChatHud.position, 1 ); + %newY = %curPos + ( 4 * 14 ); + %newPos = "0 " @ %newY; + ChatHud.position = %newPos; + } + else if( %linesOver <= 0 ) + { + ChatHud.position = "0 0"; + } + + // adjust votehud and voicecommhud to be just beneath chathud + %tempY = getWord(outerChatHud.position, 1) + getWord(outerChatHud.extent, 1) + 2; + %vTempY = %tempY + 10; + %mainVoteX = firstWord(mainVoteHud.position); + %vCommX = firstWord(voiceCommHud.position); + %voteHudPos = %mainVoteX SPC %tempY; + %vCommPos = %vCommX SPC %vTempY; + mainVoteHud.position = %voteHudPos; + voiceCommHud.position = %vCommPos; + ChatHud.resize(firstWord(ChatHud.position), getWord(ChatHud.position, 1), firstWord(ChatHud.extent), getWord(ChatHud.extent, 1)); +} + +//------------------------------------------------------------------------------ +function MainChatHud::nextChatHudLen( %this ) +{ + $pref::chatHudLength++; + if($pref::chatHudLength == 4) + { + $pref::chatHudLength = 1; + %sizeIncrease = false; + ChatPageDown.position = ( firstWord( outerChatHud.extent ) - 20 ) @ " 50"; + } + else + %sizeIncrease = true; + + %outerChatLenX = firstWord(outerChatHud.extent); + %chatScrollLenX = firstWord(chatScrollHud.extent); + %OCHextent = %outerChatLenX SPC $outerChatLenY[$pref::chatHudLength]; + %CSHextent = %chatScrollLenX SPC $chatScrollLenY[$pref::chatHudLength]; + + outerChatHud.extent = %OCHextent; + chatScrollHud.extent = %CSHextent; + + %totalLines = HudMessageVector.getNumLines(); + %posLines = $pref::chatHudLength * 4; + %linesOver = %totalLines - %posLines; + ChatPageDown.position = ( firstWord( outerChatHud.extent ) - 20 ) @ " " @ ( $chatScrollLenY[$pref::chatHudLength] - 6 ); + + if( ( %linesOver > 0 ) && !%sizeIncrease ) + { + %linesOver = %totalLines - %posLines; + %posAdjust = %linesOver * $ShellFontSize; + + %newPos = "0" @ " " @ ( -1 * %posAdjust ); + ChatHud.position = %newPos; + } + else if( %sizeIncrease && ( %linesOver > 0 ) ) + { + %curPos = getWord( ChatHud.position, 1 ); + %newY = %curPos + ( 4 * $ShellFontSize ); + %newPos = "0 " @ %newY; + ChatHud.position = %newPos; + } + else if( %linesOver <= 0 ) + { + ChatHud.position = "0 0"; + } + + // adjust votehud to be just beneath chathud + %tempY = getWord(outerChatHud.position, 1) + getWord(outerChatHud.extent, 1) + 2; + %vTempY = %tempY + 10; + %mainVoteX = firstWord(mainVoteHud.position); + %vCommX = firstWord(voiceCommHud.position); + %voteHudPos = %mainVoteX SPC %tempY; + %vCommPos = %vCommX SPC %vTempY; + mainVoteHud.position = %voteHudPos; + voiceCommHud.position = %vCommPos; + ChatHud.resize(firstWord(ChatHud.position), getWord(ChatHud.position, 1), firstWord(ChatHud.extent), getWord(ChatHud.extent, 1)); +} + +//---------------------------------------------------------------------------- +// MessageHud key handlers +function ToggleMessageHud(%make) +{ + if(%make) + { + MessageHud.isTeamMsg = false; + MessageHud.toggleState(); + } +} + +//------------------------------------------------------------------------------ +function TeamMessageHud(%make) +{ + if(%make) + { + MessageHud.isTeamMsg = true; + MessageHud.toggleState(); + } +} + +//---------------------------------------------------------------------------- +// MessageHud message handlers +function serverCmdTeamMessageSent(%client, %text) +{ + if(strlen(%text) >= $Host::MaxMessageLen) + %text = getSubStr(%text, 0, $Host::MaxMessageLen); + chatMessageTeam(%client, %client.team, '\c3%1: %2', %client.name, %text); +} + +//------------------------------------------------------------------------------ +function serverCmdMessageSent(%client, %text) +{ + if(strlen(%text) >= $Host::MaxMessageLen) + %text = getSubStr(%text, 0, $Host::MaxMessageLen); + chatMessageAll(%client, '\c4%1: %2', %client.name, %text); +} + +//-------------------------------------------------------------------------- +function toggleHuds(%tag) +{ + if($Hud[%tag] && $Hud[%tag].pushed) + hideHud(%tag); + else + showHud(%tag); +} + +//------------------------------------------------------------------------------ + +//modes are standard, pilot, passenger, object, observer +$HudMode = "Observer"; +$HudModeType = "HoverBike"; +$HudModeNode = 0; +function ClientCmdSetHudMode(%mode, %type, %node) +{ + $HudMode = detag(%mode); + $HudModeType = detag(%type); + $HudModeNode = %node; + + clientCmdDisplayHuds(); +} + +//------------------------------------------------------------------------------ +$ControlObjectReticle[AABarrelLarge, bitmap] = "ret_chaingun"; +$ControlObjectReticle[AABarrelLarge, frame] = true; +$ControlObjectReticle[ELFBarrelLarge, bitmap] = "ret_elf"; +$ControlObjectReticle[ELFBarrelLarge, frame] = true; +$ControlObjectReticle[DeployableIndoorBarrel, bitmap] = "ret_blaster"; +$ControlObjectReticle[DeployableIndoorBarrel, frame] = true; +$ControlObjectReticle[MissileBarrelLarge, bitmap] = "ret_missile"; +$ControlObjectReticle[MissileBarrelLarge, frame] = true; +$ControlObjectReticle[MortarBarrelLarge, bitmap] = "ret_mortor"; // mortor? hahaha +$ControlObjectReticle[MortarBarrelLarge, frame] = true; +$ControlObjectReticle[DeployableOutdoorBarrel, bitmap] = "ret_blaster"; +$ControlObjectReticle[DeployableOutdoorBarrel, frame] = true; +$ControlObjectReticle[PlasmaBarrelLarge, bitmap] = "ret_plasma"; +$ControlObjectReticle[PlasmaBarrelLarge, frame] = true; +$ControlObjectReticle[SentryTurretBarrel, bitmap] = "ret_blaster"; +$ControlObjectReticle[SentryTurretBarrel, frame] = true; + +function setControlObjectReticle(%type) +{ + if($ControlObjectReticle[%type, bitmap] !$= "") + { + reticleHud.setBitmap("gui/" @ $ControlObjectReticle[%type, bitmap]); + reticleFrameHud.setVisible($ControlObjectReticle[%type, frame]); + + retCenterHud.setVisible(true); + } + else + retCenterHud.setVisible(false); +} + +function updateActionMaps() +{ + //pop the action maps... + if ( isObject( moveMap ) ) + moveMap.pop(); + if ( isObject( passengerKeys ) ) + passengerKeys.pop(); + if ( isObject( observerBlockMap ) ) + observerBlockMap.pop(); + if ( isObject( observerMap ) ) + observerMap.pop(); + if ( isObject( pickTeamMap ) ) + pickTeamMap.pop(); + if ( isObject( halftimeMap ) ) + halftimeMap.delete(); + + //if (isObject(flyingCameraMove)) + // flyingCameraMove.pop(); + if (isObject(ControlActionMap)) + ControlActionMap.pop(); + + // push the proper map + switch$ ($HudMode) + { + case "Pilot": + passengerKeys.push(); + + case "Passenger": + moveMap.push(); + + case "Object": + moveMap.push(); + ControlActionMap.push(); + + case "Observer": + moveMap.push(); + if ( isObject( observerBlockMap ) ) + observerBlockMap.delete(); + // Create an action map just to block unwanted parts of the move map: + new ActionMap( observerBlockMap ); + observerBlockMap.blockBind( moveMap, jump ); + observerBlockMap.blockBind( moveMap, mouseFire ); + observerBlockMap.blockBind( moveMap, mouseJet ); + observerBlockMap.blockBind( moveMap, toggleZoom ); + observerBlockMap.blockBind( moveMap, setZoomFOV ); + observerBlockMap.push(); + observerMap.push(); + // Make sure that "Spawn" is bound: + if ( observerMap.getBinding( mouseFire ) $= "" ) + observerMap.copyBind( moveMap, mouseFire ); + + case "PickTeam": + //////////////////////// + // pickTeam Keys + ////////////////////// + if( !isObject( pickTeamMap ) ) + new ActionMap( pickTeamMap ); + pickTeamMap.copyBind( moveMap, toggleMessageHud ); + pickTeamMap.push(); + + case "SiegeHalftime": + new ActionMap( halftimeMap ); + halftimeMap.bindCmd( keyboard, escape, "", "escapeFromGame();" ); + halftimeMap.copyBind( moveMap, toggleMessageHud ); + halftimeMap.copyBind( moveMap, teamMessageHud ); + halftimeMap.copyBind( moveMap, activateChatMenuHud ); + halftimeMap.copyBind( moveMap, resizeChatHud ); + halftimeMap.copyBind( moveMap, pageMessageHudUp ); + halftimeMap.copyBind( moveMap, pageMessageHudDown ); + halftimeMap.copyBind( moveMap, voiceCapture ); + halftimeMap.push(); + + //case 'Standard': + default: + moveMap.push(); + } +} + +//------------------------------------------------------------------------------ +function ClientCmdDisplayHuds() +{ + if ( $LaunchMode $= "InteriorView" ) + return; + + // only update action maps if playGui is current content + %content = Canvas.getContent(); + %PlayGuiActive = isObject(%content) && ( %content.getName() $= "PlayGui" ); + if ( %PlayGuiActive ) + updateActionMaps(); + + ammoHud.setVisible(false); + objectiveHud.setVisible(false); + inventoryHud.setVisible(false); + backpackFrame.setVisible(false); + weaponsHud.setVisible(false); + retCenterHud.setVisible(false); + HudClusterBack.setVisible(false); + outerChatHud.setVisible(false); + clockHud.setVisible(false); + controlObjectText.setVisible(false); + siegeHalftimeHud.setVisible(false); + clientCmdToggleDashHud(false); + %hideCursor = true; + + switch$ ($HudMode) + { + case "Pilot": + clientCmdShowVehicleGauges($HudModeType, $HudModeNode); + clientCmdToggleDashHud(true); + objectiveHud.setVisible(true); + dashBoardHud.setposition(0, 0); + retCenterHud.setVisible(true); + HudClusterBack.setVisible(true); + outerChatHud.setVisible(true); + clockHud.setVisible(true); + + case "Passenger": + clientCmdShowVehicleGauges($HudModeType, $HudModeNode); + clientCmdToggleDashHud(true); + objectiveHud.setVisible(true); + dashBoardHud.setPosition(0, 0); + ammoHud.setVisible(true); + objectiveHud.setVisible(true); + inventoryHud.setVisible(true); + weaponsHud.setVisible(true); + if(backpackFrame.pack) + backpackFrame.setVisible(true); + retCenterHud.setVisible(true); + HudClusterBack.setVisible(true); + outerChatHud.setVisible(true); + clockHud.setVisible(true); + + case "Object": + ammoHud.setVisible(true); + HudClusterBack.setVisible(true); + outerChatHud.setVisible(true); + controlObjectText.setVisible(true); + clockHud.setVisible(true); + + setControlObjectReticle($HudModeType); + + case "Observer": + objectiveHud.setVisible(true); + HudClusterBack.setVisible(true); + outerChatHud.setVisible(true); + clockHud.setVisible(true); + + case "SiegeHalftime": + closeHud( "", "", 'scoreScreen' ); + closeHud( "", "", 'inventoryScreen' ); + closeHud( "", "", 'vehicleHud' ); + objectiveHud.setVisible(true); + outerChatHud.setVisible(true); + siegeHalftimeHud.setVisible(true); + %hideCursor = false; + + case "PickTeam": + ammoHud.setVisible(false); + objectiveHud.setVisible(false); + inventoryHud.setVisible(false); + backpackFrame.setVisible(false); + weaponsHud.setVisible(false); + retCenterHud.setVisible(false); + HudClusterBack.setVisible(false); + outerChatHud.setVisible(true); + controlObjectText.setVisible(false); + clockHud.setVisible(false); + + //case 'Standard': + default: + ammoHud.setVisible(true); + objectiveHud.setVisible(true); + inventoryHud.setVisible(true); + weaponsHud.setVisible(true); + if(backpackFrame.pack) + backpackFrame.setVisible(true); + retCenterHud.setVisible(true); + HudClusterBack.setVisible(true); + outerChatHud.setVisible(true); + clockHud.setVisible(true); + + if(voteHud.voting) + mainVoteHud.setVisible(1); + else + mainVoteHud.setVisible(0); + + } + + if ( PlayGui.hideCursor != %hideCursor ) + { + PlayGui.hideCursor = %hideCursor; + if ( %PlayGuiActive ) + Canvas.updateCursorState(); + } +} + +function dashboardHud::onResize(%this, %width, %height) +{ + %currentWidth = getWord(dashboardHud.getPosition(), 0); + %currentHeight = getWord(dashboardHud.getPosition(), 1); + + %screenWidth = getWord(getResolution(), 0); + %screenHeight = getWord(getResolution(), 1); + + switch$ ($HudMode) + { + case "Pilot": + if(%screenHeight <= 480) + { + if($HudModeNode == 0) + { %xVal = 0; %yVal = 339; } + else + { %xVal = 0; %yVal = 320; } + } + else if(%screenHeight <= 600) + { + if($HudModeNode == 0) + { %xVal = 80; %yVal = 455; } + else + { %xVal = 80; %yVal = 440; } + } + else + { + %xVal = (%screenWidth - 640) / 2; + %yVal = (%screenheight - 480) + 360; + } + + case "Passenger": + %xVal = (%screenWidth - 640) / 2; + %yVal = (%screenheight - 480) + 360; + } + + if(%currentWidth != %xVal || %currentHeight != %yVal) + dashBoardHud.setPosition(%xVal, %yVal); +} + +function clientcmdTogglePlayHuds(%val) +{ + ammoHud.setVisible(%val); + objectiveHud.setVisible(%val); + inventoryHud.setVisible(%val); + if(backpackFrame.pack) + backpackFrame.setVisible(%val); + weaponsHud.setVisible(%val); + retCenterHud.setVisible(%val); + HudClusterBack.setVisible(%val); + outerChatHud.setVisible(%val); + clockHud.setVisible(%val); + + if(%val) + { + if(voteHud.voting) + mainVoteHud.setVisible(1); + } + else + mainVoteHud.setVisible(0); +} + +//------------------------------------------------------------------------------ +function toggleCursorHuds(%tag) +{ + if($Hud[%tag] !$= "" && $Hud[%tag].pushed) + { + hideHud(%tag); + clientCmdTogglePlayHuds(true); + } + else + { + showHud(%tag); + clientCmdTogglePlayHuds(false); + } +} + +//------------------------------------------------------------------------------ +function showHud(%tag) +{ + commandToServer('ShowHud', %tag); +} + +//------------------------------------------------------------------------------ +function serverCmdShowHud(%client, %tag) +{ + %tagName = getWord(%tag, 1); + %tag = getWord(%tag, 0); + messageClient(%client, 'OpenHud', "", %tag); + + if (%tag $= 'scoreScreen') + serverCmdProcessGameLink(%client,%client.PDAPage); + + switch$ (%tag) + { + case 'inventoryScreen': + %client.numFavsCount = 0; + inventoryScreen::updateHud(1,%client,%tag); + case 'vehicleHud': + vehicleHud::updateHud(1,%client,%tag); + case 'scoreScreen': + updateScoreHudThread(%client, %tag); + } +} + +//------------------------------------------------------------------------------ +function updateScoreHudThread(%client, %tag) +{ + // z0dd - ZOD, 6/13/02. Need to check for game object + // for Random Teams by Founder (founder@mechina.com). + if(isObject(Game)) + { + Game.updateScoreHud(%client, %tag); + cancel(%client.scoreHudThread); + %client.scoreHudThread = schedule(3000, %client, "updateScoreHudThread", %client, %tag); + } +} + +//------------------------------------------------------------------------------ +function hideHud(%tag) +{ + commandToServer('HideHud', %tag); +} + +//------------------------------------------------------------------------------ +function serverCmdHideHud(%client, %tag) +{ + %tag = getWord(%tag, 0); + messageClient(%client, 'CloseHud', "", %tag); + switch$ (%tag) + { + case 'scoreScreen': + cancel(%client.scoreHudThread); + %client.scoreHudThread = ""; + } +} + +//------------------------------------------------------------------------------ +addMessageCallback('OpenHud', openHud); +addMessageCallback('CloseHud', closeHud); +addMessageCallback('ClearHud', clearHud); +addMessageCallback('SetLineHud', setLineHud); +addMessageCallback('RemoveLineHud', removeLineHud); + +//------------------------------------------------------------------------------ +function openHud(%msgType, %msgString, %tag) +{ + // Vehicle hud can only be pushed on the PlayGui: + if ( %tag $= 'vehicleHud' && Canvas.getContent() != PlayGui.getId() ) + return; + + %tagName = getWord(%tag, 1); + %tag = getWord(%tag, 0); + if($Hud[%tag] $= "") + { + %tagName.loadHud(%tag); + %tagName.setupHud(%tag); + } + Canvas.pushDialog($Hud[%tag]); + $Hud[%tag].pushed = 1; +} + +//------------------------------------------------------------------------------ +function closeHud(%msgType, %msgString, %tag) +{ + %tag = getWord(%tag, 0); + if($Hud[%tag].pushed) + { + $Hud[%tag].setVisible(false); + Canvas.popDialog($Hud[%tag]); + $Hud[%tag].pushed = 0; + } +} + +//------------------------------------------------------------------------------ +function clearHud(%msgType, %msgString, %tag, %a0) +{ + %tag = getWord(%tag, 0); + %startingLine = detag(%a0); + + while ($Hud[%tag].data[%startingLine, 0] !$= "") + { + for(%i = 0; %i < $Hud[%tag].numCol; %i++) + { + //remove and delete the hud line + %obj = $Hud[%tag].data[%startingLine, %i]; + $Hud[%tag].childGui.remove(%obj); + $Hud[%tag].data[%startingLine, %i] = ""; + %obj.delete(); + } + + %startingLine++; + } + + //don't forget to adjust the size accordingly... + if (%tag $= 'scoreScreen') + { + %height = 0; + %guiCtrl = $Hud[%tag].childGui; + + if(isObject(%guiCtrl)) + { + //set the new extent to be the position + extent of the last element... + %height = 0; + if (%guiCtrl.getCount() > 0) + { + %lastCtrl = %guiCtrl.getObject(%guiCtrl.getCount() - 1); + %height = getWord(%lastCtrl.position, 1) + getWord(%lastCtrl.extent, 1); + } + + //now reset the extent + %guiCtrl.resize(getWord(%guiCtrl.position, 0), getWord(%guiCtrl.position, 1), getWord(%guiCtrl.extent, 0), %height); + } + } +} + +//------------------------------------------------------------------------------ +function removeLineHud(%msgType, %msgString, %hudName, %lineNumber, %a0, %a1, %a2, %a3) +{ + %tag = getWord(%hudName, 0); + %lineNum = detag(%lineNumber); + if($Hud[%tag].data[%lineNum,0] !$= "") + for(%i = 0; %i < $Hud[%tag].numCol; %i++) + { + $Hud[%tag].childGui.remove($Hud[%tag].data[%lineNum, %i]); + $Hud[%tag].data[%lineNum, %i] = ""; + } + + //don't forget to adjust the size accordingly... + if (%tag $= 'scoreScreen') + { + %height = 0; + %guiCtrl = $Hud[%tag].childGui; + + //set the new extent to be the position + extent of the last element... + %height = 0; + if (%guiCtrl.getCount() > 0) + { + %lastCtrl = %guiCtrl.getObject(%guiCtrl.getCount() - 1); + %height = getWord(%lastCtrl.position, 1) + getWord(%lastCtrl.extent, 1); + } + + //now reset the extent + %guiCtrl.resize(getWord(%guiCtrl.position, 0), getWord(%guiCtrl.position, 1), getWord(%guiCtrl.extent, 0), %height); + } +} + +//------------------------------------------------------------------------------ +function setLineHud(%msgType, %msgString, %hudName, %lineNumber, %a0, %a1, %a2, %a3, %a4) +{ + %tag = getWord(%hudName, 0); + %lineNum = detag(%lineNumber); + + if(!isObject($Hud[%tag].data[%lineNum, 0])) + { + $Hud[%tag].numCol = addLine(%tag, %lineNum, %a0, %a1, %a2, %a3); + for(%i = 0; %i < $Hud[%tag].numCol; %i++) + $Hud[%tag].childGui.add($Hud[%tag].data[%lineNum, %i]); + } + + for(%i = 0; %i < $Hud[%tag].numCol; %i++) + $Hud[%tag].data[%lineNum, %i].hudSetValue(detag(%a[%i]),detag(%a4)); + + //don't forget to adjust the size accordingly... + if (%tag $= 'scoreScreen') + { + %height = 0; + %guiCtrl = $Hud[%tag].childGui; + + //set the new extent to be the position + extent of the last element... + %height = 0; + if (%guiCtrl.getCount() > 0) + { + %lastCtrl = %guiCtrl.getObject(%guiCtrl.getCount() - 1); + %height = getWord(%lastCtrl.position, 1) + getWord(%lastCtrl.extent, 1); + } + + //now reset the extent + %guiCtrl.resize(getWord(%guiCtrl.position, 0), getWord(%guiCtrl.position, 1), getWord(%guiCtrl.extent, 0), %height); + } +} + +//------------------------------------------------------------------------------ +function GuiButtonCtrl::hudSetValue(%obj, %text) +{ + %obj.setValue(%text); +} + +//------------------------------------------------------------------------------ +function GuiTextCtrl::hudSetValue(%obj, %text) +{ + %obj.setValue(%text); +} + +//------------------------------------------------------------------------------ +function GuiMLTextCtrl::hudSetValue(%obj, %text) +{ + %obj.setValue(%text); +} + +//------------------------------------------------------------------------------ +function ShellTabGroupCtrl::hasTab(%obj, %text) +{ + %count = %obj.tabCount(); + for (%i = 0; %i < %count; %i++) + { + %textS = %obj.getTabText( %i ); + if (%textS $= %text) + return true; + } +return false; +} + +//------------------------------------------------------------------------------ +function GuiPopUpMenuCtrl::hudSetValue(%obj, %text, %textOverFlow) +{ + if(%textOverFlow !$= "") + %text = %text @ %textOverFlow; + %obj.clear(); + %value = getField(%text,0); + %startVal = 1; + if(%value $= "noSelect") + { + %obj.replaceText(false); + %value = getField(%text,1); + %startVal = 2; + } + else + %obj.replaceText(true); + + %obj.setValue(%value); + if(getFieldCount(%text) > 1) + { + %obj.setActive(true); + for(%i = %startVal; %i < getFieldCount(%text); %i++) + %obj.add(getField(%text, %i), %i); + } + else + %obj.setActive(false); +} + +//------------------------------------------------------------------------------ +function ShellTabButton::hudSetValue( %obj, %text ) +{ + %obj.setText( %text ); +} + +//------------------------------------------------------------------------------ +function addLine(%tag, %lineNum, %a0, %a1, %a2, %a3) +{ + %colNum = 0; + if(isObject($Hud[%tag])) + %colNum = $Hud[%tag].addLine(%tag, %lineNum, detag(%a2), detag(%a3)); + return %colNum; +} + +//------------------------------------------------------------------------------ +function INV_Menu::onSelect( %obj, %index, %text ) +{ + %favList = $Hud['inventoryScreen'].data[0, 1].type TAB $Hud['inventoryScreen'].data[0, 1].getValue(); + for ( %i = 1; %i < $Hud['inventoryScreen'].count; %i++ ) + %favList = %favList TAB $Hud['inventoryScreen'].data[%i, 1].type TAB $Hud['inventoryScreen'].data[%i, 1].getValue(); + commandToServer( 'setClientFav', %favList ); +} + +//------------------------------------------------------------------------------ +function INV_ListMenu::onSelect( %obj, %id, %text, %force ) +{ + // Deselect the current tab ( because it was on the OLD list ): + if ( InventoryScreen.selId !$= "" ) + { + $Hud['inventoryScreen'].staticData[0, InventoryScreen.selId].setValue( false ); + InventoryScreen.selId = ""; + } + + $pref::FavCurrentList = %id; + %favListStart = %id * 10; + + // Select the currently selected favorite if it is now visible: + %tab = $pref::FavCurrentSelect - ( $pref::FavCurrentList * 10 ) + 1; + if ( %tab > 0 && %tab < 11 ) + { + InventoryScreen.selId = %tab; + $Hud['inventoryScreen'].staticData[0, %tab].setValue( true ); + } + + %obj.clear(); + %obj.setValue( %text ); + %count = 10; + %list = 0; + for ( %index = 0; $pref::FavNames[%index] !$= ""; %index++ ) + { + if ( %index >= %count - 1 ) + { + if ( %count != %favListStart + 10 ) + %obj.add( "Favorites " @ %index - 8 @ " - " @ %index + 1, %list ); + + %count += 10; + %list++; + } + } + + for ( %i = 0; %i < 10; %i++ ) + { + $Hud['inventoryScreen'].staticData[0, %i + 1].command = "InventoryScreen.onTabSelect(" @ %favListStart + %i @ ");"; + $Hud['inventoryScreen'].staticData[0, %i + 1].setText( strupr( $pref::FavNames[%favListStart + %i] ) ); + } +} + +//------------------------------------------------------------------------------ +function serverCmdSetClientFav(%client, %text) +{ + if ( getWord( getField( %text, 0 ), 0 ) $= armor ) + { + %client.curFavList = %text; + %validList = checkInventory( %client, %text ); + %client.favorites[0] = getField( %text, 1 ); + %armor = getArmorDatablock( %client, $NameToInv[getField( %validList,1 )] ); + %weaponCount = 0; + %packCount = 0; + %grenadeCount = 0; + %mineCount = 0; + %count = 1; + %client.weaponIndex = ""; + %client.packIndex = ""; + %client.grenadeIndex = ""; + %client.mineIndex = ""; + + for(%i = 3; %i < getFieldCount(%validList); %i = %i + 2) + { + %setItem = false; + switch$ (getField(%validList,%i-1)) + { + case weapon: + if(%weaponCount < %armor.maxWeapons) + { + if(!%weaponCount) + %client.weaponIndex = %count; + else + %client.weaponIndex = %client.weaponIndex TAB %count; + %weaponCount++; + %setItem = true; + } + case pack: + if(%packCount < 1) + { + %client.packIndex = %count; + %packCount++; + %setItem = true; + } + case grenade: + if(%grenadeCount < %armor.maxGrenades) + { + if(!%grenadeCount) + %client.grenadeIndex = %count; + else + %client.grenadeIndex = %client.grenadeIndex TAB %count; + %grenadeCount++; + %setItem = true; + } + case mine: + if(%mineCount < %armor.maxMines) + { + if(!%mineCount) + %client.mineIndex = %count; + else + %client.mineIndex = %client.mineIndex TAB %count; + %mineCount++; + %setItem = true; + } + } + if(%setItem) + { + %client.favorites[%count] = getField(%validList, %i); + %count++; + } + } + %client.numFavs = %count; + %client.numFavsCount = 0; + inventoryScreen::updateHud(1, %client, 'inventoryScreen'); + } +} + +//------------------------------------------------------------------------------ +function getCenterPos(%tag) +{ + %TerExtDivX = getWord(PlayGui.extent, 0) / 2; + %TerExtDivY = getWord(PlayGui.extent, 1) / 2; + + %HudExtDivX = getWord($Hud[%tag].extent,0) / 2; + %HudExtDivY = getWord($Hud[%tag].extent,1) / 2; + + %pos = %TerExtDivX - %HudExtDivX @ " " @ %TerExtDivY - %HudExtDivY; + return %pos; +} + +//------------------------------------------------------------------------------ +function hideZoomHud() +{ + ZoomHud.setVisible(false); + ZoomHud.hideThread = 0; +} + +function calcZoomFOV() +{ + if($pref::player::currentFOV == $pref::player::defaultFov / 2) + $pref::player::currentFOV = $pref::player::defaultFov / 5; + else + $pref::player::currentFOV = $pref::player::currentFOV / 2; + + if($pref::player::currentFOV < 4) + $pref::player::currentFOV = $pref::player::defaultFov / 2; + + if(!$ZoomOn) + { + %pos = getZoomCenter($pref::player::defaultFov / $pref::player::currentFOV); + %extent = getZoomExtent($pref::player::defaultFov / $pref::player::currentFOV); + ZoomHud.resize(getWord(%pos, 0), getWord(%pos, 1), getWord(%extent, 0), getWord(%extent, 1)); + if(ZoomHud.hideThread != 0) + cancel(ZoomHud.hideThread); + ZoomHud.hideThread = schedule(5000, 0, hideZoomHud); + ZoomHud.setVisible(true); + } + else + setFov( $pref::player::currentFOV ); +} + +//------------------------------------------------------------------------------ +function getZoomCenter(%power) +{ + %power += (%power/4); + %TerExtDivX = mFloor(getWord(PlayGui.extent, 0) / 2); + %TerExtDivY = mFloor(getWord(PlayGui.extent, 1) / 2); + + %HudExtDivX = mFloor((getWord(PlayGui.extent, 0) / %power)/2); + %HudExtDivY = mFloor((getWord(PlayGui.extent, 1) / %power)/2); + + %pos = %TerExtDivX - %HudExtDivX @ " " @ %TerExtDivY - %HudExtDivY; + return %pos; +} + +//------------------------------------------------------------------------------ +function getZoomExtent(%power) +{ + %power += (%power/4); + %HudExtDivX = mFloor(getWord(PlayGui.extent, 0) / %power); + %HudExtDivY = mFloor(getWord(PlayGui.extent, 1) / %power); + + %val = %HudExtDivX @ " " @ %HudExtDivY; + + return %val; +} + +//------------------------------------------------------------------------------ +function hideAllHuds() +{ + objectiveHud.setVisible( false ); + outerChatHud.setVisible( false ); + energyHud.setVisible( false ); + damageHud.setVisible( false ); + sensorHudBack.setVisible( false ); + controlObjectText.setVisible( false ); +} + +//------------------------------------------------------------------------------ +function restoreAllHuds() +{ + objectiveHud.setVisible( true ); + outerChatHud.setVisible( true ); + energyHud.setVisible( true ); + damageHud.setVisible( true ); + sensorHudBack.setVisible( true ); +} + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +// voting hud stuff +///////////////////////////////////////////////// +addMessageCallback('clearVoteHud', clearVoteHud); +addMessageCallback('addYesVote', addYesVote); +addMessageCallback('addNoVote', addNoVote); +addMessageCallback('openVoteHud', openVoteHud); +addMessageCallback('closeVoteHud', closeVoteHud); +addMessageCallback('VoteStarted', initVote); + +//------------------------------------------------------------------------------ +function initVote(%msgType, %msgString) +{ + if(!$BottomPrintActive) + { + %yBind = strUpr(getField(moveMap.getBinding(voteYes), 1)); + %nBind = strUpr(getField(moveMap.getBinding(voteNo), 1)); + + %message = detag(%msgString) @ "\nPress " @ %yBind @ " to vote YES or " @ %nBind @ " to vote NO."; + clientCmdBottomPrint(%message, 10, 2); + } +} + +function openVoteHud(%msgType, %msgString, %numClients, %passPercent) +{ + alxPlay(VoteInitiatedSound, 0, 0, 0); + voteHud.voting = true; + + voteHud.totalVotes = 0; + voteHud.size = %numClients; + voteHud.quorum = (%numClients / 2); + + if(voteHud.quorum < 1) + voteHud.quorum = 1; + + voteHud.pass = voteHud.quorum * %passPercent; + + voteHud.setPassValue(%passPercent); + passHash.position = firstWord( mainVoteHud.extent) * %passPercent + 1 @ " -1"; + + if( MessageHud.isVisible() ) + { + %votePos = firstWord( MainVoteHud.position ) @ " " @ ( getWord( OuterChatHud.extent, 1 ) + getWord( messageHud_Frame.extent, 1 ) + 12 ); + MainVoteHud.position = %votePos; + } + else + { + %tempY = getWord(outerChatHud.position, 1) + getWord(outerChatHud.extent, 1) + 2; + %mainVoteX = firstWord(mainVoteHud.position); + %voteHudPos = %mainVoteX SPC %tempY; + mainVoteHud.position = %voteHudPos; + } + + voteHud.setVisible(true); + mainVoteHud.setVisible(true); +} + +function stripBind(%string) +{ + return getSubstr(%string, 9, 90); +} + +//------------------------------------------------------------------------------ +function CloseVoteHud(%msgType, %msgString) +{ + voteHud.setVisible(false); + mainVoteHud.setVisible(false); + voteHud.yesCount = 0; + voteHud.noCount = 0; + voteHud.voting = false; +} + +//------------------------------------------------------------------------------ +function addYesVote(%msgType, %msgString) +{ + voteHud.yesCount++; + voteHud.totalVotes++; + + if(voteHud.isVisible()) + { + voteHud.setYesValue(voteHud.yesCount / voteHud.size); + } +} + +//------------------------------------------------------------------------------ +function addNoVote(%msgType, %msgString) +{ + voteHud.noCount++; + voteHud.totalVotes++; + + if(voteHud.isVisible()) + voteHud.setNoValue(voteHud.noCount / voteHud.size); +} + +//------------------------------------------------------------------------------ +function clearVoteHud(%msgType, %msgString) +{ + voteHud.setYesValue(0.0); + voteHud.setNoValue(0.0); +} + +//------------------------------------------------------------------------------ +function cleanUpHuds() +{ + if($Hud['inventoryScreen'] !$= "") + { + for(%lineNum = 0; $Hud['inventoryScreen'].data[%lineNum, 0] !$= ""; %lineNum++) + for(%i = 0; %i < $Hud['inventoryScreen'].numCol; %i++) + { + $Hud['inventoryScreen'].childGui.remove($Hud['inventoryScreen'].data[%lineNum, %i]); + $Hud['inventoryScreen'].data[%lineNum, %i] = ""; + } + } +} + +// z0dd - ZOD, 4/18/02. Total re-write to give players more information on who they are observing. +function displayObserverHud(%client, %targetClient, %potentialClient) +{ + %targName = getTaggedString(%targetClient.name); + %potName = getTaggedString(%potentialClient.name); + %targTeam = getTaggedString(Game.getTeamName(%targetClient.team)); + %potTeam = getTaggedString(Game.getTeamName(%potentialClient.team)); + + if (%targetClient > 0) + { + if(%targetClient.team == 1) + bottomPrint(%client, "You are now observing:\n" @ %targName @ "\nTeam: " @ %targTeam, 0, 3); + else + bottomPrint(%client, "You are now observing:\n" @ %targName @ "\nTeam: " @ %targTeam, 0, 3); + } + else if (%potentialClient > 0) + { + if(%potentialClient.team == 1) + bottomPrint(%client, "Observer Fly Mode\n" @ %potName @ "\nTeam: " @ %potTeam, 0, 3); + else + bottomPrint(%client, "Observer Fly Mode\n" @ %potName @ "\nTeam: " @ %potTeam, 0, 3); + } + else + bottomPrint(%client, "\nObserver Fly Mode", 0, 3); +} + +function hudFirstPersonToggled() +{ + ammoHud.setVisible($firstPerson); +} + +$testCount = 0; + +function testChatHud() +{ + $testCount++; + messageAll( '', "This is test number " @ $testCount ); + $tester = schedule( 50, 0, "testChatHud"); +} + +//------------------------------------------------------------------------- +function HudNetDisplay::getPrefs(%this) +{ + for(%i = 0; %i < 6; %i++) + %this.renderField[%i] = ($pref::Net::graphFields >> %i) & 1; +} + +function NetBarHud::infoUpdate(%this, %ping, %packetLoss, %sendPackets, %sendBytes, %receivePackets, %receiveBytes) +{ + NetBarHudPingText.setText(mFormatFloat(%ping, "%4.0f") @ "ms"); + NetBarHudPacketLossText.setText(mFormatFloat(%packetLoss, "%3.0f") @ "%"); + + NetBarHudSendBar.value = %sendPackets / $pref::Net::PacketRateToServer; + NetBarHudReceiveBar.value = %receivePackets / $pref::Net::PacketRateToClient; +} diff --git a/scripts/inventory.cs b/scripts/inventory.cs index 6ace54e..aeb3846 100644 --- a/scripts/inventory.cs +++ b/scripts/inventory.cs @@ -1,625 +1,625 @@ -//---------------------------------------------------------------------------- - -// Item Datablocks -// image = Name of mounted image datablock -// onUse(%this,%object) - -// Item Image Datablocks -// item = Name of item inventory datablock - -// ShapeBase Datablocks -// max[Item] = Maximum amount that can be caried - -// ShapeBase Objects -// inv[Item] = Count of item in inventory -//---------------------------------------------------------------------------- - -$TestCheats = 0; - -function serverCmdUse(%client,%data) -{ - // Item names from the client must converted - // into DataBlocks - // %data = ItemDataBlock[%item]; - - %client.getControlObject().use(%data); -} - -function serverCmdThrow(%client,%data) -{ - // Item names from the client must converted - // into DataBlocks - // %data = ItemDataBlock[%item]; - - //----------------------------------------------------------------------- - // z0dd - ZOD, 4/18/02. Let one keybind handle all grenade types. - if(%data $= Grenade) - { - // figure out which grenade type you're using - for(%x = 0; $InvGrenade[%x] !$= ""; %x++) - { - if(%client.getControlObject().inv[$NameToInv[$InvGrenade[%x]]] > 0) - { - %data = $NameToInv[$InvGrenade[%x]]; - break; - } - } - %client.getControlObject().throw(%data); - } - else if(%data $= "Ammo") - { - %weapon = %client.getControlObject().getMountedImage($WeaponSlot); - if(%weapon !$= "") - { - if(%weapon.ammo !$= "") - %client.getControlObject().throw(%weapon.ammo); - else - return; - } - } - else - %client.getControlObject().throw(%data); -} - -function serverCmdThrowWeapon(%client,%data) -{ - // Item names from the client must converted - // into DataBlocks - // %data = ItemDataBlock[%item]; - - //Don't let Draakans drop flame breath - if (%client.getControlObject().getMountedImage(0).getName() $= "FlamerImage" && %client.race $= "Draakan") - return; - - %client.getControlObject().throwWeapon(); -} - -function serverCmdThrowPack(%client,%data) -{ - %client.getControlObject().throwPack(); -} - -function serverCmdTogglePack(%client,%data) -{ - // this function is apparently never called - %client.getControlObject().togglePack(); -} - -function serverCmdThrowFlag(%client) -{ - //Game.playerDroppedFlag(%client.player); - Game.dropFlag(%client.player); -} - -function serverCmdSelectWeaponSlot( %client, %data ) -{ - %client.getControlObject().selectWeaponSlot( %data ); -} - -function serverCmdCycleWeapon( %client, %data ) -{ - %client.getControlObject().cycleWeapon( %data ); -} - -function serverCmdStartThrowCount(%client, %data) -{ - %client.player.throwStart = getSimTime(); -} - -$maxThrowStr = 2.2; // z0dd - ZOD, 8/6/02. New throw str features - -function serverCmdEndThrowCount(%client, %data) -{ - if(%client.player.throwStart == 0) - return; - - // --------------------------------------------------------------- - // z0dd - ZOD, 8/6/02. New throw str features - %throwStrength = (getSimTime() - %client.player.throwStart) / 150; - if(%throwStrength > $maxThrowStr) - %throwStrength = $maxThrowStr; - else if(%throwStrength < 0.5) - %throwStrength = 0.5; - // --------------------------------------------------------------- - - %throwScale = %throwStrength / 2; - %client.player.throwStrength = %throwScale; - - %client.player.throwStart = 0; -} - -// -------------------------------------------------------------------- -// z0dd - ZOD, 9/27/02. No buildup power. Rewrote function -function serverCmdthrowMaxEnd(%client, %data) -{ - %client.player.throwStrength = $maxThrowStr / 2; -} -// -------------------------------------------------------------------- - -function ShapeBase::throwWeapon(%this) -{ - if(Game.shapeThrowWeapon(%this)) { - %image = %this.getMountedImage($WeaponSlot); - %this.throw(%image.item); - %this.client.setWeaponsHudItem(%image.item, 0, 0); - } -} - -function ShapeBase::throwPack(%this) -{ - %image = %this.getMountedImage($BackpackSlot); - %this.throw(%image.item); - %this.client.setBackpackHudItem(%image.item, 0); -} - -function ShapeBase::throw(%this,%data) -{ - if(!isObject(%data)) - return false; - - if (%this.inv[%data.getName()] > 0) { - - // save off the ammo count on this item - if( %this.getInventory( %data ) < $AmmoIncrement[%data.getName()] ) - %data.ammoStore = %this.getInventory( %data ); - else - %data.ammoStore = $AmmoIncrement[%data.getName()]; - - // Throw item first... - %this.throwItem(%data); - if($AmmoIncrement[%data.getName()] !$= "") - %this.decInventory(%data,$AmmoIncrement[%data.getName()]); - else - %this.decInventory(%data,1); - return true; - } - return false; -} - -function ShapeBase::use(%this, %data) -{ - //if(%data.class $= "Weapon") { - // error("ShapeBase::use " @ %data); - //} - if(%data $= Grenade) - { - // figure out which grenade type you're using - for(%x = 0; $InvGrenade[%x] !$= ""; %x++) { - if(%this.inv[$NameToInv[$InvGrenade[%x]]] > 0) - { - %data = $NameToInv[$InvGrenade[%x]]; - break; - } - } - } - else if(%data $= "Backpack") { - %pack = %this.getMountedImage($BackpackSlot); - // if you don't have a pack but have placed a satchel charge, detonate it - if(!%pack && (%this.thrownChargeId > 0) && %this.thrownChargeId.armed ) - { - %this.playAudio( 0, SatchelChargeExplosionSound ); - schedule( 600, %this, "detonateSatchelCharge", %this ); // z0dd - ZOD, 8/24/02. Time after pressing fire that satchel blows. Was 800 - return true; - } - return false; - } - else if(%data $= Beacon) - { - %data.onUse(%this); - if (%this.inv[%data.getName()] > 0) - return true; - } - - // default case - if (%this.inv[%data.getName()] > 0) { - %data.onUse(%this); - return true; - } - return false; -} - -function ShapeBase::pickup(%this,%obj,%amount) -{ - %data = %obj.getDatablock(); - %delta = %this.incInventory(%data,%amount); - - if (%delta) - %data.onPickup(%obj,%this,%delta); - return %delta; -} - -function ShapeBase::hasInventory(%this, %data) -{ - // changed because it was preventing weapons cycling correctly (MES) - return (%this.inv[%data] > 0); -} - -function ShapeBase::maxInventory(%this,%data) -{ - if($TestCheats) - return 999; - else - return %this.getDatablock().max[%data.getName()]; -} - -function ShapeBase::incInventory(%this,%data,%amount) -{ - %max = %this.maxInventory(%data); - %cv = %this.inv[%data.getName()]; - if (%cv < %max) { - if (%cv + %amount > %max) - %amount = %max - %cv; - %this.setInventory(%data,%cv + %amount); - %data.incCatagory(%this); // Inc the players weapon count - return %amount; - } - return 0; -} - -function ShapeBase::decInventory(%this,%data,%amount) -{ - %name = %data.getName(); - %cv = %this.inv[%name]; - if (%cv > 0) { - if (%cv < %amount) - %amount = %cv; - %this.setInventory(%data,%cv - %amount, true); - %data.decCatagory(%this); // Dec the players weapon count - return %amount; - } - return 0; -} - -function SimObject::decCatagory(%this) -{ - //function was added to reduce console err msg spam -} - -function SimObject::incCatagory(%this) -{ - //function was added to reduce console err msg spam -} - -function ShapeBase::setInventory(%this,%data,%value,%force) -{ - if (!isObject(%data)) - return; - - %name = %data.getName(); - if (%value < 0) - %value = 0; - else - { - if (!%force) - { - // Impose inventory limits - %max = %this.maxInventory(%data); - if (%value > %max) - %value = %max; - } - } - if (%this.inv[%name] != %value) - { - %this.inv[%name] = %value; - %data.onInventory(%this,%value); - - if ( %data.className $= "Weapon" ) - { - if ( %this.weaponSlotCount $= "" ) - %this.weaponSlotCount = 0; - - %cur = -1; - for ( %slot = 0; %slot < %this.weaponSlotCount; %slot++ ) - { - if ( %this.weaponSlot[%slot] $= %name ) - { - %cur = %slot; - break; - } - } - - if ( %cur == -1 ) - { - // Put this weapon in the next weapon slot: - if ( %this.weaponSlot[%this.weaponSlotCount - 1] $= "TargetingLaser" ) - { - %this.weaponSlot[%this.weaponSlotCount - 1] = %name; - %this.weaponSlot[%this.weaponSlotCount] = "TargetingLaser"; - } - else - %this.weaponSlot[%this.weaponSlotCount] = %name; - %this.weaponSlotCount++; - } - else - { - // Remove the weapon from the weapon slot: - for ( %i = %cur; %i < %this.weaponSlotCount - 1; %i++ ) - %this.weaponSlot[%i] = %this.weaponSlot[%i + 1]; - %this.weaponSlot[%i] = ""; - %this.weaponSlotCount--; - } - } - - %this.getDataBlock().onInventory(%data,%value); - } - return %value; -} - -function ShapeBase::getInventory(%this,%data) -{ - if ( isObject( %data ) ) - return( %this.inv[%data.getName()] ); - else - return( 0 ); -} - -// z0dd - ZOD, 9/13/02. Streamlined. -function ShapeBase::hasAmmo( %this, %weapon ) -{ - if(%weapon $= LaserRifle) - return( %this.getInventory( EnergyPack ) ); - - if (%weapon.image.ammo $= "") - { - if (%weapon $= TargetingLaser) - { - return( false ); - } - else - { - return( true ); - } - } - else - { - return( %this.getInventory( %weapon.image.ammo ) > 0 ); - } -} - -function SimObject::onInventory(%this, %obj) -{ - //function was added to reduce console error msg spam -} - -function ShapeBase::throwItem(%this,%data) -{ - %item = new Item() { - dataBlock = %data; - rotation = "0 0 1 " @ (getRandom() * 360); - }; - - %item.ammoStore = %data.ammoStore; - MissionCleanup.add(%item); - %this.throwObject(%item); -} - -function ShapeBase::throwObject(%this,%obj) -{ - //------------------------------------------------------------------ - // z0dd - ZOD, 4/15/02. Allow respawn switching during tourney wait. - if(!$MatchStarted) - return; - //------------------------------------------------------------------ - - // z0dd - ZOD, 5/26/02. Remove anti-hover so flag can be thrown properly - if(%obj.getDataBlock().getName() $= "Flag") - { - %obj.static = false; - // z0dd - ZOD - SquirrelOfDeath, 10/02/02. Hack for flag collision bug. - if(Game.Class $= CTFGame || Game.Class $= PracticeCTFGame) - %obj.searchSchedule = Game.schedule(10, "startFlagCollisionSearch", %obj); - } - //------------------------------------------------------------------ - - %srcCorpse = (%this.getState() $= "Dead"); // z0dd - ZOD, 4/14/02. Flag tossed from corpse - //if the object is being thrown by a corpse, use a random vector - if (%srcCorpse && %obj.getDataBlock().getName() !$= "Flag") // z0dd - ZOD, 4/14/02. Except for flags.. - { - %vec = (-1.0 + getRandom() * 2.0) SPC (-1.0 + getRandom() * 2.0) SPC getRandom(); - %vec = vectorScale(%vec, 10); - } - else // else Initial vel based on the dir the player is looking - { - %eye = %this.getEyeVector(); - %vec = vectorScale(%eye, 20); - } - - // Add a vertical component to give the item a better arc - %dot = vectorDot("0 0 1",%eye); - if (%dot < 0) - %dot = -%dot; - %vec = vectorAdd(%vec,vectorScale("0 0 12",1 - %dot)); // z0dd - ZOD, 9/10/02. 10 was 8 - - // Add player's velocity - %vec = vectorAdd(%vec,%this.getVelocity()); - %pos = getBoxCenter(%this.getWorldBox()); - - //since flags have a huge mass (so when you shoot them, they don't bounce too far) - //we need to up the %vec so that you can still throw them... - if (%obj.getDataBlock().getName() $= "Flag") - { - %vec = vectorScale(%vec, (%srcCorpse ? 40 : 75)); // z0dd - ZOD, 4/14/02. Throw flag force. Value was 40 - // ------------------------------------------------------------ - // z0dd - ZOD, 9/27/02. Delay on grabbing flag after tossing it - %this.flagTossWait = true; - %this.schedule(1000, resetFlagTossWait); - // ------------------------------------------------------------ - } - - // - %obj.setTransform(%pos); - %obj.applyImpulse(%pos,%vec); - %obj.setCollisionTimeout(%this); - %data = %obj.getDatablock(); - - %data.onThrow(%obj,%this); - - //call the AI hook - AIThrowObject(%obj); -} - -function ShapeBase::clearInventory(%this) -{ - %this.setInventory(RepairKit,0); - - %this.setInventory(Mine,0); - //%this.setInventory(MineAir,0); - //%this.setInventory(MineLand,0); - //%this.setInventory(MineSticky,0); - - %this.setInventory(Grenade,0); - %this.setInventory(FlashGrenade,0); - %this.setInventory(ConcussionGrenade,0); - %this.setInventory(FlareGrenade,0); - %this.setInventory(CameraGrenade, 0); - - %this.setInventory(Blaster,0); - %this.setInventory(Plasma,0); - %this.setInventory(Disc,0); - %this.setInventory(Chaingun, 0); - %this.setInventory(Mortar, 0); - %this.setInventory(GrenadeLauncher, 0); - %this.setInventory(MissileLauncher, 0); - %this.setInventory(SniperRifle, 0); - %this.setInventory(TargetingLaser, 0); - %this.setInventory(ELFGun, 0); - %this.setInventory(ShockLance, 0); - %this.setInventory(Flamer, 0); //Not sure if this should be here, but what the hell. - - %this.setInventory(PlasmaAmmo,0); - %this.setInventory(ChaingunAmmo, 0); - %this.setInventory(DiscAmmo, 0); - %this.setInventory(GrenadeLauncherAmmo, 0); - %this.setInventory(MissileLauncherAmmo, 0); - %this.setInventory(MortarAmmo, 0); - %this.setInventory(Beacon, 0); - - // take away any pack the player has - %curPack = %this.getMountedImage($BackpackSlot); - if(%curPack > 0) - %this.setInventory(%curPack.item, 0); -} - -//---------------------------------------------------------------------------- -function ShapeBase::cycleWeapon( %this, %data ) -{ - if ( %this.weaponSlotCount == 0 ) - return; - - %slot = -1; - if ( %this.getMountedImage($WeaponSlot) != 0 ) - { - %curWeapon = %this.getMountedImage($WeaponSlot).item.getName(); - for ( %i = 0; %i < %this.weaponSlotCount; %i++ ) - { - //error("curWeaponName == " @ %curWeaponName); - if ( %curWeapon $= %this.weaponSlot[%i] ) - { - %slot = %i; - break; - } - } - } - - if ( %data $= "prev" ) - { - // Previous weapon... - if ( %slot == 0 || %slot == -1 ) - { - %i = %this.weaponSlotCount - 1; - %slot = 0; - } - else - %i = %slot - 1; - } - else - { - // Next weapon... - if ( %slot == ( %this.weaponSlotCount - 1 ) || %slot == -1 ) - { - %i = 0; - %slot = ( %this.weaponSlotCount - 1 ); - } - else - %i = %slot + 1; - } - - %newSlot = -1; - while ( %i != %slot ) - { - if ( %this.weaponSlot[%i] !$= "" - && %this.hasInventory( %this.weaponSlot[%i] ) - && %this.hasAmmo( %this.weaponSlot[%i] ) ) - { - // player has this weapon and it has ammo or doesn't need ammo - %newSlot = %i; - break; - } - - if ( %data $= "prev" ) - { - if ( %i == 0 ) - %i = %this.weaponSlotCount - 1; - else - %i--; - } - else - { - if ( %i == ( %this.weaponSlotCount - 1 ) ) - %i = 0; - else - %i++; - } - } - - if ( %newSlot != -1 ) - %this.use( %this.weaponSlot[%newSlot] ); -} - -//---------------------------------------------------------------------------- -function ShapeBase::selectWeaponSlot( %this, %data ) -{ - if ( %data < 0 || %data > %this.weaponSlotCount - || %this.weaponSlot[%data] $= "" || %this.weaponSlot[%data] $= "TargetingLaser" ) - return; - - %this.use( %this.weaponSlot[%data] ); -} - -//---------------------------------------------------------------------------- - -function serverCmdGiveAll(%client) -{ - if($TestCheats) - { - %player = %client.player; - %player.setInventory(RepairKit,999); - %player.setInventory(Mine,999); - //%player.setInventory(MineAir,999); - //%player.setInventory(MineLand,999); - //%player.setInventory(MineSticky,999); - %player.setInventory(Grenade,999); - %player.setInventory(FlashGrenade,999); - %player.setInventory(FlareGrenade,999); - %player.setInventory(ConcussionGrenade,999); - %player.setInventory(CameraGrenade, 999); - %player.setInventory(Blaster,1); - %player.setInventory(Plasma,1); - %player.setInventory(Chaingun, 1); - %player.setInventory(Disc,1); - %player.setInventory(GrenadeLauncher, 1); - %player.setInventory(SniperRifle, 1); - %player.setInventory(ELFGun, 1); - %player.setInventory(Mortar, 1); - %player.setInventory(MissileLauncher, 1); - %player.setInventory(ShockLance, 1); - %player.setInventory(TargetingLaser, 1); - %player.setInventory(MissileLauncherAmmo, 999); - %player.setInventory(GrenadeLauncherAmmo, 999); - %player.setInventory(MortarAmmo, 999); - %player.setInventory(PlasmaAmmo,999); - %player.setInventory(ChaingunAmmo, 999); - %player.setInventory(DiscAmmo, 999); - %player.setInventory(Beacon, 999); - } -} +//---------------------------------------------------------------------------- + +// Item Datablocks +// image = Name of mounted image datablock +// onUse(%this,%object) + +// Item Image Datablocks +// item = Name of item inventory datablock + +// ShapeBase Datablocks +// max[Item] = Maximum amount that can be caried + +// ShapeBase Objects +// inv[Item] = Count of item in inventory +//---------------------------------------------------------------------------- + +$TestCheats = 0; + +function serverCmdUse(%client,%data) +{ + // Item names from the client must converted + // into DataBlocks + // %data = ItemDataBlock[%item]; + + %client.getControlObject().use(%data); +} + +function serverCmdThrow(%client,%data) +{ + // Item names from the client must converted + // into DataBlocks + // %data = ItemDataBlock[%item]; + + //----------------------------------------------------------------------- + // z0dd - ZOD, 4/18/02. Let one keybind handle all grenade types. + if(%data $= Grenade) + { + // figure out which grenade type you're using + for(%x = 0; $InvGrenade[%x] !$= ""; %x++) + { + if(%client.getControlObject().inv[$NameToInv[$InvGrenade[%x]]] > 0) + { + %data = $NameToInv[$InvGrenade[%x]]; + break; + } + } + %client.getControlObject().throw(%data); + } + else if(%data $= "Ammo") + { + %weapon = %client.getControlObject().getMountedImage($WeaponSlot); + if(%weapon !$= "") + { + if(%weapon.ammo !$= "") + %client.getControlObject().throw(%weapon.ammo); + else + return; + } + } + else + %client.getControlObject().throw(%data); +} + +function serverCmdThrowWeapon(%client,%data) +{ + // Item names from the client must converted + // into DataBlocks + // %data = ItemDataBlock[%item]; + + //Don't let Draakans drop flame breath + if (!isObject(%client) || (%client.getControlObject().getMountedImage(0).getName() $= "FlamerImage" && %client.race $= "Draakan")) + return; + + %client.getControlObject().throwWeapon(); +} + +function serverCmdThrowPack(%client,%data) +{ + %client.getControlObject().throwPack(); +} + +function serverCmdTogglePack(%client,%data) +{ + // this function is apparently never called + %client.getControlObject().togglePack(); +} + +function serverCmdThrowFlag(%client) +{ + //Game.playerDroppedFlag(%client.player); + Game.dropFlag(%client.player); +} + +function serverCmdSelectWeaponSlot( %client, %data ) +{ + %client.getControlObject().selectWeaponSlot( %data ); +} + +function serverCmdCycleWeapon( %client, %data ) +{ + %client.getControlObject().cycleWeapon( %data ); +} + +function serverCmdStartThrowCount(%client, %data) +{ + %client.player.throwStart = getSimTime(); +} + +$maxThrowStr = 2.2; // z0dd - ZOD, 8/6/02. New throw str features + +function serverCmdEndThrowCount(%client, %data) +{ + if(%client.player.throwStart == 0) + return; + + // --------------------------------------------------------------- + // z0dd - ZOD, 8/6/02. New throw str features + %throwStrength = (getSimTime() - %client.player.throwStart) / 150; + if(%throwStrength > $maxThrowStr) + %throwStrength = $maxThrowStr; + else if(%throwStrength < 0.5) + %throwStrength = 0.5; + // --------------------------------------------------------------- + + %throwScale = %throwStrength / 2; + %client.player.throwStrength = %throwScale; + + %client.player.throwStart = 0; +} + +// -------------------------------------------------------------------- +// z0dd - ZOD, 9/27/02. No buildup power. Rewrote function +function serverCmdthrowMaxEnd(%client, %data) +{ + %client.player.throwStrength = $maxThrowStr / 2; +} +// -------------------------------------------------------------------- + +function ShapeBase::throwWeapon(%this) +{ + if(Game.shapeThrowWeapon(%this)) { + %image = %this.getMountedImage($WeaponSlot); + %this.throw(%image.item); + %this.client.setWeaponsHudItem(%image.item, 0, 0); + } +} + +function ShapeBase::throwPack(%this) +{ + %image = %this.getMountedImage($BackpackSlot); + %this.throw(%image.item); + %this.client.setBackpackHudItem(%image.item, 0); +} + +function ShapeBase::throw(%this,%data) +{ + if(!isObject(%data)) + return false; + + if (%this.inv[%data.getName()] > 0) { + + // save off the ammo count on this item + if( %this.getInventory( %data ) < $AmmoIncrement[%data.getName()] ) + %data.ammoStore = %this.getInventory( %data ); + else + %data.ammoStore = $AmmoIncrement[%data.getName()]; + + // Throw item first... + %this.throwItem(%data); + if($AmmoIncrement[%data.getName()] !$= "") + %this.decInventory(%data,$AmmoIncrement[%data.getName()]); + else + %this.decInventory(%data,1); + return true; + } + return false; +} + +function ShapeBase::use(%this, %data) +{ + //if(%data.class $= "Weapon") { + // error("ShapeBase::use " @ %data); + //} + if(%data $= Grenade) + { + // figure out which grenade type you're using + for(%x = 0; $InvGrenade[%x] !$= ""; %x++) { + if(%this.inv[$NameToInv[$InvGrenade[%x]]] > 0) + { + %data = $NameToInv[$InvGrenade[%x]]; + break; + } + } + } + else if(%data $= "Backpack") { + %pack = %this.getMountedImage($BackpackSlot); + // if you don't have a pack but have placed a satchel charge, detonate it + if(!%pack && (%this.thrownChargeId > 0) && %this.thrownChargeId.armed ) + { + %this.playAudio( 0, SatchelChargeExplosionSound ); + schedule( 600, %this, "detonateSatchelCharge", %this ); // z0dd - ZOD, 8/24/02. Time after pressing fire that satchel blows. Was 800 + return true; + } + return false; + } + else if(%data $= Beacon) + { + %data.onUse(%this); + if (%this.inv[%data.getName()] > 0) + return true; + } + + // default case + if (%this.inv[%data.getName()] > 0) { + %data.onUse(%this); + return true; + } + return false; +} + +function ShapeBase::pickup(%this,%obj,%amount) +{ + %data = %obj.getDatablock(); + %delta = %this.incInventory(%data,%amount); + + if (%delta) + %data.onPickup(%obj,%this,%delta); + return %delta; +} + +function ShapeBase::hasInventory(%this, %data) +{ + // changed because it was preventing weapons cycling correctly (MES) + return (%this.inv[%data] > 0); +} + +function ShapeBase::maxInventory(%this,%data) +{ + if($TestCheats) + return 999; + else + return %this.getDatablock().max[%data.getName()]; +} + +function ShapeBase::incInventory(%this,%data,%amount) +{ + %max = %this.maxInventory(%data); + %cv = %this.inv[%data.getName()]; + if (%cv < %max) { + if (%cv + %amount > %max) + %amount = %max - %cv; + %this.setInventory(%data,%cv + %amount); + %data.incCatagory(%this); // Inc the players weapon count + return %amount; + } + return 0; +} + +function ShapeBase::decInventory(%this,%data,%amount) +{ + %name = %data.getName(); + %cv = %this.inv[%name]; + if (%cv > 0) { + if (%cv < %amount) + %amount = %cv; + %this.setInventory(%data,%cv - %amount, true); + %data.decCatagory(%this); // Dec the players weapon count + return %amount; + } + return 0; +} + +function SimObject::decCatagory(%this) +{ + //function was added to reduce console err msg spam +} + +function SimObject::incCatagory(%this) +{ + //function was added to reduce console err msg spam +} + +function ShapeBase::setInventory(%this,%data,%value,%force) +{ + if (!isObject(%data)) + return; + + %name = %data.getName(); + if (%value < 0) + %value = 0; + else + { + if (!%force) + { + // Impose inventory limits + %max = %this.maxInventory(%data); + if (%value > %max) + %value = %max; + } + } + if (%this.inv[%name] != %value) + { + %this.inv[%name] = %value; + %data.onInventory(%this,%value); + + if ( %data.className $= "Weapon" ) + { + if ( %this.weaponSlotCount $= "" ) + %this.weaponSlotCount = 0; + + %cur = -1; + for ( %slot = 0; %slot < %this.weaponSlotCount; %slot++ ) + { + if ( %this.weaponSlot[%slot] $= %name ) + { + %cur = %slot; + break; + } + } + + if ( %cur == -1 ) + { + // Put this weapon in the next weapon slot: + if ( %this.weaponSlot[%this.weaponSlotCount - 1] $= "TargetingLaser" ) + { + %this.weaponSlot[%this.weaponSlotCount - 1] = %name; + %this.weaponSlot[%this.weaponSlotCount] = "TargetingLaser"; + } + else + %this.weaponSlot[%this.weaponSlotCount] = %name; + %this.weaponSlotCount++; + } + else + { + // Remove the weapon from the weapon slot: + for ( %i = %cur; %i < %this.weaponSlotCount - 1; %i++ ) + %this.weaponSlot[%i] = %this.weaponSlot[%i + 1]; + %this.weaponSlot[%i] = ""; + %this.weaponSlotCount--; + } + } + + %this.getDataBlock().onInventory(%data,%value); + } + return %value; +} + +function ShapeBase::getInventory(%this,%data) +{ + if ( isObject( %data ) ) + return( %this.inv[%data.getName()] ); + else + return( 0 ); +} + +// z0dd - ZOD, 9/13/02. Streamlined. +function ShapeBase::hasAmmo( %this, %weapon ) +{ + if(%weapon $= LaserRifle) + return( %this.getInventory( EnergyPack ) ); + + if (%weapon.image.ammo $= "") + { + if (%weapon $= TargetingLaser) + { + return( false ); + } + else + { + return( true ); + } + } + else + { + return( %this.getInventory( %weapon.image.ammo ) > 0 ); + } +} + +function SimObject::onInventory(%this, %obj) +{ + //function was added to reduce console error msg spam +} + +function ShapeBase::throwItem(%this,%data) +{ + %item = new Item() { + dataBlock = %data; + rotation = "0 0 1 " @ (getRandom() * 360); + }; + + %item.ammoStore = %data.ammoStore; + MissionCleanup.add(%item); + %this.throwObject(%item); +} + +function ShapeBase::throwObject(%this,%obj) +{ + //------------------------------------------------------------------ + // z0dd - ZOD, 4/15/02. Allow respawn switching during tourney wait. + if(!$MatchStarted) + return; + //------------------------------------------------------------------ + + // z0dd - ZOD, 5/26/02. Remove anti-hover so flag can be thrown properly + if(%obj.getDataBlock().getName() $= "Flag") + { + %obj.static = false; + // z0dd - ZOD - SquirrelOfDeath, 10/02/02. Hack for flag collision bug. + if(Game.Class $= CTFGame || Game.Class $= PracticeCTFGame) + %obj.searchSchedule = Game.schedule(10, "startFlagCollisionSearch", %obj); + } + //------------------------------------------------------------------ + + %srcCorpse = (%this.getState() $= "Dead"); // z0dd - ZOD, 4/14/02. Flag tossed from corpse + //if the object is being thrown by a corpse, use a random vector + if (%srcCorpse && %obj.getDataBlock().getName() !$= "Flag") // z0dd - ZOD, 4/14/02. Except for flags.. + { + %vec = (-1.0 + getRandom() * 2.0) SPC (-1.0 + getRandom() * 2.0) SPC getRandom(); + %vec = vectorScale(%vec, 10); + } + else // else Initial vel based on the dir the player is looking + { + %eye = %this.getEyeVector(); + %vec = vectorScale(%eye, 20); + } + + // Add a vertical component to give the item a better arc + %dot = vectorDot("0 0 1",%eye); + if (%dot < 0) + %dot = -%dot; + %vec = vectorAdd(%vec,vectorScale("0 0 12",1 - %dot)); // z0dd - ZOD, 9/10/02. 10 was 8 + + // Add player's velocity + %vec = vectorAdd(%vec,%this.getVelocity()); + %pos = getBoxCenter(%this.getWorldBox()); + + //since flags have a huge mass (so when you shoot them, they don't bounce too far) + //we need to up the %vec so that you can still throw them... + if (%obj.getDataBlock().getName() $= "Flag") + { + %vec = vectorScale(%vec, (%srcCorpse ? 40 : 75)); // z0dd - ZOD, 4/14/02. Throw flag force. Value was 40 + // ------------------------------------------------------------ + // z0dd - ZOD, 9/27/02. Delay on grabbing flag after tossing it + %this.flagTossWait = true; + %this.schedule(1000, resetFlagTossWait); + // ------------------------------------------------------------ + } + + // + %obj.setTransform(%pos); + %obj.applyImpulse(%pos,%vec); + %obj.setCollisionTimeout(%this); + %data = %obj.getDatablock(); + + %data.onThrow(%obj,%this); + + //call the AI hook + AIThrowObject(%obj); +} + +function ShapeBase::clearInventory(%this) +{ + %this.setInventory(RepairKit,0); + + %this.setInventory(Mine,0); + //%this.setInventory(MineAir,0); + //%this.setInventory(MineLand,0); + //%this.setInventory(MineSticky,0); + + %this.setInventory(Grenade,0); + %this.setInventory(FlashGrenade,0); + %this.setInventory(ConcussionGrenade,0); + %this.setInventory(FlareGrenade,0); + %this.setInventory(CameraGrenade, 0); + + %this.setInventory(Blaster,0); + %this.setInventory(Plasma,0); + %this.setInventory(Disc,0); + %this.setInventory(Chaingun, 0); + %this.setInventory(Mortar, 0); + %this.setInventory(GrenadeLauncher, 0); + %this.setInventory(MissileLauncher, 0); + %this.setInventory(SniperRifle, 0); + %this.setInventory(TargetingLaser, 0); + %this.setInventory(ELFGun, 0); + %this.setInventory(ShockLance, 0); + %this.setInventory(Flamer, 0); //Not sure if this should be here, but what the hell. + + %this.setInventory(PlasmaAmmo,0); + %this.setInventory(ChaingunAmmo, 0); + %this.setInventory(DiscAmmo, 0); + %this.setInventory(GrenadeLauncherAmmo, 0); + %this.setInventory(MissileLauncherAmmo, 0); + %this.setInventory(MortarAmmo, 0); + %this.setInventory(Beacon, 0); + + // take away any pack the player has + %curPack = %this.getMountedImage($BackpackSlot); + if(%curPack > 0) + %this.setInventory(%curPack.item, 0); +} + +//---------------------------------------------------------------------------- +function ShapeBase::cycleWeapon( %this, %data ) +{ + if ( %this.weaponSlotCount == 0 ) + return; + + %slot = -1; + if ( %this.getMountedImage($WeaponSlot) != 0 ) + { + %curWeapon = %this.getMountedImage($WeaponSlot).item.getName(); + for ( %i = 0; %i < %this.weaponSlotCount; %i++ ) + { + //error("curWeaponName == " @ %curWeaponName); + if ( %curWeapon $= %this.weaponSlot[%i] ) + { + %slot = %i; + break; + } + } + } + + if ( %data $= "prev" ) + { + // Previous weapon... + if ( %slot == 0 || %slot == -1 ) + { + %i = %this.weaponSlotCount - 1; + %slot = 0; + } + else + %i = %slot - 1; + } + else + { + // Next weapon... + if ( %slot == ( %this.weaponSlotCount - 1 ) || %slot == -1 ) + { + %i = 0; + %slot = ( %this.weaponSlotCount - 1 ); + } + else + %i = %slot + 1; + } + + %newSlot = -1; + while ( %i != %slot ) + { + if ( %this.weaponSlot[%i] !$= "" + && %this.hasInventory( %this.weaponSlot[%i] ) + && %this.hasAmmo( %this.weaponSlot[%i] ) ) + { + // player has this weapon and it has ammo or doesn't need ammo + %newSlot = %i; + break; + } + + if ( %data $= "prev" ) + { + if ( %i == 0 ) + %i = %this.weaponSlotCount - 1; + else + %i--; + } + else + { + if ( %i == ( %this.weaponSlotCount - 1 ) ) + %i = 0; + else + %i++; + } + } + + if ( %newSlot != -1 ) + %this.use( %this.weaponSlot[%newSlot] ); +} + +//---------------------------------------------------------------------------- +function ShapeBase::selectWeaponSlot( %this, %data ) +{ + if ( %data < 0 || %data > %this.weaponSlotCount + || %this.weaponSlot[%data] $= "" || %this.weaponSlot[%data] $= "TargetingLaser" ) + return; + + %this.use( %this.weaponSlot[%data] ); +} + +//---------------------------------------------------------------------------- + +function serverCmdGiveAll(%client) +{ + if($TestCheats) + { + %player = %client.player; + %player.setInventory(RepairKit,999); + %player.setInventory(Mine,999); + //%player.setInventory(MineAir,999); + //%player.setInventory(MineLand,999); + //%player.setInventory(MineSticky,999); + %player.setInventory(Grenade,999); + %player.setInventory(FlashGrenade,999); + %player.setInventory(FlareGrenade,999); + %player.setInventory(ConcussionGrenade,999); + %player.setInventory(CameraGrenade, 999); + %player.setInventory(Blaster,1); + %player.setInventory(Plasma,1); + %player.setInventory(Chaingun, 1); + %player.setInventory(Disc,1); + %player.setInventory(GrenadeLauncher, 1); + %player.setInventory(SniperRifle, 1); + %player.setInventory(ELFGun, 1); + %player.setInventory(Mortar, 1); + %player.setInventory(MissileLauncher, 1); + %player.setInventory(ShockLance, 1); + %player.setInventory(TargetingLaser, 1); + %player.setInventory(MissileLauncherAmmo, 999); + %player.setInventory(GrenadeLauncherAmmo, 999); + %player.setInventory(MortarAmmo, 999); + %player.setInventory(PlasmaAmmo,999); + %player.setInventory(ChaingunAmmo, 999); + %player.setInventory(DiscAmmo, 999); + %player.setInventory(Beacon, 999); + } +} diff --git a/scripts/inventoryHud.cs b/scripts/inventoryHud.cs index ba6d6f9..625b9ae 100644 --- a/scripts/inventoryHud.cs +++ b/scripts/inventoryHud.cs @@ -1,1113 +1,1113 @@ -//------------------------------------------------------------------------------ -function setUpFavPrefs() -{ - if($pref::FavCurrentSelect $= "") - $pref::FavCurrentSelect = 0; - for(%i = 0; %i < 10; %i++) - { - if($pref::FavNames[%i] $= "") - $pref::FavNames[%i] = "Favorite " @ %i + 1; - if($pref::Favorite[%i] $= "") - $pref::Favorite[%i] = "armor\tLight Armor"; - } - if($pref::FavCurrentList $= "") - $pref::FavCurrentList = 0; -} - -$FavCurrent = 0; -setUpFavPrefs(); - -$InvArmor[0] = "Scout"; -$InvArmor[1] = "Assault"; -$InvArmor[2] = "Juggernaut"; - -$NameToInv["Scout"] = "Light"; -$NameToInv["Assault"] = "Medium"; -$NameToInv["Juggernaut"] = "Heavy"; - - -$InvWeapon[0] = "Blaster"; -$InvWeapon[1] = "Plasma Rifle"; -$InvWeapon[2] = "Chaingun"; -$InvWeapon[3] = "Spinfusor"; -$InvWeapon[4] = "Grenade Launcher"; -$InvWeapon[5] = "Laser Rifle"; -$InvWeapon[6] = "ELF Projector"; -$InvWeapon[7] = "Fusion Mortar"; -$InvWeapon[8] = "Missile Launcher"; -$InvWeapon[9] = "Shocklance"; -//$InvWeapon[10] = "Targeting Laser"; - -// ------------------------------------- -// z0dd - ZOD, 9/12/02. TR2 need -$InvWeapon[10] = "TR2 Spinfusor"; -$InvWeapon[11] = "TR2 Grenade Launcher"; -$InvWeapon[12] = "TR2 Chaingun"; -$InvWeapon[13] = "TR2 Shocklance"; -$InvWeapon[14] = "TR2 Mortar"; -// ------------------------------------- - -$NameToInv["Blaster"] = "Blaster"; -$NameToInv["Plasma Rifle"] = "Plasma"; -$NameToInv["Chaingun"] = "Chaingun"; -$NameToInv["Spinfusor"] = "Disc"; -$NameToInv["Grenade Launcher"] = "GrenadeLauncher"; -$NameToInv["Laser Rifle"] = "SniperRifle"; -$NameToInv["ELF Projector"] = "ELFGun"; -$NameToInv["Fusion Mortar"] = "Mortar"; -$NameToInv["Missile Launcher"] = "MissileLauncher"; -$NameToInv["Shocklance"] = "ShockLance"; -//$NameToInv["Targeting Laser"] = "TargetingLaser"; - -// ------------------------------------------------------- -// z0dd - ZOD, 9/12/02. TR2 need -$NameToInv["TR2 Spinfusor"] = "TR2Disc"; -$NameToInv["TR2 Grenade Launcher"] = "TR2GrenadeLauncher"; -$NameToInv["TR2 Chaingun"] = "TR2Chaingun"; -$NameToInv["TR2 Energy Pack"] = "TR2EnergyPack"; -$NameToInv["TR2 Shocklance"] = "TR2Shocklance"; -$NameToInv["TR2 Mortar"] = "TR2Mortar"; -// ------------------------------------------------------- - - -$InvPack[0] = "Energy Pack"; -$InvPack[1] = "Repair Pack"; -$InvPack[2] = "Shield Pack"; -$InvPack[3] = "Cloak Pack"; -$InvPack[4] = "Sensor Jammer Pack"; -$InvPack[5] = "Ammunition Pack"; -$InvPack[6] = "Satchel Charge"; -$InvPack[7] = "Motion Sensor Pack"; -$InvPack[8] = "Pulse Sensor Pack"; -$InvPack[9] = "Inventory Station"; -$InvPack[10] = "Landspike Turret"; -$InvPack[11] = "Spider Clamp Turret"; -$InvPack[12] = "ELF Turret Barrel"; -$InvPack[13] = "Mortar Turret Barrel"; -$InvPack[14] = "Plasma Turret Barrel"; -$InvPack[15] = "AA Turret Barrel"; -$InvPack[16] = "Missile Turret Barrel"; -$InvPack[17] = "TR2 Energy Pack"; // z0dd - ZOD, 9/12/02. TR2 need -$InvPack[18] = "Mining Tool"; - -// non-team mission pack choices (DM, Hunters, Rabbit) - -$NTInvPack[0] = "Energy Pack"; -$NTInvPack[1] = "Repair Pack"; -$NTInvPack[2] = "Shield Pack"; -$NTInvPack[3] = "Cloak Pack"; -$NTInvPack[4] = "Sensor Jammer Pack"; -$NTInvPack[5] = "Ammunition Pack"; -$NTInvPack[6] = "Satchel Charge"; -$NTInvPack[7] = "Motion Sensor Pack"; -$NTInvPack[8] = "Pulse Sensor Pack"; -$NTInvPack[9] = "Inventory Station"; -$NTInvPack[10] = "TR2 Energy Pack"; // z0dd - ZOD, 9/12/02. TR2 need - -$NameToInv["Energy Pack"] = "EnergyPack"; -$NameToInv["Repair Pack"] = "RepairPack"; -$NameToInv["Shield Pack"] = "ShieldPack"; -$NameToInv["Cloak Pack"] = "CloakingPack"; -$NameToInv["Sensor Jammer Pack"] = "SensorJammerPack"; -$NameToInv["Ammunition Pack"] = "AmmoPack"; -$NameToInv["Satchel Charge"] = "SatchelCharge"; -$NameToInv["Motion Sensor Pack"] = "MotionSensorDeployable"; -$NameToInv["Pulse Sensor Pack"] = "PulseSensorDeployable"; -$NameToInv["Inventory Station"] = "InventoryDeployable"; -$NameToInv["Landspike Turret"] = "TurretOutdoorDeployable"; -$NameToInv["Spider Clamp Turret"] = "TurretIndoorDeployable"; -$NameToInv["ELF Turret Barrel"] = "ELFBarrelPack"; -$NameToInv["Mortar Turret Barrel"] = "MortarBarrelPack"; -$NameToInv["Plasma Turret Barrel"] = "PlasmaBarrelPack"; -$NameToInv["AA Turret Barrel"] = "AABarrelPack"; -$NameToInv["Missile Turret Barrel"] = "MissileBarrelPack"; -$NameToInv["Mining Tool"] = "MiningTool"; - - -$InvGrenade[0] = "Grenade"; -$InvGrenade[1] = "Whiteout Grenade"; -$InvGrenade[2] = "Concussion Grenade"; -$InvGrenade[3] = "Flare Grenade"; -$InvGrenade[4] = "Deployable Camera"; -$InvGrenade[5] = "TR2Grenade"; // z0dd - ZOD, 9/12/02. TR2 need - -$NameToInv["Grenade"] = "Grenade"; -$NameToInv["Whiteout Grenade"] = "FlashGrenade"; -$NameToInv["Concussion Grenade"] = "ConcussionGrenade"; -$NameToInv["Flare Grenade"] = "FlareGrenade"; -$NameToInv["Deployable Camera"] = "CameraGrenade"; -$NameToInv["TR2Grenade"] = "TR2Grenade"; // z0dd - ZOD, 9/12/02. TR2 need - - -$InvMine[0] = "Mine"; - -$NameToInv["Mine"] = "Mine"; - -//$InvBanList[DeployInv, "ElfBarrelPack"] = 1; -//$InvBanList[DeployInv, "MortarBarrelPack"] = 1; -//$InvBanList[DeployInv, "PlasmaBarrelPack"] = 1; -//$InvBanList[DeployInv, "AABarrelPack"] = 1; -//$InvBanList[DeployInv, "MissileBarrelPack"] = 1; -$InvBanList[DeployInv, "InventoryDeployable"] = 1; - -//------------------------------------------------------------------------------ -function InventoryScreen::loadHud( %this, %tag ) -{ - $Hud[%tag] = InventoryScreen; - $Hud[%tag].childGui = INV_Root; - $Hud[%tag].parent = INV_Root; -} - -//------------------------------------------------------------------------------ -function InventoryScreen::setupHud( %this, %tag ) -{ - %favListStart = $pref::FavCurrentList * 10; - %this.selId = $pref::FavCurrentSelect - %favListStart + 1; - - // Add the list menu: - $Hud[%tag].staticData[0, 0] = new ShellPopupMenu(INV_ListMenu) - { - profile = "ShellPopupProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "16 313"; - extent = "170 36"; - minExtent = "8 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - helpTag = "0"; - maxPopupHeight = "220"; - text = ""; - }; - - // Add favorite tabs: - for( %i = 0; %i < 10; %i++ ) - { - %yOffset = ( %i * 30 ) + 10; - $Hud[%tag].staticData[0, %i + 1] = new ShellTabButton() { - profile = "ShellTabProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 " @ %yOffset; - extent = "206 38"; - minExtent = "8 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - helpTag = "0"; - command = "InventoryScreen.onTabSelect(" @ %favListStart + %i @ ");"; - text = strupr( $pref::FavNames[%favListStart + %i] ); - }; - $Hud[%tag].staticData[0, %i + 1].setValue( ( %favListStart + %i ) == $pref::FavCurrentSelect ); - - $Hud[%tag].parent.add( $Hud[%tag].staticData[0, %i + 1] ); - } - - %text = "Favorites " @ %favListStart + 1 SPC "-" SPC %favListStart + 10; - $Hud[%tag].staticData[0, 0].onSelect( $pref::FavCurrentList, %text, true ); - - $Hud[%tag].parent.add( $Hud[%tag].staticData[0, 0] ); - - // Add the SAVE button: - $Hud[%tag].staticData[1, 0] = new ShellBitmapButton() - { - profile = "ShellButtonProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "409 295"; - extent = "75 38"; - minExtent = "8 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - helpTag = "0"; - command = "saveFavorite();"; - text = "SAVE"; - }; - - // Add the name edit control: - $Hud[%tag].staticData[1, 1] = new ShellTextEditCtrl() - { - profile = "NewTextEditProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "217 295"; - extent = "196 38"; - minExtent = "8 8"; - visible = "1"; - altCommand = "saveFavorite()"; - setFirstResponder = "1"; - modal = "1"; - helpTag = "0"; - historySize = "0"; - maxLength = "16"; - }; - - $Hud[%tag].staticData[1, 1].setValue( $pref::FavNames[$pref::FavCurrentSelect] ); - - $Hud[%tag].parent.add( $Hud[%tag].staticData[1, 0] ); - $Hud[%tag].parent.add( $Hud[%tag].staticData[1, 1] ); -} - -//------------------------------------------------------------------------------ -function InventoryScreen::addLine( %this, %tag, %lineNum, %type, %count ) -{ - $Hud[%tag].count = %count; - - // Add label: - %yOffset = ( %lineNum * 30 ) + 28; - $Hud[%tag].data[%lineNum, 0] = new GuiTextCtrl() - { - profile = "ShellTextRightProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "228 " @ %yOffset; - extent = "80 22"; - minExtent = "8 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - helpTag = "0"; - text = ""; - }; - - // Add drop menu: - $Hud[%tag].data[%lineNum, 1] = new ShellPopupMenu(INV_Menu) - { - profile = "ShellPopupProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "305 " @ %yOffset - 9; - extent = "180 36"; - minExtent = "8 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - helpTag = "0"; - maxPopupHeight = "200"; - text = ""; - type = %type; - }; - - return 2; -} - -//------------------------------------------------------------------------------ -function InventoryScreen::updateHud( %this, %client, %tag ) -{ - %noSniperRifle = true; - %armor = getArmorDatablock( %client, $NameToInv[%client.favorites[0]] ); - if ( %client.lastArmor !$= %armor ) - { - %client.lastArmor = %armor; - for ( %x = 0; %x < %client.lastNumFavs; %x++ ) - messageClient( %client, 'RemoveLineHud', "", 'inventoryScreen', %x ); - %setLastNum = true; - } - - %cmt = $CurrentMissionType; -//Create - ARMOR - List - %armorList = %client.favorites[0]; - for ( %y = 0; $InvArmor[%y] !$= ""; %y++ ) - if ( $InvArmor[%y] !$= %client.favorites[0] ) - %armorList = %armorList TAB $InvArmor[%y]; - -//Create - WEAPON - List - for ( %y = 0; $InvWeapon[%y] !$= ""; %y++ ) - { - %notFound = true; - for ( %i = 0; %i < getFieldCount( %client.weaponIndex ); %i++ ) - { - %WInv = $NameToInv[$InvWeapon[%y]]; - if ( ( $InvWeapon[%y] $= %client.favorites[getField( %client.weaponIndex,%i )] ) || !%armor.max[%WInv] ) - { - %notFound = false; - break; - } - else if ( "SniperRifle" $= $NameToInv[%client.favorites[getField( %client.weaponIndex,%i )]] ) - { - %noSniperRifle = false; - %packList = "noSelect\tEnergy Pack\tEnergy Pack must be used when \tLaser Rifle is selected!"; - %client.favorites[getField(%client.packIndex,0)] = "Energy Pack"; - } - } - - if ( !($InvBanList[%cmt, %WInv]) ) - { - if ( %notFound && %weaponList $= "" ) - %weaponList = $InvWeapon[%y]; - else if ( %notFound ) - %weaponList = %weaponList TAB $InvWeapon[%y]; - } - } - -//Create - PACK - List - if ( %noSniperRifle ) - { - if ( getFieldCount( %client.packIndex ) ) - %packList = %client.favorites[getField( %client.packIndex, 0 )]; - else - { - %packList = "EMPTY"; - %client.numFavs++; - } - for ( %y = 0; $InvPack[%y] !$= ""; %y++ ) - { - %PInv = $NameToInv[$InvPack[%y]]; - if ( ( $InvPack[%y] !$= %client.favorites[getField( %client.packIndex, 0 )]) && - %armor.max[%PInv] && !($InvBanList[%cmt, %PInv])) - %packList = %packList TAB $Invpack[%y]; - } - } -//Create - GRENADE - List - for ( %y = 0; $InvGrenade[%y] !$= ""; %y++ ) - { - %notFound = true; - for(%i = 0; %i < getFieldCount( %client.grenadeIndex ); %i++) - { - %GInv = $NameToInv[$InvGrenade[%y]]; - if ( ( $InvGrenade[%y] $= %client.favorites[getField( %client.grenadeIndex, %i )] ) || !%armor.max[%GInv] ) - { - %notFound = false; - break; - } - } - if ( !($InvBanList[%cmt, %GInv]) ) - { - if ( %notFound && %grenadeList $= "" ) - %grenadeList = $InvGrenade[%y]; - else if ( %notFound ) - %grenadeList = %grenadeList TAB $InvGrenade[%y]; - } - } - -//Create - MINE - List - for ( %y = 0; $InvMine[%y] !$= "" ; %y++ ) - { - %notFound = true; - // ----------------------------------------------------------------------------------------------------- - // z0dd - ZOD, 4/24/02. This was broken, Fixed. - for(%i = 0; %i < getFieldCount( %client.mineIndex ); %i++) - { - %MInv = $NameToInv[$InvMine[%y]]; - if ( ( $InvMine[%y] $= %client.favorites[getField( %client.mineIndex, %i )] ) || !%armor.max[%MInv] ) - { - %notFound = false; - break; - } - } - // ----------------------------------------------------------------------------------------------------- - if ( !($InvBanList[%cmt, %MInv]) ) - { - if ( %notFound && %mineList $= "" ) - %mineList = $InvMine[%y]; - else if ( %notFound ) - %mineList = %mineList TAB $InvMine[%y]; - } - } - %client.numFavsCount++; - messageClient( %client, 'SetLineHud', "", %tag, 0, "Armor:", %armorList, armor, %client.numFavsCount ); - %lineCount = 1; - - for ( %x = 0; %x < %armor.maxWeapons; %x++ ) - { - %client.numFavsCount++; - if ( %x < getFieldCount( %client.weaponIndex ) ) - { - %list = %client.favorites[getField( %client.weaponIndex,%x )]; - if ( %list $= Invalid ) - { - %client.favorites[%client.numFavs] = "INVALID"; - %client.weaponIndex = %client.weaponIndex TAB %client.numFavs; - } - } - else - { - %list = "EMPTY"; - %client.favorites[%client.numFavs] = "EMPTY"; - %client.weaponIndex = %client.weaponIndex TAB %client.numFavs; - %client.numFavs++; - } - if ( %list $= empty ) - %list = %list TAB %weaponList; - else - %list = %list TAB %weaponList TAB "EMPTY"; - messageClient( %client, 'SetLineHud', "", %tag, %x + %lineCount, "Weapon Slot " @ %x + 1 @ ": ", %list , weapon, %client.numFavsCount ); - } - %lineCount = %lineCount + %armor.maxWeapons; - - %client.numFavsCount++; - if ( getField( %packList, 0 ) !$= empty && %noSniperRifle ) - %packList = %packList TAB "EMPTY"; - %packText = %packList; - %packOverFlow = ""; - if ( strlen( %packList ) > 255 ) - { - %packText = getSubStr( %packList, 0, 255 ); - %packOverFlow = getSubStr( %packList, 255, 512 ); - } - messageClient( %client, 'SetLineHud', "", %tag, %lineCount, "Pack:", %packText, pack, %client.numFavsCount, %packOverFlow ); - %lineCount++; - - for( %x = 0; %x < %armor.maxGrenades; %x++ ) - { - %client.numFavsCount++; - if ( %x < getFieldCount( %client.grenadeIndex ) ) - { - %list = %client.favorites[getField( %client.grenadeIndex, %x )]; - if (%list $= Invalid) - { - %client.favorites[%client.numFavs] = "INVALID"; - %client.grenadeIndex = %client.grenadeIndex TAB %client.numFavs; - } - } - else - { - %list = "EMPTY"; - %client.favorites[%client.numFavs] = "EMPTY"; - %client.grenadeIndex = %client.grenadeIndex TAB %client.numFavs; - %client.numFavs++; - } - - if ( %list $= empty ) - %list = %list TAB %grenadeList; - else - %list = %list TAB %grenadeList TAB "EMPTY"; - - messageClient( %client, 'SetLineHud', "", %tag, %x + %lineCount, "Grenade:", %list, grenade, %client.numFavsCount ); - } - %lineCount = %lineCount + %armor.maxGrenades; - - for ( %x = 0; %x < %armor.maxMines; %x++ ) - { - %client.numFavsCount++; - if ( %x < getFieldCount( %client.mineIndex ) ) - { - %list = %client.favorites[getField( %client.mineIndex, %x )]; - if ( %list $= Invalid ) - { - %client.favorites[%client.numFavs] = "INVALID"; - %client.mineIndex = %client.mineIndex TAB %client.numFavs; - } - } - else - { - %list = "EMPTY"; - %client.favorites[%client.numFavs] = "EMPTY"; - %client.mineIndex = %client.mineIndex TAB %client.numFavs; - %client.numFavs++; - } - - if ( %list !$= Invalid ) - { - if ( %list $= empty ) - %list = %list TAB %mineList; - else if ( %mineList !$= "" ) - %list = %list TAB %mineList TAB "EMPTY"; - else - %list = %list TAB "EMPTY"; - } - - messageClient( %client, 'SetLineHud', "", %tag, %x + %lineCount, "Mine:", %list, mine, %client.numFavsCount ); - } - - if ( %setLastNum ) - %client.lastNumFavs = %client.numFavs; -} - -//------------------------------------------------------------------------------ -function buyFavorites(%client) -{ - // don't forget -- for many functions, anything done here also needs to be done - // below in buyDeployableFavorites !!! - %client.player.clearInventory(); - %client.setWeaponsHudClearAll(); - %cmt = $CurrentMissionType; - - %curArmor = %client.player.getDatablock(); - %curDmgPct = getDamagePercent(%curArmor.maxDamage, %client.player.getDamageLevel()); - - // armor - %client.armor = $NameToInv[%client.favorites[0]]; - %client.player.setArmor( %client.armor ); - %newArmor = %client.player.getDataBlock(); - - %client.player.setDamageLevel(%curDmgPct * %newArmor.maxDamage); - %weaponCount = 0; - - - // weapons - for(%i = 0; %i < getFieldCount( %client.weaponIndex ); %i++) - { - %inv = $NameToInv[%client.favorites[getField( %client.weaponIndex, %i )]]; - - if( %inv !$= "" ) - { - %weaponCount++; - %client.player.setInventory( %inv, 1 ); - } - - // ---------------------------------------------------- - // z0dd - ZOD, 4/24/02. Code optimization. - if ( %inv.image.ammo !$= "" ) - %client.player.setInventory( %inv.image.ammo, 999 ); - // ---------------------------------------------------- - } - %client.player.weaponCount = %weaponCount; - - // pack - %pCh = $NameToInv[%client.favorites[%client.packIndex]]; - if ( %pCh $= "" ) - %client.clearBackpackIcon(); - else - %client.player.setInventory( %pCh, 1 ); - - // if this pack is a deployable that has a team limit, warn the purchaser - // if it's a deployable turret, the limit depends on the number of players (deployables.cs) - if(%pCh $= "TurretIndoorDeployable" || %pCh $= "TurretOutdoorDeployable") - %maxDep = countTurretsAllowed(%pCh); - else - %maxDep = $TeamDeployableMax[%pCh]; - - if(%maxDep !$= "") - { - %depSoFar = $TeamDeployedCount[%client.player.team, %pCh]; - %packName = %client.favorites[%client.packIndex]; - - if(Game.numTeams > 1) - %msTxt = "Your team has "@%depSoFar@" of "@%maxDep SPC %packName@"s deployed."; - else - %msTxt = "You have deployed "@%depSoFar@" of "@%maxDep SPC %packName@"s."; - - messageClient(%client, 'MsgTeamDepObjCount', %msTxt); - } - - // grenades - for ( %i = 0; %i < getFieldCount( %client.grenadeIndex ); %i++ ) - { - if ( !($InvBanList[%cmt, $NameToInv[%client.favorites[getField( %client.grenadeIndex, %i )]]]) ) - %client.player.setInventory( $NameToInv[%client.favorites[getField( %client.grenadeIndex,%i )]], 30 ); - } - - %client.player.lastGrenade = $NameToInv[%client.favorites[getField( %client.grenadeIndex,%i )]]; - - // if player is buying cameras, show how many are already deployed - if(%client.favorites[%client.grenadeIndex] $= "Deployable Camera") - { - %maxDep = $TeamDeployableMax[DeployedCamera]; - %depSoFar = $TeamDeployedCount[%client.player.team, DeployedCamera]; - if(Game.numTeams > 1) - %msTxt = "Your team has "@%depSoFar@" of "@%maxDep@" Deployable Cameras placed."; - else - %msTxt = "You have placed "@%depSoFar@" of "@%maxDep@" Deployable Cameras."; - messageClient(%client, 'MsgTeamDepObjCount', %msTxt); - } - - // mines - // ----------------------------------------------------------------------------------------------------- - // z0dd - ZOD, 4/24/02. Old code did not check to see if mines are banned, fixed. - for ( %i = 0; %i < getFieldCount( %client.mineIndex ); %i++ ) - { - if ( !($InvBanList[%cmt, $NameToInv[%client.favorites[getField( %client.mineIndex, %i )]]]) ) - %client.player.setInventory( $NameToInv[%client.favorites[getField( %client.mineIndex,%i )]], 30 ); - } - // ----------------------------------------------------------------------------------------------------- - // miscellaneous stuff -- Repair Kit, Beacons, Targeting Laser - if ( !($InvBanList[%cmt, RepairKit]) ) - %client.player.setInventory( RepairKit, 1 ); - if ( !($InvBanList[%cmt, Beacon]) ) - %client.player.setInventory( Beacon, 20 ); // z0dd - ZOD, 4/24/02. 400 was a bit much, changed to 20 - if ( !($InvBanList[%cmt, TargetingLaser]) ) - %client.player.setInventory( TargetingLaser, 1 ); - - // ammo pack pass -- hack! hack! - if( %pCh $= "AmmoPack" ) - invAmmoPackPass(%client); -} - -//------------------------------------------------------------------------------ -function buyDeployableFavorites(%client) -{ - %player = %client.player; - %prevPack = %player.getMountedImage($BackpackSlot); - %player.clearInventory(); - %client.setWeaponsHudClearAll(); - %cmt = $CurrentMissionType; - - // players cannot buy armor from deployable inventory stations - %weapCount = 0; - for ( %i = 0; %i < getFieldCount( %client.weaponIndex ); %i++ ) - { - %inv = $NameToInv[%client.favorites[getField( %client.weaponIndex, %i )]]; - if ( !($InvBanList[DeployInv, %inv]) ) - { - %player.setInventory( %inv, 1 ); - // increment weapon count if current armor can hold this weapon - if(%player.getDatablock().max[%inv] > 0) - %weapCount++; - // --------------------------------------------- - // z0dd - ZOD, 4/24/02. Code streamlining. - if ( %inv.image.ammo !$= "" ) - %player.setInventory( %inv.image.ammo, 999 ); - // --------------------------------------------- - if(%weapCount >= %player.getDatablock().maxWeapons) - break; - } - } - %player.weaponCount = %weapCount; - // give player the grenades and mines they chose, beacons, and a repair kit - for ( %i = 0; %i < getFieldCount( %client.grenadeIndex ); %i++) - { - %GInv = $NameToInv[%client.favorites[getField( %client.grenadeIndex, %i )]]; - %client.player.lastGrenade = %GInv; - if ( !($InvBanList[DeployInv, %GInv]) ) - %player.setInventory( %GInv, 30 ); - - } - - // if player is buying cameras, show how many are already deployed - if(%client.favorites[%client.grenadeIndex] $= "Deployable Camera") - { - %maxDep = $TeamDeployableMax[DeployedCamera]; - %depSoFar = $TeamDeployedCount[%client.player.team, DeployedCamera]; - if(Game.numTeams > 1) - %msTxt = "Your team has "@%depSoFar@" of "@%maxDep@" Deployable Cameras placed."; - else - %msTxt = "You have placed "@%depSoFar@" of "@%maxDep@" Deployable Cameras."; - messageClient(%client, 'MsgTeamDepObjCount', %msTxt); - } - - for ( %i = 0; %i < getFieldCount( %client.mineIndex ); %i++ ) - { - %MInv = $NameToInv[%client.favorites[getField( %client.mineIndex, %i )]]; - if ( !($InvBanList[DeployInv, %MInv]) ) - %player.setInventory( %MInv, 30 ); - } - if ( !($InvBanList[DeployInv, Beacon]) && !($InvBanList[%cmt, Beacon]) ) - %player.setInventory( Beacon, 20 ); // z0dd - ZOD, 4/24/02. 400 was a bit much, changed to 20. - if ( !($InvBanList[DeployInv, RepairKit]) && !($InvBanList[%cmt, RepairKit]) ) - %player.setInventory( RepairKit, 1 ); - if ( !($InvBanList[DeployInv, TargetingLaser]) && !($InvBanList[%cmt, TargetingLaser]) ) - %player.setInventory( TargetingLaser, 1 ); - - // players cannot buy deployable station packs from a deployable inventory station - %packChoice = $NameToInv[%client.favorites[%client.packIndex]]; - if ( !($InvBanList[DeployInv, %packChoice]) ) - %player.setInventory( %packChoice, 1 ); - - // if this pack is a deployable that has a team limit, warn the purchaser - // if it's a deployable turret, the limit depends on the number of players (deployables.cs) - if(%packChoice $= "TurretIndoorDeployable" || %packChoice $= "TurretOutdoorDeployable") - %maxDep = countTurretsAllowed(%packChoice); - else - %maxDep = $TeamDeployableMax[%packChoice]; - if((%maxDep !$= "") && (%packChoice !$= "InventoryDeployable")) - { - %depSoFar = $TeamDeployedCount[%client.player.team, %packChoice]; - %packName = %client.favorites[%client.packIndex]; - - if(Game.numTeams > 1) - %msTxt = "Your team has "@%depSoFar@" of "@%maxDep SPC %packName@"s deployed."; - else - %msTxt = "You have deployed "@%depSoFar@" of "@%maxDep SPC %packName@"s."; - - messageClient(%client, 'MsgTeamDepObjCount', %msTxt); - } - - if(%prevPack > 0) - { - // if player had a "forbidden" pack (such as a deployable inventory station) - // BEFORE visiting a deployed inventory station AND still has that pack chosen - // as a favorite, give it back - if((%packChoice $= %prevPack.item) && ($InvBanList[DeployInv, %packChoice])) - %player.setInventory( %prevPack.item, 1 ); - } - - if(%packChoice $= "AmmoPack") - invAmmoPackPass(%client); -} - -//------------------------------------------------------------------------------------- -function getAmmoStationLovin(%client) -{ - // z0dd - ZOD, 4/24/02. This function was quite a mess, needed rewrite - - %cmt = $CurrentMissionType; - - // weapons - for(%i = 0; %i < %client.player.weaponSlotCount; %i++) - { - %weapon = %client.player.weaponSlot[%i]; - if ( %weapon.image.ammo !$= "" ) - %client.player.setInventory( %weapon.image.ammo, 999 ); - } - - // grenades - %client.player.setInventory( Grenade, 0 ); - %client.player.setInventory( ConcussionGrenade, 0 ); - %client.player.setInventory( CameraGrenade, 0 ); - %client.player.setInventory( FlashGrenade, 0 ); - %client.player.setInventory( FlareGrenade, 0 ); - for ( %i = 0; %i < getFieldCount( %client.grenadeIndex ); %i++ ) - { - %client.player.lastGrenade = $NameToInv[%client.favorites[getField( %client.grenadeIndex, %i )]]; - } - %grenType = %client.player.lastGrenade; - if(%grenType $= "") - { - %grenType = Grenade; - } - if ( !($InvBanList[%cmt, %grenType]) ) - %client.player.setInventory( %grenType, 30 ); - - if(%grenType $= "Deployable Camera") - { - %maxDep = $TeamDeployableMax[DeployedCamera]; - %depSoFar = $TeamDeployedCount[%client.player.team, DeployedCamera]; - if(Game.numTeams > 1) - %msTxt = "Your team has "@%depSoFar@" of "@%maxDep@" Deployable Cameras placed."; - else - %msTxt = "You have placed "@%depSoFar@" of "@%maxDep@" Deployable Cameras."; - messageClient(%client, 'MsgTeamDepObjCount', %msTxt); - } - - // Mines - %client.player.setInventory( Mine, 0 ); - for ( %i = 0; %i < getFieldCount( %client.mineIndex ); %i++ ) - { - %client.player.lastMine = $NameToInv[%client.favorites[getField( %client.mineIndex, %i )]]; - } - %mineType = %client.player.lastMine; - if(%mineType $= "") - { - %mineType = Mine; - } - if ( !($InvBanList[%cmt, %mineType]) ) - %client.player.setInventory( %mineType, 30 ); - - // miscellaneous stuff -- Repair Kit, Beacons, Targeting Laser - if ( !($InvBanList[%cmt, RepairKit]) ) - %client.player.setInventory( RepairKit, 1 ); - - if ( !($InvBanList[%cmt, Beacon]) ) - %client.player.setInventory( Beacon, 20 ); - - if ( !($InvBanList[%cmt, TargetingLaser]) ) - %client.player.setInventory( TargetingLaser, 1 ); - - if( %client.player.getMountedImage($BackpackSlot) $= "AmmoPack" ) - invAmmoPackPass(%client); -} - - -function invAmmoPackPass(%client) -{ - // "normal" ammo stuff (everything but mines and grenades) - for ( %idx = 0; %idx < $numAmmoItems; %idx++ ) - { - %ammo = $AmmoItem[%idx]; - %client.player.incInventory(%ammo, AmmoPack.max[%ammo]); - } - //our good friends, the grenade family *SIGH* - // first find out what type of grenade the player has selected - %grenFav = %client.favorites[getField(%client.grenadeIndex, 0)]; - if((%grenFav !$= "EMPTY") && (%grenFav !$= "INVALID")) - %client.player.incInventory($NameToInv[%grenFav], AmmoPack.max[$NameToInv[%grenFav]]); - // now the same check for mines - %mineFav = %client.favorites[getField(%client.mineIndex, 0)]; - if((%mineFav !$= "EMPTY") && (%mineFav !$= "INVALID") && !($InvBanList[%cmt, Mine])) - %client.player.incInventory($NameToInv[%mineFav], AmmoPack.max[$NameToInv[%mineFav]]); -} - -//------------------------------------------------------------------------------ -function loadFavorite( %index, %echo ) -{ - $pref::FavCurrentSelect = %index; - %list = mFloor( %index / 10 ); - - if ( isObject( $Hud['inventoryScreen'] ) ) - { - // Deselect the old tab: - if ( InventoryScreen.selId !$= "" ) - $Hud['inventoryScreen'].staticData[0, InventoryScreen.selId].setValue( false ); - - // Make sure we are looking at the same list: - if ( $pref::FavCurrentList != %list ) - { - %favListStart = %list * 10; - %text = "Favorites " @ %favListStart + 1 SPC "-" SPC %favListStart + 10; - $Hud['inventoryScreen'].staticData[0, 0].onSelect( %list, %text, true ); - } - - // Select the new tab: - %tab = $pref::FavCurrentSelect - ( $pref::FavCurrentList * 10 ) + 1; - InventoryScreen.selId = %tab; - $Hud['inventoryScreen'].staticData[0, %tab].setValue( true ); - - // Update the Edit Name field: - $Hud['inventoryScreen'].staticData[1, 1].setValue( $pref::FavNames[%index] ); - } - - if ( %echo ) - addMessageHudLine( "Inventory set \"" @ $pref::FavNames[%index] @ "\" selected." ); - - commandToServer( 'setClientFav', $pref::Favorite[%index] ); -} - -//------------------------------------------------------------------------------ -function saveFavorite() -{ - if ( $pref::FavCurrentSelect !$= "" ) - { - %favName = $Hud['inventoryScreen'].staticData[1, 1].getValue(); - $pref::FavNames[$pref::FavCurrentSelect] = %favName; - $Hud['inventoryScreen'].staticData[0, $pref::FavCurrentSelect - ($pref::FavCurrentList * 10) + 1].setText( strupr( %favName ) ); - //$Hud[%tag].staticData[1, 1].setValue( %favName ); - %favList = $Hud['inventoryScreen'].data[0, 1].type TAB $Hud['inventoryScreen'].data[0, 1].getValue(); - for ( %i = 1; %i < $Hud['inventoryScreen'].count; %i++ ) - { - %name = $Hud['inventoryScreen'].data[%i, 1].getValue(); - if ( %name $= invalid ) - %name = "EMPTY"; - %favList = %favList TAB $Hud['inventoryScreen'].data[%i, 1].type TAB %name; - } - $pref::Favorite[$pref::FavCurrentSelect] = %favList; - echo("exporting pref::* to ClientPrefs.cs"); - export("$pref::*", "prefs/ClientPrefs.cs", False); - } -// else -// addMessageHudLine("Must First Select A Favorite Button."); -} - -//------------------------------------------------------------------------------ -function addQuickPackFavorite( %pack, %item ) -{ - // this has been such a success it has been changed to handle grenades - // and other equipment as well as packs so everything seems to be called 'pack' - // including the function itself. The default IS pack - - if(%item $= "") - %item = "Pack"; - %packFailMsg = "You cannot use that equipment with your selected loadout."; - if ( !isObject($Hud['inventoryScreen'].staticData[1, 1]) || $Hud['inventoryScreen'].staticData[1, 1].getValue() $= "" ) - { - //if the player hasnt brought up the inv screen we use his current fav - %currentFav = $pref::Favorite[$pref::FavCurrentSelect]; - //echo(%currentFav); - - for ( %i = 0; %i < getFieldCount( %currentFav ); %i++ ) - { - %type = getField( %currentFav, %i ); - %equipment = getField( %currentFav, %i++ ); - - %invalidPack = checkPackValidity(%pack, %equipment, %item ); - if(%invalidPack) - { - addMessageHudLine( %packFailMsg ); - return; - - } - // Success-------------------------------------------------- - if ( %type $= %item ) - %favList = %favList @ %type TAB %pack @ "\t"; - else - %favList = %favList @ %type TAB %equipment @ "\t"; - } - //echo(%favList); - } - else - { - //otherwise we go with whats on the invScreen (even if its asleep) - %armor = $Hud['inventoryScreen'].data[0, 1].getValue(); - - // check pack validity with armor - %invalidPack = checkPackValidity(%pack, %armor, %item ); - if(%invalidPack) - { - addMessageHudLine( %packFailMsg ); - return; - - } - %favList = $Hud['inventoryScreen'].data[0, 1].type TAB %armor; - for ( %i = 1; %i < $Hud['inventoryScreen'].count; %i++ ) - { - //echo( $Hud['inventoryScreen'].Data[%i, 1].type); - %type = $Hud['inventoryScreen'].data[%i, 1].type; - %equipment = $Hud['inventoryScreen'].data[%i, 1].getValue(); - - if(%type $= %item) - %equipment = %pack; - - // Special Cases again------------------------------------------------ - %invalidPack = checkPackValidity(%pack, %equipment, %item ); - if(%invalidPack) - { - addMessageHudLine( %packFailMsg ); - return; - - } - - %favList = %favList TAB %type TAB %equipment; - } - //echo(%favList); - } - commandToServer( 'setClientFav', %favList ); - - //we message the player real nice like - addMessageHudLine( "Inventory updated to " @ %pack @ "." ); -} - -function checkPackValidity(%pack, %equipment, %item) -{ - //echo("validityChecking:" SPC %pack SPC %equipment); - - // this is mostly for ease of mod makers - // this is the base restrictions stuff - // for your mod just overwrite this function and - // change the restrictions and onlyUses - - // you must have #1 to use #2 - //%restrict[#1, #2] = true; - - %restrict["Scout", "Inventory Station"] = true; - %restrict["Scout", "Landspike Turret"] = true; - %restrict["Scout", "Spider Clamp Turret"] = true; - %restrict["Scout", "ELF Turret Barrel"] = true; - %restrict["Scout", "Mortar Turret Barrel"] = true; - %restrict["Scout", "AA Turret Barrel"] = true; - %restrict["Scout", "Plasma Turret Barrel"] = true; - %restrict["Scout", "Missile Turret Barrel"] = true; - %restrict["Assault", "Cloak Pack"] = true; - %restrict["Juggernaut", "Cloak Pack"] = true; - - // you can only use #1 if you have a #2 of type #3 - //%require[#1] = #2 TAB #3; - - %require["Laser Rifle"] = "Pack" TAB "Energy Pack"; - - - if(%restrict[%equipment, %pack] ) - return true; - - else if(%require[%equipment] !$="" ) - { - if(%item $= getField(%require[%equipment], 0) ) - { - if(%pack !$= getField(%require[%equipment], 1) ) - return true; - } - } -} - - -//------------------------------------------------------------------------------ -function setDefaultInventory(%client) -{ - commandToClient(%client,'InitLoadClientFavorites'); -} - -//------------------------------------------------------------------------------ -function checkInventory( %client, %text ) -{ - %armor = getArmorDatablock( %client, $NameToInv[getField( %text, 1 )] ); - %list = getField( %text, 0 ) TAB getField( %text, 1 ); - %cmt = $CurrentMissionType; - for( %i = 3; %i < getFieldCount( %text ); %i = %i + 2 ) - { - %inv = $NameToInv[getField(%text,%i)]; - if ( (( %armor.max[%inv] && !($InvBanList[%cmt, %inv]) ) || - getField( %text, %i ) $= Empty || getField( %text, %i ) $= Invalid) - && (($InvTotalCount[getField( %text, %i - 1 )] - $BanCount[getField( %text, %i - 1 )]) > 0)) - %list = %list TAB getField( %text, %i - 1 ) TAB getField( %text, %i ); - else if( $InvBanList[%cmt, %inv] || %inv $= empty || %inv $= "") - %list = %list TAB getField( %text, %i - 1 ) TAB "INVALID"; - } - return %list; -} - -//------------------------------------------------------------------------------ -function getArmorDatablock(%client, %size) -{ - if ( %client.race $= "Bioderm" ) - %armor = %size @ "Male" @ %client.race @ Armor; - else - %armor = %size @ %client.sex @ %client.race @ Armor; - return %armor; -} - -//------------------------------------------------------------------------------ -function InventoryScreen::onWake(%this) -{ - if ( $HudHandle[inventoryScreen] !$= "" ) - alxStop( $HudHandle[inventoryScreen] ); - alxPlay(HudInventoryActivateSound, 0, 0, 0); - $HudHandle[inventoryScreen] = alxPlay(HudInventoryHumSound, 0, 0, 0); - - if ( isObject( hudMap ) ) - { - hudMap.pop(); - hudMap.delete(); - } - new ActionMap( hudMap ); - hudMap.blockBind( moveMap, toggleScoreScreen ); - hudMap.blockBind( moveMap, toggleCommanderMap ); - hudMap.bindCmd( keyboard, escape, "", "InventoryScreen.onDone();" ); - hudMap.push(); -} - -//------------------------------------------------------------------------------ -function InventoryScreen::onSleep() -{ - hudMap.pop(); - hudMap.delete(); - alxStop($HudHandle[inventoryScreen]); - alxPlay(HudInventoryDeactivateSound, 0, 0, 0); - $HudHandle[inventoryScreen] = ""; -} - -//------------------------------------------------------------------------------ -function InventoryScreen::onDone( %this ) -{ - toggleCursorHuds( 'inventoryScreen' ); -} - -//------------------------------------------------------------------------------ -function InventoryScreen::onTabSelect( %this, %favId ) -{ - loadFavorite( %favId, 0 ); -} - -function createInvBanCount() -{ - $BanCount["Armor"] = 0; - $BanCount["Weapon"] = 0; - $BanCount["Pack"] = 0; - $BanCount["Grenade"] = 0; - $BanCount["Mine"] = 0; - - for(%i = 0; $InvArmor[%i] !$= ""; %i++) - if($InvBanList[$CurrentMissionType, $NameToInv[$InvArmor[%i]]]) - $BanCount["Armor"]++; - $InvTotalCount["Armor"] = %i; - - for(%i = 0; $InvWeapon[%i] !$= ""; %i++) - if($InvBanList[$CurrentMissionType, $NameToInv[$InvWeapon[%i]]]) - $BanCount["Weapon"]++; - $InvTotalCount["Weapon"] = %i; - - for(%i = 0; $InvPack[%i] !$= ""; %i++) - if($InvBanList[$CurrentMissionType, $NameToInv[$InvPack[%i]]]) - $BanCount["Pack"]++; - $InvTotalCount["Pack"] = %i; - - for(%i = 0; $InvGrenade[%i] !$= ""; %i++) - if($InvBanList[$CurrentMissionType, $NameToInv[$InvGrenade[%i]]]) - $BanCount["Grenade"]++; - $InvTotalCount["Grenade"] = %i; - - for(%i = 0; $InvMine[%i] !$= ""; %i++) - if($InvBanList[$CurrentMissionType, $NameToInv[$InvMine[%i]]]) - $BanCount["Mine"]++; - $InvTotalCount["Mine"] = %i; -} +//------------------------------------------------------------------------------ +function setUpFavPrefs() +{ + if($pref::FavCurrentSelect $= "") + $pref::FavCurrentSelect = 0; + for(%i = 0; %i < 10; %i++) + { + if($pref::FavNames[%i] $= "") + $pref::FavNames[%i] = "Favorite " @ %i + 1; + if($pref::Favorite[%i] $= "") + $pref::Favorite[%i] = "armor\tLight Armor"; + } + if($pref::FavCurrentList $= "") + $pref::FavCurrentList = 0; +} + +$FavCurrent = 0; +setUpFavPrefs(); + +$InvArmor[0] = "Scout"; +$InvArmor[1] = "Assault"; +$InvArmor[2] = "Juggernaut"; + +$NameToInv["Scout"] = "Light"; +$NameToInv["Assault"] = "Medium"; +$NameToInv["Juggernaut"] = "Heavy"; + + +$InvWeapon[0] = "Blaster"; +$InvWeapon[1] = "Plasma Rifle"; +$InvWeapon[2] = "Chaingun"; +$InvWeapon[3] = "Spinfusor"; +$InvWeapon[4] = "Grenade Launcher"; +$InvWeapon[5] = "Laser Rifle"; +$InvWeapon[6] = "ELF Projector"; +$InvWeapon[7] = "Fusion Mortar"; +$InvWeapon[8] = "Missile Launcher"; +$InvWeapon[9] = "Shocklance"; +//$InvWeapon[10] = "Targeting Laser"; + +// ------------------------------------- +// z0dd - ZOD, 9/12/02. TR2 need +$InvWeapon[10] = "TR2 Spinfusor"; +$InvWeapon[11] = "TR2 Grenade Launcher"; +$InvWeapon[12] = "TR2 Chaingun"; +$InvWeapon[13] = "TR2 Shocklance"; +$InvWeapon[14] = "TR2 Mortar"; +// ------------------------------------- + +$NameToInv["Blaster"] = "Blaster"; +$NameToInv["Plasma Rifle"] = "Plasma"; +$NameToInv["Chaingun"] = "Chaingun"; +$NameToInv["Spinfusor"] = "Disc"; +$NameToInv["Grenade Launcher"] = "GrenadeLauncher"; +$NameToInv["Laser Rifle"] = "SniperRifle"; +$NameToInv["ELF Projector"] = "ELFGun"; +$NameToInv["Fusion Mortar"] = "Mortar"; +$NameToInv["Missile Launcher"] = "MissileLauncher"; +$NameToInv["Shocklance"] = "ShockLance"; +//$NameToInv["Targeting Laser"] = "TargetingLaser"; + +// ------------------------------------------------------- +// z0dd - ZOD, 9/12/02. TR2 need +$NameToInv["TR2 Spinfusor"] = "TR2Disc"; +$NameToInv["TR2 Grenade Launcher"] = "TR2GrenadeLauncher"; +$NameToInv["TR2 Chaingun"] = "TR2Chaingun"; +$NameToInv["TR2 Energy Pack"] = "TR2EnergyPack"; +$NameToInv["TR2 Shocklance"] = "TR2Shocklance"; +$NameToInv["TR2 Mortar"] = "TR2Mortar"; +// ------------------------------------------------------- + + +$InvPack[0] = "Energy Pack"; +$InvPack[1] = "Repair Pack"; +$InvPack[2] = "Shield Pack"; +$InvPack[3] = "Cloak Pack"; +$InvPack[4] = "Sensor Jammer Pack"; +$InvPack[5] = "Ammunition Pack"; +$InvPack[6] = "Satchel Charge"; +$InvPack[7] = "Motion Sensor Pack"; +$InvPack[8] = "Pulse Sensor Pack"; +$InvPack[9] = "Inventory Station"; +$InvPack[10] = "Landspike Turret"; +$InvPack[11] = "Spider Clamp Turret"; +$InvPack[12] = "ELF Turret Barrel"; +$InvPack[13] = "Mortar Turret Barrel"; +$InvPack[14] = "Plasma Turret Barrel"; +$InvPack[15] = "AA Turret Barrel"; +$InvPack[16] = "Missile Turret Barrel"; +$InvPack[17] = "TR2 Energy Pack"; // z0dd - ZOD, 9/12/02. TR2 need +$InvPack[18] = "Mining Tool"; + +// non-team mission pack choices (DM, Hunters, Rabbit) + +$NTInvPack[0] = "Energy Pack"; +$NTInvPack[1] = "Repair Pack"; +$NTInvPack[2] = "Shield Pack"; +$NTInvPack[3] = "Cloak Pack"; +$NTInvPack[4] = "Sensor Jammer Pack"; +$NTInvPack[5] = "Ammunition Pack"; +$NTInvPack[6] = "Satchel Charge"; +$NTInvPack[7] = "Motion Sensor Pack"; +$NTInvPack[8] = "Pulse Sensor Pack"; +$NTInvPack[9] = "Inventory Station"; +$NTInvPack[10] = "TR2 Energy Pack"; // z0dd - ZOD, 9/12/02. TR2 need + +$NameToInv["Energy Pack"] = "EnergyPack"; +$NameToInv["Repair Pack"] = "RepairPack"; +$NameToInv["Shield Pack"] = "ShieldPack"; +$NameToInv["Cloak Pack"] = "CloakingPack"; +$NameToInv["Sensor Jammer Pack"] = "SensorJammerPack"; +$NameToInv["Ammunition Pack"] = "AmmoPack"; +$NameToInv["Satchel Charge"] = "SatchelCharge"; +$NameToInv["Motion Sensor Pack"] = "MotionSensorDeployable"; +$NameToInv["Pulse Sensor Pack"] = "PulseSensorDeployable"; +$NameToInv["Inventory Station"] = "InventoryDeployable"; +$NameToInv["Landspike Turret"] = "TurretOutdoorDeployable"; +$NameToInv["Spider Clamp Turret"] = "TurretIndoorDeployable"; +$NameToInv["ELF Turret Barrel"] = "ELFBarrelPack"; +$NameToInv["Mortar Turret Barrel"] = "MortarBarrelPack"; +$NameToInv["Plasma Turret Barrel"] = "PlasmaBarrelPack"; +$NameToInv["AA Turret Barrel"] = "AABarrelPack"; +$NameToInv["Missile Turret Barrel"] = "MissileBarrelPack"; +$NameToInv["Mining Tool"] = "MiningTool"; + + +$InvGrenade[0] = "Grenade"; +$InvGrenade[1] = "Whiteout Grenade"; +$InvGrenade[2] = "Concussion Grenade"; +$InvGrenade[3] = "Flare Grenade"; +$InvGrenade[4] = "Deployable Camera"; +$InvGrenade[5] = "TR2Grenade"; // z0dd - ZOD, 9/12/02. TR2 need + +$NameToInv["Grenade"] = "Grenade"; +$NameToInv["Whiteout Grenade"] = "FlashGrenade"; +$NameToInv["Concussion Grenade"] = "ConcussionGrenade"; +$NameToInv["Flare Grenade"] = "FlareGrenade"; +$NameToInv["Deployable Camera"] = "CameraGrenade"; +$NameToInv["TR2Grenade"] = "TR2Grenade"; // z0dd - ZOD, 9/12/02. TR2 need + + +$InvMine[0] = "Mine"; + +$NameToInv["Mine"] = "Mine"; + +//$InvBanList[DeployInv, "ElfBarrelPack"] = 1; +//$InvBanList[DeployInv, "MortarBarrelPack"] = 1; +//$InvBanList[DeployInv, "PlasmaBarrelPack"] = 1; +//$InvBanList[DeployInv, "AABarrelPack"] = 1; +//$InvBanList[DeployInv, "MissileBarrelPack"] = 1; +$InvBanList[DeployInv, "InventoryDeployable"] = 1; + +//------------------------------------------------------------------------------ +function InventoryScreen::loadHud( %this, %tag ) +{ + $Hud[%tag] = InventoryScreen; + $Hud[%tag].childGui = INV_Root; + $Hud[%tag].parent = INV_Root; +} + +//------------------------------------------------------------------------------ +function InventoryScreen::setupHud( %this, %tag ) +{ + %favListStart = $pref::FavCurrentList * 10; + %this.selId = $pref::FavCurrentSelect - %favListStart + 1; + + // Add the list menu: + $Hud[%tag].staticData[0, 0] = new ShellPopupMenu(INV_ListMenu) + { + profile = "ShellPopupProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "16 313"; + extent = "170 36"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + helpTag = "0"; + maxPopupHeight = "220"; + text = ""; + }; + + // Add favorite tabs: + for( %i = 0; %i < 10; %i++ ) + { + %yOffset = ( %i * 30 ) + 10; + $Hud[%tag].staticData[0, %i + 1] = new ShellTabButton() { + profile = "ShellTabProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "4 " @ %yOffset; + extent = "206 38"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + helpTag = "0"; + command = "InventoryScreen.onTabSelect(" @ %favListStart + %i @ ");"; + text = strupr( $pref::FavNames[%favListStart + %i] ); + }; + $Hud[%tag].staticData[0, %i + 1].setValue( ( %favListStart + %i ) == $pref::FavCurrentSelect ); + + $Hud[%tag].parent.add( $Hud[%tag].staticData[0, %i + 1] ); + } + + %text = "Favorites " @ %favListStart + 1 SPC "-" SPC %favListStart + 10; + $Hud[%tag].staticData[0, 0].onSelect( $pref::FavCurrentList, %text, true ); + + $Hud[%tag].parent.add( $Hud[%tag].staticData[0, 0] ); + + // Add the SAVE button: + $Hud[%tag].staticData[1, 0] = new ShellBitmapButton() + { + profile = "ShellButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "409 295"; + extent = "75 38"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + helpTag = "0"; + command = "saveFavorite();"; + text = "SAVE"; + }; + + // Add the name edit control: + $Hud[%tag].staticData[1, 1] = new ShellTextEditCtrl() + { + profile = "NewTextEditProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "217 295"; + extent = "196 38"; + minExtent = "8 8"; + visible = "1"; + altCommand = "saveFavorite()"; + setFirstResponder = "1"; + modal = "1"; + helpTag = "0"; + historySize = "0"; + maxLength = "16"; + }; + + $Hud[%tag].staticData[1, 1].setValue( $pref::FavNames[$pref::FavCurrentSelect] ); + + $Hud[%tag].parent.add( $Hud[%tag].staticData[1, 0] ); + $Hud[%tag].parent.add( $Hud[%tag].staticData[1, 1] ); +} + +//------------------------------------------------------------------------------ +function InventoryScreen::addLine( %this, %tag, %lineNum, %type, %count ) +{ + $Hud[%tag].count = %count; + + // Add label: + %yOffset = ( %lineNum * 30 ) + 28; + $Hud[%tag].data[%lineNum, 0] = new GuiTextCtrl() + { + profile = "ShellTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "228 " @ %yOffset; + extent = "80 22"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + helpTag = "0"; + text = ""; + }; + + // Add drop menu: + $Hud[%tag].data[%lineNum, 1] = new ShellPopupMenu(INV_Menu) + { + profile = "ShellPopupProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "305 " @ %yOffset - 9; + extent = "180 36"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + helpTag = "0"; + maxPopupHeight = "200"; + text = ""; + type = %type; + }; + + return 2; +} + +//------------------------------------------------------------------------------ +function InventoryScreen::updateHud( %this, %client, %tag ) +{ + %noSniperRifle = true; + %armor = getArmorDatablock( %client, $NameToInv[%client.favorites[0]] ); + if ( %client.lastArmor !$= %armor ) + { + %client.lastArmor = %armor; + for ( %x = 0; %x < %client.lastNumFavs; %x++ ) + messageClient( %client, 'RemoveLineHud', "", 'inventoryScreen', %x ); + %setLastNum = true; + } + + %cmt = $CurrentMissionType; +//Create - ARMOR - List + %armorList = %client.favorites[0]; + for ( %y = 0; $InvArmor[%y] !$= ""; %y++ ) + if ( $InvArmor[%y] !$= %client.favorites[0] ) + %armorList = %armorList TAB $InvArmor[%y]; + +//Create - WEAPON - List + for ( %y = 0; $InvWeapon[%y] !$= ""; %y++ ) + { + %notFound = true; + for ( %i = 0; %i < getFieldCount( %client.weaponIndex ); %i++ ) + { + %WInv = $NameToInv[$InvWeapon[%y]]; + if ( ( $InvWeapon[%y] $= %client.favorites[getField( %client.weaponIndex,%i )] ) || !%armor.max[%WInv] ) + { + %notFound = false; + break; + } + else if ( "SniperRifle" $= $NameToInv[%client.favorites[getField( %client.weaponIndex,%i )]] ) + { + %noSniperRifle = false; + %packList = "noSelect\tEnergy Pack\tEnergy Pack must be used when \tLaser Rifle is selected!"; + %client.favorites[getField(%client.packIndex,0)] = "Energy Pack"; + } + } + + if ( !($InvBanList[%cmt, %WInv]) ) + { + if ( %notFound && %weaponList $= "" ) + %weaponList = $InvWeapon[%y]; + else if ( %notFound ) + %weaponList = %weaponList TAB $InvWeapon[%y]; + } + } + +//Create - PACK - List + if ( %noSniperRifle ) + { + if ( getFieldCount( %client.packIndex ) ) + %packList = %client.favorites[getField( %client.packIndex, 0 )]; + else + { + %packList = "EMPTY"; + %client.numFavs++; + } + for ( %y = 0; $InvPack[%y] !$= ""; %y++ ) + { + %PInv = $NameToInv[$InvPack[%y]]; + if ( ( $InvPack[%y] !$= %client.favorites[getField( %client.packIndex, 0 )]) && + %armor.max[%PInv] && !($InvBanList[%cmt, %PInv])) + %packList = %packList TAB $Invpack[%y]; + } + } +//Create - GRENADE - List + for ( %y = 0; $InvGrenade[%y] !$= ""; %y++ ) + { + %notFound = true; + for(%i = 0; %i < getFieldCount( %client.grenadeIndex ); %i++) + { + %GInv = $NameToInv[$InvGrenade[%y]]; + if ( ( $InvGrenade[%y] $= %client.favorites[getField( %client.grenadeIndex, %i )] ) || !%armor.max[%GInv] ) + { + %notFound = false; + break; + } + } + if ( !($InvBanList[%cmt, %GInv]) ) + { + if ( %notFound && %grenadeList $= "" ) + %grenadeList = $InvGrenade[%y]; + else if ( %notFound ) + %grenadeList = %grenadeList TAB $InvGrenade[%y]; + } + } + +//Create - MINE - List + for ( %y = 0; $InvMine[%y] !$= "" ; %y++ ) + { + %notFound = true; + // ----------------------------------------------------------------------------------------------------- + // z0dd - ZOD, 4/24/02. This was broken, Fixed. + for(%i = 0; %i < getFieldCount( %client.mineIndex ); %i++) + { + %MInv = $NameToInv[$InvMine[%y]]; + if ( ( $InvMine[%y] $= %client.favorites[getField( %client.mineIndex, %i )] ) || !%armor.max[%MInv] ) + { + %notFound = false; + break; + } + } + // ----------------------------------------------------------------------------------------------------- + if ( !($InvBanList[%cmt, %MInv]) ) + { + if ( %notFound && %mineList $= "" ) + %mineList = $InvMine[%y]; + else if ( %notFound ) + %mineList = %mineList TAB $InvMine[%y]; + } + } + %client.numFavsCount++; + messageClient( %client, 'SetLineHud', "", %tag, 0, "Armor:", %armorList, armor, %client.numFavsCount ); + %lineCount = 1; + + for ( %x = 0; %x < %armor.maxWeapons; %x++ ) + { + %client.numFavsCount++; + if ( %x < getFieldCount( %client.weaponIndex ) ) + { + %list = %client.favorites[getField( %client.weaponIndex,%x )]; + if ( %list $= Invalid ) + { + %client.favorites[%client.numFavs] = "INVALID"; + %client.weaponIndex = %client.weaponIndex TAB %client.numFavs; + } + } + else + { + %list = "EMPTY"; + %client.favorites[%client.numFavs] = "EMPTY"; + %client.weaponIndex = %client.weaponIndex TAB %client.numFavs; + %client.numFavs++; + } + if ( %list $= empty ) + %list = %list TAB %weaponList; + else + %list = %list TAB %weaponList TAB "EMPTY"; + messageClient( %client, 'SetLineHud', "", %tag, %x + %lineCount, "Weapon Slot " @ %x + 1 @ ": ", %list , weapon, %client.numFavsCount ); + } + %lineCount = %lineCount + %armor.maxWeapons; + + %client.numFavsCount++; + if ( getField( %packList, 0 ) !$= empty && %noSniperRifle ) + %packList = %packList TAB "EMPTY"; + %packText = %packList; + %packOverFlow = ""; + if ( strlen( %packList ) > 255 ) + { + %packText = getSubStr( %packList, 0, 255 ); + %packOverFlow = getSubStr( %packList, 255, 512 ); + } + messageClient( %client, 'SetLineHud', "", %tag, %lineCount, "Pack:", %packText, pack, %client.numFavsCount, %packOverFlow ); + %lineCount++; + + for( %x = 0; %x < %armor.maxGrenades; %x++ ) + { + %client.numFavsCount++; + if ( %x < getFieldCount( %client.grenadeIndex ) ) + { + %list = %client.favorites[getField( %client.grenadeIndex, %x )]; + if (%list $= Invalid) + { + %client.favorites[%client.numFavs] = "INVALID"; + %client.grenadeIndex = %client.grenadeIndex TAB %client.numFavs; + } + } + else + { + %list = "EMPTY"; + %client.favorites[%client.numFavs] = "EMPTY"; + %client.grenadeIndex = %client.grenadeIndex TAB %client.numFavs; + %client.numFavs++; + } + + if ( %list $= empty ) + %list = %list TAB %grenadeList; + else + %list = %list TAB %grenadeList TAB "EMPTY"; + + messageClient( %client, 'SetLineHud', "", %tag, %x + %lineCount, "Grenade:", %list, grenade, %client.numFavsCount ); + } + %lineCount = %lineCount + %armor.maxGrenades; + + for ( %x = 0; %x < %armor.maxMines; %x++ ) + { + %client.numFavsCount++; + if ( %x < getFieldCount( %client.mineIndex ) ) + { + %list = %client.favorites[getField( %client.mineIndex, %x )]; + if ( %list $= Invalid ) + { + %client.favorites[%client.numFavs] = "INVALID"; + %client.mineIndex = %client.mineIndex TAB %client.numFavs; + } + } + else + { + %list = "EMPTY"; + %client.favorites[%client.numFavs] = "EMPTY"; + %client.mineIndex = %client.mineIndex TAB %client.numFavs; + %client.numFavs++; + } + + if ( %list !$= Invalid ) + { + if ( %list $= empty ) + %list = %list TAB %mineList; + else if ( %mineList !$= "" ) + %list = %list TAB %mineList TAB "EMPTY"; + else + %list = %list TAB "EMPTY"; + } + + messageClient( %client, 'SetLineHud', "", %tag, %x + %lineCount, "Mine:", %list, mine, %client.numFavsCount ); + } + + if ( %setLastNum ) + %client.lastNumFavs = %client.numFavs; +} + +//------------------------------------------------------------------------------ +function buyFavorites(%client) +{ + // don't forget -- for many functions, anything done here also needs to be done + // below in buyDeployableFavorites !!! + %client.player.clearInventory(); + %client.setWeaponsHudClearAll(); + %cmt = $CurrentMissionType; + + %curArmor = %client.player.getDatablock(); + %curDmgPct = getDamagePercent(%curArmor.maxDamage, %client.player.getDamageLevel()); + + // armor + %client.armor = $NameToInv[%client.favorites[0]]; + %client.player.setArmor( %client.armor ); + %newArmor = %client.player.getDataBlock(); + + %client.player.setDamageLevel(%curDmgPct * %newArmor.maxDamage); + %weaponCount = 0; + + + // weapons + for(%i = 0; %i < getFieldCount( %client.weaponIndex ); %i++) + { + %inv = $NameToInv[%client.favorites[getField( %client.weaponIndex, %i )]]; + + if( %inv !$= "" ) + { + %weaponCount++; + %client.player.setInventory( %inv, 1 ); + } + + // ---------------------------------------------------- + // z0dd - ZOD, 4/24/02. Code optimization. + if ( %inv.image.ammo !$= "" ) + %client.player.setInventory( %inv.image.ammo, 999 ); + // ---------------------------------------------------- + } + %client.player.weaponCount = %weaponCount; + + // pack + %pCh = $NameToInv[%client.favorites[%client.packIndex]]; + if ( %pCh $= "" ) + %client.clearBackpackIcon(); + else + %client.player.setInventory( %pCh, 1 ); + + // if this pack is a deployable that has a team limit, warn the purchaser + // if it's a deployable turret, the limit depends on the number of players (deployables.cs) + if(%pCh $= "TurretIndoorDeployable" || %pCh $= "TurretOutdoorDeployable") + %maxDep = countTurretsAllowed(%pCh); + else + %maxDep = $TeamDeployableMax[%pCh]; + + if(%maxDep !$= "") + { + %depSoFar = $TeamDeployedCount[%client.player.team, %pCh]; + %packName = %client.favorites[%client.packIndex]; + + if(Game.numTeams > 1) + %msTxt = "Your team has "@%depSoFar@" of "@%maxDep SPC %packName@"s deployed."; + else + %msTxt = "You have deployed "@%depSoFar@" of "@%maxDep SPC %packName@"s."; + + messageClient(%client, 'MsgTeamDepObjCount', %msTxt); + } + + // grenades + for ( %i = 0; %i < getFieldCount( %client.grenadeIndex ); %i++ ) + { + if ( !($InvBanList[%cmt, $NameToInv[%client.favorites[getField( %client.grenadeIndex, %i )]]]) ) + %client.player.setInventory( $NameToInv[%client.favorites[getField( %client.grenadeIndex,%i )]], 30 ); + } + + %client.player.lastGrenade = $NameToInv[%client.favorites[getField( %client.grenadeIndex,%i )]]; + + // if player is buying cameras, show how many are already deployed + if(%client.favorites[%client.grenadeIndex] $= "Deployable Camera") + { + %maxDep = $TeamDeployableMax[DeployedCamera]; + %depSoFar = $TeamDeployedCount[%client.player.team, DeployedCamera]; + if(Game.numTeams > 1) + %msTxt = "Your team has "@%depSoFar@" of "@%maxDep@" Deployable Cameras placed."; + else + %msTxt = "You have placed "@%depSoFar@" of "@%maxDep@" Deployable Cameras."; + messageClient(%client, 'MsgTeamDepObjCount', %msTxt); + } + + // mines + // ----------------------------------------------------------------------------------------------------- + // z0dd - ZOD, 4/24/02. Old code did not check to see if mines are banned, fixed. + for ( %i = 0; %i < getFieldCount( %client.mineIndex ); %i++ ) + { + if ( !($InvBanList[%cmt, $NameToInv[%client.favorites[getField( %client.mineIndex, %i )]]]) ) + %client.player.setInventory( $NameToInv[%client.favorites[getField( %client.mineIndex,%i )]], 30 ); + } + // ----------------------------------------------------------------------------------------------------- + // miscellaneous stuff -- Repair Kit, Beacons, Targeting Laser + if ( !($InvBanList[%cmt, RepairKit]) ) + %client.player.setInventory( RepairKit, 1 ); + if ( !($InvBanList[%cmt, Beacon]) ) + %client.player.setInventory( Beacon, 20 ); // z0dd - ZOD, 4/24/02. 400 was a bit much, changed to 20 + if ( !($InvBanList[%cmt, TargetingLaser]) ) + %client.player.setInventory( TargetingLaser, 1 ); + + // ammo pack pass -- hack! hack! + if( %pCh $= "AmmoPack" ) + invAmmoPackPass(%client); +} + +//------------------------------------------------------------------------------ +function buyDeployableFavorites(%client) +{ + %player = %client.player; + %prevPack = %player.getMountedImage($BackpackSlot); + %player.clearInventory(); + %client.setWeaponsHudClearAll(); + %cmt = $CurrentMissionType; + + // players cannot buy armor from deployable inventory stations + %weapCount = 0; + for ( %i = 0; %i < getFieldCount( %client.weaponIndex ); %i++ ) + { + %inv = $NameToInv[%client.favorites[getField( %client.weaponIndex, %i )]]; + if ( !($InvBanList[DeployInv, %inv]) ) + { + %player.setInventory( %inv, 1 ); + // increment weapon count if current armor can hold this weapon + if(%player.getDatablock().max[%inv] > 0) + %weapCount++; + // --------------------------------------------- + // z0dd - ZOD, 4/24/02. Code streamlining. + if ( %inv.image.ammo !$= "" ) + %player.setInventory( %inv.image.ammo, 999 ); + // --------------------------------------------- + if(%weapCount >= %player.getDatablock().maxWeapons) + break; + } + } + %player.weaponCount = %weapCount; + // give player the grenades and mines they chose, beacons, and a repair kit + for ( %i = 0; %i < getFieldCount( %client.grenadeIndex ); %i++) + { + %GInv = $NameToInv[%client.favorites[getField( %client.grenadeIndex, %i )]]; + %client.player.lastGrenade = %GInv; + if ( !($InvBanList[DeployInv, %GInv]) ) + %player.setInventory( %GInv, 30 ); + + } + + // if player is buying cameras, show how many are already deployed + if(%client.favorites[%client.grenadeIndex] $= "Deployable Camera") + { + %maxDep = $TeamDeployableMax[DeployedCamera]; + %depSoFar = $TeamDeployedCount[%client.player.team, DeployedCamera]; + if(Game.numTeams > 1) + %msTxt = "Your team has "@%depSoFar@" of "@%maxDep@" Deployable Cameras placed."; + else + %msTxt = "You have placed "@%depSoFar@" of "@%maxDep@" Deployable Cameras."; + messageClient(%client, 'MsgTeamDepObjCount', %msTxt); + } + + for ( %i = 0; %i < getFieldCount( %client.mineIndex ); %i++ ) + { + %MInv = $NameToInv[%client.favorites[getField( %client.mineIndex, %i )]]; + if ( !($InvBanList[DeployInv, %MInv]) ) + %player.setInventory( %MInv, 30 ); + } + if ( !($InvBanList[DeployInv, Beacon]) && !($InvBanList[%cmt, Beacon]) ) + %player.setInventory( Beacon, 20 ); // z0dd - ZOD, 4/24/02. 400 was a bit much, changed to 20. + if ( !($InvBanList[DeployInv, RepairKit]) && !($InvBanList[%cmt, RepairKit]) ) + %player.setInventory( RepairKit, 1 ); + if ( !($InvBanList[DeployInv, TargetingLaser]) && !($InvBanList[%cmt, TargetingLaser]) ) + %player.setInventory( TargetingLaser, 1 ); + + // players cannot buy deployable station packs from a deployable inventory station + %packChoice = $NameToInv[%client.favorites[%client.packIndex]]; + if ( !($InvBanList[DeployInv, %packChoice]) ) + %player.setInventory( %packChoice, 1 ); + + // if this pack is a deployable that has a team limit, warn the purchaser + // if it's a deployable turret, the limit depends on the number of players (deployables.cs) + if(%packChoice $= "TurretIndoorDeployable" || %packChoice $= "TurretOutdoorDeployable") + %maxDep = countTurretsAllowed(%packChoice); + else + %maxDep = $TeamDeployableMax[%packChoice]; + if((%maxDep !$= "") && (%packChoice !$= "InventoryDeployable")) + { + %depSoFar = $TeamDeployedCount[%client.player.team, %packChoice]; + %packName = %client.favorites[%client.packIndex]; + + if(Game.numTeams > 1) + %msTxt = "Your team has "@%depSoFar@" of "@%maxDep SPC %packName@"s deployed."; + else + %msTxt = "You have deployed "@%depSoFar@" of "@%maxDep SPC %packName@"s."; + + messageClient(%client, 'MsgTeamDepObjCount', %msTxt); + } + + if(%prevPack > 0) + { + // if player had a "forbidden" pack (such as a deployable inventory station) + // BEFORE visiting a deployed inventory station AND still has that pack chosen + // as a favorite, give it back + if((%packChoice $= %prevPack.item) && ($InvBanList[DeployInv, %packChoice])) + %player.setInventory( %prevPack.item, 1 ); + } + + if(%packChoice $= "AmmoPack") + invAmmoPackPass(%client); +} + +//------------------------------------------------------------------------------------- +function getAmmoStationLovin(%client) +{ + // z0dd - ZOD, 4/24/02. This function was quite a mess, needed rewrite + + %cmt = $CurrentMissionType; + + // weapons + for(%i = 0; %i < %client.player.weaponSlotCount; %i++) + { + %weapon = %client.player.weaponSlot[%i]; + if ( %weapon.image.ammo !$= "" ) + %client.player.setInventory( %weapon.image.ammo, 999 ); + } + + // grenades + %client.player.setInventory( Grenade, 0 ); + %client.player.setInventory( ConcussionGrenade, 0 ); + %client.player.setInventory( CameraGrenade, 0 ); + %client.player.setInventory( FlashGrenade, 0 ); + %client.player.setInventory( FlareGrenade, 0 ); + for ( %i = 0; %i < getFieldCount( %client.grenadeIndex ); %i++ ) + { + %client.player.lastGrenade = $NameToInv[%client.favorites[getField( %client.grenadeIndex, %i )]]; + } + %grenType = %client.player.lastGrenade; + if(%grenType $= "") + { + %grenType = Grenade; + } + if ( !($InvBanList[%cmt, %grenType]) ) + %client.player.setInventory( %grenType, 30 ); + + if(%grenType $= "Deployable Camera") + { + %maxDep = $TeamDeployableMax[DeployedCamera]; + %depSoFar = $TeamDeployedCount[%client.player.team, DeployedCamera]; + if(Game.numTeams > 1) + %msTxt = "Your team has "@%depSoFar@" of "@%maxDep@" Deployable Cameras placed."; + else + %msTxt = "You have placed "@%depSoFar@" of "@%maxDep@" Deployable Cameras."; + messageClient(%client, 'MsgTeamDepObjCount', %msTxt); + } + + // Mines + %client.player.setInventory( Mine, 0 ); + for ( %i = 0; %i < getFieldCount( %client.mineIndex ); %i++ ) + { + %client.player.lastMine = $NameToInv[%client.favorites[getField( %client.mineIndex, %i )]]; + } + %mineType = %client.player.lastMine; + if(%mineType $= "") + { + %mineType = Mine; + } + if ( !($InvBanList[%cmt, %mineType]) ) + %client.player.setInventory( %mineType, 30 ); + + // miscellaneous stuff -- Repair Kit, Beacons, Targeting Laser + if ( !($InvBanList[%cmt, RepairKit]) ) + %client.player.setInventory( RepairKit, 1 ); + + if ( !($InvBanList[%cmt, Beacon]) ) + %client.player.setInventory( Beacon, 20 ); + + if ( !($InvBanList[%cmt, TargetingLaser]) ) + %client.player.setInventory( TargetingLaser, 1 ); + + if( %client.player.getMountedImage($BackpackSlot) $= "AmmoPack" ) + invAmmoPackPass(%client); +} + + +function invAmmoPackPass(%client) +{ + // "normal" ammo stuff (everything but mines and grenades) + for ( %idx = 0; %idx < $numAmmoItems; %idx++ ) + { + %ammo = $AmmoItem[%idx]; + %client.player.incInventory(%ammo, AmmoPack.max[%ammo]); + } + //our good friends, the grenade family *SIGH* + // first find out what type of grenade the player has selected + %grenFav = %client.favorites[getField(%client.grenadeIndex, 0)]; + if((%grenFav !$= "EMPTY") && (%grenFav !$= "INVALID")) + %client.player.incInventory($NameToInv[%grenFav], AmmoPack.max[$NameToInv[%grenFav]]); + // now the same check for mines + %mineFav = %client.favorites[getField(%client.mineIndex, 0)]; + if((%mineFav !$= "EMPTY") && (%mineFav !$= "INVALID") && !($InvBanList[%cmt, Mine])) + %client.player.incInventory($NameToInv[%mineFav], AmmoPack.max[$NameToInv[%mineFav]]); +} + +//------------------------------------------------------------------------------ +function loadFavorite( %index, %echo ) +{ + $pref::FavCurrentSelect = %index; + %list = mFloor( %index / 10 ); + + if ( isObject( $Hud['inventoryScreen'] ) ) + { + // Deselect the old tab: + if ( InventoryScreen.selId !$= "" ) + $Hud['inventoryScreen'].staticData[0, InventoryScreen.selId].setValue( false ); + + // Make sure we are looking at the same list: + if ( $pref::FavCurrentList != %list ) + { + %favListStart = %list * 10; + %text = "Favorites " @ %favListStart + 1 SPC "-" SPC %favListStart + 10; + $Hud['inventoryScreen'].staticData[0, 0].onSelect( %list, %text, true ); + } + + // Select the new tab: + %tab = $pref::FavCurrentSelect - ( $pref::FavCurrentList * 10 ) + 1; + InventoryScreen.selId = %tab; + $Hud['inventoryScreen'].staticData[0, %tab].setValue( true ); + + // Update the Edit Name field: + $Hud['inventoryScreen'].staticData[1, 1].setValue( $pref::FavNames[%index] ); + } + + if ( %echo ) + addMessageHudLine( "Inventory set \"" @ $pref::FavNames[%index] @ "\" selected." ); + + commandToServer( 'setClientFav', $pref::Favorite[%index] ); +} + +//------------------------------------------------------------------------------ +function saveFavorite() +{ + if ( $pref::FavCurrentSelect !$= "" ) + { + %favName = $Hud['inventoryScreen'].staticData[1, 1].getValue(); + $pref::FavNames[$pref::FavCurrentSelect] = %favName; + $Hud['inventoryScreen'].staticData[0, $pref::FavCurrentSelect - ($pref::FavCurrentList * 10) + 1].setText( strupr( %favName ) ); + //$Hud[%tag].staticData[1, 1].setValue( %favName ); + %favList = $Hud['inventoryScreen'].data[0, 1].type TAB $Hud['inventoryScreen'].data[0, 1].getValue(); + for ( %i = 1; %i < $Hud['inventoryScreen'].count; %i++ ) + { + %name = $Hud['inventoryScreen'].data[%i, 1].getValue(); + if ( %name $= invalid ) + %name = "EMPTY"; + %favList = %favList TAB $Hud['inventoryScreen'].data[%i, 1].type TAB %name; + } + $pref::Favorite[$pref::FavCurrentSelect] = %favList; + echo("exporting pref::* to ClientPrefs.cs"); + export("$pref::*", "prefs/ClientPrefs.cs", False); + } +// else +// addMessageHudLine("Must First Select A Favorite Button."); +} + +//------------------------------------------------------------------------------ +function addQuickPackFavorite( %pack, %item ) +{ + // this has been such a success it has been changed to handle grenades + // and other equipment as well as packs so everything seems to be called 'pack' + // including the function itself. The default IS pack + + if(%item $= "") + %item = "Pack"; + %packFailMsg = "You cannot use that equipment with your selected loadout."; + if ( !isObject($Hud['inventoryScreen'].staticData[1, 1]) || $Hud['inventoryScreen'].staticData[1, 1].getValue() $= "" ) + { + //if the player hasnt brought up the inv screen we use his current fav + %currentFav = $pref::Favorite[$pref::FavCurrentSelect]; + //echo(%currentFav); + + for ( %i = 0; %i < getFieldCount( %currentFav ); %i++ ) + { + %type = getField( %currentFav, %i ); + %equipment = getField( %currentFav, %i++ ); + + %invalidPack = checkPackValidity(%pack, %equipment, %item ); + if(%invalidPack) + { + addMessageHudLine( %packFailMsg ); + return; + + } + // Success-------------------------------------------------- + if ( %type $= %item ) + %favList = %favList @ %type TAB %pack @ "\t"; + else + %favList = %favList @ %type TAB %equipment @ "\t"; + } + //echo(%favList); + } + else + { + //otherwise we go with whats on the invScreen (even if its asleep) + %armor = $Hud['inventoryScreen'].data[0, 1].getValue(); + + // check pack validity with armor + %invalidPack = checkPackValidity(%pack, %armor, %item ); + if(%invalidPack) + { + addMessageHudLine( %packFailMsg ); + return; + + } + %favList = $Hud['inventoryScreen'].data[0, 1].type TAB %armor; + for ( %i = 1; %i < $Hud['inventoryScreen'].count; %i++ ) + { + //echo( $Hud['inventoryScreen'].Data[%i, 1].type); + %type = $Hud['inventoryScreen'].data[%i, 1].type; + %equipment = $Hud['inventoryScreen'].data[%i, 1].getValue(); + + if(%type $= %item) + %equipment = %pack; + + // Special Cases again------------------------------------------------ + %invalidPack = checkPackValidity(%pack, %equipment, %item ); + if(%invalidPack) + { + addMessageHudLine( %packFailMsg ); + return; + + } + + %favList = %favList TAB %type TAB %equipment; + } + //echo(%favList); + } + commandToServer( 'setClientFav', %favList ); + + //we message the player real nice like + addMessageHudLine( "Inventory updated to " @ %pack @ "." ); +} + +function checkPackValidity(%pack, %equipment, %item) +{ + //echo("validityChecking:" SPC %pack SPC %equipment); + + // this is mostly for ease of mod makers + // this is the base restrictions stuff + // for your mod just overwrite this function and + // change the restrictions and onlyUses + + // you must have #1 to use #2 + //%restrict[#1, #2] = true; + + %restrict["Scout", "Inventory Station"] = true; + %restrict["Scout", "Landspike Turret"] = true; + %restrict["Scout", "Spider Clamp Turret"] = true; + %restrict["Scout", "ELF Turret Barrel"] = true; + %restrict["Scout", "Mortar Turret Barrel"] = true; + %restrict["Scout", "AA Turret Barrel"] = true; + %restrict["Scout", "Plasma Turret Barrel"] = true; + %restrict["Scout", "Missile Turret Barrel"] = true; + %restrict["Assault", "Cloak Pack"] = true; + %restrict["Juggernaut", "Cloak Pack"] = true; + + // you can only use #1 if you have a #2 of type #3 + //%require[#1] = #2 TAB #3; + + %require["Laser Rifle"] = "Pack" TAB "Energy Pack"; + + + if(%restrict[%equipment, %pack] ) + return true; + + else if(%require[%equipment] !$="" ) + { + if(%item $= getField(%require[%equipment], 0) ) + { + if(%pack !$= getField(%require[%equipment], 1) ) + return true; + } + } +} + + +//------------------------------------------------------------------------------ +function setDefaultInventory(%client) +{ + commandToClient(%client,'InitLoadClientFavorites'); +} + +//------------------------------------------------------------------------------ +function checkInventory( %client, %text ) +{ + %armor = getArmorDatablock( %client, $NameToInv[getField( %text, 1 )] ); + %list = getField( %text, 0 ) TAB getField( %text, 1 ); + %cmt = $CurrentMissionType; + for( %i = 3; %i < getFieldCount( %text ); %i = %i + 2 ) + { + %inv = $NameToInv[getField(%text,%i)]; + if ( (( %armor.max[%inv] && !($InvBanList[%cmt, %inv]) ) || + getField( %text, %i ) $= Empty || getField( %text, %i ) $= Invalid) + && (($InvTotalCount[getField( %text, %i - 1 )] - $BanCount[getField( %text, %i - 1 )]) > 0)) + %list = %list TAB getField( %text, %i - 1 ) TAB getField( %text, %i ); + else if( $InvBanList[%cmt, %inv] || %inv $= empty || %inv $= "") + %list = %list TAB getField( %text, %i - 1 ) TAB "INVALID"; + } + return %list; +} + +//------------------------------------------------------------------------------ +function getArmorDatablock(%client, %size) +{ + if ( %client.race $= "Bioderm" ) + %armor = %size @ "Male" @ %client.race @ Armor; + else + %armor = %size @ %client.sex @ %client.race @ Armor; + return %armor; +} + +//------------------------------------------------------------------------------ +function InventoryScreen::onWake(%this) +{ + if ( $HudHandle[inventoryScreen] !$= "" ) + alxStop( $HudHandle[inventoryScreen] ); + alxPlay(HudInventoryActivateSound, 0, 0, 0); + $HudHandle[inventoryScreen] = alxPlay(HudInventoryHumSound, 0, 0, 0); + + if ( isObject( hudMap ) ) + { + hudMap.pop(); + hudMap.delete(); + } + new ActionMap( hudMap ); + hudMap.blockBind( moveMap, toggleScoreScreen ); + hudMap.blockBind( moveMap, toggleCommanderMap ); + hudMap.bindCmd( keyboard, escape, "", "InventoryScreen.onDone();" ); + hudMap.push(); +} + +//------------------------------------------------------------------------------ +function InventoryScreen::onSleep() +{ + hudMap.pop(); + hudMap.delete(); + alxStop($HudHandle[inventoryScreen]); + alxPlay(HudInventoryDeactivateSound, 0, 0, 0); + $HudHandle[inventoryScreen] = ""; +} + +//------------------------------------------------------------------------------ +function InventoryScreen::onDone( %this ) +{ + toggleCursorHuds( 'inventoryScreen' ); +} + +//------------------------------------------------------------------------------ +function InventoryScreen::onTabSelect( %this, %favId ) +{ + loadFavorite( %favId, 0 ); +} + +function createInvBanCount() +{ + $BanCount["Armor"] = 0; + $BanCount["Weapon"] = 0; + $BanCount["Pack"] = 0; + $BanCount["Grenade"] = 0; + $BanCount["Mine"] = 0; + + for(%i = 0; $InvArmor[%i] !$= ""; %i++) + if($InvBanList[$CurrentMissionType, $NameToInv[$InvArmor[%i]]]) + $BanCount["Armor"]++; + $InvTotalCount["Armor"] = %i; + + for(%i = 0; $InvWeapon[%i] !$= ""; %i++) + if($InvBanList[$CurrentMissionType, $NameToInv[$InvWeapon[%i]]]) + $BanCount["Weapon"]++; + $InvTotalCount["Weapon"] = %i; + + for(%i = 0; $InvPack[%i] !$= ""; %i++) + if($InvBanList[$CurrentMissionType, $NameToInv[$InvPack[%i]]]) + $BanCount["Pack"]++; + $InvTotalCount["Pack"] = %i; + + for(%i = 0; $InvGrenade[%i] !$= ""; %i++) + if($InvBanList[$CurrentMissionType, $NameToInv[$InvGrenade[%i]]]) + $BanCount["Grenade"]++; + $InvTotalCount["Grenade"] = %i; + + for(%i = 0; $InvMine[%i] !$= ""; %i++) + if($InvBanList[$CurrentMissionType, $NameToInv[$InvMine[%i]]]) + $BanCount["Mine"]++; + $InvTotalCount["Mine"] = %i; +} diff --git a/scripts/item.cs b/scripts/item.cs index 8e6bf81..997a9d8 100644 --- a/scripts/item.cs +++ b/scripts/item.cs @@ -1,757 +1,757 @@ -//---------------------------------------------------------------------------- - -// When first mounted (assuming there is ammo): -// SingleShot activate -> ready -// Spinning activate -> idle (spin 0) -// Sustained activate -> ready -// DiscLauncher activate -> reload -> spinup -> ready -// -// Normal operation: -// SingleShot ready -> fire -> reload -> ready -// Spinning idle (spin 0) -> spinup -> ready -> fire -> spindown -> idle -// Sustained ready -> fire -> reload -> ready -// DiscLauncher ready -> fire -> reload -> spinup -> ready - -// Image properties -// emap -// preload -// shapeFile -// mountPoint -// offset -// rotation -// firstPerson -// mass -// usesEnergy -// minEnergy -// accuFire -// lightType -// lightTime -// lightRadius -// lightColor - -// Image state variables -// stateName -// stateTransitionOnLoaded -// stateTransitionOnNotLoaded -// stateTransitionOnAmmo -// stateTransitionOnNoAmmo -// stateTransitionOnTriggerUp -// stateTransitionOnTriggerDown -// stateTransitionOnTimeout -// stateTimeoutValue -// stateFire -// stateEnergyDrain -// stateAllowImageChange -// stateScaleAnimation -// stateDirection -// stateLoadedFlag -// stateSpinThread -// stateRecoil -// stateSequence -// stateSound -// stateScript -// stateEmitter -// stateEmitterTime -// stateEmitterNode - -//---------------------------------------------------------------------------- - -$ItemRespawnTime = 30000; -$ItemPopTime = 30 * 1000; // 30 seconds - -$WeaponSlot = 0; -$AuxiliarySlot = 1; -$BackpackSlot = 2; -$FlagSlot = 3; - -//---------------------------------------------------------------------------- -datablock EffectProfile(ItemPickupEffect) -{ - effectname = "packs/packs.pickupPack"; - minDistance = 2.5; -}; - -datablock AudioProfile(ItemPickupSound) -{ - filename = "fx/packs/packs.pickuppack.wav"; - description = AudioClosest3d; - effect = ItemPickupEffect; - preload = true; -}; - -datablock EffectProfile(ItemThrowEffect) -{ - effectname = "packs/packs.throwpack"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock AudioProfile(ItemThrowSound) -{ - filename = "fx/packs/packs.throwpack.wav"; - description = AudioClosest3d; - effect = ItemThrowEffect; - preload = true; -}; - -datablock AudioProfile(RepairPatchSound) -{ - filename = "fx/misc/health_patch.wav"; - description = AudioClosest3d; - preload = true; - effect = ItemPickupEffect; - preload = true; -}; - -function ItemData::create(%block) -{ - if(%block $= "flag") - %obj = new Item() { - className = FlagObj; - dataBlock = %block; - static = false; - rotate = false; - }; - else - %obj = new Item() { - dataBlock = %block; - static = true; - //rotate = true; - // don't make "placed items" rotate - rotate = false; - }; - return(%obj); -} - -//-------------------------------------------------------------------------- -function Item::schedulePop(%this) -{ - %itemFadeTime = 1000; // items will take 1 second (1000 milliseconds) to fade out - %this.startFade(%itemFadeTime, $ItemPopTime - %itemFadeTime, true); - %this.schedule($ItemPopTime, "delete"); -} - -function Item::respawn(%this) -{ - %this.startFade(0, 0, true); - %this.schedule($ItemRespawnTime + 100, "startFade", 1000, 0, false); - %this.hide(true); - %this.schedule($ItemRespawnTime, "hide", false); -} - -function ItemData::onThrow(%data,%obj,%shape) -{ - serverPlay3D(ItemThrowSound, %obj.getTransform()); - // don't schedule a delete for satchelCharges when they're deployed - if(!%data.noTimeout) - %obj.schedulePop(); -} - -function ItemData::onInventory(%data,%shape,%value) -{ - if (!%value) { - // If we don't have any more of these items, make sure - // we don't have an image mounted. - %slot = %shape.getMountSlot(%data.image); - if (%slot != -1) - %shape.unmountImage(%slot); - } -} - -function ItemData::onEnterLiquid(%data, %obj, %coverage, %type) -{ - if(%data.isInvincible) - return; - - switch(%type) - { - case 0: - //Water - case 1: - //Ocean Water - case 2: - //River Water - case 3: - //Stagnant Water - case 4: - //Lava - %obj.delete(); - case 5: - //Hot Lava - %obj.delete(); - case 6: - //Crusty Lava - %obj.delete(); - case 7: - //Quick Sand - } -} - -function ItemData::onLeaveLiquid(%data, %obj, %type) -{ - // dummy -} - -function ItemData::onCollision(%data,%obj,%col) -{ - // Default behavior for items is to get picked - // by the colliding object. - if (%col.getDataBlock().className $= Armor && %col.getState() !$= "Dead") - { - if (%col.isMounted()) - return; - - if (%col.pickup(%obj, 1)) - { - if (%col.client) - { - messageClient(%col.client, 'MsgItemPickup', '\c0You picked up %1.', %data.pickUpName); - serverPlay3D(ItemPickupSound, %col.getTransform()); - } - if (%obj.isStatic()) - %obj.respawn(); - else - %obj.delete(); - } - } -} - -//---------------------------------------------------------------------------- -datablock ItemData(RepairKit) -{ - className = HandInventory; - catagory = "Misc"; - shapeFile = "repair_kit.dts"; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2.0; - pickUpName = "a repair kit"; - alwaysAmbient = true; - - computeCRC = true; - emap = true; - -}; - -function RepairKit::onUse(%data,%obj) -{ - //---------------------------------------------------------------------------- - // z0dd - ZOD, 8/10/02. Let players use repair kit regardless of health status - // if they choose so via client $pref:: - if (%obj.client.wasteRepKit == 1) - { - %obj.decInventory(%data,1); - messageClient(%obj.client, 'MsgRepairKitUsed', '\c2Repair Kit Used.'); - if (%obj.getDamageLevel() != 0) - { - %obj.applyRepair(0.2); - } - } - else - { - // Don't use the kit unless we're damaged - if (%obj.getDamageLevel() != 0) - { - %obj.applyRepair(0.2); - %obj.decInventory(%data,1); - messageClient(%obj.client, 'MsgRepairKitUsed', '\c2Repair Kit Used.'); - } - } -} - -function serverCmdSetRepairKitWaste(%client, %value) -{ - %val = deTag(%value); - %client.wasteRepKit = %val; -} - -//---------------------------------------------------------------------------- - -datablock ItemData(RepairPatch) -{ - catagory = "Misc"; - shapeFile = "repair_patch.dts"; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2.0; - pickUpName = "a repair patch"; - alwaysAmbient = true; - - computeCRC = true; - emap = true; - -}; - -function RepairPatch::onCollision(%data,%obj,%col) -{ - if ( %col.getDataBlock().className $= Armor - && %col.getDamageLevel() != 0 - && %col.getState() !$= "Dead" ) - { - if (%col.isMounted()) - return; - - %col.playAudio(0, RepairPatchSound); - %col.applyRepair(0.125); - %obj.respawn(); - if (%col.client > 0) - messageClient(%col.client, 'MsgItemPickup', '\c0You picked up %1.', %data.pickUpName); - } -} - -//---------------------------------------------------------------------------- -// Flag: -//---------------------------------------------------------------------------- -datablock ShapeBaseImageData(FlagImage) -{ - shapeFile = "flag.dts"; - item = Flag; - mountPoint = 2; - offset = "0 0 0"; - - lightType = "PulsingLight"; - lightColor = "0.5 0.5 0.5 1.0"; - lightTime = "1000"; - lightRadius = "3"; - cloakable = false; -}; - -datablock ItemData(Flag) -{ - catagory = "Objectives"; - shapefile = "flag.dts"; - mass = 80; // z0dd - ZOD, 3/27/02. Keep flag from flying all over when damaged. was 55. - elasticity = 0.2; - friction = 0.6; - pickupRadius = 4.0; // z0dd - ZOD, 8/11/02. Was 3 - pickUpName = "a flag"; - computeCRC = true; - - lightType = "PulsingLight"; - lightColor = "0.5 0.5 0.5 1.0"; - lightTime = "1000"; - lightRadius = "3"; - - isInvincible = true; - cmdCategory = "Objectives"; - cmdIcon = CMDFlagIcon; - cmdMiniIconName = "commander/MiniIcons/com_flag_grey"; - targetTypeTag = 'Flag'; - - //used in CTF to mark the flag during a stalemate... - hudImageNameFriendly[1] = "commander/MiniIcons/com_flag_grey"; - hudImageNameEnemy[1] = "commander/MiniIcons/com_flag_grey"; - hudRenderModulated[1] = true; - hudRenderAlways[1] = true; - hudRenderCenter[1] = true; - hudRenderDistance[1] = true; - hudRenderName[1] = true; -}; - -//---------------------------------------------------------------------------- -function Flag::onThrow(%data,%obj,%src) -{ - Game.playerDroppedFlag(%src); -} - -function Flag::onAdd(%this, %obj) -{ - // make sure flags play "flapping" ambient thread - Parent::onAdd(%this, %obj); - %obj.playThread($AmbientThread, "ambient"); - - %blocker = new VehicleBlocker() - { - position = %obj.position; - rotation = %obj.rotation; - dimensions = "2 2 4"; - }; - MissionCleanup.add(%blocker); -} - -function Flag::onCollision(%data,%obj,%col) -{ - if (%col.getDataBlock().className $= Armor) - { - if (%col.isMounted()) - return; - - // z0dd - ZOD, 6/13/02. Touch the flag and your invincibility and cloaking goes away. - if(%col.station $= "" && %col.isCloaked()) - { - if( %col.respawnCloakThread !$= "" ) - { - Cancel(%col.respawnCloakThread); - %col.setCloaked( false ); - %col.respawnCloakThread = ""; - } - } - if( %col.client > 0 ) - { - %col.setInvincibleMode(0, 0.00); - %col.setInvincible( false ); - } - - // a player hit the flag - Game.playerTouchFlag(%col, %obj); - } -} - -//---------------------------------------------------------------------------- -// HuntersFlag: -//---------------------------------------------------------------------------- -datablock ShapeBaseImageData(HuntersFlagImage) -{ - shapeFile = "Huntersflag.dts"; - item = Flag; - mountPoint = 2; - offset = "0 0 0"; - - lightType = "PulsingLight"; - lightColor = "0.5 0.5 0.5 1.0"; - lightTime = "1000"; - lightRadius = "3"; -}; - -// 1: red -// 2: blue -// 4: yellow -// 8: green -datablock ItemData(HuntersFlag1) -{ - className = HuntersFlag; - - shapefile = "Huntersflag.dts"; - mass = 80; // z0dd - ZOD, 3/27/02. Keep flag from flying all over when damaged. was 55. - elasticity = 0.2; - friction = 0.6; - pickupRadius = 4.0; // z0dd - ZOD, 8/11/02. Was 3 - isInvincible = true; - pickUpName = "a flag"; - computeCRC = true; - - lightType = "PulsingLight"; - lightColor = "0.8 0.2 0.2 1.0"; - lightTime = "1000"; - lightRadius = "3"; -}; - -datablock ItemData(HuntersFlag2) : HuntersFlag1 -{ - lightColor = "0.2 0.2 0.8 1.0"; -}; - -datablock ItemData(HuntersFlag4) : HuntersFlag1 -{ - lightColor = "0.8 0.8 0.2 1.0"; -}; - -datablock ItemData(HuntersFlag8) : HuntersFlag1 -{ - lightColor = "0.2 0.8 0.2 1.0"; -}; - -function HuntersFlag::onRemove(%data, %obj) -{ - // dont want target removed... -} - -function HuntersFlag::onThrow(%data,%obj,%src) -{ - Game.playerDroppedFlag(%src); -} - -function HuntersFlag::onCollision(%data,%obj,%col) -{ - if (%col.getDataBlock().className $= Armor) - { - if (%col.isMounted()) - return; - - // a player hit the flag - Game.playerTouchFlag(%col, %obj); - } -} - -//---------------------------------------------------------------------------- -// Nexus: -//---------------------------------------------------------------------------- -datablock ItemData(Nexus) -{ - catagory = "Objectives"; - shapefile = "nexus_effect.dts"; - mass = 10; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - icon = "CMDNexusIcon"; - targetTypeTag = 'Nexus'; - - computeCRC = true; - -}; - -datablock ParticleData(NexusParticleDenied) -{ - dragCoeffiecient = 0.4; - gravityCoefficient = 3.0; - inheritedVelFactor = 0.0; - - lifetimeMS = 1200; - lifetimeVarianceMS = 400; - - textureName = "particleTest"; - - useInvAlpha = false; - spinRandomMin = -200.0; - spinRandomMax = 200.0; - - colors[0] = "0.3 0.0 0.0 1.0"; - colors[1] = "0.5 0.0 0.0 0.5"; - colors[2] = "0.7 0.0 0.0 0.0"; - sizes[0] = 0.2; - sizes[1] = 0.1; - sizes[2] = 0.0; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData(NexusParticleDeniedEmitter) -{ - ejectionPeriodMS = 2; - ejectionOffset = 0.2; - periodVarianceMS = 0.5; - ejectionVelocity = 10.0; - velocityVariance = 4.0; - thetaMin = 0.0; - thetaMax = 30.0; - lifetimeMS = 0; - - particles = "NexusParticleDenied"; -}; - -datablock ParticleData(NexusParticleCap) -{ - dragCoeffiecient = 0.4; - gravityCoefficient = 3.0; - inheritedVelFactor = 0.0; - - lifetimeMS = 1200; - lifetimeVarianceMS = 400; - - textureName = "particleTest"; - - useInvAlpha = false; - spinRandomMin = -200.0; - spinRandomMax = 200.0; - - colors[0] = "0.5 0.8 0.2 1.0"; - colors[1] = "0.6 0.9 0.3 1.0"; - colors[2] = "0.7 1.0 0.4 1.0"; - sizes[0] = 0.2; - sizes[1] = 0.1; - sizes[2] = 0.0; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData(NexusParticleCapEmitter) -{ - ejectionPeriodMS = 2; - ejectionOffset = 0.5; - periodVarianceMS = 0.5; - ejectionVelocity = 10.0; - velocityVariance = 4.0; - thetaMin = 0.0; - thetaMax = 30.0; - lifetimeMS = 0; - - particles = "NexusParticleCap"; -}; - -//---------------------------------------------------------------------------- - -function getVector(%string, %num) -{ - %start = %num * 3; - return getWords(%string,%start, %start + 2); -} - -// -------------------------------------------- -// explosion datablock -// -------------------------------------------- - -datablock ExplosionData(DeployablesExplosion) -{ - soundProfile = DeployablesExplosionSound; - faceViewer = true; - - explosionShape = "effect_plasma_explosion.dts"; - sizes[0] = "0.2 0.2 0.2"; - sizes[1] = "0.3 0.3 0.3"; -}; - -$TeamDeployableMax[TargetBeacon] = 10; -$TeamDeployableMax[MarkerBeacon] = 20; - -datablock ItemData(Beacon) -{ - className = HandInventory; - catagory = "Misc"; - shapeFile = "beacon.dts"; - mass = 1; - elasticity = 0.2; - friction = 0.8; - pickupRadius = 1; - pickUpName = "a deployable beacon"; - - computeCRC = true; - -}; - -datablock StaticShapeData(DeployedBeacon) : StaticShapeDamageProfile -{ - shapeFile = "beacon.dts"; - explosion = DeployablesExplosion; - maxDamage = 0.45; - disabledLevel = 0.45; - destroyedLevel = 0.45; - targetNameTag = 'beacon'; - - deployedObject = true; - - dynamicType = $TypeMasks::SensorObjectType; - - debrisShapeName = "debris_generic_small.dts"; - debris = SmallShapeDebris; -}; - -function DeployedBeacon::onDestroyed(%data, %obj, %prevState) -{ - if(%obj.getBeaconType() $= "friend") - %bType = "MarkerBeacon"; - else - %bType = "TargetBeacon"; - $TeamDeployedCount[%obj.team, %bType]--; - %obj.schedule(500, delete); -} - -function Beacon::onUse(%data, %obj) -{ - // look for 3 meters along player's viewpoint for interior or terrain - %searchRange = 3.0; - %mask = $TypeMasks::TerrainObjectType | $TypeMasks::InteriorObjectType | $TypeMasks::StaticShapeObjectType | $TypeMasks::ForceFieldObjectType; - // get the eye vector and eye transform of the player - %eyeVec = %obj.getEyeVector(); - %eyeTrans = %obj.getEyeTransform(); - // extract the position of the player's camera from the eye transform (first 3 words) - %eyePos = posFromTransform(%eyeTrans); - // normalize the eye vector - %nEyeVec = VectorNormalize(%eyeVec); - // scale (lengthen) the normalized eye vector according to the search range - %scEyeVec = VectorScale(%nEyeVec, %searchRange); - // 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, 0); - - %allowTargBeac = (Game.class $= "PracticeCTFGame"); // z0dd - ZOD, 10/5/02. Targeting beacons only allowed in Practice mode - %newBeacType = (%allowTargBeac ? TargetBeacon : MarkerBeacon); - - if(!%searchResult ) - { - // no terrain/interior collision within search range - if(%obj.inv[%data.getName()] > 0) - messageClient(%obj.client, 'MsgBeaconNoSurface', '\c2Cannot place beacon. Too far from surface.'); - return 0; - } - else - { - %searchObj = GetWord(%searchResult, 0); - if(%searchObj.getType() & ($TypeMasks::StaticShapeObjectType | $TypeMasks::ForceFieldObjectType) ) - { - // if there's already a beacon where player is aiming, switch its type - // otherwise, player can't deploy a beacon there - if((%searchObj.getDataBlock().getName() $= DeployedBeacon)) - { - if(%allowTargBeac) // z0dd - ZOD, 10/5/02. Targeting beacons only allowed in Practice mode - switchBeaconType(%searchObj); - } - else - messageClient(%obj.client, 'MsgBeaconNoSurface', '\c2Cannot place beacon. Not a valid surface.'); - return 0; - } - else if(%obj.inv[%data.getName()] <= 0) - return 0; - } - // newly deployed beacons default to "target" type. - if($TeamDeployedCount[%obj.team, %newBeacType] >= $TeamDeployableMax[%newBeacType]) // z0dd - ZOD, 10/5/02. Targeting beacons only allowed in Practice mode - { - messageClient(%obj.client, 'MsgDeployFailed', '\c2Your team\'s control network has reached its capacity for this item.~wfx/misc/misc.error.wav'); - return 0; - } - %terrPt = posFromRaycast(%searchResult); - %terrNrm = normalFromRaycast(%searchResult); - - %intAngle = getTerrainAngle(%terrNrm); // getTerrainAngle() function found in staticShape.cs - %rotAxis = vectorNormalize(vectorCross(%terrNrm, "0 0 1")); - if (getWord(%terrNrm, 2) == 1 || getWord(%terrNrm, 2) == -1) - %rotAxis = vectorNormalize(vectorCross(%terrNrm, "0 1 0")); - %rotation = %rotAxis @ " " @ %intAngle; - - %obj.decInventory(%data, 1); - %depBeac = new BeaconObject() { - dataBlock = "DeployedBeacon"; - position = VectorAdd(%terrPt, VectorScale(%terrNrm, 0.05)); - rotation = %rotation; - }; - - // -------------------------------------------------------------------- - // z0dd - ZOD, 10/5/02. Targeting beacons only allowed in Practice mode - if (!%allowTargBeac) - { - %depBeac.setBeaconType(friend); - } - $TeamDeployedCount[%obj.team, %newBeacType]++; - // -------------------------------------------------------------------- - - %depBeac.playThread($AmbientThread, "ambient"); - %depBeac.team = %obj.team; - %depBeac.sourceObject = %obj; - - // give it a team target - %depBeac.setTarget(%depBeac.team); - MissionCleanup.add(%depBeac); -} - -function switchBeaconType(%beacon) -{ - if(%beacon.getBeaconType() $= "friend") - { - // switch from marker beacon to target beacon - if($TeamDeployedCount[%beacon.team, TargetBeacon] >= $TeamDeployableMax[TargetBeacon]) - { - messageClient(%beacon.sourceObject.client, 'MsgDeployFailed', '\c2Your team\'s control network has reached its capacity for this item.~wfx/misc/misc.error.wav'); - return 0; - } - %beacon.setBeaconType(enemy); - $TeamDeployedCount[%beacon.team, MarkerBeacon]--; - $TeamDeployedCount[%beacon.team, TargetBeacon]++; - } - else - { - // switch from target beacon to marker beacon - if($TeamDeployedCount[%beacon.team, MarkerBeacon] >= $TeamDeployableMax[MarkerBeacon]) - { - messageClient(%beacon.sourceObject.client, 'MsgDeployFailed', '\c2Your team\'s control network has reached its capacity for this item.~wfx/misc/misc.error.wav'); - return 0; - } - %beacon.setBeaconType(friend); - $TeamDeployedCount[%beacon.team, TargetBeacon]--; - $TeamDeployedCount[%beacon.team, MarkerBeacon]++; - } -} +//---------------------------------------------------------------------------- + +// When first mounted (assuming there is ammo): +// SingleShot activate -> ready +// Spinning activate -> idle (spin 0) +// Sustained activate -> ready +// DiscLauncher activate -> reload -> spinup -> ready +// +// Normal operation: +// SingleShot ready -> fire -> reload -> ready +// Spinning idle (spin 0) -> spinup -> ready -> fire -> spindown -> idle +// Sustained ready -> fire -> reload -> ready +// DiscLauncher ready -> fire -> reload -> spinup -> ready + +// Image properties +// emap +// preload +// shapeFile +// mountPoint +// offset +// rotation +// firstPerson +// mass +// usesEnergy +// minEnergy +// accuFire +// lightType +// lightTime +// lightRadius +// lightColor + +// Image state variables +// stateName +// stateTransitionOnLoaded +// stateTransitionOnNotLoaded +// stateTransitionOnAmmo +// stateTransitionOnNoAmmo +// stateTransitionOnTriggerUp +// stateTransitionOnTriggerDown +// stateTransitionOnTimeout +// stateTimeoutValue +// stateFire +// stateEnergyDrain +// stateAllowImageChange +// stateScaleAnimation +// stateDirection +// stateLoadedFlag +// stateSpinThread +// stateRecoil +// stateSequence +// stateSound +// stateScript +// stateEmitter +// stateEmitterTime +// stateEmitterNode + +//---------------------------------------------------------------------------- + +$ItemRespawnTime = 30000; +$ItemPopTime = 30 * 1000; // 30 seconds + +$WeaponSlot = 0; +$AuxiliarySlot = 1; +$BackpackSlot = 2; +$FlagSlot = 3; + +//---------------------------------------------------------------------------- +datablock EffectProfile(ItemPickupEffect) +{ + effectname = "packs/packs.pickupPack"; + minDistance = 2.5; +}; + +datablock AudioProfile(ItemPickupSound) +{ + filename = "fx/packs/packs.pickuppack.wav"; + description = AudioClosest3d; + effect = ItemPickupEffect; + preload = true; +}; + +datablock EffectProfile(ItemThrowEffect) +{ + effectname = "packs/packs.throwpack"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock AudioProfile(ItemThrowSound) +{ + filename = "fx/packs/packs.throwpack.wav"; + description = AudioClosest3d; + effect = ItemThrowEffect; + preload = true; +}; + +datablock AudioProfile(RepairPatchSound) +{ + filename = "fx/misc/health_patch.wav"; + description = AudioClosest3d; + preload = true; + effect = ItemPickupEffect; + preload = true; +}; + +function ItemData::create(%block) +{ + if(%block $= "flag") + %obj = new Item() { + className = FlagObj; + dataBlock = %block; + static = false; + rotate = false; + }; + else + %obj = new Item() { + dataBlock = %block; + static = true; + //rotate = true; + // don't make "placed items" rotate + rotate = false; + }; + return(%obj); +} + +//-------------------------------------------------------------------------- +function Item::schedulePop(%this) +{ + %itemFadeTime = 1000; // items will take 1 second (1000 milliseconds) to fade out + %this.startFade(%itemFadeTime, $ItemPopTime - %itemFadeTime, true); + %this.schedule($ItemPopTime, "delete"); +} + +function Item::respawn(%this) +{ + %this.startFade(0, 0, true); + %this.schedule($ItemRespawnTime + 100, "startFade", 1000, 0, false); + %this.hide(true); + %this.schedule($ItemRespawnTime, "hide", false); +} + +function ItemData::onThrow(%data,%obj,%shape) +{ + serverPlay3D(ItemThrowSound, %obj.getTransform()); + // don't schedule a delete for satchelCharges when they're deployed + if(!%data.noTimeout) + %obj.schedulePop(); +} + +function ItemData::onInventory(%data,%shape,%value) +{ + if (!%value) { + // If we don't have any more of these items, make sure + // we don't have an image mounted. + %slot = %shape.getMountSlot(%data.image); + if (%slot != -1) + %shape.unmountImage(%slot); + } +} + +function ItemData::onEnterLiquid(%data, %obj, %coverage, %type) +{ + if(%data.isInvincible) + return; + + switch(%type) + { + case 0: + //Water + case 1: + //Ocean Water + case 2: + //River Water + case 3: + //Stagnant Water + case 4: + //Lava + %obj.delete(); + case 5: + //Hot Lava + %obj.delete(); + case 6: + //Crusty Lava + %obj.delete(); + case 7: + //Quick Sand + } +} + +function ItemData::onLeaveLiquid(%data, %obj, %type) +{ + // dummy +} + +function ItemData::onCollision(%data,%obj,%col) +{ + // Default behavior for items is to get picked + // by the colliding object. + if (%col.getDataBlock().className $= Armor && %col.getState() !$= "Dead") + { + if (%col.isMounted()) + return; + + if (%col.pickup(%obj, 1)) + { + if (%col.client) + { + messageClient(%col.client, 'MsgItemPickup', '\c0You picked up %1.', %data.pickUpName); + serverPlay3D(ItemPickupSound, %col.getTransform()); + } + if (%obj.isStatic()) + %obj.respawn(); + else + %obj.delete(); + } + } +} + +//---------------------------------------------------------------------------- +datablock ItemData(RepairKit) +{ + className = HandInventory; + catagory = "Misc"; + shapeFile = "repair_kit.dts"; + mass = 1; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 2.0; + pickUpName = "a repair kit"; + alwaysAmbient = true; + + computeCRC = true; + emap = true; + +}; + +function RepairKit::onUse(%data,%obj) +{ + //---------------------------------------------------------------------------- + // z0dd - ZOD, 8/10/02. Let players use repair kit regardless of health status + // if they choose so via client $pref:: + if (%obj.client.wasteRepKit == 1) + { + %obj.decInventory(%data,1); + messageClient(%obj.client, 'MsgRepairKitUsed', '\c2Repair Kit Used.'); + if (%obj.getDamageLevel() != 0) + { + %obj.applyRepair(0.2); + } + } + else + { + // Don't use the kit unless we're damaged + if (%obj.getDamageLevel() != 0) + { + %obj.applyRepair(0.2); + %obj.decInventory(%data,1); + messageClient(%obj.client, 'MsgRepairKitUsed', '\c2Repair Kit Used.'); + } + } +} + +function serverCmdSetRepairKitWaste(%client, %value) +{ + %val = deTag(%value); + %client.wasteRepKit = %val; +} + +//---------------------------------------------------------------------------- + +datablock ItemData(RepairPatch) +{ + catagory = "Misc"; + shapeFile = "repair_patch.dts"; + mass = 1; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 2.0; + pickUpName = "a repair patch"; + alwaysAmbient = true; + + computeCRC = true; + emap = true; + +}; + +function RepairPatch::onCollision(%data,%obj,%col) +{ + if ( %col.getDataBlock().className $= Armor + && %col.getDamageLevel() != 0 + && %col.getState() !$= "Dead" ) + { + if (%col.isMounted()) + return; + + %col.playAudio(0, RepairPatchSound); + %col.applyRepair(0.125); + %obj.respawn(); + if (%col.client > 0) + messageClient(%col.client, 'MsgItemPickup', '\c0You picked up %1.', %data.pickUpName); + } +} + +//---------------------------------------------------------------------------- +// Flag: +//---------------------------------------------------------------------------- +datablock ShapeBaseImageData(FlagImage) +{ + shapeFile = "flag.dts"; + item = Flag; + mountPoint = 2; + offset = "0 0 0"; + + lightType = "PulsingLight"; + lightColor = "0.5 0.5 0.5 1.0"; + lightTime = "1000"; + lightRadius = "3"; + cloakable = false; +}; + +datablock ItemData(Flag) +{ + catagory = "Objectives"; + shapefile = "flag.dts"; + mass = 80; // z0dd - ZOD, 3/27/02. Keep flag from flying all over when damaged. was 55. + elasticity = 0.2; + friction = 0.6; + pickupRadius = 4.0; // z0dd - ZOD, 8/11/02. Was 3 + pickUpName = "a flag"; + computeCRC = true; + + lightType = "PulsingLight"; + lightColor = "0.5 0.5 0.5 1.0"; + lightTime = "1000"; + lightRadius = "3"; + + isInvincible = true; + cmdCategory = "Objectives"; + cmdIcon = CMDFlagIcon; + cmdMiniIconName = "commander/MiniIcons/com_flag_grey"; + targetTypeTag = 'Flag'; + + //used in CTF to mark the flag during a stalemate... + hudImageNameFriendly[1] = "commander/MiniIcons/com_flag_grey"; + hudImageNameEnemy[1] = "commander/MiniIcons/com_flag_grey"; + hudRenderModulated[1] = true; + hudRenderAlways[1] = true; + hudRenderCenter[1] = true; + hudRenderDistance[1] = true; + hudRenderName[1] = true; +}; + +//---------------------------------------------------------------------------- +function Flag::onThrow(%data,%obj,%src) +{ + Game.playerDroppedFlag(%src); +} + +function Flag::onAdd(%this, %obj) +{ + // make sure flags play "flapping" ambient thread + Parent::onAdd(%this, %obj); + %obj.playThread($AmbientThread, "ambient"); + + %blocker = new VehicleBlocker() + { + position = %obj.position; + rotation = %obj.rotation; + dimensions = "2 2 4"; + }; + MissionCleanup.add(%blocker); +} + +function Flag::onCollision(%data,%obj,%col) +{ + if (%col.getDataBlock().className $= Armor) + { + if (%col.isMounted()) + return; + + // z0dd - ZOD, 6/13/02. Touch the flag and your invincibility and cloaking goes away. + if(%col.station $= "" && %col.isCloaked()) + { + if( %col.respawnCloakThread !$= "" ) + { + Cancel(%col.respawnCloakThread); + %col.setCloaked( false ); + %col.respawnCloakThread = ""; + } + } + if( %col.client > 0 ) + { + %col.setInvincibleMode(0, 0.00); + %col.setInvincible( false ); + } + + // a player hit the flag + Game.playerTouchFlag(%col, %obj); + } +} + +//---------------------------------------------------------------------------- +// HuntersFlag: +//---------------------------------------------------------------------------- +datablock ShapeBaseImageData(HuntersFlagImage) +{ + shapeFile = "Huntersflag.dts"; + item = Flag; + mountPoint = 2; + offset = "0 0 0"; + + lightType = "PulsingLight"; + lightColor = "0.5 0.5 0.5 1.0"; + lightTime = "1000"; + lightRadius = "3"; +}; + +// 1: red +// 2: blue +// 4: yellow +// 8: green +datablock ItemData(HuntersFlag1) +{ + className = HuntersFlag; + + shapefile = "Huntersflag.dts"; + mass = 80; // z0dd - ZOD, 3/27/02. Keep flag from flying all over when damaged. was 55. + elasticity = 0.2; + friction = 0.6; + pickupRadius = 4.0; // z0dd - ZOD, 8/11/02. Was 3 + isInvincible = true; + pickUpName = "a flag"; + computeCRC = true; + + lightType = "PulsingLight"; + lightColor = "0.8 0.2 0.2 1.0"; + lightTime = "1000"; + lightRadius = "3"; +}; + +datablock ItemData(HuntersFlag2) : HuntersFlag1 +{ + lightColor = "0.2 0.2 0.8 1.0"; +}; + +datablock ItemData(HuntersFlag4) : HuntersFlag1 +{ + lightColor = "0.8 0.8 0.2 1.0"; +}; + +datablock ItemData(HuntersFlag8) : HuntersFlag1 +{ + lightColor = "0.2 0.8 0.2 1.0"; +}; + +function HuntersFlag::onRemove(%data, %obj) +{ + // dont want target removed... +} + +function HuntersFlag::onThrow(%data,%obj,%src) +{ + Game.playerDroppedFlag(%src); +} + +function HuntersFlag::onCollision(%data,%obj,%col) +{ + if (%col.getDataBlock().className $= Armor) + { + if (%col.isMounted()) + return; + + // a player hit the flag + Game.playerTouchFlag(%col, %obj); + } +} + +//---------------------------------------------------------------------------- +// Nexus: +//---------------------------------------------------------------------------- +datablock ItemData(Nexus) +{ + catagory = "Objectives"; + shapefile = "nexus_effect.dts"; + mass = 10; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 2; + icon = "CMDNexusIcon"; + targetTypeTag = 'Nexus'; + + computeCRC = true; + +}; + +datablock ParticleData(NexusParticleDenied) +{ + dragCoeffiecient = 0.4; + gravityCoefficient = 3.0; + inheritedVelFactor = 0.0; + + lifetimeMS = 1200; + lifetimeVarianceMS = 400; + + textureName = "particleTest"; + + useInvAlpha = false; + spinRandomMin = -200.0; + spinRandomMax = 200.0; + + colors[0] = "0.3 0.0 0.0 1.0"; + colors[1] = "0.5 0.0 0.0 0.5"; + colors[2] = "0.7 0.0 0.0 0.0"; + sizes[0] = 0.2; + sizes[1] = 0.1; + sizes[2] = 0.0; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; +}; + +datablock ParticleEmitterData(NexusParticleDeniedEmitter) +{ + ejectionPeriodMS = 2; + ejectionOffset = 0.2; + periodVarianceMS = 0.5; + ejectionVelocity = 10.0; + velocityVariance = 4.0; + thetaMin = 0.0; + thetaMax = 30.0; + lifetimeMS = 0; + + particles = "NexusParticleDenied"; +}; + +datablock ParticleData(NexusParticleCap) +{ + dragCoeffiecient = 0.4; + gravityCoefficient = 3.0; + inheritedVelFactor = 0.0; + + lifetimeMS = 1200; + lifetimeVarianceMS = 400; + + textureName = "particleTest"; + + useInvAlpha = false; + spinRandomMin = -200.0; + spinRandomMax = 200.0; + + colors[0] = "0.5 0.8 0.2 1.0"; + colors[1] = "0.6 0.9 0.3 1.0"; + colors[2] = "0.7 1.0 0.4 1.0"; + sizes[0] = 0.2; + sizes[1] = 0.1; + sizes[2] = 0.0; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; +}; + +datablock ParticleEmitterData(NexusParticleCapEmitter) +{ + ejectionPeriodMS = 2; + ejectionOffset = 0.5; + periodVarianceMS = 0.5; + ejectionVelocity = 10.0; + velocityVariance = 4.0; + thetaMin = 0.0; + thetaMax = 30.0; + lifetimeMS = 0; + + particles = "NexusParticleCap"; +}; + +//---------------------------------------------------------------------------- + +function getVector(%string, %num) +{ + %start = %num * 3; + return getWords(%string,%start, %start + 2); +} + +// -------------------------------------------- +// explosion datablock +// -------------------------------------------- + +datablock ExplosionData(DeployablesExplosion) +{ + soundProfile = DeployablesExplosionSound; + faceViewer = true; + + explosionShape = "effect_plasma_explosion.dts"; + sizes[0] = "0.2 0.2 0.2"; + sizes[1] = "0.3 0.3 0.3"; +}; + +$TeamDeployableMax[TargetBeacon] = 10; +$TeamDeployableMax[MarkerBeacon] = 20; + +datablock ItemData(Beacon) +{ + className = HandInventory; + catagory = "Misc"; + shapeFile = "beacon.dts"; + mass = 1; + elasticity = 0.2; + friction = 0.8; + pickupRadius = 1; + pickUpName = "a deployable beacon"; + + computeCRC = true; + +}; + +datablock StaticShapeData(DeployedBeacon) : StaticShapeDamageProfile +{ + shapeFile = "beacon.dts"; + explosion = DeployablesExplosion; + maxDamage = 0.45; + disabledLevel = 0.45; + destroyedLevel = 0.45; + targetNameTag = 'beacon'; + + deployedObject = true; + + dynamicType = $TypeMasks::SensorObjectType; + + debrisShapeName = "debris_generic_small.dts"; + debris = SmallShapeDebris; +}; + +function DeployedBeacon::onDestroyed(%data, %obj, %prevState) +{ + if(%obj.getBeaconType() $= "friend") + %bType = "MarkerBeacon"; + else + %bType = "TargetBeacon"; + $TeamDeployedCount[%obj.team, %bType]--; + %obj.schedule(500, delete); +} + +function Beacon::onUse(%data, %obj) +{ + // look for 3 meters along player's viewpoint for interior or terrain + %searchRange = 3.0; + %mask = $TypeMasks::TerrainObjectType | $TypeMasks::InteriorObjectType | $TypeMasks::StaticShapeObjectType | $TypeMasks::ForceFieldObjectType; + // get the eye vector and eye transform of the player + %eyeVec = %obj.getEyeVector(); + %eyeTrans = %obj.getEyeTransform(); + // extract the position of the player's camera from the eye transform (first 3 words) + %eyePos = posFromTransform(%eyeTrans); + // normalize the eye vector + %nEyeVec = VectorNormalize(%eyeVec); + // scale (lengthen) the normalized eye vector according to the search range + %scEyeVec = VectorScale(%nEyeVec, %searchRange); + // 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, 0); + + %allowTargBeac = (Game.class $= "PracticeCTFGame"); // z0dd - ZOD, 10/5/02. Targeting beacons only allowed in Practice mode + %newBeacType = (%allowTargBeac ? TargetBeacon : MarkerBeacon); + + if(!%searchResult ) + { + // no terrain/interior collision within search range + if(%obj.inv[%data.getName()] > 0) + messageClient(%obj.client, 'MsgBeaconNoSurface', '\c2Cannot place beacon. Too far from surface.'); + return 0; + } + else + { + %searchObj = GetWord(%searchResult, 0); + if(%searchObj.getType() & ($TypeMasks::StaticShapeObjectType | $TypeMasks::ForceFieldObjectType) ) + { + // if there's already a beacon where player is aiming, switch its type + // otherwise, player can't deploy a beacon there + if((%searchObj.getDataBlock().getName() $= DeployedBeacon)) + { + if(%allowTargBeac) // z0dd - ZOD, 10/5/02. Targeting beacons only allowed in Practice mode + switchBeaconType(%searchObj); + } + else + messageClient(%obj.client, 'MsgBeaconNoSurface', '\c2Cannot place beacon. Not a valid surface.'); + return 0; + } + else if(%obj.inv[%data.getName()] <= 0) + return 0; + } + // newly deployed beacons default to "target" type. + if($TeamDeployedCount[%obj.team, %newBeacType] >= $TeamDeployableMax[%newBeacType]) // z0dd - ZOD, 10/5/02. Targeting beacons only allowed in Practice mode + { + messageClient(%obj.client, 'MsgDeployFailed', '\c2Your team\'s control network has reached its capacity for this item.~wfx/misc/misc.error.wav'); + return 0; + } + %terrPt = posFromRaycast(%searchResult); + %terrNrm = normalFromRaycast(%searchResult); + + %intAngle = getTerrainAngle(%terrNrm); // getTerrainAngle() function found in staticShape.cs + %rotAxis = vectorNormalize(vectorCross(%terrNrm, "0 0 1")); + if (getWord(%terrNrm, 2) == 1 || getWord(%terrNrm, 2) == -1) + %rotAxis = vectorNormalize(vectorCross(%terrNrm, "0 1 0")); + %rotation = %rotAxis @ " " @ %intAngle; + + %obj.decInventory(%data, 1); + %depBeac = new BeaconObject() { + dataBlock = "DeployedBeacon"; + position = VectorAdd(%terrPt, VectorScale(%terrNrm, 0.05)); + rotation = %rotation; + }; + + // -------------------------------------------------------------------- + // z0dd - ZOD, 10/5/02. Targeting beacons only allowed in Practice mode + if (!%allowTargBeac) + { + %depBeac.setBeaconType(friend); + } + $TeamDeployedCount[%obj.team, %newBeacType]++; + // -------------------------------------------------------------------- + + %depBeac.playThread($AmbientThread, "ambient"); + %depBeac.team = %obj.team; + %depBeac.sourceObject = %obj; + + // give it a team target + %depBeac.setTarget(%depBeac.team); + MissionCleanup.add(%depBeac); +} + +function switchBeaconType(%beacon) +{ + if(%beacon.getBeaconType() $= "friend") + { + // switch from marker beacon to target beacon + if($TeamDeployedCount[%beacon.team, TargetBeacon] >= $TeamDeployableMax[TargetBeacon]) + { + messageClient(%beacon.sourceObject.client, 'MsgDeployFailed', '\c2Your team\'s control network has reached its capacity for this item.~wfx/misc/misc.error.wav'); + return 0; + } + %beacon.setBeaconType(enemy); + $TeamDeployedCount[%beacon.team, MarkerBeacon]--; + $TeamDeployedCount[%beacon.team, TargetBeacon]++; + } + else + { + // switch from target beacon to marker beacon + if($TeamDeployedCount[%beacon.team, MarkerBeacon] >= $TeamDeployableMax[MarkerBeacon]) + { + messageClient(%beacon.sourceObject.client, 'MsgDeployFailed', '\c2Your team\'s control network has reached its capacity for this item.~wfx/misc/misc.error.wav'); + return 0; + } + %beacon.setBeaconType(friend); + $TeamDeployedCount[%beacon.team, TargetBeacon]--; + $TeamDeployedCount[%beacon.team, MarkerBeacon]++; + } +} diff --git a/scripts/loadingGui.cs b/scripts/loadingGui.cs index 651e799..ef1c365 100644 --- a/scripts/loadingGui.cs +++ b/scripts/loadingGui.cs @@ -1,447 +1,447 @@ -//------------------------------------------------------------------------------ -// -// LoadingGui.cs -// -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -function LoadingGui::onAdd(%this) -{ - %this.qLineCount = 0; -} - -//------------------------------------------------------------------------------ -function LoadingGui::onWake(%this) -{ - if ( $HudHandle[shellScreen] !$= "" ) - { - alxStop($HudHandle[shellScreen]); - $HudHandle[shellScreen] = ""; - } - $HudHandle[loadingScreen] = alxPlay(LoadingScreenSound, 0, 0, 0); - - CloseMessagePopup(); -} - -//------------------------------------------------------------------------------ -function LoadingGui::onSleep(%this) -{ - // Clear the load info: - if ( %this.qLineCount !$= "" ) - { - for ( %line = 0; %line < %this.qLineCount; %line++ ) - %this.qLine[%line] = ""; - } - %this.qLineCount = 0; - - LOAD_MapPic.setBitmap( "gui/Loading" ); - LOAD_MapName.setText( "" ); - LOAD_MapText.setText( "" ); - LOAD_MissionType.setText( "" ); - LOAD_GameText.setText( "" ); - LoadingProgress.setValue( 0 ); - - alxStop($HudHandle[loadingScreen]); -} - -//------------------------------------------------------------------------------ -function clearLoadInfo() -{ - for ( %line = 0; %line < $LoadQuoteLineCount; %line++ ) - $LoadQuoteLine[%line] = ""; - $LoadQuoteLineCount = 0; - - for ( %line = 0; %line < $LoadObjLineCount; %line++ ) - $LoadObjLine[%line] = ""; - $LoadObjLineCount = 0; - - for ( %line = 0; %line < $LoadRuleLineCount; %line++ ) - $LoadRuleLine[%line] = ""; - $LoadRuleLineCount = 0; -} - -//------------------------------------------------------------------------------ -function buildLoadInfo( %mission, %missionType ) -{ - clearLoadInfo(); - $CurrentMission = %mission; - $MissionDisplayName = %mission; - $MissionTypeDisplayName = %missionType; - - // Extract the map quote and objectives from the .mis file: - %mapFile = "missions/" @ %mission @ ".mis"; - %file = new FileObject(); - if ( %file.openForRead( %mapFile ) ) - { - %state = "none"; - while ( !%file.isEOF() ) - { - %line = %file.readLine(); - - if ( %state $= "none" ) - { - if ( getSubStr( %line, 0, 17 ) $= "// DisplayName = " ) - $MissionDisplayName = getSubStr( %line, 17, 1000 ); - else if ( %line $= "//--- MISSION QUOTE BEGIN ---" ) - %state = "quote"; - else if ( %line $= "//--- MISSION STRING BEGIN ---" ) - %state = "objectives"; - else if ( %missionType $= "SinglePlayer" ) - { - if ( getSubStr( %line, 0, 16 ) $= "// PlanetName = " ) - $MissionTypeDisplayName = getSubStr( %line, 16, 1000 ); - else if ( %line $= "//--- MISSION BLURB BEGIN ---" ) - %state = "blurb"; - } - } - else if ( %state $= "quote" ) - { - if ( %line $= "//--- MISSION QUOTE END ---" ) - %state = "none"; - else - { - $LoadQuoteLine[$LoadQuoteLineCount] = getSubStr( %line, 2, 1000 ); - $LoadQuoteLineCount++; - } - } - else if ( %state $= "objectives" ) - { - if ( %line $= "//--- MISSION STRING END ---" ) - { - if ( %missionType $= "SinglePlayer" ) - %state = "none"; - else - { - // Once we've got the end of the mission string, we are through. - %state = "done"; - break; - } - } - else - { - %pos = strstr( %line, "]" ); - if ( %pos == -1 ) - { - $LoadObjLine[$LoadObjLineCount] = getSubStr( %line, 2, 1000 ); - $LoadObjLineCount++; - } - else if ( %pos > 3 ) - { - // Filter objective lines by mission type: - %typeList = getSubStr( %line, 3, %pos - 3 ); - // ------------------------------------------------------------------------ - // z0dd - ZOD, 5/15/02. Add practice gametype so we get objectives printed. - if(%typeList $= "CTF") - %typeList = rtrim(%typeList) @ " PracticeCTF"; - // ------------------------------------------------------------------------ - if ( strstr( %typeList, %missionType ) != -1 ) - { - $LoadObjLine[$LoadObjLineCount] = getSubStr( %line, %pos + 1, 1000 ); - $LoadObjLineCount++; - } - } - else - error( "Invalid mission objective line - \"" @ %line @ "\"" ); - } - } - else if ( %state $= "blurb" ) - { - if ( %line $= "//--- MISSION BLURB END ---" ) - { - %state = "done"; - break; - } - else - { - $LoadRuleLine[$LoadRuleLineCount] = getSubStr( %line, 2, 1000 ); - $LoadRuleLineCount++; - } - } - } - %file.close(); - } - - // Extract the rules of engagement from the Game.cs file: - if ( %missionType !$= "SinglePlayer" ) - { - %gameFile = "scripts/" @ %missionType @ "Game.cs"; - if ( %file.openForRead( %gameFile ) ) - { - %state = "none"; - while ( !%file.isEOF() ) - { - %line = %file.readLine(); - if ( %state $= "none" ) - { - if ( getSubStr( %line, 0, 17 ) $= "// DisplayName = " ) - $MissionTypeDisplayName = getSubStr( %line, 17, 1000 ); - if ( %line $= "//--- GAME RULES BEGIN ---" ) - %state = "rules"; - } - else if ( %state $= "rules" ) - { - if ( %line $= "//--- GAME RULES END ---" ) - { - %state = "done"; - break; - } - else - { - $LoadRuleLine[$LoadRuleLineCount] = getSubStr( %line, 2, 1000 ); - $LoadRuleLineCount++; - } - } - } - %file.close(); - } - } - - %file.delete(); -} - -//------------------------------------------------------------------------------ -function dumpLoadInfo() -{ - echo( "Mission = \"" @ $MissionDisplayName @ "\", Mission Type = \"" @ $MissionTypeDisplayName @ "\"" ); - echo( "MISSION QUOTE: ( " @ $LoadQuoteLineCount @ " lines )" ); - for ( %line = 0; %line < $LoadQuoteLineCount; %line++ ) - echo( $LoadQuoteLine[%line] ); - - echo( " " ); - - echo( "MISSION STRING: ( " @ $LoadObjLineCount @ " lines )" ); - for ( %line = 0; %line < $LoadObjLineCount; %line++ ) - echo( $LoadObjLine[%line] ); - - echo( " " ); - - echo( "GAME RULES: ( " @ $LoadRuleLineCount @ " lines )" ); - for ( %line = 0; %line < $LoadRuleLineCount; %line++ ) - echo( $LoadRuleLine[%line] ); -} - -//------------------------------------------------------------------------------ -// z0dd - ZOD, 5/12/02. Added another varible so we can send this twice -function sendLoadInfoToClient( %client, %second ) -{ - //error( "** SENDING LOAD INFO TO CLIENT " @ %client @ "! **" ); - %singlePlayer = $CurrentMissionType $= "SinglePlayer"; - messageClient( %client, 'MsgLoadInfo', "", $CurrentMission, $MissionDisplayName, $MissionTypeDisplayName ); - - // Send map quote: - for ( %line = 0; %line < $LoadQuoteLineCount; %line++ ) - { - if ( $LoadQuoteLine[%line] !$= "" ) - messageClient( %client, 'MsgLoadQuoteLine', "", $LoadQuoteLine[%line] ); - } - - // Send map objectives: - if ( %singlePlayer ) - { - switch ( $pref::TrainingDifficulty ) - { - case 2: %diff = "Medium"; - case 3: %diff = "Hard"; - default: %diff = "Easy"; - } - messageClient( %client, 'MsgLoadObjectiveLine', "", "DIFFICULTY: " @ %diff ); - } - - for ( %line = 0; %line < $LoadObjLineCount; %line++ ) - { - if ( $LoadObjLine[%line] !$= "" ) - messageClient( %client, 'MsgLoadObjectiveLine', "", $LoadObjLine[%line], !%singlePlayer ); - } - - // Send rules of engagement: - if ( !%singlePlayer ) - messageClient( %client, 'MsgLoadRulesLine', "", "RULES OF ENGAGEMENT:", false ); - - for ( %line = 0; %line < $LoadRuleLineCount; %line++ ) - { - if ( $LoadRuleLine[%line] !$= "" ) - messageClient( %client, 'MsgLoadRulesLine', "", $LoadRuleLine[%line], !%singlePlayer ); - } - - messageClient( %client, 'MsgLoadInfoDone' ); - - // ---------------------------------------------------------------------------------------------- - // z0dd - ZOD, 5/12/02. Send the mod info screen if this isn't the second showing of mission info - if(!%second) - schedule(6000, 0, "sendModInfoToClient", %client); - // ---------------------------------------------------------------------------------------------- -} - -function sendModInfoToClient(%client) //Kinda Jacked Classic's loadScreen here.. but it is generally not used -{ - %on = "On"; - %off = "Off"; - %line[0] = "Game Type: " @ $CurrentMissionType; - %modName = "T2Bol" SPC $ModVersionText @ ""; - %ModCnt = 1; - %ModLine[0] = "Developers: DarkDragonDX"; - - %SpecialCnt = 3; - %SpecialTextLine[0] = "Map:" SPC $CurrentMission; - %SpecialTextLine[1] = "Game Type:" SPC $CurrentMissionType; - - if ($Host::BotsEnabled) - %SpecialTextLine[2] = "Bot Count:" SPC $HostGameBotCount; - - %ServerCnt = 1; - %ServerTextLine[0] = ""; - %ServerTextLine[1] = ""; - - %singlePlayer = $CurrentMissionType $= "SinglePlayer"; - messageClient( %client, 'MsgLoadInfo', "", $CurrentMission, %modName, $Host::GameName ); - - // Send mod details (non bulleted list, small text): - for(%line = 0; %line < %ModCnt; %line++) - { - if(%ModLine[%line] !$= "") - messageClient(%client, 'MsgLoadQuoteLine', "", %ModLine[%line]); - } - - // Send mod special settings (bulleted list, large text): - for (%line = 0; %line < %SpecialCnt; %line++) - { - if(%SpecialTextLine[%line] !$= "") - messageClient( %client, 'MsgLoadObjectiveLine', "", %SpecialTextLine[%line], !%singlePlayer); - } - - // Send server info: - if ( !%singlePlayer ) - messageClient( %client, 'MsgLoadRulesLine', "", "" @ $Host::Info, false ); - - for(%line = 0; %line < %ServerCnt; %line++) - { - if (%ServerTextLine[%line] !$= "") - messageClient(%client, 'MsgLoadRulesLine', "", %ServerTextLine[%line], !%singlePlayer); - } - messageClient(%client, 'MsgLoadInfoDone'); - // z0dd - ZOD, 5/12/02. Send mission info again so as not to conflict with cs scripts. - schedule(7000, 0, "sendLoadInfoToClient", %client, true); -} - -//------------------------------------------------------------------------------ -addMessageCallback( 'MsgLoadInfo', handleLoadInfoMessage ); -addMessageCallback( 'MsgLoadQuoteLine', handleLoadQuoteLineMessage ); -addMessageCallback( 'MsgLoadObjectiveLine', handleLoadObjectiveLineMessage ); -addMessageCallback( 'MsgLoadRulesLine', handleLoadRulesLineMessage ); -addMessageCallback( 'MsgLoadInfoDone', handleLoadInfoDoneMessage ); - -//------------------------------------------------------------------------------ -function handleLoadInfoMessage( %msgType, %msgString, %bitmapName, %mapName, %missionType ) -{ - // Clear all of the loading info lines: - for ( %line = 0; %line < LoadingGui.qLineCount; %line++ ) - LoadingGui.qLine[%line] = ""; - LoadingGui.qLineCount = 0; - - for ( %line = 0; %line < LobbyGui.objLineCount; %line++ ) - LobbyGui.objLine[%line] = ""; - LobbyGui.objLineCount = 0; - - // --------------------------------------------------- - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - %loadBmp = "gui/load_" @ %bitmapName @ ".png"; - // --------------------------------------------------- - - if ( !isFile( "textures/" @ %loadBmp ) ) - %loadBmp = "gui/loading"; - LOAD_MapPic.setBitmap( %loadBmp ); - LOAD_MapName.setText( %mapName ); - LOAD_MissionType.setText( %missionType ); - LOAD_MapText.setText( "" ); - LOAD_GameText.setText( "" ); -} - -//------------------------------------------------------------------------------ -function handleLoadQuoteLineMessage( %msgType, %msgString, %line ) -{ - LoadingGui.qLine[LoadingGui.qLineCount] = %line; - LoadingGui.qLineCount++; - - %text = ""; - for ( %line = 0; %line < LoadingGui.qLineCount - 1; %line++ ) - %text = %text @ LoadingGui.qLine[%line] @ "\n"; - %text = %text @ ""; - %text = %text @ LoadingGui.qLine[%line] @ "\n"; // tag line - - LOAD_MapText.setText( %text ); -} - -//------------------------------------------------------------------------------ -function handleLoadObjectiveLineMessage( %msgType, %msgString, %line, %bulletStyle ) -{ - LobbyGui.objLine[LobbyGui.objLineCount] = %line; - LobbyGui.objLineCount++; - - if ( %bulletStyle ) - %line = "" @ %line @ ""; - - %newText = LOAD_MapText.getText(); - if ( %newText $= "" ) // In case there's no quote - %newText = %line; - else - %newText = %newText NL %line; - LOAD_MapText.setText( %newText ); -} - -//------------------------------------------------------------------------------ -function handleLoadRulesLineMessage( %msgType, %msgString, %line, %bulletStyle ) -{ - if ( %bulletStyle ) - %line = "" @ %line @ ""; - - %newText = LOAD_GameText.getText(); - if ( %newText $= "" ) - %newText = %line; - else - %newText = %newText NL %line; - LOAD_GameText.setText( %newText ); -} - -//------------------------------------------------------------------------------ -function handleLoadInfoDoneMessage( %msgType, %msgString ) -{ - LoadingGui.gotLoadInfo = true; -} - -package debriefload -{ -function debriefLoad(%client) - { - if (isObject(Game)) - %game = Game.getId(); - else - return; - - if ($HostGameType $= "SinglePlayer") - return; - - //Clear the debrief first - messageClient( %client, 'MsgClearDebrief', ""); - - messageClient( %client, 'MsgDebriefResult', "", ""@$Host::GameName@"\nTribes 2: Birth Of Legend"); - messageClient( %client, 'MsgDebriefAddLine', "", "A mod by: Dark Dragon DX (Vector)" ); - - messageClient( %client, 'MsgDebriefAddLine', "", "Hello "@%client.race@" "@%client.namebase@"."); - messageClient( %client, 'MsgDebriefAddLine', "", ""); - messageClient( %client, 'MsgDebriefAddLine', "", "You are in a Tribes 2: Birth of Legend server!"); - messageClient( %client, 'MsgDebriefAddLine', "", ""); - messageClient( %client, 'MsgDebriefAddLine', "", "Server Information:"); - messageClient( %client, 'MsgDebriefAddLine', "", "Player Count: "@$HostGamePlayerCount@""); - messageClient( %client, 'MsgDebriefAddLine', "", "Game Mode: "@$CurrentMissionType@""); - - if ($CurrentMissionType $= "RPG" && !$Data::IsRPGReady[%client.GUID]) //Make sure the client knows. - messageClient( %client, 'MsgDebriefAddLine', "", "The race/gender settings you have joined with have been saved."); - - messageClient( %client, 'MsgDebriefAddLine', "", "" ); - - //Go to the debrief gui. - messageClient( %client, 'MsgGameOver', "" ); - - } -}; -activatepackage(Debriefload); +//------------------------------------------------------------------------------ +// +// LoadingGui.cs +// +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +function LoadingGui::onAdd(%this) +{ + %this.qLineCount = 0; +} + +//------------------------------------------------------------------------------ +function LoadingGui::onWake(%this) +{ + if ( $HudHandle[shellScreen] !$= "" ) + { + alxStop($HudHandle[shellScreen]); + $HudHandle[shellScreen] = ""; + } + $HudHandle[loadingScreen] = alxPlay(LoadingScreenSound, 0, 0, 0); + + CloseMessagePopup(); +} + +//------------------------------------------------------------------------------ +function LoadingGui::onSleep(%this) +{ + // Clear the load info: + if ( %this.qLineCount !$= "" ) + { + for ( %line = 0; %line < %this.qLineCount; %line++ ) + %this.qLine[%line] = ""; + } + %this.qLineCount = 0; + + LOAD_MapPic.setBitmap( "gui/Loading" ); + LOAD_MapName.setText( "" ); + LOAD_MapText.setText( "" ); + LOAD_MissionType.setText( "" ); + LOAD_GameText.setText( "" ); + LoadingProgress.setValue( 0 ); + + alxStop($HudHandle[loadingScreen]); +} + +//------------------------------------------------------------------------------ +function clearLoadInfo() +{ + for ( %line = 0; %line < $LoadQuoteLineCount; %line++ ) + $LoadQuoteLine[%line] = ""; + $LoadQuoteLineCount = 0; + + for ( %line = 0; %line < $LoadObjLineCount; %line++ ) + $LoadObjLine[%line] = ""; + $LoadObjLineCount = 0; + + for ( %line = 0; %line < $LoadRuleLineCount; %line++ ) + $LoadRuleLine[%line] = ""; + $LoadRuleLineCount = 0; +} + +//------------------------------------------------------------------------------ +function buildLoadInfo( %mission, %missionType ) +{ + clearLoadInfo(); + $CurrentMission = %mission; + $MissionDisplayName = %mission; + $MissionTypeDisplayName = %missionType; + + // Extract the map quote and objectives from the .mis file: + %mapFile = "missions/" @ %mission @ ".mis"; + %file = new FileObject(); + if ( %file.openForRead( %mapFile ) ) + { + %state = "none"; + while ( !%file.isEOF() ) + { + %line = %file.readLine(); + + if ( %state $= "none" ) + { + if ( getSubStr( %line, 0, 17 ) $= "// DisplayName = " ) + $MissionDisplayName = getSubStr( %line, 17, 1000 ); + else if ( %line $= "//--- MISSION QUOTE BEGIN ---" ) + %state = "quote"; + else if ( %line $= "//--- MISSION STRING BEGIN ---" ) + %state = "objectives"; + else if ( %missionType $= "SinglePlayer" ) + { + if ( getSubStr( %line, 0, 16 ) $= "// PlanetName = " ) + $MissionTypeDisplayName = getSubStr( %line, 16, 1000 ); + else if ( %line $= "//--- MISSION BLURB BEGIN ---" ) + %state = "blurb"; + } + } + else if ( %state $= "quote" ) + { + if ( %line $= "//--- MISSION QUOTE END ---" ) + %state = "none"; + else + { + $LoadQuoteLine[$LoadQuoteLineCount] = getSubStr( %line, 2, 1000 ); + $LoadQuoteLineCount++; + } + } + else if ( %state $= "objectives" ) + { + if ( %line $= "//--- MISSION STRING END ---" ) + { + if ( %missionType $= "SinglePlayer" ) + %state = "none"; + else + { + // Once we've got the end of the mission string, we are through. + %state = "done"; + break; + } + } + else + { + %pos = strstr( %line, "]" ); + if ( %pos == -1 ) + { + $LoadObjLine[$LoadObjLineCount] = getSubStr( %line, 2, 1000 ); + $LoadObjLineCount++; + } + else if ( %pos > 3 ) + { + // Filter objective lines by mission type: + %typeList = getSubStr( %line, 3, %pos - 3 ); + // ------------------------------------------------------------------------ + // z0dd - ZOD, 5/15/02. Add practice gametype so we get objectives printed. + if(%typeList $= "CTF") + %typeList = rtrim(%typeList) @ " PracticeCTF"; + // ------------------------------------------------------------------------ + if ( strstr( %typeList, %missionType ) != -1 ) + { + $LoadObjLine[$LoadObjLineCount] = getSubStr( %line, %pos + 1, 1000 ); + $LoadObjLineCount++; + } + } + else + error( "Invalid mission objective line - \"" @ %line @ "\"" ); + } + } + else if ( %state $= "blurb" ) + { + if ( %line $= "//--- MISSION BLURB END ---" ) + { + %state = "done"; + break; + } + else + { + $LoadRuleLine[$LoadRuleLineCount] = getSubStr( %line, 2, 1000 ); + $LoadRuleLineCount++; + } + } + } + %file.close(); + } + + // Extract the rules of engagement from the Game.cs file: + if ( %missionType !$= "SinglePlayer" ) + { + %gameFile = "scripts/" @ %missionType @ "Game.cs"; + if ( %file.openForRead( %gameFile ) ) + { + %state = "none"; + while ( !%file.isEOF() ) + { + %line = %file.readLine(); + if ( %state $= "none" ) + { + if ( getSubStr( %line, 0, 17 ) $= "// DisplayName = " ) + $MissionTypeDisplayName = getSubStr( %line, 17, 1000 ); + if ( %line $= "//--- GAME RULES BEGIN ---" ) + %state = "rules"; + } + else if ( %state $= "rules" ) + { + if ( %line $= "//--- GAME RULES END ---" ) + { + %state = "done"; + break; + } + else + { + $LoadRuleLine[$LoadRuleLineCount] = getSubStr( %line, 2, 1000 ); + $LoadRuleLineCount++; + } + } + } + %file.close(); + } + } + + %file.delete(); +} + +//------------------------------------------------------------------------------ +function dumpLoadInfo() +{ + echo( "Mission = \"" @ $MissionDisplayName @ "\", Mission Type = \"" @ $MissionTypeDisplayName @ "\"" ); + echo( "MISSION QUOTE: ( " @ $LoadQuoteLineCount @ " lines )" ); + for ( %line = 0; %line < $LoadQuoteLineCount; %line++ ) + echo( $LoadQuoteLine[%line] ); + + echo( " " ); + + echo( "MISSION STRING: ( " @ $LoadObjLineCount @ " lines )" ); + for ( %line = 0; %line < $LoadObjLineCount; %line++ ) + echo( $LoadObjLine[%line] ); + + echo( " " ); + + echo( "GAME RULES: ( " @ $LoadRuleLineCount @ " lines )" ); + for ( %line = 0; %line < $LoadRuleLineCount; %line++ ) + echo( $LoadRuleLine[%line] ); +} + +//------------------------------------------------------------------------------ +// z0dd - ZOD, 5/12/02. Added another varible so we can send this twice +function sendLoadInfoToClient( %client, %second ) +{ + //error( "** SENDING LOAD INFO TO CLIENT " @ %client @ "! **" ); + %singlePlayer = $CurrentMissionType $= "SinglePlayer"; + messageClient( %client, 'MsgLoadInfo', "", $CurrentMission, $MissionDisplayName, $MissionTypeDisplayName ); + + // Send map quote: + for ( %line = 0; %line < $LoadQuoteLineCount; %line++ ) + { + if ( $LoadQuoteLine[%line] !$= "" ) + messageClient( %client, 'MsgLoadQuoteLine', "", $LoadQuoteLine[%line] ); + } + + // Send map objectives: + if ( %singlePlayer ) + { + switch ( $pref::TrainingDifficulty ) + { + case 2: %diff = "Medium"; + case 3: %diff = "Hard"; + default: %diff = "Easy"; + } + messageClient( %client, 'MsgLoadObjectiveLine', "", "DIFFICULTY: " @ %diff ); + } + + for ( %line = 0; %line < $LoadObjLineCount; %line++ ) + { + if ( $LoadObjLine[%line] !$= "" ) + messageClient( %client, 'MsgLoadObjectiveLine', "", $LoadObjLine[%line], !%singlePlayer ); + } + + // Send rules of engagement: + if ( !%singlePlayer ) + messageClient( %client, 'MsgLoadRulesLine', "", "RULES OF ENGAGEMENT:", false ); + + for ( %line = 0; %line < $LoadRuleLineCount; %line++ ) + { + if ( $LoadRuleLine[%line] !$= "" ) + messageClient( %client, 'MsgLoadRulesLine', "", $LoadRuleLine[%line], !%singlePlayer ); + } + + messageClient( %client, 'MsgLoadInfoDone' ); + + // ---------------------------------------------------------------------------------------------- + // z0dd - ZOD, 5/12/02. Send the mod info screen if this isn't the second showing of mission info + if(!%second) + schedule(6000, 0, "sendModInfoToClient", %client); + // ---------------------------------------------------------------------------------------------- +} + +function sendModInfoToClient(%client) //Kinda Jacked Classic's loadScreen here.. but it is generally not used +{ + %on = "On"; + %off = "Off"; + %line[0] = "Game Type: " @ $CurrentMissionType; + %modName = "T2Bol" SPC $ModVersionText @ ""; + %ModCnt = 1; + %ModLine[0] = "Developers: DarkDragonDX"; + + %SpecialCnt = 3; + %SpecialTextLine[0] = "Map:" SPC $CurrentMission; + %SpecialTextLine[1] = "Game Type:" SPC $CurrentMissionType; + + if ($Host::BotsEnabled) + %SpecialTextLine[2] = "Bot Count:" SPC $HostGameBotCount; + + %ServerCnt = 1; + %ServerTextLine[0] = ""; + %ServerTextLine[1] = ""; + + %singlePlayer = $CurrentMissionType $= "SinglePlayer"; + messageClient( %client, 'MsgLoadInfo', "", $CurrentMission, %modName, $Host::GameName ); + + // Send mod details (non bulleted list, small text): + for(%line = 0; %line < %ModCnt; %line++) + { + if(%ModLine[%line] !$= "") + messageClient(%client, 'MsgLoadQuoteLine', "", %ModLine[%line]); + } + + // Send mod special settings (bulleted list, large text): + for (%line = 0; %line < %SpecialCnt; %line++) + { + if(%SpecialTextLine[%line] !$= "") + messageClient( %client, 'MsgLoadObjectiveLine', "", %SpecialTextLine[%line], !%singlePlayer); + } + + // Send server info: + if ( !%singlePlayer ) + messageClient( %client, 'MsgLoadRulesLine', "", "" @ $Host::Info, false ); + + for(%line = 0; %line < %ServerCnt; %line++) + { + if (%ServerTextLine[%line] !$= "") + messageClient(%client, 'MsgLoadRulesLine', "", %ServerTextLine[%line], !%singlePlayer); + } + messageClient(%client, 'MsgLoadInfoDone'); + // z0dd - ZOD, 5/12/02. Send mission info again so as not to conflict with cs scripts. + schedule(7000, 0, "sendLoadInfoToClient", %client, true); +} + +//------------------------------------------------------------------------------ +addMessageCallback( 'MsgLoadInfo', handleLoadInfoMessage ); +addMessageCallback( 'MsgLoadQuoteLine', handleLoadQuoteLineMessage ); +addMessageCallback( 'MsgLoadObjectiveLine', handleLoadObjectiveLineMessage ); +addMessageCallback( 'MsgLoadRulesLine', handleLoadRulesLineMessage ); +addMessageCallback( 'MsgLoadInfoDone', handleLoadInfoDoneMessage ); + +//------------------------------------------------------------------------------ +function handleLoadInfoMessage( %msgType, %msgString, %bitmapName, %mapName, %missionType ) +{ + // Clear all of the loading info lines: + for ( %line = 0; %line < LoadingGui.qLineCount; %line++ ) + LoadingGui.qLine[%line] = ""; + LoadingGui.qLineCount = 0; + + for ( %line = 0; %line < LobbyGui.objLineCount; %line++ ) + LobbyGui.objLine[%line] = ""; + LobbyGui.objLineCount = 0; + + // --------------------------------------------------- + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + %loadBmp = "gui/load_" @ %bitmapName @ ".png"; + // --------------------------------------------------- + + if ( !isFile( "textures/" @ %loadBmp ) ) + %loadBmp = "gui/loading"; + LOAD_MapPic.setBitmap( %loadBmp ); + LOAD_MapName.setText( %mapName ); + LOAD_MissionType.setText( %missionType ); + LOAD_MapText.setText( "" ); + LOAD_GameText.setText( "" ); +} + +//------------------------------------------------------------------------------ +function handleLoadQuoteLineMessage( %msgType, %msgString, %line ) +{ + LoadingGui.qLine[LoadingGui.qLineCount] = %line; + LoadingGui.qLineCount++; + + %text = ""; + for ( %line = 0; %line < LoadingGui.qLineCount - 1; %line++ ) + %text = %text @ LoadingGui.qLine[%line] @ "\n"; + %text = %text @ ""; + %text = %text @ LoadingGui.qLine[%line] @ "\n"; // tag line + + LOAD_MapText.setText( %text ); +} + +//------------------------------------------------------------------------------ +function handleLoadObjectiveLineMessage( %msgType, %msgString, %line, %bulletStyle ) +{ + LobbyGui.objLine[LobbyGui.objLineCount] = %line; + LobbyGui.objLineCount++; + + if ( %bulletStyle ) + %line = "" @ %line @ ""; + + %newText = LOAD_MapText.getText(); + if ( %newText $= "" ) // In case there's no quote + %newText = %line; + else + %newText = %newText NL %line; + LOAD_MapText.setText( %newText ); +} + +//------------------------------------------------------------------------------ +function handleLoadRulesLineMessage( %msgType, %msgString, %line, %bulletStyle ) +{ + if ( %bulletStyle ) + %line = "" @ %line @ ""; + + %newText = LOAD_GameText.getText(); + if ( %newText $= "" ) + %newText = %line; + else + %newText = %newText NL %line; + LOAD_GameText.setText( %newText ); +} + +//------------------------------------------------------------------------------ +function handleLoadInfoDoneMessage( %msgType, %msgString ) +{ + LoadingGui.gotLoadInfo = true; +} + +package debriefload +{ +function debriefLoad(%client) + { + if (isObject(Game)) + %game = Game.getId(); + else + return; + + if ($HostGameType $= "SinglePlayer") + return; + + //Clear the debrief first + messageClient( %client, 'MsgClearDebrief', ""); + + messageClient( %client, 'MsgDebriefResult', "", ""@$Host::GameName@"\nTribes 2: Birth Of Legend"); + messageClient( %client, 'MsgDebriefAddLine', "", "A mod by: Dark Dragon DX (Vector)" ); + + messageClient( %client, 'MsgDebriefAddLine', "", "Hello "@%client.race@" "@%client.namebase@"."); + messageClient( %client, 'MsgDebriefAddLine', "", ""); + messageClient( %client, 'MsgDebriefAddLine', "", "You are in a Tribes 2: Birth of Legend server!"); + messageClient( %client, 'MsgDebriefAddLine', "", ""); + messageClient( %client, 'MsgDebriefAddLine', "", "Server Information:"); + messageClient( %client, 'MsgDebriefAddLine', "", "Player Count: "@$HostGamePlayerCount@""); + messageClient( %client, 'MsgDebriefAddLine', "", "Game Mode: "@$CurrentMissionType@""); + + if ($CurrentMissionType $= "RPG" && !$Data::IsRPGReady[%client.GUID]) //Make sure the client knows. + messageClient( %client, 'MsgDebriefAddLine', "", "The race/gender settings you have joined with have been saved."); + + messageClient( %client, 'MsgDebriefAddLine', "", "" ); + + //Go to the debrief gui. + messageClient( %client, 'MsgGameOver', "" ); + + } +}; +activatepackage(Debriefload); diff --git a/scripts/message.cs b/scripts/message.cs index 5f3854b..06af3c6 100644 --- a/scripts/message.cs +++ b/scripts/message.cs @@ -1,490 +1,463 @@ -$MaxMessageWavLength = 5200; - -function addMessageCallback(%msgType, %func) -{ - for(%i = 0; (%afunc = $MSGCB[%msgType, %i]) !$= ""; %i++) - { - // only add each callback once - if(%afunc $= %func) - return; - } - $MSGCB[%msgType, %i] = %func; -} - -function messagePump(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7 ,%a8, %a9, %a10) -{ - clientCmdServerMessage(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10); -} - -function clientCmdServerMessage(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10) -{ - %tag = getWord(%msgType, 0); - for(%i = 0; (%func = $MSGCB["", %i]) !$= ""; %i++) - call(%func, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10); - - if(%tag !$= "") - for(%i = 0; (%func = $MSGCB[%tag, %i]) !$= ""; %i++) - call(%func, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10); -} - -function defaultMessageCallback(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10) -{ - if ( %msgString $= "" ) - return; - - %message = detag( %msgString ); - // search for wav tag marker - %wavStart = strstr( %message, "~w" ); - if ( %wavStart != -1 ) - { - %wav = getSubStr( %message, %wavStart + 2, 1000 ); - %wavLengthMS = alxGetWaveLen( %wav ); - if ( %wavLengthMS <= $MaxMessageWavLength ) - { - %handle = alxCreateSource( AudioChat, %wav ); - alxPlay( %handle ); - } - else - error( "WAV file \"" @ %wav @ "\" is too long! **" ); - - %message = getSubStr( %message, 0, %wavStart ); - if ( %message !$= "" ) - addMessageHudLine( %message ); - } - else - addMessageHudLine( %message ); -} - -//-------------------------------------------------------------------------- -function handleClientJoin(%msgType, %msgString, %clientName, %clientId, %targetId, %isAI, %isAdmin, %isSuperAdmin, %isSmurf, %guid) -{ - logEcho("got client join: " @ detag(%clientName) @ " : " @ %clientId); - - //create the player list group, and add it to the ClientConnectionGroup... - if(!isObject("PlayerListGroup")) - { - %newGroup = new SimGroup("PlayerListGroup"); - ClientConnectionGroup.add(%newGroup); - } - - %player = new ScriptObject() - { - className = "PlayerRep"; - name = detag(%clientName); - guid = %guid; - clientId = %clientId; - targetId = %targetId; - teamId = 0; // start unassigned - score = 0; - ping = 0; - packetLoss = 0; - chatMuted = false; - canListen = false; - voiceEnabled = false; - isListening = false; - isBot = %isAI; - isAdmin = %isAdmin; - isSuperAdmin = %isSuperAdmin; - isSmurf = %isSmurf; - }; - PlayerListGroup.add(%player); - $PlayerList[%clientId] = %player; - - if ( !%isAI ) - getPlayerPrefs(%player); - lobbyUpdatePlayer( %clientId ); -} - -function handleClientDrop( %msgType, %msgString, %clientName, %clientId ) -{ - logEcho("got client drop: " @ detag(%clientName) @ " : " @ %clientId); - - %player = $PlayerList[%clientId]; - if( %player ) - { - %player.delete(); - $PlayerList[%clientId] = ""; - lobbyRemovePlayer( %clientId ); - } -} - -function handleClientJoinTeam( %msgType, %msgString, %clientName, %teamName, %clientId, %teamId ) -{ - %player = $PlayerList[%clientId]; - if( %player ) - { - %player.teamId = %teamId; - lobbyUpdatePlayer( %clientId ); - } -} - -function handleClientNameChanged( %msgType, %msgString, %oldName, %newName, %clientId ) -{ - %player = $PlayerList[%clientId]; - if( %player ) - { - %player.name = detag( %newName ); - lobbyUpdatePlayer( %clientId ); - } -} - -addMessageCallback("", defaultMessageCallback); -addMessageCallback('MsgClientJoin', handleClientJoin); -addMessageCallback('MsgClientDrop', handleClientDrop); -addMessageCallback('MsgClientJoinTeam', handleClientJoinTeam); -addMessageCallback('MsgClientNameChanged', handleClientNameChanged); - -//--------------------------------------------------------------------------- -// Client chat'n -//--------------------------------------------------------------------------- -function isClientChatMuted(%client) -{ - %player = $PlayerList[%client]; - if(%player) - return(%player.chatMuted ? true : false); - return(true); -} - -//--------------------------------------------------------------------------- -function clientCmdChatMessage(%sender, %voice, %pitch, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10) -{ - %message = detag( %msgString ); - %voice = detag( %voice ); - - if ( ( %message $= "" ) || isClientChatMuted( %sender ) ) - return; - - // search for wav tag marker - %wavStart = strstr( %message, "~w" ); - if ( %wavStart == -1 ) - addMessageHudLine( %message ); - else - { - %wav = getSubStr(%message, %wavStart + 2, 1000); - if (%voice !$= "") - %wavFile = "voice/" @ %voice @ "/" @ %wav @ ".wav"; - else - %wavFile = %wav; - - //only play voice files that are < 5000ms in length - if (%pitch < 0.5 || %pitch > 2.0) - %pitch = 1.0; - %wavLengthMS = alxGetWaveLen(%wavFile) * %pitch; - if (%wavLengthMS < $MaxMessageWavLength ) - { - if ( $ClientChatHandle[%sender] != 0 ) - alxStop( $ClientChatHandle[%sender] ); - $ClientChatHandle[%sender] = alxCreateSource( AudioChat, %wavFile ); - - //pitch the handle - if (%pitch != 1.0) - alxSourcef($ClientChatHandle[%sender], "AL_PITCH", %pitch); - alxPlay( $ClientChatHandle[%sender] ); - } - else - error( "** WAV file \"" @ %wavFile @ "\" is too long! **" ); - - %message = getSubStr(%message, 0, %wavStart); - addMessageHudLine(%message); - } -} - -//--------------------------------------------------------------------------- -function clientCmdCannedChatMessage( %sender, %msgString, %name, %string, %keys, %voiceTag, %pitch ) -{ - %message = detag( %msgString ); - %voice = detag( %voiceTag ); - if ( $defaultVoiceBinds ) - clientCmdChatMessage( %sender, %voice, %pitch, "[" @ %keys @ "]" SPC %message ); - else - clientCmdChatMessage( %sender, %voice, %pitch, %message ); -} - -//--------------------------------------------------------------------------- -// 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($Host::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 cannedChatMessageClient( %client, %sender, %msgString, %name, %string, %keys ) -{ - if ( !%client.muted[%sender] ) - commandToClient( %client, 'CannedChatMessage', %sender, %msgString, %name, %string, %keys, %sender.voiceTag, %sender.voicePitch ); -} - -function chatMessageTeam( %sender, %team, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 ) -{ - if ( ( %msgString $= "" ) || spamAlert( %sender ) ) - return; - - if ($CurrentMissionType $= "RPG") - { - if (!%sender.hasRadio) - { - messageClient(%sender,'msgNoRadio',"\c3You must have a radio."); - return; - } - - %count = ClientGroup.getCount(); - for ( %i = 0; %i < %count; %i++ ) - { - %obj = ClientGroup.getObject( %i ); - if ( %obj.team == %sender.team ) - messageClient(%obj,'msgClient',"\c3"@%sender.namebase@" (1): "@%a2@" ~wfx/misc/static.wav"); - //chatMessageClient( %obj, %sender, %sender.voiceTag, %sender.voicePitch, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 ); - } - } - else - { - %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 cannedChatMessageTeam( %sender, %team, %msgString, %name, %string, %keys ) -{ - if ( ( %msgString $= "" ) || spamAlert( %sender ) ) - return; - - %count = ClientGroup.getCount(); - for ( %i = 0; %i < %count; %i++ ) - { - %obj = ClientGroup.getObject( %i ); - if ( %obj.team == %sender.team ) - cannedChatMessageClient( %obj, %sender, %msgString, %name, %string, %keys ); - } -} - -function chatMessageAll( %sender, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 ) -{ - if ( ( %msgString $= "" ) || spamAlert( %sender ) ) - { - return; - } - - if ($CurrentMissionType $= "RPG" && !$Host::GlobalChat) - { - %count = MissionCleanup.getCount(); - for (%i = 0; %i < %count; %i++) - { - %obj = MissionCleanup.getObject(%i); - if (%obj.getClassName() $= "Player") - { - %dist = vectorDist(%sender.player.getPosition(),%obj.getPosition()); - if (%dist < 200) - chatMessageClient( %obj.client, %sender, %sender.voiceTag, %sender.voicePitch, %msgString, addTaggedString("(Radius - 200)" SPC getTaggedString(%a1)), %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 ); - } - } - } - else - { - %count = ClientGroup.getCount(); - for ( %i = 0; %i < %count; %i++ ) - { - %obj = ClientGroup.getObject( %i ); - - //---------------------------------------------------------------------------------------------------------------------------------------------------- - // z0dd - ZOD, 6/03/02. Allow observer global chat to be seen by all, not just admins and other observers - chatMessageClient( %obj, %sender, %sender.voiceTag, %sender.voicePitch, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 ); - - //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 || %obj.isAdmin || %obj.isSuperAdmin) - //{ - // chatMessageClient( %obj, %sender, %sender.voiceTag, %sender.voicePitch, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 ); - //} - //} - //---------------------------------------------------------------------------------------------------------------------------------------------------- - } - } - - // z0dd - ZOD 5/13/02. Echo chat to console for remote telnet apps. - if($Host::ClassicEchoChat) - { - echo( stripTaggedVar(%sender.name), ": ", %a2 ); - } - //echo( "SAY: " @ stripchars(detag(gettaggedstring(%sender.name)),"\cp\co\c6\c7\c8\c9") @ " \"" @ %a2 @ "\""); -} - -function cannedChatMessageAll( %sender, %msgString, %name, %string, %keys ) -{ - if ( ( %msgString $= "" ) || spamAlert( %sender ) ) - return; - - - if ($CurrentMissionType $= "RPG" && !$Host::GlobalChat) - { - %count = MissionCleanup.getCount(); - for (%i = 0; %i < %count; %i++) - { - %obj = MissionCleanup.getObject(%i); - if (%obj.getClassName() $= "Player") - { - %dist = vectorDist(%sender.player.getPosition(),%obj.getPosition()); - if (%dist < 200) - cannedChatMessageClient( %obj.client, %sender, addTaggedString("\c4(Radius - "@%dist@")" SPC getTaggedString(%msgString)), %name, %string, %keys ); - } - } - } - else - { - %count = ClientGroup.getCount(); - for ( %i = 0; %i < %count; %i++ ) - cannedChatMessageClient( ClientGroup.getObject(%i), %sender, %msgString, %name, %string, %keys ); - } - - // z0dd - ZOD 5/13/02. Echo chat to console for remote telnet apps. - if($Host::ClassicEchoChat) - { - echo( stripTaggedVar(%sender.name), ": ", getSubStr(%string, 0, strstr(%string, "~w")) ); - } - //echo("SAY: " @ stripchars(detag(gettaggedstring(%sender.name)),"\cp\co\c6\c7\c8\c9") @ " \"" @ %string @ "\""); -} - -//--------------------------------------------------------------------------- -function messageClient(%client, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13) -{ - commandToClient(%client, 'ServerMessage', %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13); -} - -function messageTeam(%team, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13) -{ - %count = ClientGroup.getCount(); - for(%cl= 0; %cl < %count; %cl++) - { - %recipient = ClientGroup.getObject(%cl); - if(%recipient.team == %team) - messageClient(%recipient, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13); - } -} - -function messageTeamExcept(%client, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13) -{ - %team = %client.team; - %count = ClientGroup.getCount(); - for(%cl= 0; %cl < %count; %cl++) - { - %recipient = ClientGroup.getObject(%cl); - if((%recipient.team == %team) && (%recipient != %client)) - messageClient(%recipient, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13); - } -} - -function messageAll(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13) -{ - %count = ClientGroup.getCount(); - for(%cl = 0; %cl < %count; %cl++) - { - %client = ClientGroup.getObject(%cl); - messageClient(%client, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13); - } -} - -function messageAllExcept(%client, %team, %msgtype, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13) -{ - //can exclude a client, a team or both. A -1 value in either field will ignore that exclusion, so - //messageAllExcept(-1, -1, $Mesblah, 'Blah!'); will message everyone (since there shouldn't be a client -1 or client on team -1). - %count = ClientGroup.getCount(); - for(%cl= 0; %cl < %count; %cl++) - { - %recipient = ClientGroup.getObject(%cl); - if((%recipient != %client) && (%recipient.team != %team)) - messageClient(%recipient, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13); - } -} - -//--------------------------------------------------------------------------- -// functions to support repair messaging -//--------------------------------------------------------------------------- -function clientCmdTeamRepairMessage(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - if($pref::ignoreTeamRepairMessages) - %msgString = ""; // z0dd - ZOD, 8/23/02. Yogi. The message gets to the client but is "muted" from the HUD - clientCmdServerMessage(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6); -} - -function teamRepairMessage(%client, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - %team = %client.team; - - %count = ClientGroup.getCount(); - for(%i = 0; %i < %count; %i++) - { - %recipient = ClientGroup.getObject(%i); // z0dd - ZOD, 8/20/02. param to getObject was $cl, which is an error - if((%recipient.team == %team) && (%recipient != %client)) - { - commandToClient(%recipient, 'TeamRepairMessage', %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6); // z0dd - ZOD, 6/18/02. Was sending to the wrong variable. 1st param was %client - } - } -} - -// ----------------------------------------------------------------------------------------------------------- -// z0dd - ZOD, 8/20/02. Added this team destroy message function -function teamDestroyMessage(%client, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - %team = %client.team; - - %count = ClientGroup.getCount(); - for(%i = 0; %i < %count; %i++) - { - %recipient = ClientGroup.getObject(%i); - if((%recipient.team == %team) && (%recipient != %client)) - { - commandToClient(%recipient, 'TeamDestroyMessage', %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6); - } - } -} -// ----------------------------------------------------------------------------------------------------------- +$MaxMessageWavLength = 5200; + +function addMessageCallback(%msgType, %func) +{ + for(%i = 0; (%afunc = $MSGCB[%msgType, %i]) !$= ""; %i++) + { + // only add each callback once + if(%afunc $= %func) + return; + } + $MSGCB[%msgType, %i] = %func; +} + +function messagePump(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7 ,%a8, %a9, %a10) +{ + clientCmdServerMessage(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10); +} + +function clientCmdServerMessage(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10) +{ + %tag = getWord(%msgType, 0); + for(%i = 0; (%func = $MSGCB["", %i]) !$= ""; %i++) + call(%func, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10); + + if(%tag !$= "") + for(%i = 0; (%func = $MSGCB[%tag, %i]) !$= ""; %i++) + call(%func, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10); +} + +function defaultMessageCallback(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10) +{ + if ( %msgString $= "" ) + return; + + %message = detag( %msgString ); + // search for wav tag marker + %wavStart = strstr( %message, "~w" ); + if ( %wavStart != -1 ) + { + %wav = getSubStr( %message, %wavStart + 2, 1000 ); + %wavLengthMS = alxGetWaveLen( %wav ); + if ( %wavLengthMS <= $MaxMessageWavLength ) + { + %handle = alxCreateSource( AudioChat, %wav ); + alxPlay( %handle ); + } + else + error( "WAV file \"" @ %wav @ "\" is too long! **" ); + + %message = getSubStr( %message, 0, %wavStart ); + if ( %message !$= "" ) + addMessageHudLine( %message ); + } + else + addMessageHudLine( %message ); +} + +//-------------------------------------------------------------------------- +function handleClientJoin(%msgType, %msgString, %clientName, %clientId, %targetId, %isAI, %isAdmin, %isSuperAdmin, %isSmurf, %guid) +{ + logEcho("got client join: " @ detag(%clientName) @ " : " @ %clientId); + + //create the player list group, and add it to the ClientConnectionGroup... + if(!isObject("PlayerListGroup")) + { + %newGroup = new SimGroup("PlayerListGroup"); + ClientConnectionGroup.add(%newGroup); + } + + %player = new ScriptObject() + { + className = "PlayerRep"; + name = detag(%clientName); + guid = %guid; + clientId = %clientId; + targetId = %targetId; + teamId = 0; // start unassigned + score = 0; + ping = 0; + packetLoss = 0; + chatMuted = false; + canListen = false; + voiceEnabled = false; + isListening = false; + isBot = %isAI; + isAdmin = %isAdmin; + isSuperAdmin = %isSuperAdmin; + isSmurf = %isSmurf; + }; + PlayerListGroup.add(%player); + $PlayerList[%clientId] = %player; + + if ( !%isAI ) + getPlayerPrefs(%player); + lobbyUpdatePlayer( %clientId ); +} + +function handleClientDrop( %msgType, %msgString, %clientName, %clientId ) +{ + logEcho("got client drop: " @ detag(%clientName) @ " : " @ %clientId); + + %player = $PlayerList[%clientId]; + if( %player ) + { + %player.delete(); + $PlayerList[%clientId] = ""; + lobbyRemovePlayer( %clientId ); + } +} + +function handleClientJoinTeam( %msgType, %msgString, %clientName, %teamName, %clientId, %teamId ) +{ + %player = $PlayerList[%clientId]; + if( %player ) + { + %player.teamId = %teamId; + lobbyUpdatePlayer( %clientId ); + } +} + +function handleClientNameChanged( %msgType, %msgString, %oldName, %newName, %clientId ) +{ + %player = $PlayerList[%clientId]; + if( %player ) + { + %player.name = detag( %newName ); + lobbyUpdatePlayer( %clientId ); + } +} + +addMessageCallback("", defaultMessageCallback); +addMessageCallback('MsgClientJoin', handleClientJoin); +addMessageCallback('MsgClientDrop', handleClientDrop); +addMessageCallback('MsgClientJoinTeam', handleClientJoinTeam); +addMessageCallback('MsgClientNameChanged', handleClientNameChanged); + +//--------------------------------------------------------------------------- +// Client chat'n +//--------------------------------------------------------------------------- +function isClientChatMuted(%client) +{ + %player = $PlayerList[%client]; + if(%player) + return(%player.chatMuted ? true : false); + return(true); +} + +//--------------------------------------------------------------------------- +function clientCmdChatMessage(%sender, %voice, %pitch, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10) +{ + %message = detag( %msgString ); + %voice = detag( %voice ); + + if ( ( %message $= "" ) || isClientChatMuted( %sender ) ) + return; + + // search for wav tag marker + %wavStart = strstr( %message, "~w" ); + if ( %wavStart == -1 ) + addMessageHudLine( %message ); + else + { + %wav = getSubStr(%message, %wavStart + 2, 1000); + if (%voice !$= "") + %wavFile = "voice/" @ %voice @ "/" @ %wav @ ".wav"; + else + %wavFile = %wav; + + //only play voice files that are < 5000ms in length + if (%pitch < 0.5 || %pitch > 2.0) + %pitch = 1.0; + %wavLengthMS = alxGetWaveLen(%wavFile) * %pitch; + if (%wavLengthMS < $MaxMessageWavLength ) + { + if ( $ClientChatHandle[%sender] != 0 ) + alxStop( $ClientChatHandle[%sender] ); + $ClientChatHandle[%sender] = alxCreateSource( AudioChat, %wavFile ); + + //pitch the handle + if (%pitch != 1.0) + alxSourcef($ClientChatHandle[%sender], "AL_PITCH", %pitch); + alxPlay( $ClientChatHandle[%sender] ); + } + else + error( "** WAV file \"" @ %wavFile @ "\" is too long! **" ); + + %message = getSubStr(%message, 0, %wavStart); + addMessageHudLine(%message); + } +} + +//--------------------------------------------------------------------------- +function clientCmdCannedChatMessage( %sender, %msgString, %name, %string, %keys, %voiceTag, %pitch ) +{ + %message = detag( %msgString ); + %voice = detag( %voiceTag ); + if ( $defaultVoiceBinds ) + clientCmdChatMessage( %sender, %voice, %pitch, "[" @ %keys @ "]" SPC %message ); + else + clientCmdChatMessage( %sender, %voice, %pitch, %message ); +} + +//--------------------------------------------------------------------------- +// 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($Host::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 cannedChatMessageClient( %client, %sender, %msgString, %name, %string, %keys ) +{ + if ( !%client.muted[%sender] ) + commandToClient( %client, 'CannedChatMessage', %sender, %msgString, %name, %string, %keys, %sender.voiceTag, %sender.voicePitch ); +} + +function chatMessageTeam( %sender, %team, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 ) +{ + if ( ( %msgString $= "" ) || spamAlert( %sender ) ) + return; + + if ($CurrentMissionType $= "RPG") + radioChatMessageTeam(%sender, %team, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10); + else + { + %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 cannedChatMessageTeam( %sender, %team, %msgString, %name, %string, %keys ) +{ + if ( ( %msgString $= "" ) || spamAlert( %sender ) ) + return; + + %count = ClientGroup.getCount(); + for ( %i = 0; %i < %count; %i++ ) + { + %obj = ClientGroup.getObject( %i ); + if ( %obj.team == %sender.team ) + cannedChatMessageClient( %obj, %sender, %msgString, %name, %string, %keys ); + } +} + +function chatMessageAll( %sender, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 ) +{ + if ( ( %msgString $= "" ) || spamAlert( %sender ) ) + { + return; + } + + if ($CurrentMissionType $= "RPG" && !$Host::GlobalChat) + rangedChatMessageAll(%sender, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %c8, %a9, %a10); + else + { + %count = ClientGroup.getCount(); + for ( %i = 0; %i < %count; %i++ ) + { + %obj = ClientGroup.getObject( %i ); + + //---------------------------------------------------------------------------------------------------------------------------------------------------- + // z0dd - ZOD, 6/03/02. Allow observer global chat to be seen by all, not just admins and other observers + chatMessageClient( %obj, %sender, %sender.voiceTag, %sender.voicePitch, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 ); + + //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 || %obj.isAdmin || %obj.isSuperAdmin) + //{ + // chatMessageClient( %obj, %sender, %sender.voiceTag, %sender.voicePitch, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 ); + //} + //} + //---------------------------------------------------------------------------------------------------------------------------------------------------- + } + } + + // z0dd - ZOD 5/13/02. Echo chat to console for remote telnet apps. + if($Host::ClassicEchoChat) + { + echo( stripTaggedVar(%sender.name), ": ", %a2 ); + } + //echo( "SAY: " @ stripchars(detag(gettaggedstring(%sender.name)),"\cp\co\c6\c7\c8\c9") @ " \"" @ %a2 @ "\""); +} + +function cannedChatMessageAll( %sender, %msgString, %name, %string, %keys ) +{ + if ( ( %msgString $= "" ) || spamAlert( %sender ) ) + return; + + + if ($CurrentMissionType $= "RPG" && !$Host::GlobalChat) + { + %count = MissionCleanup.getCount(); + for (%i = 0; %i < %count; %i++) + { + %obj = MissionCleanup.getObject(%i); + if (%obj.getClassName() $= "Player") + { + %dist = vectorDist(%sender.player.getPosition(),%obj.getPosition()); + if (%dist < 200) + cannedChatMessageClient( %obj.client, %sender, addTaggedString("\c4(Radius - "@%dist@")" SPC getTaggedString(%msgString)), %name, %string, %keys ); + } + } + } + else + { + %count = ClientGroup.getCount(); + for ( %i = 0; %i < %count; %i++ ) + cannedChatMessageClient( ClientGroup.getObject(%i), %sender, %msgString, %name, %string, %keys ); + } + + // z0dd - ZOD 5/13/02. Echo chat to console for remote telnet apps. + if($Host::ClassicEchoChat) + { + echo( stripTaggedVar(%sender.name), ": ", getSubStr(%string, 0, strstr(%string, "~w")) ); + } + //echo("SAY: " @ stripchars(detag(gettaggedstring(%sender.name)),"\cp\co\c6\c7\c8\c9") @ " \"" @ %string @ "\""); +} + +//--------------------------------------------------------------------------- +function messageClient(%client, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13) +{ + commandToClient(%client, 'ServerMessage', %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13); +} + +function messageTeam(%team, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13) +{ + %count = ClientGroup.getCount(); + for(%cl= 0; %cl < %count; %cl++) + { + %recipient = ClientGroup.getObject(%cl); + if(%recipient.team == %team) + messageClient(%recipient, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13); + } +} + +function messageTeamExcept(%client, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13) +{ + %team = %client.team; + %count = ClientGroup.getCount(); + for(%cl= 0; %cl < %count; %cl++) + { + %recipient = ClientGroup.getObject(%cl); + if((%recipient.team == %team) && (%recipient != %client)) + messageClient(%recipient, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13); + } +} + +function messageAll(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13) +{ + %count = ClientGroup.getCount(); + for(%cl = 0; %cl < %count; %cl++) + { + %client = ClientGroup.getObject(%cl); + messageClient(%client, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13); + } +} + +function messageAllExcept(%client, %team, %msgtype, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13) +{ + //can exclude a client, a team or both. A -1 value in either field will ignore that exclusion, so + //messageAllExcept(-1, -1, $Mesblah, 'Blah!'); will message everyone (since there shouldn't be a client -1 or client on team -1). + %count = ClientGroup.getCount(); + for(%cl= 0; %cl < %count; %cl++) + { + %recipient = ClientGroup.getObject(%cl); + if((%recipient != %client) && (%recipient.team != %team)) + messageClient(%recipient, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13); + } +} + +//--------------------------------------------------------------------------- +// functions to support repair messaging +//--------------------------------------------------------------------------- +function clientCmdTeamRepairMessage(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + if($pref::ignoreTeamRepairMessages) + %msgString = ""; // z0dd - ZOD, 8/23/02. Yogi. The message gets to the client but is "muted" from the HUD + clientCmdServerMessage(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6); +} + +function teamRepairMessage(%client, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + %team = %client.team; + + %count = ClientGroup.getCount(); + for(%i = 0; %i < %count; %i++) + { + %recipient = ClientGroup.getObject(%i); // z0dd - ZOD, 8/20/02. param to getObject was $cl, which is an error + if((%recipient.team == %team) && (%recipient != %client)) + { + commandToClient(%recipient, 'TeamRepairMessage', %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6); // z0dd - ZOD, 6/18/02. Was sending to the wrong variable. 1st param was %client + } + } +} + +// ----------------------------------------------------------------------------------------------------------- +// z0dd - ZOD, 8/20/02. Added this team destroy message function +function teamDestroyMessage(%client, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + %team = %client.team; + + %count = ClientGroup.getCount(); + for(%i = 0; %i < %count; %i++) + { + %recipient = ClientGroup.getObject(%i); + if((%recipient.team == %team) && (%recipient != %client)) + { + commandToClient(%recipient, 'TeamDestroyMessage', %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6); + } + } +} +// ----------------------------------------------------------------------------------------------------------- diff --git a/scripts/modScripts/Note.txt b/scripts/modScripts/Note.txt deleted file mode 100644 index 6c7d112..0000000 --- a/scripts/modScripts/Note.txt +++ /dev/null @@ -1,2 +0,0 @@ -These scripts are the internal functioning of the T2BoL mod. It is recommended you don't touch these and just use the BASIC API -to make your changes to the game. \ No newline at end of file diff --git a/scripts/modScripts/server/RPG/GameTriggers.cs b/scripts/modScripts/server/RPG/GameTriggers.cs deleted file mode 100644 index 193ae84..0000000 --- a/scripts/modScripts/server/RPG/GameTriggers.cs +++ /dev/null @@ -1,81 +0,0 @@ -//------------------------------------------------------------------------------ -// Application SDK for the PDA. (to make my life easier) -// Trigger code for RPG Gamemode -// Copyright (c) 2012 The DarkDragonDX -//============================================================================== - -function RPGGame::onEnterTrigger(%game, %name, %data, %obj, %colObj) -{ - switch$(%obj.type) - { - case "Transport": if (%obj.targetTransform $= "") return; - %Colobj.setTransform(%obj.targetTransform); - if (%Colobj.Usewhiteout) - %Obj.setWhiteout(0.8); - break; - case "Territory": - if (%obj.race $= "") - return; - %obj.client.isOnTerritory[%Colobj.race] = true; - setClientTeam(%Colobj.client,getRaceTeam(%Obj.race)); - if (%obj.location $= "") - { - messageClient(%Colobj.client,'MsgSPCurrentObjective1',"",'Location: %1.', %obj.race SPC "Territory"); - messageClient(%colObj.client,'msgEnteredRaceTerritory','\c3You have entered %1 territory.',%obj.race); - } - else - { - messageClient(%colObj.client,'msgEnteredRaceTerritory','\c3You have entered %1.',%obj.location); - messageClient(%Colobj.client,'MsgSPCurrentObjective1',"",'Location: %1.', %obj.location); - } - break; - case "Damage": //Will add lots o' vars onto it.. - %obj.damage[%colobj] = true; - %colObj.isinLava = true; - break; - } - if (%Colobj.message $= "" && %Colobj.type !$= "Territory") - messageClient(%Colobj.client,'MsgTrigger',%obj.message); - return true; -} - -function RPGGame::onLeaveTrigger(%game, %name, %data, %obj, %colObj) -{ - switch$(%obj.type) - { - case "Territory": - if (%obj.race $= "") - return; - - if (%obj.location $= "") - messageClient(%Colobj.client,'MsgExitedRaceTerritory',"\c3You have exited "@%obj.race@" territory. Your sensor data is now undetectable."); - else - messageClient(%Colobj.client,'MsgExitedRaceTerritory',"\c3You have exited "@%obj.location@"."); - %Colobj.client.isOnTerritory[%obj.race] = false; - messageClient(%colObj.client,'MsgSPCurrentObjective1',"",'Location: Unknown.'); - setClientTeam(%Colobj.client,0); //Not on the sensor, I think - break; - case "Damage": - %obj.damage[%obj] = false; - %colObj.isInLava = true; - break; - } - return true; -} - -function RPGGame::onTickTrigger(%game, %name, %data, %obj) -{ - switch(%obj.type) - { - case "Damage": - for (%i = 0; %i < MissionCleanup.getCount(); %i++) - { - %objT = MissionCleanup.getObject(%i); - if (%objt.getClassName() $= "Player" && %objt.getState() $= "move") - if (%obj.damage[%objT] && %objT.isInLava) - %objT.damage(0, %objT.getPosition(), %obj.damage, %obj,damageType); - break; - } - } - return true; -} diff --git a/scripts/modScripts/server/initialise.cs b/scripts/modScripts/server/initialise.cs deleted file mode 100644 index 5876e58..0000000 --- a/scripts/modScripts/server/initialise.cs +++ /dev/null @@ -1,15 +0,0 @@ -//------------------------------------------------------------------------------ -// Server Scripts Init -//============================================================================== -exec("scripts/modScripts/server/propData.cs"); -exec("scripts/modScripts/server/mining.cs"); -exec("scripts/modScripts/server/propertyOwning.cs"); -exec("scripts/modScripts/server/looting.cs"); -exec("scripts/modScripts/server/serverFunctions.cs"); -exec("scripts/modScripts/server/bloodHuman.cs"); -exec("scripts/modScripts/server/bloodBioderm.cs"); -exec("scripts/modScripts/server/dataImport.cs"); -exec("scripts/modScripts/server/serverNetworking.cs"); -exec("scripts/modScripts/server/HTTPServer.cs"); -exec("scripts/modScripts/server/TorqueExServer.cs"); - diff --git a/scripts/modScripts/shared/initialise.cs b/scripts/modScripts/shared/initialise.cs deleted file mode 100644 index 6f72d9d..0000000 --- a/scripts/modScripts/shared/initialise.cs +++ /dev/null @@ -1,11 +0,0 @@ -//------------------------------------------------------------------------------ -// initialise.cs -// Shared Functions for T2Bol -// Copyright (c) 2012 The DarkDragonDX -//============================================================================== -exec("scripts/modScripts/shared/Array.cs"); -exec("scripts/modScripts/shared/stringProcessing.cs"); -exec("scripts/modScripts/shared/fileProcessing.cs"); -exec("scripts/modScripts/shared/basicDataStorage.cs"); - - diff --git a/scripts/modScripts/AICharacter.cs b/scripts/modscripts/AICharacter.cs similarity index 100% rename from scripts/modScripts/AICharacter.cs rename to scripts/modscripts/AICharacter.cs diff --git a/scripts/modScripts/client/RPGBrowserGui.cs b/scripts/modscripts/client/RPGBrowserGui.cs similarity index 100% rename from scripts/modScripts/client/RPGBrowserGui.cs rename to scripts/modscripts/client/RPGBrowserGui.cs diff --git a/scripts/modScripts/client/clientFunctions.cs b/scripts/modscripts/client/clientFunctions.cs similarity index 100% rename from scripts/modScripts/client/clientFunctions.cs rename to scripts/modscripts/client/clientFunctions.cs diff --git a/scripts/modScripts/client/initialise.cs b/scripts/modscripts/client/initialise.cs similarity index 100% rename from scripts/modScripts/client/initialise.cs rename to scripts/modscripts/client/initialise.cs diff --git a/scripts/modScripts/client/initialize.cs b/scripts/modscripts/client/initialize.cs similarity index 100% rename from scripts/modScripts/client/initialize.cs rename to scripts/modscripts/client/initialize.cs diff --git a/scripts/modScripts/client/serverRequestHandler.cs b/scripts/modscripts/client/serverRequestHandler.cs similarity index 100% rename from scripts/modScripts/client/serverRequestHandler.cs rename to scripts/modscripts/client/serverRequestHandler.cs diff --git a/scripts/modscripts/server/HTTP/ActivePlayers.cs b/scripts/modscripts/server/HTTP/ActivePlayers.cs new file mode 100644 index 0000000..8f3898f --- /dev/null +++ b/scripts/modscripts/server/HTTP/ActivePlayers.cs @@ -0,0 +1 @@ +//------------------------------------------------------------------------------ // ActivePlayers.cs // .cs code listing currently active players // Copyright (c) 2012 Robert MacGregor //------------------------------------------------------------------------------ // Function that returns raw HTML formatting for the web browser on the client end to read function ActivePlayers::contents(%this) { %data = "T2BoL Webserver Testing | Active Players" @ "
" @ "Currently Active Players" @ "


" @ ""; %data = %data @ ""; %data = %data @ ""; %data = %data @ ""; for (%i = 0; %i < ClientGroup.getCount(); %i++) { %client = ClientGroup.getObject(%i); %data = %data @ ""; %data = %data @ ""; %data = %data @ ""; } //"" @ //"" @ //"" @ %data = %data @ "
Name
Species
Gender
" @ %client.namebase @ "
" @ %client.race @ "
" @ %client.sex @ "
Active Players
" @ ""; return %data; } \ No newline at end of file diff --git a/scripts/modscripts/server/HTTP/Index.cs b/scripts/modscripts/server/HTTP/Index.cs new file mode 100644 index 0000000..536f8ff --- /dev/null +++ b/scripts/modscripts/server/HTTP/Index.cs @@ -0,0 +1,21 @@ +//------------------------------------------------------------------------------ +// Index.cs +// Home page for the BoL inbuilt web server +// Copyright (c) 2012 Robert MacGregor +//------------------------------------------------------------------------------ + +// Function that returns raw HTML formatting for the web browser on the client end to read +function Index::contents(%this) +{ + %data = "T2BoL Webserver Testing" @ + "
" @ + "Welcome! This is the testing index page!" @ + "


" @ + "" @ + "" @ + "" @ + "" @ + "
Active Players
" @ + ""; + return %data; +} \ No newline at end of file diff --git a/scripts/modscripts/server/HTTP/PlayerDirectory.cs b/scripts/modscripts/server/HTTP/PlayerDirectory.cs new file mode 100644 index 0000000..e69de29 diff --git a/scripts/modScripts/server/HTTPServer.cs b/scripts/modscripts/server/HTTPServer.cs similarity index 92% rename from scripts/modScripts/server/HTTPServer.cs rename to scripts/modscripts/server/HTTPServer.cs index c6b33cf..438b808 100644 --- a/scripts/modScripts/server/HTTPServer.cs +++ b/scripts/modscripts/server/HTTPServer.cs @@ -1,349 +1,336 @@ -//------------------------------------------------------------------------------ -// HTTPServer.cs -// An experimental HTTP Server written in Torque! -// Copyright (c) 2012 The DarkDragonDX -//------------------------------------------------------------------------------ - -// -- -// BoL Specific Code -- automatically load the server if enabled -if (!IsObject(HTTPServerPrefs)) - new ScriptObject(HTTPServerPrefs) { class = "BasicDataParser"; }; -HTTPServerPrefs.empty(); -HTTPServerPrefs.load("prefs/WebServer.conf"); -%generic = HTTPServerPrefs.get("Generic",0); -if(%generic.element("Enabled") $= "true") -{ - new ScriptObject(WebServer) { class = "HTTPServer"; }; - WebServer.listen(%generic.element("Host"),%generic.element("Port"),%generic.element("StartWorkers")); -} -// -- - - -// Replicate Code for Servers -$HTTPServer::ServerReplicate = "function *UNIQUESOCKET*::onConnectRequest(%this, %address, %socket)\n" @ -"{\n" @ -"%this.Parent.connectionCreated(%address, %socket);\n" @ -"return true;\n" @ -"}\n"; -// Replicate Code for Clients -$HTTPServer::ClientReplicate = "function *UNIQUESOCKET*::onLine(%this, %line)\n" @ -"{\n" @ -"%this.Parent.onLine(%this, %line);\n" @ -"return true;\n" @ -"}\n" @ -"function *UNIQUESOCKET*::onDisconnect(%this) { %this.Parent.connectionDropped(%this); return true; }\n" @ -"function *UNIQUESOCKET*::sendPacket(%this,%packet)\n" @ -"{\n" @ -"%this.send(%packet.statusCode);\n" @ -"for (%i = 0; %i < %packet.headerCount; %i++)\n" @ -"{\n" @ -"echo(%packet.headers[%packet.headerName[%i]]);\n" @ -"%this.send(%packet.headers[%packet.headerName[%i]]);\n" @ -"}\n" @ -"%this.send(\"\\n\");\n" @ -"%this.send(%packet.payLoad);\n" @ -"%this.disconnect();\n" @ -"}\n"; - -function HTTPServer::listen(%this, %address, %port, %maxClients) -{ - %uniqueNameLength = 6; // Adjust this if need be, but there should never be a reason to - %this.allowMultiConnect = false; // If false, when a client connects twice, its old connection is killed and replaced with a new one. - if (%this.isListening) - return false; - if (%maxClients < 1 || %maxClients == 0) - %maxClients = 8; - %oldAddr = $Host::BindAddress; - %address = strlwr(%address); - if (%address $= "local" || %address $="localhost" ) %address = "127.0.0.1"; - else if (%address $= "any") %address = "0.0.0.0"; - - %charList = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - // Generate A name for a TCPObject (and make sure it's unique) - %uniqueStringLen = 6; // Adjust this if needed, but there shouldn't be a reason to - %uniqueString = ""; - while (true) - { - %uniqueString = generateString(%uniqueNameLength, %charList); - if (!isObject(%uniqueString)) break; - else %uniqueString = ""; - } - %evalCode = $HTTPServer::ServerReplicate; - %evalCode = strReplace(%evalCode, "*UNIQUESOCKET*", %uniqueString); - eval(%evalCode); - - // Generate a list of unique names that this TCPServer will use (to keep down function def count) - for (%i = 0; %i < %maxClients; %i++) - while (true) - { - %uniqueName = generateString(%uniqueNameLength, %charList); - if (!isObject(%uniqueName)) - { - %eval = strReplace($HTTPServer::ClientReplicate, "*UNIQUESOCKET*", %uniqueName); - eval(%eval); - %this.uniqueName[%i] = %uniqueName; - %this.uniqueNameInUse[%uniqueName] = false; - break; - } - } - - // Create the Socket and we'll rock n' roll - $Host::BindAddress = %address; - %this.Server = new TCPObject(%uniqueString); - %this.Server.listen(%port); - %this.Server.Parent = %this; - %this.connectionCount = 0; - %this.maximumClients = %maxClients; - $Host::BindAddress = %oldAddr; - %this.isListening = true; - - %statusCodes = HTTPServerPrefs.get("StatusCodes",0); - %this.Page[404] = %statusCodes.element("404"); - %this.Page[403] = %statusCodes.element("403"); - - %generic = HTTPServerPrefs.get("Generic",0); - %this.Root = %generic.element("Root"); - - %this.Variables = Array.create(); - %this.MimeTypes = HTTPServerPrefs.get("MIME"); - - logEcho("Server " @ %uniqueString SPC "is ready on " @ %address @ ":" @ %port); - return true; -} - -function HTTPServer::disconnect(%this) -{ -} - -function HTTPServer::connectionDropped(%this, %socket) -{ - if (!IsObject(%socket)) - return false; - %socket.disconnect(); - if (!%this.allowMultiConnect) - %this.connections[%socket.Address] = ""; - else - %this.connections[%socket.Address, %socket.Port] = ""; - %this.uniqueNameInUse[%socket.getName()] = false; - %this.connectionCount--; - %this.onClientDisconnect(%socket); -} - -function HTTPServer::connectionCreated(%this, %address, %socket) -{ - %isReplicate = false; - // Get the Port No. and Address respectively - %address = strReplace(%address, "IP:",""); - %portPos = strStr(%address, ":"); - %port = getSubStr(%address, %portPos+1, strLen(%address)); - %address = getSubStr(%address, 0, %portPos); - - // Pick a unique name - %uniqueName = ""; - for (%i = 0; %i < %this.maximumClients; %i++) - { - %name = %this.uniqueName[%i]; - if (!%this.uniqueNameInUse[%name]) - { - %uniqueName = %name; - %this.uniqueNameInUse[%name] = true; - break; - } - } - - // If we were unable to find a good unique name - %charList = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - %uniqueStringLen = 6; // Adjust this if needed, but there shouldn't be a reason to - if (%uniqueName $= "") - { - while (true) - { - %uniqueName = generateString(%uniqueStringLen, %charList); - if (!isObject(%uniqueName)) break; - else %uniqueName = ""; - } - %eval = strReplace($HTTPServer::ClientReplicate, "*UNIQUESOCKET*", %uniqueName); - eval(%eval); - - %this.uniqueName[%this.maximumClients] = %uniqueName; - %this.uniqueNameInUse[%uniqueName] = true; - %this.maximumClients++; - } - // Create The Client Socket - %connection = new TCPObject(%uniqueName,%socket) { class = ConnectionTCP; parent = %this; Address = %address; Port = %port; }; - if (!%this.allowMultiConnect) - %this.connections[%address] = %connection; - else - %this.connections[%address, %port] = %connection; - - %this.connectionCount++; - %this.onClientConnect(%address, %connection); - logEcho("Received client connection from " @ %address); - - %this.schedule(10000,"connectionDropped",%connection); - - return true; -} - -// Callbacks -- make these do whatever you please! -function HTTPServer::onClientConnect(%this, %address, %socket) -{ - echo("Received connection from " @ %address @ ". ID:" @ %socket); - //%socket.disconnect(); - return true; -} -function HTTPServer::onClientRejected(%this, %socket, %reason) // %reason is always zero as of now. -{ - return true; -} -function HTTPServer::onClientDisconnect(%this, %socket) -{ - logEcho("Received Disconnect (" @ %socket @ ")"); - %socket.delete(); - return true; -} -function HTTPServer::onLine(%this, %socket, %line) -{ - logEcho(%socket SPC "says: " @ %line); - %reqType = getWord(%line, 0); - if (%reqType $= "GET") - { - %req = getWord(%line, 1); - %reqLen = strLen(%req); - %socket.request = getSubStr(%req, 1, %reqLen); - %socket.request = strReplace(%socket.request, "%20", " "); - %socket.request = %this.Root @ %socket.request; - %socket.requestType = "GET"; - } - - %data = "
404 - Not Found
Oops!
File not found."; - %forbiddenData = "
403- Forbidden
Oops!
You're not allowed to see this."; - - %packet = new ScriptObject(){ class = "HTTPResponsePacket"; }; - //return; - // We received the end-of-packet from a socket - if (%line $= "") - { - //Shitty - if (strStr(%socket.request,".") != -1) - { - if (!isFile(%socket.request)) - %packet.setStatusCode(404); - - else if (%socket.request $= "prefs/ClientPrefs.cs") - { - %packet.setStatusCode(403); - %data = %forbiddenData; - } - else - { - %packet.setStatusCode(200); - %file = new FileObject(); - %file.openForRead(%socket.request); - %data = ""; - while (!%file.isEOF()) - { - %line = %file.readLine(); - echo(%line); - - if (strStr(%socket.request,".html") == -1) - { - %line = strReplace(%line,">",">"); - %line = strReplace(%line,"<","<"); - %line = strReplace(%line," "," "); - %line = strReplace(%line,"\t","    "); - %data = %data @ %line @ "
\n"; - } - else - %data = %data @ %line @ "\n"; - } - %file.close(); - %file.delete(); - } - - // Check the file type - %extension = getFileExtensionFromString(%socket.request); - if (%extension $= "html" || %extension $= "htm") - { - %script = strReplace(%socket.request,".html",".cs"); - if (isFile(%script)) - { - exec(%script); - %Object = new ScriptObject(){ class = "ServerApp"; }; - %data = %Object.execute(%data); - %Object.delete(); - } - } - } - else - { - %packet.setStatusCode(200); - %data = "\n
\n\nDirectory\n\n
\n

Directory of " @ %socket.request @ "

\n"; - for( %file = findFirstFile( %socket.request @ "*.*" ); %file !$= ""; %file = findNextFile( %socket.request @ "*.*" ) ) - { - %file = strReplace(%file, %socket.request, ""); - if (strStr(%file, "/") != -1) - { - %dir = getSubStr(%file, 0, strStr(%file, "/")) @ "/"; - if (!%dirAdded[%dir]) - { - %data = %data @ "" @ %dir @ "
\n"; - %dirAdded[%dir] = true; - } - } - else - %data = %data @ "" @ %file @ "
\n"; - } - %data = %data @ "\n\n"; - } - %packet.setHeader("Date",formatTimeString("DD, dd MM yy hh:nn:ss ") @ "Eastern"); - %packet.setHeader("Server","Tribes 2"); - %packet.setHeader("Content-Type","text/html"); - %packet.setPayload(%data); - %socket.sendPacket(%packet); - %packet.delete(); - %this.connectionDropped(%socket); - } - if (isObject(%packet)) - %packet.delete(); - return true; -} - -// Packet Functions (used for packet generation/reading) -function HTTPResponsePacket::setHeader(%this, %name, %value) -{ - if (%this.headerCount == "") - %this.headerCount = 0; - - if (%this.headers[%name] $= "") - { - %this.headerName[%this.headerCount] = %name; - %this.headerCount++; - } - %this.headers[%name] = %name @ ": " @ %value @ "\n"; - return true; -} - -function HTTPResponsePacket::setStatusCode(%this, %code) -{ - %this.statusCode = "HTTP/1.1 " @ %code SPC "OK\n"; - return true; -} - -function HTTPResponsePacket::setPayload(%this, %data) -{ - %this.payLoad = %data; - %this.payloadSize = strLen(%data); - %this.setHeader("Content-Length", %this.payloadSize); - return true; -} - -// Lib Functions -function generateString(%length, %alpha) -{ - %len = strLen(%alpha); - %result = ""; - for (%i = 0; %i < %length; %i++) - %result = %result @ getSubStr(%alpha, getRandom(0, %len), 1); - return %result; -} \ No newline at end of file +//------------------------------------------------------------------------------ +// HTTPServer.cs +// An experimental HTTP Server written in Torque! +// Copyright (c) 2012 Robert MacGregor +//------------------------------------------------------------------------------ + +// Replicate Code for Servers +$HTTPServer::ServerReplicate = "function *UNIQUESOCKET*::onConnectRequest(%this, %address, %socket)\n" @ +"{\n" @ +"%this.Parent.connectionCreated(%address, %socket);\n" @ +"return true;\n" @ +"}\n"; +// Replicate Code for Clients +$HTTPServer::ClientReplicate = "function *UNIQUESOCKET*::onLine(%this, %line)\n" @ +"{\n" @ +"%this.Parent.onLine(%this, %line);\n" @ +"return true;\n" @ +"}\n" @ +"function *UNIQUESOCKET*::onDisconnect(%this) { %this.Parent.connectionDropped(%this); return true; }\n" @ +"function *UNIQUESOCKET*::sendPacket(%this,%packet)\n" @ +"{\n" @ +"%this.send(%packet.statusCode);\n" @ +"for (%i = 0; %i < %packet.headerCount; %i++)\n" @ +"{\n" @ +"%this.send(%packet.headers[%packet.headerName[%i]]);\n" @ +"}\n" @ +"%this.send(\"\\n\");\n" @ +"%this.send(%packet.payLoad);\n" @ +"%this.disconnect();\n" @ +"}\n"; + +function HTTPServer::listen(%this, %address, %port, %maxClients) +{ + %uniqueNameLength = 6; // Adjust this if need be, but there should never be a reason to + %this.allowMultiConnect = false; // If false, when a client connects twice, its old connection is killed and replaced with a new one. + if (%this.isListening) + return false; + if (%maxClients < 1 || %maxClients == 0) + %maxClients = 8; + %oldAddr = $Host::BindAddress; + %address = strlwr(%address); + if (%address $= "local" || %address $="localhost" ) %address = "127.0.0.1"; + else if (%address $= "any") %address = "0.0.0.0"; + + %charList = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + // Generate A name for a TCPObject (and make sure it's unique) + %uniqueStringLen = 6; // Adjust this if needed, but there shouldn't be a reason to + %uniqueString = ""; + while (true) + { + %uniqueString = generateString(%uniqueNameLength, %charList); + if (!isObject(%uniqueString)) break; + else %uniqueString = ""; + } + %evalCode = $HTTPServer::ServerReplicate; + %evalCode = strReplace(%evalCode, "*UNIQUESOCKET*", %uniqueString); + eval(%evalCode); + + // Generate a list of unique names that this TCPServer will use (to keep down function def count) + for (%i = 0; %i < %maxClients; %i++) + while (true) + { + %uniqueName = generateString(%uniqueNameLength, %charList); + if (!isObject(%uniqueName)) + { + %eval = strReplace($HTTPServer::ClientReplicate, "*UNIQUESOCKET*", %uniqueName); + eval(%eval); + %this.uniqueName[%i] = %uniqueName; + %this.uniqueNameInUse[%uniqueName] = false; + break; + } + } + + // Create the Socket and we'll rock n' roll + $Host::BindAddress = %address; + %this.Server = new TCPObject(%uniqueString); + %this.Server.listen(%port); + %this.Server.Parent = %this; + %this.connectionCount = 0; + %this.maximumClients = %maxClients; + $Host::BindAddress = %oldAddr; + %this.isListening = true; + + %statusCodes = HTTPServerPrefs.get("StatusCodes",0); + %this.Page[404] = %statusCodes.element("404"); + %this.Page[403] = %statusCodes.element("403"); + + %generic = HTTPServerPrefs.get("Generic",0); + %this.Root = %generic.element("Root"); + + %this.Variables = Array.create(); + %this.MimeTypes = HTTPServerPrefs.get("MIME"); + + logEcho("Server " @ %uniqueString SPC "is ready on " @ %address @ ":" @ %port); + return true; +} + +function HTTPServer::disconnect(%this) +{ +} + +function HTTPServer::connectionDropped(%this, %socket) +{ + if (!IsObject(%socket)) + return false; + %socket.disconnect(); + if (!%this.allowMultiConnect) + %this.connections[%socket.Address] = ""; + else + %this.connections[%socket.Address, %socket.Port] = ""; + %this.uniqueNameInUse[%socket.getName()] = false; + %this.connectionCount--; + %this.onClientDisconnect(%socket); +} + +function HTTPServer::connectionCreated(%this, %address, %socket) +{ + %isReplicate = false; + // Get the Port No. and Address respectively + %address = strReplace(%address, "IP:",""); + %portPos = strStr(%address, ":"); + %port = getSubStr(%address, %portPos+1, strLen(%address)); + %address = getSubStr(%address, 0, %portPos); + + // Pick a unique name + %uniqueName = ""; + for (%i = 0; %i < %this.maximumClients; %i++) + { + %name = %this.uniqueName[%i]; + if (!%this.uniqueNameInUse[%name]) + { + %uniqueName = %name; + %this.uniqueNameInUse[%name] = true; + break; + } + } + + // If we were unable to find a good unique name + %charList = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + %uniqueStringLen = 6; // Adjust this if needed, but there shouldn't be a reason to + if (%uniqueName $= "") + { + while (true) + { + %uniqueName = generateString(%uniqueStringLen, %charList); + if (!isObject(%uniqueName)) break; + else %uniqueName = ""; + } + %eval = strReplace($HTTPServer::ClientReplicate, "*UNIQUESOCKET*", %uniqueName); + eval(%eval); + + %this.uniqueName[%this.maximumClients] = %uniqueName; + %this.uniqueNameInUse[%uniqueName] = true; + %this.maximumClients++; + } + // Create The Client Socket + %connection = new TCPObject(%uniqueName,%socket) { class = ConnectionTCP; parent = %this; Address = %address; Port = %port; }; + if (!%this.allowMultiConnect) + %this.connections[%address] = %connection; + else + %this.connections[%address, %port] = %connection; + + %this.connectionCount++; + %this.onClientConnect(%address, %connection); + logEcho("Received client connection from " @ %address); + + %this.schedule(10000,"connectionDropped",%connection); + + return true; +} + +// Callbacks -- make these do whatever you please! +function HTTPServer::onClientConnect(%this, %address, %socket) +{ + echo("Received connection from " @ %address @ ". ID:" @ %socket); + return true; +} +function HTTPServer::onClientRejected(%this, %socket, %reason) // %reason is always zero as of now. +{ + return true; +} +function HTTPServer::onClientDisconnect(%this, %socket) +{ + logEcho("Received Disconnect (" @ %socket @ ")"); + %socket.delete(); + return true; +} +function HTTPServer::onLine(%this, %socket, %line) +{ + %reqType = getWord(%line, 0); + if (%reqType $= "GET") + { + %req = getWord(%line, 1); + %reqLen = strLen(%req); + %socket.request = getSubStr(%req, 1, %reqLen); + %socket.request = strReplace(%socket.request, "%20", " "); + %socket.request = %this.Root @ %socket.request; + %socket.requestType = "GET"; + } + + %data = "
404 - Not Found
Oops!
File not found."; + %forbiddenData = "
403- Forbidden
Oops!
You're not allowed to see this."; + + %packet = new ScriptObject(){ class = "HTTPResponsePacket"; }; + //return; + // We received the end-of-packet from a socket + if (%line $= "") + { + //Shitty + if (strStr(%socket.request,".") != -1) + { + if (!isFile(%socket.request)) + %packet.setStatusCode(404); + + else if (%socket.request $= "prefs/ClientPrefs.cs") + { + %packet.setStatusCode(403); + %data = %forbiddenData; + } + else if (getFileExtensionFromString(%socket.request) $= "cs") + { + %packet.setStatusCode(200); + + // FIXME: INSECURE and gay + exec(%socket.request); + %class = strReplace(getFileNameFromString(%socket.request), ".cs", ""); // FIXME: Crappy + %instance = new ScriptObject() { class = %class; }; + %data = %instance.contents(); + %instance.delete(); + } + else + { + %packet.setStatusCode(403); + %data = %forbiddenData; + } + + // Check the file type + %extension = getFileExtensionFromString(%socket.request); + if (%extension $= "html" || %extension $= "htm") + { + %script = strReplace(%socket.request,".html",".cs"); + if (isFile(%script)) + { + exec(%script); + %Object = new ScriptObject(){ class = "ServerApp"; }; + %data = %Object.execute(%data); + %Object.delete(); + } + } + } + else + { + %packet.setStatusCode(200); + %data = "\n
\n\nDirectory\n\n
\n

Directory of " @ %socket.request @ "

\n"; + for( %file = findFirstFile( %socket.request @ "*.*" ); %file !$= ""; %file = findNextFile( %socket.request @ "*.*" ) ) + { + %file = strReplace(%file, %socket.request, ""); + if (strStr(%file, "/") != -1) + { + %dir = getSubStr(%file, 0, strStr(%file, "/")) @ "/"; + if (!%dirAdded[%dir]) + { + %data = %data @ "" @ %dir @ "
\n"; + %dirAdded[%dir] = true; + } + } + else + %data = %data @ "" @ %file @ "
\n"; + } + %data = %data @ "\n\n"; + } + %packet.setHeader("Date",formatTimeString("DD, dd MM yy hh:nn:ss ") @ "Eastern"); + %packet.setHeader("Server","Tribes 2"); + %packet.setHeader("Content-Type","text/html"); + %packet.setPayload(%data); + %socket.sendPacket(%packet); + %packet.delete(); + %this.connectionDropped(%socket); + } + if (isObject(%packet)) + %packet.delete(); + return true; +} + +// Packet Functions (used for packet generation/reading) +function HTTPResponsePacket::setHeader(%this, %name, %value) +{ + if (%this.headerCount == "") + %this.headerCount = 0; + + if (%this.headers[%name] $= "") + { + %this.headerName[%this.headerCount] = %name; + %this.headerCount++; + } + %this.headers[%name] = %name @ ": " @ %value @ "\n"; + return true; +} + +function HTTPResponsePacket::setStatusCode(%this, %code) +{ + %this.statusCode = "HTTP/1.1 " @ %code SPC "OK\n"; + return true; +} + +function HTTPResponsePacket::setPayload(%this, %data) +{ + %this.payLoad = %data; + %this.payloadSize = strLen(%data); + %this.setHeader("Content-Length", %this.payloadSize); + return true; +} + +// Lib Functions +function generateString(%length, %alpha) +{ + %len = strLen(%alpha); + %result = ""; + for (%i = 0; %i < %length; %i++) + %result = %result @ getSubStr(%alpha, getRandom(0, %len), 1); + return %result; +} + +// -- +// BoL Specific Code -- automatically load the server if enabled +if (!IsObject(HTTPServerPrefs)) + new ScriptObject(HTTPServerPrefs) { class = "BasicDataParser"; }; +HTTPServerPrefs.empty(); +HTTPServerPrefs.load("prefs/WebServer.conf"); +%generic = HTTPServerPrefs.get("Generic",0); +if(%generic.element("Enabled") $= "true") +{ + new ScriptObject(WebServer) { class = "HTTPServer"; }; + WebServer.listen(%generic.element("Host"),%generic.element("Port"),%generic.element("StartWorkers")); +} +// -- \ No newline at end of file diff --git a/scripts/modscripts/server/RPG/ClientFunctions.cs b/scripts/modscripts/server/RPG/ClientFunctions.cs new file mode 100644 index 0000000..dfbf391 --- /dev/null +++ b/scripts/modscripts/server/RPG/ClientFunctions.cs @@ -0,0 +1,49 @@ +//------------------------------------------------------------------------------ +// BoLFunctions.cs +// T2BoL Specific Functions +// Copyright (c) 2012 Robert MacGregor +//------------------------------------------------------------------------------ + +function GameConnection::saveState(%this) +{ + if ($CurrentMissionType !$= "RPG") + { + error("Not running the BoL gamemode."); + return false; + } + + return true; +} + +function GameConnection::loadState(%this, %file) +{ + if ($CurrentMissionType !$= "RPG") + { + error("Not running the BoL gamemode."); + return false; + } + + return true; +} + +function AIConnection::saveState(%this) +{ + if ($CurrentMissionType !$= "RPG") + { + error("Not running the BoL gamemode."); + return false; + } + + return true; +} + +function AIConnection::loadState(%this, %file) +{ + if ($CurrentMissionType !$= "RPG") + { + error("Not running the BoL gamemode."); + return false; + } + + return true; +} \ No newline at end of file diff --git a/scripts/modscripts/server/RPG/GameTriggers.cs b/scripts/modscripts/server/RPG/GameTriggers.cs new file mode 100644 index 0000000..de1a929 --- /dev/null +++ b/scripts/modscripts/server/RPG/GameTriggers.cs @@ -0,0 +1,31 @@ +//------------------------------------------------------------------------------ +// GameTriggers.cs +// Trigger code for RPG Gamemode +// Copyright (c) 2012 Robert MacGregor +//============================================================================== + +$BOL::Triggers::Territory = 0; +$BOL::Triggers::Damage = 1; +$BOL::Triggers::TeleportStart = 2; +$PDA::Triggers::TeleportEnd = 3; + +function RPGGame::onEnterTrigger(%game, %name, %data, %obj, %colObj) +{ + switch (%obj.Type) + { + case $BOL::Triggers::Territory: + echo("LOL"); + return; + } +} + +function RPGGame::onLeaveTrigger(%game, %name, %data, %obj, %colObj) +{ + return true; +} + +function RPGGame::onTickTrigger(%game, %name, %data, %obj) +{ + + return true; +} diff --git a/scripts/modscripts/server/RPG/Interact.cs b/scripts/modscripts/server/RPG/Interact.cs new file mode 100644 index 0000000..166a1c5 --- /dev/null +++ b/scripts/modscripts/server/RPG/Interact.cs @@ -0,0 +1,63 @@ +//--$BOL::PDA::Page::Interact---------------------------------------------------------------------------- +// Interact.cs +// Functions for object interaction in T2BoL +// Copyright (c) 2012 Robert MacGregor +//------------------------------------------------------------------------------ + +$BOL::Interact::Type::General = 0; // Generic; jus makes conversation + +$BOL::Interact::Range = 50; // In Meters +function serverCmdInteractWithObject(%client) +{ + if (!IsObject(%client.player) || %client.player.getState() !$= "Move") + { + messageClient(%client, 'MsgClient', "\c3Sorry, you appear to be dead."); + return false; + } + + %player = %client.player; + %pos = getWords(%player.getEyeTransform(), 0, 2); + %vec = %player.getMuzzleVector($WeaponSlot); + %targetpos=vectoradd(%pos,vectorscale(%vec,5000)); + + %object = getWord(containerRayCast(%pos,%targetpos,$TypeMasks::PlayerObjectType | $TypeMasks::VehicleObjectType,%player),0); + echo(%object); + if (!isObject(%object) || !%object.isInteractive) + return false; + + %client.pdaPage = $BOL::PDA::Page::Interacted; + serverCmdShowHud(%client, 'scoreScreen'); + return true; +} + +function Player::interactListUpdate(%this) +{ + if (!isObject(%this.interactList)) + %this.interactList = Array.create(); + + // We don't want to run multiple threads ... + cancel(%this.interactListUpdateThread); + // We also don't need dead people or bots to be doing this either + if ((%this.getState() !$= "Move" && %this.getState() !$= "Mounted") || %this.client.isAIControlled()) + return; + + %found = Array.create(); // This takes up one objID per call, but objID's go up to 2^32, so this shouldn't matter as it helps make cleaner code here + %found_anything = false; + InitContainerRadiusSearch(%this.getWorldBoxCenter(), $BOL::Interact::Range, $TypeMasks::PlayerObjectType | $TypeMasks::VehicleObjectType); + while ((%target = containerSearchNext()) != 0) + { + //if (!calcExplosionCoverage(%this.getWorldBoxCenter(), %target,$TypeMasks::PlayerObjectType | $TypeMasks::VehicleObjectType)) + // continue; + %found.setElement(%found.count(), %target); + if(isObject(%target) && %target !$= %this && !%this.interactList.hasElementValue(%target)) + %this.interactList.setElement(%this.interactList.count(), %target); + } + + // Remove any non-found elements from the interact list + for (%i = %this.interactList.count(); %i > -1; %i--) + if (!%found.hasElementValue(%this.interactList.element(%i))) + %this.interactList.removeElement(%i); + + %found.delete(); + %this.interactListUpdateThread = %this.schedule(100, "interactListUpdate"); +} \ No newline at end of file diff --git a/scripts/modscripts/server/RPG/PDA.cs b/scripts/modscripts/server/RPG/PDA.cs new file mode 100644 index 0000000..626e6b9 --- /dev/null +++ b/scripts/modscripts/server/RPG/PDA.cs @@ -0,0 +1,268 @@ +//------------------------------------------------------------------------------ +// PDA.cs +// PDA code for T2BoL +// Copyright (c) 2012 Robert MacGregor +//============================================================================== + +// 0-100 +$BOL::PDA::Page::Main = 0; + +$BOL::PDA::Page::Applications = 1; +$BOL::PDA::Page::Close = 2; // Not even necessarily a page but it's used to signal the client wants to close +$BOL::PDA::Page::Stats = 3; +$BOL::PDA::Page::Save = 4; +$BOL::PDA::Page::FactionManagement = 5; + +$BOL::PDA::Page::Radio = 6; +$BOL::PDA::Page::Voice = 7; + +$BOL::PDA::Function::Increment = 1; +$BOL::PDA::Function::Decrement = 2; + +$BOL::PDA::Page::EMail = 8; +$BOL::PDA::Page::Inbox = 9; +$BOL::PDA::Page::Outbox = 10; +$BOL::PDA::Page::Compose = 11; + +$BOL::PDA::Page::Wiki = 12; + +// 101-201 +$BOL::PDA::Page::Interact = 101; +$BOL::PDA::Page::Interacted = 102; +$BOL::PDA::Page::Hack = 103; +$BOL::PDA::Page::Information = 104; + +function RPGGame::updateScoreHud(%game, %client, %tag) +{ + if (%client.PDAPage == $BOL::PDA::Page::Main || %client.PDAPage == $BOL::PDA::Page::Interact) + Game.processGameLink(%client, %client.PDAPage); +} + +function RPGGame::processGameLink(%game, %client, %arg1, %arg2, %arg3, %arg4, %arg5) +{ + %index = 0; + if (%arg1 != $BOL::PDA::Page::Close) + %client.PDAPage = %arg1; + messageClient( %client, 'ClearHud', "", 'scoreScreen', 0 ); + + switch(%arg1) + { + //------------------------------------------------------------------------------ + // PDA Applications + //------------------------------------------------------------------------------ + case $BOL::PDA::Page::Applications: + messageClient( %client, 'SetScoreHudSubheader', "", 'Applications | Main'); + messageClient( %client, 'SetScoreHudHeader', "", "| Wiki | Applications | E-Mail | Close"); + + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Command List:"); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "- Self Diagnosis"); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "- Interact with Object"); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "- Radio"); + %index++; + if (!$Host::GlobalChat) + { + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "- Voice Settings"); + %index++; + } + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "- Faction Management"); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "- Save State"); + return; + + case $BOL::PDA::Page::Stats: + messageClient( %client, 'SetScoreHudHeader', "", "Automated Self Diagnosis Systems v1.2Close"); + messageClient( %client, 'SetScoreHudSubheader', "", 'Copyright (c) 3030 S.G.S. Corporation'); + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Subject Name: " @ %client.namebase); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Subject Species: " @ %client.race); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Subject Condition: " @ 100 - mfloor(100*%client.player.getDamageLevel()) @ "%"); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, " "); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "REFRESH"); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "RETURN TO MAIN"); + return; + + case $BOL::PDA::Page::Radio: + messageClient( %client, 'SetScoreHudSubheader', "", 'Applications | Radio'); + + if (!%client.hasRadio) + { + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "-- You do not have a radio to manage --"); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, " "); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "RETURN TO MAIN"); + return; + } + + switch (%arg2) + { + case $BOL::PDA::Function::Increment: + ServerCmdIncreaseRadioFrequency(%client, true); + case $BOL::PDA::Function::Decrement: + ServerCmdDecreaseRadioFrequency(%client, true); + } + + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Radio Status: Normal"); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Current Frequency: " @ %client.radioFrequency @ "MHz"); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "[Increment Frequency - Decrement Frequency]"); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, " "); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "RETURN TO MAIN"); + return; + + case $BOL::PDA::Page::Voice: + messageClient( %client, 'SetScoreHudSubheader', "", 'Applications | Voice Settings'); + + switch (%arg2) + { + case $BOL::PDA::Function::Increment: + serverCmdIncreaseVoiceRange(%client, true); + case $BOL::PDA::Function::Decrement: + serverCmdDecreaseVoiceRange(%client, true); + } + + %voice = %client.voiceMode; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Voice Status: Normal"); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Current Voice: \x22" @ $BOL::Voice::Display[%voice] @ "\x22 (" @ $BOL::Voice::Range[%voice] @ " meters)"); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "[Increment Range - Decrement Range]"); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, " "); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "RETURN TO MAIN"); + return; + + case $BOL::PDA::Page::Interact: + messageClient( %client, 'SetScoreHudSubheader', "", 'Applications | Interact with Object'); + + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "-- Objects within Range --"); + %index++; + + %client_team = getTargetSensorGroup(%client.target); + %object_count = %client.player.interactList.count(); + if (%object_count > 0) + for (%i = 0; %i < %object_count; %i++) + { + %object = %client.player.interactList.element(%i); + if (isObject(%object)) + { + %object_target = %object.target; + if (%object_target != -1) + { + %object_team = getTargetSensorGroup(%object_target); + %object_friendly = %client_team == %object_team; + %object_friend_text = %object_friendly ? "Friendly" : "Enemy"; + %display = %object_friend_text SPC %object.getClassName() SPC "\x22" @ getTaggedString(getTargetName(%object_target)) @ "\x22"; + } + else + %display = "Unknown" SPC %object.getClassName() SPC "(" @ %object @ ")"; + + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "" @ %display); + %index++; + } + } + else + { + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "There are no objects in range."); + %index++; + } + + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, " "); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "RETURN TO MAIN"); + return; + + + case $BOL::PDA::Page::FactionManagement: + messageClient( %client, 'SetScoreHudSubheader', "", 'Applications | Faction Management'); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "RETURN TO MAIN"); + return; + + case $BOL::PDA::Page::Save: + messageClient( %client, 'SetScoreHudHeader', "", 'Save StateClose'); + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Save function is not supported as of now!"); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "RETURN TO MAIN"); + return; + + //------------------------------------------------------------------------------ + // PDA E-Mail System + //------------------------------------------------------------------------------ + case $BOL::PDA::Page::Inbox: + messageClient( %client, 'SetScoreHudSubheader', "", 'E-Mail | Your Inbox'); + return; + case $BOL::PDA::Page::Outbox: + messageClient( %client, 'SetScoreHudSubheader', "", 'E-Mail | Your Outbox'); + return; + case $BOL::PDA::Page::Compose: + messageClient( %client, 'SetScoreHudSubheader', "", 'E-Mail | Compose a New Mail'); + return; + + + //------------------------------------------------------------------------------ + // Interaction Commands + //------------------------------------------------------------------------------ + case $BOL::PDA::Page::Interact: + return; + + //------------------------------------------------------------------------------ + // Handle for Normal PDA functions + //------------------------------------------------------------------------------ + case $BOL::PDA::Page::Main: + messageClient( %client, 'SetScoreHudHeader', "", "| Wiki | Applications | E-Mail | Close"); + messageClient( %client, 'SetScoreHudSubheader', "", 'Welcome to the PDA'); + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Welcome to the PDA, this is where you will accomplish some daily tasks."); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Click any of the text in the subheader to begin exploring your PDA."); + return; + + case $BOL::PDA::Page::EMail: + messageClient( %client, 'SetScoreHudSubheader', "", 'E-Mail | Main'); + messageClient( %client, 'SetScoreHudHeader', "", "| Wiki | Applications | E-Mail | Close"); + + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "E-Mail Functions:"); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, " - Your Inbox (?)"); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, " - Your Outbox (?)"); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, " - Compose a New Mail"); + return; + + case $BOL::PDA::Page::Close: + serverCmdHideHud(%client, 'scoreScreen'); + commandToClient(%client, 'DisplayHuds'); + return; + + case $BOL::PDA::Page::Wiki: + messageClient( %client, 'SetScoreHudHeader', "", "| Wiki | Applications | E-Mail | Close"); + messageClient( %client, 'SetScoreHudSubheader', "", 'Wiki | Main'); + return; + + default: // In case something stupid happens + messageClient( %client, 'SetScoreHudHeader', "", "| Information | Applications | E-Mail | Wiki | Close"); + messageClient( %client, 'SetScoreHudSubheader', "", 'Error | Main'); + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "-- An ERROR has occurred in the PDA Subsystem code --"); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "-- Please report this error to DarkDragonDX --"); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "Unknown PDA page: " @ %arg1); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, " "); + %index++; + messageClient( %client, 'SetLineHud', "", 'scoreScreen', %index, "-- RETURN TO MAIN --"); + return; + } +} \ No newline at end of file diff --git a/scripts/modScripts/server/RPG/PDAApplication.cs b/scripts/modscripts/server/RPG/PDAApplication.cs similarity index 90% rename from scripts/modScripts/server/RPG/PDAApplication.cs rename to scripts/modscripts/server/RPG/PDAApplication.cs index 94e7e87..34e8e2a 100644 --- a/scripts/modScripts/server/RPG/PDAApplication.cs +++ b/scripts/modscripts/server/RPG/PDAApplication.cs @@ -1,32 +1,32 @@ -//------------------------------------------------------------------------------ -// PDAApplication.cs -// Application SDK for the PDA. (to make my life easier) -// Copyright (c) 2012 The DarkDragonDX -//============================================================================== - -function PDAApplication::main(%this, %client) -{ -} - -function PDAApplication::action(%this, %client, %page) -{ -} - -function PDAApplication::exit(%this, %client, %page) -{ -} - -// API Functions -function PDAApplication::setTitle(%this, %title) -{ - // Won't do anything for now because the title is a clientside thing, actually. -} - -function PDAApplication::cls(%this) -{ -} - -// The script parses = $BOL::Radio::Max) %client.radioFrequency = $BOL::Radio::Min; else %client.radioFrequency++; if (!%noDisplay) messageClient(%client, 'msgClient',"\c3You tune your radio to " @ %client.radioFrequency @ $BOL::Radio::Units @ "."); } function ServerCmdDecreaseRadioFrequency(%client, %noDisplay) { if (!%client.hasRadio) { messageClient(%client, 'msgClient', "\c3You have no radio to tune."); return; } if (%client.radioFrequency == 0) %client.radioFrequency = 1; if (%client.radioFrequency <= $BOL::Radio::Min) %client.radioFrequency = $BOL::Radio::Max; else %client.radioFrequency--; if (!%noDisplay) messageClient(%client, 'msgClient',"\c3You tune your radio to " @ %client.radioFrequency @ $BOL::Radio::Units @ "."); } function radioBroadcast( %text, %frequency ) { %units = $BOL::Radio::Units; %count = ClientGroup.getCount(); for ( %i = 0; %i < %count; %i++ ) { %client = ClientGroup.getObject( %i ); if ( %client.hasRadio && %client.radioFrequency == %frequency ) messageClient(%client,'msgClient',"\c3(" @ %frequency @ %units @ "): " @ %text @ "~wfx/misc/static.wav"); } } function radioChatMessageTeam( %sender, %team, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 ) { if (!%sender.hasRadio) { messageClient(%sender,'msgNoRadio',"\c3You must have a radio."); return; } %frequency = %sender.radioFrequency; if (%frequency < $BOL::Radio::Min || %frequency > $BOL::Radio::Max) { %sender.radioFrequency = $BOL::Radio::Min; messageClient(%sender,'msgClient',"\c3Your radio appears to be in dire need of retuning."); return; } %units = $BOL::Radio::Units; %count = ClientGroup.getCount(); for ( %i = 0; %i < %count; %i++ ) { %client = ClientGroup.getObject(%i); if ( %client.hasRadio && %client.radioFrequency == %sender.radioFrequency ) messageClient(%client,'msgClient',"\c3"@ %sender.namebase@ " (" @ %frequency @ %units @ "): "@%a2@" ~wfx/misc/static.wav"); } } \ No newline at end of file diff --git a/scripts/modscripts/server/RPG/RangedVoice.cs b/scripts/modscripts/server/RPG/RangedVoice.cs new file mode 100644 index 0000000..d129951 --- /dev/null +++ b/scripts/modscripts/server/RPG/RangedVoice.cs @@ -0,0 +1,98 @@ +//------------------------------------------------------------------------------ +// rangedVoice.cs +// Functions for ranged voice in T2BoL +// Copyright (c) 2012 Robert MacGregor +//------------------------------------------------------------------------------ + +$BOL::Voice::Whisper = 0; +$BOL::Voice::Range[0] = 15; +$BOL::Voice::Display[0] = "Whispering"; + +$BOL::Voice::Speak = 1; +$BOL::voice::Range[1] = 25; +$BOL::Voice::Display[1] = "Speaking"; + +$BOL::Voice::Yell = 2; +$BOL::Voice::Range[2] = 50; +$BOL::Voice::Display[2] = "Yelling"; + +$BOL::Voice::Scream = 3; +$BOL::Voice::Range[3] = 100; +$BOL::Voice::Display[3] = "Screaming"; + +$BOL::Voice::Total = 4; + +function serverCmdIncreaseVoiceRange(%client, %noDisplay) +{ + if ($CurrentMissionType $= "RPG" && $Host::GlobalChat) + { + messageClient(%client, 'msgClient', "\c3Server has global chat enabled."); + return; + } + else if ($CurrentMissionType !$= "RPG") + { + messageClient(%client, 'msgClient', "\c3Server is not running the RPG gamemode currently."); + return; + } + + if (%client.voiceMode >= $BOL::Voice::Total-1) + %client.voiceMode = 0; + else + %client.voiceMode++; + %display = $BOL::Voice::Display[%client.voiceMode]; + %range = $BOL::Voice::Range[%client.voiceMode]; + if (!%noDisplay) + messageClient(%client, 'msgClient',"\c3Voice mode set to \"" @ %display @ "\" (" @ %range @ "m)"); +} + +function serverCmdDecreaseVoiceRange(%client, %noDisplay) +{ + if ($CurrentMissionType $= "RPG" && $Host::GlobalChat) + { + messageClient(%client, 'msgClient', "\c3Server has global chat enabled."); + return; + } + else if ($CurrentMissionType !$= "RPG") + { + messageClient(%client, 'msgClient', "\c3Server is not running the RPG gamemode currently."); + return; + } + + if (%client.voiceMode <= 0) + %client.voiceMode = $BOL::Voice::Total-1; + else + %client.voiceMode--; + %display = $BOL::Voice::Display[%client.voiceMode]; + %range = $BOL::Voice::Range[%client.voiceMode]; + if (!%noDisplay) + messageClient(%client, 'msgClient',"\c3Voice mode set to \"" @ %display @ "\" (" @ %range @ "m)"); +} + +function rangedchatMessageAll(%sender, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10) +{ + %mode = %sender.voiceMode; + + if (%mode < 0 || %mode >= $BOL::Voice::Total) + { + %sender.voiceMode = 0; + %mode = 0; + messageClient(%sender,'msgClient',"\c3Your throat feels agitated."); + } + %voicedist = $BOL::Voice::Range[%sender.voiceMode]; + %display = $BOL::Voice::Display[%sender.voiceMode]; + %count = MissionCleanup.getCount(); + + for (%i = 0; %i < %count; %i++) + { + %obj = MissionCleanup.getObject(%i); + if (%obj.getClassName() $= "Player") + { + %dist = vectorDist(%sender.player.getPosition(),%obj.getPosition()); + if (%dist <= %voicedist) + { + %string = addTaggedString("(" @ %display @ " - " @ %voicedist @ "m) " @ getTaggedString(%a1)); + chatMessageClient( %obj.client, %sender, %sender.voiceTag, %sender.voicePitch, %msgString, %string, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 ); + } + } + } +} \ No newline at end of file diff --git a/scripts/modscripts/server/RPG/dataImport.cs b/scripts/modscripts/server/RPG/dataImport.cs new file mode 100644 index 0000000..49bc831 --- /dev/null +++ b/scripts/modscripts/server/RPG/dataImport.cs @@ -0,0 +1,302 @@ +//------------------------------------------------------------------------------ +// scripts/modScripts/server/dataImport.cs +// Copyright (c) 2012 Robert MacGregor +//------------------------------------------------------------------------------ + +function gameConnection::writeSaveFile(%this) +{ + //Compile Main Variable List + %mission = $CurrentMission; + %player = %this.player; + %transform = %player.getTransform(); + %velocity = %player.getVelocity(); + %damage = %player.getDamageLevel(); + %race = %this.race; + %armor = %this.armor; + %energy = %player.getEnergyLevel(); + %whiteout = %player.getWhiteout(); + %damageFlash = %player.getDamageFlash(); + %cash = %this.cash; + %hasRadio = %this.hasRadio; + %underStandsHuman = %this.underStandsHuman; + %underStandsBioderm = %this.underStandsBioderm; + %underStandsDraakan = %this.underStandsDraakan; + %underStandsCriollos = %this.underStandsCriollos; + + %time = formatTimeString("hh:nn A"); + %date = formatTimeString("mm/dd/yy"); + + %file = "data/game/saves/" @ %mission @ "/" @ %this.guid @ ".txt"; + %fileObj = new fileObject(); + %fileObj.openForWrite(%file); + %fileObj.writeLine(";Saved by" SPC %this.nameBase SPC "on" SPC %date SPC "at" SPC %time); + %fileObj.writeLine(""); + + //Todo: Make this writing method more efficient ... + %fileObj.writeLine("[Character]"); + %fileObj.writeLine("transform = \x22" @ %transform @ "\x22;"); + %fileObj.writeLine("velocity = \x22" @ %velocity @ "\x22;"); + %fileObj.writeLine("damage = \x22" @ %damage @ "\x22;"); + %fileObj.writeLine("race = \x22" @ %race @ "\x22;"); + %fileObj.writeLine("armor = \x22" @ %armor @ "\x22;"); + %fileObj.writeLine("energy = \x22" @ %energy @ "\x22;"); + %fileObj.writeLine("whiteOut = \x22" @ %whiteout @ "\x22;"); + %fileObj.writeLine("damageFlash = \x22" @ %damageFlash @ "\x22;"); + %fileObj.writeLine("cash = \x22" @ %cash @ "\x22;"); + %fileObj.writeLine("hasRadio = \x22" @ %hasRadio @ "\x22;"); + %fileObj.writeLine("underStandsHuman = \x22" @ %underStandsHuman @ "\x22;"); + %fileObj.writeLine("underStandsBioderm = \x22" @ %underStandsBioderm @ "\x22;"); + %fileObj.writeLine("underStandsDraakan = \x22" @ %underStandsDraakan @ "\x22;"); + %fileObj.writeLine("underStandsCriollos = \x22" @ %underStandsCriollos @ "\x22;"); + %fileObj.writeLine(""); + + //Compile Inventory List + %slotCount = %player.weaponSlotCount; + %healthKits = %player.invRepairKit; + %fileObj.writeLine("[Inventory]"); + %fileObj.writeLine("slotCount = \x22" @ %slotCount @ "\x22;"); + + for (%i = 0; %i < %slotCount; %i++) + { + %weaponName = %player.weaponSlot[%i]; + %weaponAmmo = eval("%weaponAmmo = %player.inv" @ %weaponName @ "Ammo" @ ";"); + %fileObj.writeLine("slot" @ %i SPC "= \x22" @ %weaponName @ "\x22;"); + %fileObj.writeLine("slot" @ %i @ "Ammo" SPC "= \x22" @ %weaponAmmo @ "\x22;"); + } + + %fileObj.writeLine("healthKits = \x22" @ %healthKits @ "\x22;"); + %fileObj.detach(); + logEcho(" -- Save File Written for Player:" SPC %this.namebase SPC "--"); + return true; +} + +function gameConnection::applySaveFile(%this) +{ + //Compile Main Variable List + %mission = $CurrentMission; + %file = "data/game/saves/" @ %mission @ "/" @ %this.guid @ ".txt"; + + if (!isFile(%file)) + return false; + + %transform = getBlockData(%file,"Character",1,"transform"); + %velocity = getBlockData(%file,"Character",1,"velocity"); + %damage = getBlockData(%file,"Character",1,"damage"); + %race = getBlockData(%file,"Character",1,"race"); + %armor = getBlockData(%file,"Character",1,"armor"); + %energy = getBlockData(%file,"Character",1,"energyLevel"); + %whiteout = getBlockData(%file,"Character",1,"whiteOut"); + %damageFlash = getBlockData(%file,"Character",1,"damageFlash"); + %cash = getBlockData(%file,"Character",1,"cash"); + %hasRadio = getBlockData(%file,"Character",1,"hasRadio"); + %underStandsHuman = getBlockData(%file,"Character",1,"underStandsHuman"); + %underStandsBioderm = getBlockData(%file,"Character",1,"underStandsBioderm"); + %underStandsDraakan = getBlockData(%file,"Character",1,"underStandsDraakan"); + %underStandsCriollos = getBlockData(%file,"Character",1,"underStandsCriollos"); + + %player = %this.player; + %player.setTransform(%transform); + %player.setVelocity(%velocity); + %player.applyDamage(%damage); + %player.setArmor(%armor); + %player.setEnergyLevel(%energy); + %player.setWhiteout(%whiteOut); + %player.setDamageFlash(%damageFlash); + %this.cash = %cash; + %this.underStandsHuman = %underStandsHuman; + %this.underStandsBioderm = %underStandsBioderm; + %this.underStandsDraakan = %underStandsDraakan; + %this.underStandsCriollos = %underStandsCriollos; + + return true; + for (%i = 0; %i < %slotCount; %i++) + { + %weaponName = %player.weaponSlot[%i]; + %weaponAmmo = eval("%weaponAmmo = %player.inv" @ %weaponName @ "Ammo" @ ";"); + %fileObj.writeLine("slot" @ %i SPC "= \x22" @ %weaponName @ "\x22;"); + %fileObj.writeLine("slot" @ %i @ "Ammo" SPC "= \x22" @ %weaponAmmo @ "\x22;"); + } + + %fileObj.writeLine("healthKits = \x22" @ %healthKits @ "\x22;"); + return; +} + +// Generic Import Functions +function importGameData() +{ + importGems(); + importOres(); + importCharacters(); + return true; +} + +// Gem Import Functions +function importGems() +{ + if (!IsObject(GemData)) + { + new ScriptObject(GemData); + + if (!IsObject(GameData)) + new simGroup(GameData); + + GameData.add(GemData); + } + else + return true; + + %file = "data/game/gems.txt"; + %count = getBlockCount(%file,"Gem") + 1; + + for (%i = 1; %i < %count; %i++) + { + %name = getBlockData(%file,"Gem",%i,"Name"); + %price = getBlockData(%file,"Gem",%i,"Price"); + %sellPrice = getBlockData(%file,"Gem",%i,"SellPrice"); + + GemData.gem[%i] = %name; + GemData.price[%name] = %price; + GemData.sellPrice[%name] = %sellPrice; + warn("Imported gem:" SPC %name); + + GemData.gemCount = %count--; + } + +// Ore Import Functions +function importOres() +{ + if (!IsObject(OreData)) + { + new ScriptObject(OreData); + + if (!IsObject(GameData)) + new simGroup(GameData); + + GameData.add(OreData); + } + else + return true; + + %file = "data/game/ores.txt"; + %count = getBlockCount(%file,"Ore") + 1; + + for (%i = 1; %i < %count; %i++) + { + %name = getBlockData(%file,"Ore",%i,"Name"); + %price = getBlockData(%file,"Ore",%i,"Price"); + %sellPrice = getBlockData(%file,"Ore",%i,"SellPrice"); + + OreData.ore[%i] = %name; + OreData.price[%name] = %price; + OreData.sellPrice[%name] = %sellPrice; + warn("Imported ore:" SPC %name); + } + OreData.oreCount = %count--; +} + +// Character Import Functions +function spawnCharacter(%name,%trans,%aimPos,%team) +{ + %object = "Character" @ %name; + + if (!IsObject(%object)) + return false; + + %Bname = %object.name; + %race = %object.race; + %skin = %object.skin; + %voice = %object.voice; + %voicePitch = %object.voicePitch; + %sex = %object.sex; + + %bot = aiConnectByName(%Bname,%team); + %bot.race = %race; + %bot.skin = addTaggedString(%skin); + %bot.voice = %voice; + %bot.voiceTag = addTaggedString(%voice); + %bot.voicePitch = %voicePitch; + %bot.sex = %sex; + setVoice(%bot,%voice, %voicePitch); + setSkin(%bot,%skin); + setSkin(%bot,%skin); + setTeam(%bot, %team); + %bot.player.setArmor("light"); + %bot.player.setTransform(%trans); + %bot.aimAt(%aimPos); + warn("Spawned Character:" SPC %name); +} + +function importCharacters() +{ + %path = "data/game/characters/*.txt"; + for( %file = findFirstFile( %path ); %file !$= ""; %file = findNextFile( %path ) ) + { + %name = getFileNameFromString(%file); + %pos = strStr(%name,"."); + %character = getSubStr(%name,0,%pos); + importCharacter(%character); + } +} + +function importCharacter(%character) +{ + %prefix = "data/game/characters/"; + %file = %prefix @ %character @ ".txt"; + %charName = %character; + %character = strReplace("Character" @ %character," ","_"); + + if (!IsFile(%file)) + return false; + + if (!IsObject(%character)) + { + new scriptObject(%character); + if (!IsObject(GameData)) + new simGroup(GameData); + + GameData.add(%character); + } + else + return true; + + //Get our variable values ... + %name = getBlockData(%file,"Character",1,"Name"); + %race = getBlockData(%file,"Character",1,"Race"); + %sex = getBlockData(%file,"Character",1,"Sex"); + %skin = getBlockData(%file,"Character",1,"Skin"); + %voice = getBlockData(%file,"Character",1,"Voice"); + %voicePitch = getBlockData(%file,"Character",1,"VoicePitch"); + + //Import Message Arrays ... and assign them + %arrayName[0] = "Death"; + %arrayName[1] = "Kill"; + %arrayName[2] = "Healed"; + %arrayCount = 3; + + for (%i = 0; %i < %arrayCount; %i++) + { + %arrayVariableName[%i] = %arrayName[%i] @ "MessageArray"; + for (%j = 0; %j < 100; %j++) + { + %arrayTest = getArrayData(%file,%arrayName[%i],%j); + if (%arrayTest !$= "}") + { + if (%j == 0) + %arrayData[%i] = %arrayData[%i] @ %arrayTest; + else + %arrayData[%i] = %arrayData[%i] @ "\t" @ %arrayTest; + } + else + break; + } + eval(%character @ "." @ %arrayVariableName[%i] SPC "= \x22" @ %arrayData[%i] @ "\x22;"); + } + //Assign the variables now ... + %character.name = %name; + %character.race = %race; + %character.sex = %sex; + %character.skin = %skin; + %character.voice = %voice; + %character.voicePitch = %voicePitch; + warn("Imported Character:" SPC %charname); +} diff --git a/scripts/modscripts/server/RPG/initialise.cs b/scripts/modscripts/server/RPG/initialise.cs new file mode 100644 index 0000000..d7373bb --- /dev/null +++ b/scripts/modscripts/server/RPG/initialise.cs @@ -0,0 +1 @@ +//------------------------------------------------------------------------------ // initialise.cs // Code executed by scripts/RPGGame.cs to load up any BoL specific components. // Copyright (c) 2012 Robert MacGregor //============================================================================== exec("scripts/ModScripts/Server/RPG/ClientFunctions.cs"); exec("scripts/ModScripts/Server/RPG/GameTriggers.cs"); exec("scripts/ModScripts/Server/RPG/PDA.cs"); exec("scripts/ModScripts/Server/RPG/RangedVoice.cs"); exec("scripts/ModScripts/Server/RPG/RadioChat.cs"); exec("scripts/ModScripts/Server/RPG/Interact.cs"); \ No newline at end of file diff --git a/scripts/modScripts/server/looting.cs b/scripts/modscripts/server/RPG/looting.cs similarity index 96% rename from scripts/modScripts/server/looting.cs rename to scripts/modscripts/server/RPG/looting.cs index f75f674..e56db10 100644 --- a/scripts/modScripts/server/looting.cs +++ b/scripts/modscripts/server/RPG/looting.cs @@ -1,106 +1,106 @@ -//Component: Lootage -//Description: You can loot corpses. (w00t) - -//---------------------------------------------------------------------------- -// DATABLOCKS -//---------------------------------------------------------------------------- -datablock ItemData(Lootbag) -{ - className = Weapon; - catagory = "Misc"; - shapeFile = "moneybag.dts"; - mass = 1; - elasticity = 0.2; - friction = 50; - pickupRadius = 2; - pickUpPrefix = "a bag of items"; - alwaysAmbient = true; - description = "lootbag_model"; - - computeCRC = false; - emap = true; -}; - -//---------------------------------------------------------------------------- -// BOUND FUNCTIONS -//---------------------------------------------------------------------------- - -//Realized this isn't required.. -//function LootBag::onAdd(%this,%obj) //Force a loot check on creation. -//{ -//LootBagCheckForPickUp(%obj); -//parent::onAdd(%this,%obj); -//} - -//---------------------------------------------------------------------------- -// FUNCTIONS -//---------------------------------------------------------------------------- - -function LootBagCheckForPickUp(%this) //Not sure why, loot bags won't do a T2 system pickup.. -{ - cancel(%this.loop); - - if (!IsObject(%this)) - return; - - %count = MissionCleanUp.getCount(); - - for(%i = 0; %i < %count; %i++) - { - %test = MissionCleanUp.getObject(%i); - - if (%test.getClassName() $= "Player" && %test.getState() !$= "dead" && !%test.client.isAIControlled()) - { - %dist = vectorDist(%this.getPosition(),%test.getPosition()); - - if (%dist < %this.getDatablock().pickUpRadius) - { - LootBagPickedUp(%this,%test.client); - return; - } - - %this.loop = schedule(100,0,"LootBagCheckForPickup",%this); - } - } -} - -function LootBagPickedUp(%this,%client) -{ - %db = %client.player.getDatablock(); //The player's datablock - %money = %this.money; //Monies? - %numItems = %this.numItems; //Giving out items. - %numAmmo = %this.numAmmo; //..Ammo too! - //Does the bag have money? - if (%money $= "") - %hasMoney = false; - else - %hasMoney = true; - - if (%money !$= "") - %client.money = %client.money + %money; //Give some monies. - - for (%i = 0; %i < %numItems; %i++) - { - if (%db.max[%this.item[%i]] != 0) //Don't want people in light armor running around with mortars, do we? - { - %client.player.setInventory(%this.item[%i],1); - %client.player.setInventory(%this.ammo[%i],%this.ammoNum[%i]); - } - } - %this.delete(); //Delete the bag. - - //Let the player know. - switch (%hasMoney) - { - case 0: - if (%numItems > 1) - messageClient(%client,'MsgClient','You picked up a bag of items that contained %1 items.',%numitems); - else - messageClient(%client,'MsgClient','You picked up a bag of items that contained 1 item.'); - case 1: - if (%numItems > 1) - messageClient(%client,'MsgClient','You picked up a bag of items that contained $%1 and %2 items.',%money,%numitems); - else - messageClient(%client,'MsgClient','You picked up a bag of items that contained $%1 and 1 item.',%money); - } -} +//Component: Lootage +//Description: You can loot corpses. (w00t) + +//---------------------------------------------------------------------------- +// DATABLOCKS +//---------------------------------------------------------------------------- +datablock ItemData(Lootbag) +{ + className = Weapon; + catagory = "Misc"; + shapeFile = "moneybag.dts"; + mass = 1; + elasticity = 0.2; + friction = 50; + pickupRadius = 2; + pickUpPrefix = "a bag of items"; + alwaysAmbient = true; + description = "lootbag_model"; + + computeCRC = false; + emap = true; +}; + +//---------------------------------------------------------------------------- +// BOUND FUNCTIONS +//---------------------------------------------------------------------------- + +//Realized this isn't required.. +//function LootBag::onAdd(%this,%obj) //Force a loot check on creation. +//{ +//LootBagCheckForPickUp(%obj); +//parent::onAdd(%this,%obj); +//} + +//---------------------------------------------------------------------------- +// FUNCTIONS +//---------------------------------------------------------------------------- + +function LootBagCheckForPickUp(%this) //Not sure why, loot bags won't do a T2 system pickup.. +{ + cancel(%this.loop); + + if (!IsObject(%this)) + return; + + %count = MissionCleanUp.getCount(); + + for(%i = 0; %i < %count; %i++) + { + %test = MissionCleanUp.getObject(%i); + + if (%test.getClassName() $= "Player" && %test.getState() !$= "dead" && !%test.client.isAIControlled()) + { + %dist = vectorDist(%this.getPosition(),%test.getPosition()); + + if (%dist < %this.getDatablock().pickUpRadius) + { + LootBagPickedUp(%this,%test.client); + return; + } + + %this.loop = schedule(100,0,"LootBagCheckForPickup",%this); + } + } +} + +function LootBagPickedUp(%this,%client) +{ + %db = %client.player.getDatablock(); //The player's datablock + %money = %this.money; //Monies? + %numItems = %this.numItems; //Giving out items. + %numAmmo = %this.numAmmo; //..Ammo too! + //Does the bag have money? + if (%money $= "") + %hasMoney = false; + else + %hasMoney = true; + + if (%money !$= "") + %client.money = %client.money + %money; //Give some monies. + + for (%i = 0; %i < %numItems; %i++) + { + if (%db.max[%this.item[%i]] != 0) //Don't want people in light armor running around with mortars, do we? + { + %client.player.setInventory(%this.item[%i],1); + %client.player.setInventory(%this.ammo[%i],%this.ammoNum[%i]); + } + } + %this.delete(); //Delete the bag. + + //Let the player know. + switch (%hasMoney) + { + case 0: + if (%numItems > 1) + messageClient(%client,'MsgClient','You picked up a bag of items that contained %1 items.',%numitems); + else + messageClient(%client,'MsgClient','You picked up a bag of items that contained 1 item.'); + case 1: + if (%numItems > 1) + messageClient(%client,'MsgClient','You picked up a bag of items that contained $%1 and %2 items.',%money,%numitems); + else + messageClient(%client,'MsgClient','You picked up a bag of items that contained $%1 and 1 item.',%money); + } +} diff --git a/scripts/modScripts/server/mining.cs b/scripts/modscripts/server/RPG/mining.cs similarity index 93% rename from scripts/modScripts/server/mining.cs rename to scripts/modscripts/server/RPG/mining.cs index d7d87c1..0785134 100644 --- a/scripts/modScripts/server/mining.cs +++ b/scripts/modscripts/server/RPG/mining.cs @@ -1,38 +1,39 @@ -// ----------------------------------------------------- -// Datablocks -// Note: You can't actually target interiors with beams, -// so make an interior and put this box around it. -// ----------------------------------------------------- -datablock StaticShapeData(MiningBox) : StaticShapeDamageProfile { - className = "MineBox"; - shapeFile = "Pmiscf.dts"; - - maxDamage = 5000; - destroyedLevel = 0; - disabledLevel = 0; - - isShielded = false; - energyPerDamagePoint = 240; - - dynamicType = $TypeMasks::StaticShapeObjectType; - deployedObject = true; - cmdCategory = "DSupport"; - cmdIcon = CMDSensorIcon; - cmdMiniIconName = "commander/MiniIcons/com_deploymotionsensor"; - targetNameTag = 'Mining Detection Box'; - deployAmbientThread = true; - debrisShapeName = "debris_generic_small.dts"; - debris = DeployableDebris; - heatSignature = 0; - needsPower = false; -}; - -// ----------------------------------------------------- -// Code -// Note: Weapon code is in weapons/miningTool.cs -// ----------------------------------------------------- -function MiningBox::onAdd(%this, %obj) -{ - %obj.startFade(1,0,1); - %obj.applyDamage(%obj.getDataBlock().maxDamage); //Start the rock off -} +// ----------------------------------------------------- +// Datablocks +// Note: You can't actually target interiors with beams, +// so make an interior and put this box around it. +// Copyright (c) 2012 Robert MacGregor +// ----------------------------------------------------- +datablock StaticShapeData(MiningBox) : StaticShapeDamageProfile { + className = "MineBox"; + shapeFile = "Pmiscf.dts"; + + maxDamage = 5000; + destroyedLevel = 0; + disabledLevel = 0; + + isShielded = false; + energyPerDamagePoint = 240; + + dynamicType = $TypeMasks::StaticShapeObjectType; + deployedObject = true; + cmdCategory = "DSupport"; + cmdIcon = CMDSensorIcon; + cmdMiniIconName = "commander/MiniIcons/com_deploymotionsensor"; + targetNameTag = 'Mining Detection Box'; + deployAmbientThread = true; + debrisShapeName = "debris_generic_small.dts"; + debris = DeployableDebris; + heatSignature = 0; + needsPower = false; +}; + +// ----------------------------------------------------- +// Code +// Note: Weapon code is in weapons/miningTool.cs +// ----------------------------------------------------- +function MiningBox::onAdd(%this, %obj) +{ + %obj.startFade(1,0,1); + %obj.applyDamage(%obj.getDataBlock().maxDamage); //Start the rock off +} diff --git a/scripts/modScripts/server/RPG/propertyOwning.cs b/scripts/modscripts/server/RPG/propertyOwning.cs similarity index 100% rename from scripts/modScripts/server/RPG/propertyOwning.cs rename to scripts/modscripts/server/RPG/propertyOwning.cs diff --git a/scripts/modScripts/server/serverNetworking.cs b/scripts/modscripts/server/RPG/serverNetworking.cs similarity index 91% rename from scripts/modScripts/server/serverNetworking.cs rename to scripts/modscripts/server/RPG/serverNetworking.cs index 065a962..e4ebe53 100644 --- a/scripts/modScripts/server/serverNetworking.cs +++ b/scripts/modscripts/server/RPG/serverNetworking.cs @@ -1,49 +1,50 @@ -//------------------------------------------------------------------------------ -// scripts/modScripts/server/serverNetworking.cs -//------------------------------------------------------------------------------ - -if (!IsObject(ServerNetwork)) -new TCPObject(ServerNetwork); - -function ServerNetwork::onConnect(%this) -{ -} - -function ServerNetwork::onConnectFailed(%this) -{ - if (%this.testingServer) - { - error("Error: Unable to verify connection to server "@%this.testIP@" at port "@%this.testPort@"!"); - %this.testIP = ""; - %this.testPort = ""; - %this.testingServer = false; - } -} - -function ServerNetwork::onDisconnect(%this) -{ -} - -function ServerNetwork::onDisconnectFailed(%this) -{ -} - -function ServerNetwork::listen(%this) -{ -} - -function ServerNetwork::send(%this) -{ -} - -function ServerNetwork::onLine(%this, %line) -{ -} - -function ServerNetwork::testServerIP(%this, %IP, %port) -{ - %this.testingServer = true; - %this.testIP = %ip; - %this.testPort = %port; - %this.connect(%ip @ ":" @ %port); -} +//------------------------------------------------------------------------------ +// scripts/modScripts/server/serverNetworking.cs +// Copyright (c) 2012 Robert MacGregor +//------------------------------------------------------------------------------ + +if (!IsObject(ServerNetwork)) +new TCPObject(ServerNetwork); + +function ServerNetwork::onConnect(%this) +{ +} + +function ServerNetwork::onConnectFailed(%this) +{ + if (%this.testingServer) + { + error("Error: Unable to verify connection to server "@%this.testIP@" at port "@%this.testPort@"!"); + %this.testIP = ""; + %this.testPort = ""; + %this.testingServer = false; + } +} + +function ServerNetwork::onDisconnect(%this) +{ +} + +function ServerNetwork::onDisconnectFailed(%this) +{ +} + +function ServerNetwork::listen(%this) +{ +} + +function ServerNetwork::send(%this) +{ +} + +function ServerNetwork::onLine(%this, %line) +{ +} + +function ServerNetwork::testServerIP(%this, %IP, %port) +{ + %this.testingServer = true; + %this.testIP = %ip; + %this.testPort = %port; + %this.connect(%ip @ ":" @ %port); +} diff --git a/scripts/modScripts/server/TCPServer.cs b/scripts/modscripts/server/TCPServer.cs similarity index 93% rename from scripts/modScripts/server/TCPServer.cs rename to scripts/modscripts/server/TCPServer.cs index 186a769..bdab03a 100644 --- a/scripts/modScripts/server/TCPServer.cs +++ b/scripts/modscripts/server/TCPServer.cs @@ -1,175 +1,182 @@ -//------------------------------------------------------------------------------ -// TCPServer.cs -// Needed this type of thing for communication between servers in the game, -// so after some googling -- this is what I put out. -// forum.blockland.us/index.php?topic=105360 -// Copyright (c) 2012 The DarkDragonDX -//------------------------------------------------------------------------------ - -// Replicate Code for Servers -$TCPServer::ServerReplicate = "function *UNIQUESOCKET*::onConnectRequest(%this, %address, %socket)" @ -"{" @ -"%this.Parent.connectionCreated(%address, %socket); " @ -"return true;" @ -"}"; -// Replicate Code for Clients -$TCPServer::ClientReplicate = "function *UNIQUESOCKET*::onLine(%this, %line)" @ -"{" @ -"%this.Parent.onLine(%this, %line);" @ -"return true;" @ -"}" @ -"function *UNIQUESOCKET*::onDisconnect(%this) { %this.Parent.connectionDropped(%this); return true; }"; - -function TCPServer::listen(%this, %address, %port, %maxClients) -{ - %uniqueNameLength = 6; // Adjust this if need be, but there should never be a reason to - %this.allowMultiConnect = false; // If false, when a client connects twice, its old connection is killed and replaced with a new one. - if (%this.isListening) - return false; - if (%maxClients < 1 || %maxClients == 0) - %maxClients = 8; - %oldAddr = $Host::BindAddress; - %address = strlwr(%address); - if (%address $= "local" || %address $="localhost" ) %address = "127.0.0.1"; - else if (%address $= "any") %address = "0.0.0.0"; - - %charList = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - // Generate A name for a TCPObject (and make sure it's unique) - %uniqueStringLen = 6; // Adjust this if needed, but there shouldn't be a reason to - %uniqueString = ""; - while (true) - { - %uniqueString = generateString(%uniqueNameLength, %charList); - if (!isObject(%uniqueString)) break; - else %uniqueString = ""; - } - %evalCode = $TCPServer::ServerReplicate; - %evalCode = strReplace(%evalCode, "*UNIQUESOCKET*", %uniqueString); - eval(%evalCode); - - // Generate a list of unique names that this TCPServer will use (to keep down function def count) - for (%i = 0; %i < %maxClients; %i++) - while (true) - { - %uniqueName = generateString(%uniqueNameLength, %charList); - if (!isObject(%uniqueName)) - { - %eval = strReplace($TCPServer::ClientReplicate, "*UNIQUESOCKET*", %uniqueName); - eval(%eval); - %this.uniqueName[%i] = %uniqueName; - %this.uniqueNameInUse[%uniqueName] = false; - break; - } - } - - // Create the Socket and we'll rock n' roll - $Host::BindAddress = %address; - %this.Server = new TCPObject(%uniqueString); - %this.Server.listen(%port); - %this.Server.Parent = %this; - %this.connectionCount = 0; - %this.maximumClients = %maxClients; - $Host::BindAddress = %oldAddr; - %this.isListening = true; - - logEcho("Server " @ %uniqueString SPC "is ready on " @ %address @ ":" @ %port); - return true; -} - -function TCPServer::disconnect(%this) -{ -} - -function TCPServer::connectionDropped(%this, %socket) -{ - if (!%this.allowMultiConnect) - %this.connections[%socket.Address] = ""; - else - %this.connections[%socket.Address, %socket.Port] = ""; - %this.connectionCount--; - %this.onClientDisconnect(%socket); -} - -function TCPServer::connectionCreated(%this, %address, %socket) -{ - %isReplicate = false; - // Get the Port No. and Address respectively - %address = strReplace(%address, "IP:",""); - %portPos = strStr(%address, ":"); - %port = getSubStr(%address, %portPos+1, strLen(%address)); - %address = getSubStr(%address, 0, %portPos); - if (!%this.allowMultiConnect && %this.connections[%address] != 0) - { - %this.connections[%address].disconnect(); - %this.connections[%address].delete(); - %isReplicate = true; - } - - if (%this.connectionCount >= %this.maximumClients) - { - // Create the connection so we can disconnect it *lol* - %connection = new TCPObject(%uniqueName,%socket) { class = ConnectionTCP; parent = %this; Address = %address; Port = %port; }; - %this.onClientRejected(%connection, 0); - logEcho("Unable to accept connection from " @ %address SPC " -- already at maximum client count! (" @ %this.maximumClients @ ")"); - %connection.disconnect(); - %connection.delete(); - return false; - } - - // Pick a unique name - %uniqueName = ""; - for (%i = 0; %i < %this.maximumClients; %i++) - { - %name = %this.uniqueName[%i]; - if (!%this.uniqueNameInUse[%name]) - { - %uniqueName = %name; - %this.uniqueNameInUse[%name] = true; - break; - } - } - // Create The Client Socket - %connection = new TCPObject(%uniqueName,%socket) { class = ConnectionTCP; parent = %this; Address = %address; Port = %port; }; - - if (!%this.allowMultiConnect) - %this.connections[%address] = %connection; - else - %this.connections[%address, %port] = %connection; - - %this.connectionCount++; - %this.onClientConnect(%address, %connection); - logEcho("Received client connection from " @ %address); - - return true; -} - -// Callbacks -- make these do whatever you please! -function TCPServer::onClientConnect(%this, %address, %socket) -{ - echo("Received connection from " @ %address @ ". ID:" @ %socket); - return true; -} -function TCPServer::onClientRejected(%this, %socket, %reason) // %reason is always zero as of now. -{ - return true; -} -function TCPServer::onClientDisconnect(%this, %socket) -{ - error("Received Disconnect (" @ %socket @ ")"); - return true; -} -function TCPServer::onLine(%this, %socket, %line) -{ - echo(%socket SPC "says: " @ %line); - return true; -} - -// Lib Functions -function generateString(%length, %alpha) -{ - %len = strLen(%alpha); - %result = ""; - for (%i = 0; %i < %length; %i++) - %result = %result @ getSubStr(%alpha, getRandom(0, %len), 1); - return %result; +//------------------------------------------------------------------------------ +// TCPServer.cs +// Needed this type of thing for communication between servers in the game, +// so after some googling -- this is what I put out. +// forum.blockland.us/index.php?topic=105360 +// Copyright (c) 2012 Robert MacGregor +//------------------------------------------------------------------------------ + +// Replicate Code for Servers +$TCPServer::ServerReplicate = "function *UNIQUESOCKET*::onConnectRequest(%this, %address, %socket)" @ +"{" @ +"%this.Parent.connectionCreated(%address, %socket); " @ +"return true;" @ +"}"; +// Replicate Code for Clients +$TCPServer::ClientReplicate = "function *UNIQUESOCKET*::onLine(%this, %line)" @ +"{" @ +"%this.Parent.onLine(%this, %line);" @ +"return true;" @ +"}" @ +"function *UNIQUESOCKET*::onDisconnect(%this) { %this.Parent.connectionDropped(%this); return true; }"; + +function TCPServer::listen(%this, %address, %port, %maxClients) +{ + %uniqueNameLength = 6; // Adjust this if need be, but there should never be a reason to + %this.allowMultiConnect = false; // If false, when a client connects twice, its old connection is killed and replaced with a new one. + if (%this.isListening) + return false; + if (%maxClients < 1 || %maxClients == 0) + %maxClients = 8; + %oldAddr = $Host::BindAddress; + %address = strlwr(%address); + if (%address $= "local" || %address $="localhost" ) %address = "127.0.0.1"; + else if (%address $= "any") %address = "0.0.0.0"; + + %charList = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + // Generate A name for a TCPObject (and make sure it's unique) + %uniqueStringLen = 6; // Adjust this if needed, but there shouldn't be a reason to + %uniqueString = ""; + while (true) + { + %uniqueString = generateString(%uniqueNameLength, %charList); + if (!isObject(%uniqueString)) break; + else %uniqueString = ""; + } + %evalCode = $TCPServer::ServerReplicate; + %evalCode = strReplace(%evalCode, "*UNIQUESOCKET*", %uniqueString); + eval(%evalCode); + + // Generate a list of unique names that this TCPServer will use (to keep down function def count) + for (%i = 0; %i < %maxClients; %i++) + while (true) + { + %uniqueName = generateString(%uniqueNameLength, %charList); + if (!isObject(%uniqueName)) + { + %eval = strReplace($TCPServer::ClientReplicate, "*UNIQUESOCKET*", %uniqueName); + eval(%eval); + %this.uniqueName[%i] = %uniqueName; + %this.uniqueNameInUse[%uniqueName] = false; + break; + } + } + + // Create the Socket and we'll rock n' roll + $Host::BindAddress = %address; + %this.Server = new TCPObject(%uniqueString); + %this.Server.listen(%port); + %this.Server.Parent = %this; + %this.connectionCount = 0; + %this.maximumClients = %maxClients; + $Host::BindAddress = %oldAddr; + %this.isListening = true; + + logEcho("Server " @ %uniqueString SPC "is ready on " @ %address @ ":" @ %port); + return true; +} + +function TCPServer::disconnect(%this) +{ +} + +function TCPServer::connectionDropped(%this, %socket) +{ + if (!%this.allowMultiConnect) + %this.connections[%socket.Address] = ""; + else + %this.connections[%socket.Address, %socket.Port] = ""; + %this.connectionCount--; + %this.onClientDisconnect(%socket); +} + +function TCPServer::connectionCreated(%this, %address, %socket) +{ + %isReplicate = false; + // Get the Port No. and Address respectively + %address = strReplace(%address, "IP:",""); + %portPos = strStr(%address, ":"); + %port = getSubStr(%address, %portPos+1, strLen(%address)); + %address = getSubStr(%address, 0, %portPos); + if (!%this.allowMultiConnect && %this.connections[%address] != 0) + { + %this.connections[%address].disconnect(); + %this.connections[%address].delete(); + %isReplicate = true; + } + + if (%this.connectionCount >= %this.maximumClients) + { + // Create the connection so we can disconnect it *lol* + %connection = new TCPObject(%uniqueName,%socket) { class = ConnectionTCP; parent = %this; Address = %address; Port = %port; }; + %this.onClientRejected(%connection, 0); + logEcho("Unable to accept connection from " @ %address SPC " -- already at maximum client count! (" @ %this.maximumClients @ ")"); + %connection.disconnect(); + %connection.delete(); + return false; + } + + // Pick a unique name + %uniqueName = ""; + for (%i = 0; %i < %this.maximumClients; %i++) + { + %name = %this.uniqueName[%i]; + if (!%this.uniqueNameInUse[%name]) + { + %uniqueName = %name; + %this.uniqueNameInUse[%name] = true; + break; + } + } + // Create The Client Socket + %connection = new TCPObject(%uniqueName,%socket) { class = ConnectionTCP; parent = %this; Address = %address; Port = %port; }; + + if (!%this.allowMultiConnect) + %this.connections[%address] = %connection; + else + %this.connections[%address, %port] = %connection; + + %this.connectionCount++; + %this.onClientConnect(%address, %connection); + logEcho("Received client connection from " @ %address); + + return true; +} + +// Callbacks -- make these do whatever you please! +function TCPServer::onClientConnect(%this, %address, %socket) +{ + %this.client = %socket; + echo("Received connection from " @ %address @ ". ID:" @ %socket); + return true; +} +function TCPServer::onClientRejected(%this, %socket, %reason) // %reason is always zero as of now. +{ + return true; +} +function TCPServer::onClientDisconnect(%this, %socket) +{ + error("Received Disconnect (" @ %socket @ ")"); + return true; +} +function TCPServer::onLine(%this, %socket, %line) +{ + messageAll('msgClient',"Telnet: " @ %line); + echo(%socket SPC "says: " @ %line); + return true; +} + +function TCPServer::message(%this, %message) +{ + %this.client.send(%message @ "\n"); +} + +// Lib Functions +function generateString(%length, %alpha) +{ + %len = strLen(%alpha); + %result = ""; + for (%i = 0; %i < %length; %i++) + %result = %result @ getSubStr(%alpha, getRandom(0, %len), 1); + return %result; } \ No newline at end of file diff --git a/scripts/modScripts/server/bloodbioderm.cs b/scripts/modscripts/server/bloodbioderm.cs similarity index 96% rename from scripts/modScripts/server/bloodbioderm.cs rename to scripts/modscripts/server/bloodbioderm.cs index c3fc430..0091d21 100644 --- a/scripts/modScripts/server/bloodbioderm.cs +++ b/scripts/modscripts/server/bloodbioderm.cs @@ -1,405 +1,405 @@ -//------------------------------------------------------------------------------ -// Bioderm Death Effects v3.0 -// Effects by: LuCiD -//============================================================================== - -// see player.cs for functions. -//------------------------------------------------------------------------------ -// Splash Mist -//============================================================================== -datablock ParticleData(BiodermPlayerSplashMist) -{ - dragCoefficient = 2.0; - gravityCoefficient = -0.05; - inheritedVelFactor = 0.0; - constantAcceleration = 0.0; - lifetimeMS = 600; - lifetimeVarianceMS = 100; - useInvAlpha = false; - spinRandomMin = -90.0; - spinRandomMax = 500.0; - textureName = "particleTest"; - colors[0] = "0.1 0.9 0.1 0.5"; - colors[1] = "0.2 0.09 0.05 0.5"; - colors[2] = "0.0 0.4 0.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(BiodermPlayerSplashMistEmitter) -{ - ejectionPeriodMS = 6; - periodVarianceMS = 0; - ejectionVelocity = 3.0; - velocityVariance = 2.0; - ejectionOffset = 0.0; - thetaMin = 85; - thetaMax = 85; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - lifetimeMS = 450; - particles = "BiodermPlayerSplashMist"; -}; - -//------------------------------------------------------------------------------ -// Bioderm Green Pool -//============================================================================== -datablock ShockwaveData(GreenBloodHit) -{ - width = 3.0; - numSegments = 164; - numVertSegments = 35; - velocity = -1.5; - acceleration = 2.0; - lifetimeMS = 800; - height = 0.1; - verticalCurve = 0.5; - - mapToTerrain = false; - renderBottom = true; - orientToNormal = true; - - texture[0] = "special/shockwave4"; - texture[1] = "special/droplet";//"special/gradient"; - texWrap = 8.0; - - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - - colors[0] = "0.1 0.9 0.1 0.5"; - colors[1] = "0.5 0.06 0.05 0.5"; - colors[2] = "0.0 0.4 0.0 0.0"; -}; - -//------------------------------------------------------------------------------ -// Bioderm Blood -//============================================================================== -datablock ParticleData(BiodermBloodParticle) -{ - dragCoeffiecient = 0.0; - gravityCoefficient = 120.0; // drops quickly - inheritedVelFactor = 0; - - lifetimeMS = 1600; // lasts 2 second - lifetimeVarianceMS = 000; // ...more or less - - textureName = "snowflake8x8";//"particletest"; - - useInvAlpha = true; - spinRandomMin = -30.0; - spinRandomMax = 30.0; - - colors[0] = "0.1 0.9 0.1 0.5"; - colors[1] = "0.2 0.06 0.05 0.5"; - colors[2] = "0.0 0.4 0.0 0.0"; - - sizes[0] = 0.2; - sizes[1] = 0.05; - sizes[2] = 0.06; - - times[0] = 0.0; - times[1] = 0.2; - times[2] = 1.0; -}; - -datablock ParticleEmitterData(BiodermBloodEmitter) -{ - ejectionPeriodMS = 15; - periodVarianceMS = 5; - - ejectionVelocity = 1.25; - velocityVariance = 0.50; - - thetaMin = 0.0; - thetaMax = 90.0; - - particles = "BiodermBloodParticle"; -}; - -//------------------------------------------------------------------------------ -// Bioderm Droplets Particle -//============================================================================== -datablock ParticleData( BiodermDropletsParticle ) -{ - dragCoefficient = 1; - gravityCoefficient = 0.5; - inheritedVelFactor = 0.5; - constantAcceleration = 0.1; - lifetimeMS = 300; - lifetimeVarianceMS = 100; - textureName = "special/droplet"; - colors[0] = "0.1 0.9 0.1 1.0"; - colors[1] = "0.2 0.06 0.05 1.0"; - colors[2] = "0.0 0.4 0.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( BiodermDropletsEmitter ) -{ - ejectionPeriodMS = 7; - periodVarianceMS = 0; - ejectionVelocity = 2; - velocityVariance = 1.0; - ejectionOffset = 0.0; - thetaMin = 60; - thetaMax = 80; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - orientParticles = true; - particles = "BiodermDropletsParticle"; -}; - -//------------------------------------------------------------------------------ -// Bioderm Explosion -//============================================================================== -datablock ExplosionData(BiodermExplosion) -{ - soundProfile = BloodSplashSound; - particleEmitter = BiodermBloodEmitter; - particleDensity = 250; - particleRadius = 1.25; - faceViewer = true; - - emitter[0] = BiodermPlayerSplashMistEmitter; - emitter[1] = BiodermDropletsEmitter; - shockwave = GreenBloodHit; -}; - -datablock GrenadeProjectileData(BiodermBlood) -{ - projectileShapeName = "turret_muzzlepoint.dts"; //Really small and hard to see - emitterDelay = -1; - directDamage = 0.15; - hasDamageRadius = false; - indirectDamage = 0.0; - damageRadius = 0.15; - radiusDamageType = $DamageType::ArmorDeath; - kickBackStrength = 0; - bubbleEmitTime = 1.0; - //sound = BloodSplashSound; - explosion = BiodermExplosion; - //explodeOnMaxBounce = true; - velInheritFactor = 0.5; - baseEmitter[0] = BiodermBloodEmitter; - - grenadeElasticity = 0.4; - grenadeFriction = 0.2; - armingDelayMS = 100; // was 400 - muzzleVelocity = 0; - drag = 0.1; - -}; -//------------------------------------------------------------------------------ -// Purple Bioderm blood -//============================================================================== - -//------------------------------------------------------------------------------ -// Purple Splash Mist -//============================================================================== -datablock ParticleData(PurpleBiodermPlayerSplashMist) -{ - dragCoefficient = 2.0; - gravityCoefficient = -0.05; - inheritedVelFactor = 0.0; - constantAcceleration = 0.0; - lifetimeMS = 600; - lifetimeVarianceMS = 100; - useInvAlpha = false; - spinRandomMin = -90.0; - spinRandomMax = 500.0; - textureName = "particleTest"; - colors[0] = "0.25 0.12 0.40 0.5"; - colors[1] = "0.25 0.12 0.40 0.5"; - colors[2] = "0.4 0.0 0.5 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(PurpleBiodermPlayerSplashMistEmitter) -{ - ejectionPeriodMS = 6; - periodVarianceMS = 0; - ejectionVelocity = 3.0; - velocityVariance = 2.0; - ejectionOffset = 0.0; - thetaMin = 85; - thetaMax = 85; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - lifetimeMS = 450; - particles = "PurpleBiodermPlayerSplashMist"; -}; - -//------------------------------------------------------------------------------ -// Bioderm Purple Pool -//============================================================================== -datablock ShockwaveData(PurpleBloodHit) -{ - width = 3.0; - numSegments = 164; - numVertSegments = 35; - velocity = -1.5; - acceleration = 2.0; - lifetimeMS = 800; - height = 0.1; - verticalCurve = 0.5; - - mapToTerrain = false; - renderBottom = true; - orientToNormal = true; - - texture[0] = "special/shockwave4"; - texture[1] = "special/droplet";//"special/gradient"; - texWrap = 8.0; - - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - - colors[0] = "0.25 0.12 0.40 0.5"; - colors[1] = "0.25 0.12 0.40 0.5"; - colors[2] = "0.4 0.0 0.5 0.0"; -}; - -//------------------------------------------------------------------------------ -// Purple Bioderm Blood -//============================================================================== -datablock ParticleData(PurpleBiodermBloodParticle) -{ - dragCoeffiecient = 0.0; - gravityCoefficient = 120.0; // drops quickly - inheritedVelFactor = 0; - - lifetimeMS = 1550; // lasts 2 second - lifetimeVarianceMS = 300; // ...more or less - - textureName = "snowflake8x8";//"particletest"; - - useInvAlpha = true; - spinRandomMin = -30.0; - spinRandomMax = 30.0; - - colors[0] = "0.25 0.12 0.40 0.5"; - colors[1] = "0.25 0.12 0.40 0.5"; - colors[2] = "0.4 0.0 0.5 0.0"; - - sizes[0] = 0.2; - sizes[1] = 0.05; - sizes[2] = 0.05; - - times[0] = 0.0; - times[1] = 0.2; - times[2] = 1.0; -}; - -datablock ParticleEmitterData(PurpleBiodermBloodEmitter) -{ - ejectionPeriodMS = 15; - periodVarianceMS = 5; - - ejectionVelocity = 1.25; - velocityVariance = 0.50; - - thetaMin = 0.0; - thetaMax = 90.0; - - particles = "PurpleBiodermBloodParticle"; -}; - -//------------------------------------------------------------------------------ -// purple Bioderm Droplets Particle -//============================================================================== -datablock ParticleData( PurpleBiodermDropletsParticle ) -{ - dragCoefficient = 1; - gravityCoefficient = 0.5; - inheritedVelFactor = 0.5; - constantAcceleration = -0.0; - lifetimeMS = 300; - lifetimeVarianceMS = 100; - textureName = "special/droplet"; - colors[0] = "0.25 0.12 0.40 0.5"; - colors[1] = "0.25 0.12 0.40 0.5"; - colors[2] = "0.4 0.0 0.5 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( PurpleBiodermDropletsEmitter ) -{ - ejectionPeriodMS = 7; - periodVarianceMS = 0; - ejectionVelocity = 2; - velocityVariance = 1.0; - ejectionOffset = 0.0; - thetaMin = 60; - thetaMax = 80; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - orientParticles = true; - particles = "PurpleBiodermDropletsParticle"; -}; - -//------------------------------------------------------------------------------ -// Purple Bioderm Explosion -//============================================================================== -datablock ExplosionData(PurpleBiodermExplosion) -{ - soundProfile = BloodSplashSound; - particleEmitter = PurpleBiodermBloodEmitter; - particleDensity = 250; - particleRadius = 1.25; - faceViewer = true; - - emitter[0] = PurpleBiodermPlayerSplashMistEmitter; - emitter[1] = PurpleBiodermDropletsEmitter; - shockwave = PurpleBloodHit; -}; - -datablock GrenadeProjectileData(PurpleBiodermBlood) -{ - projectileShapeName = "turret_muzzlepoint.dts"; //Really small and hard to see - emitterDelay = -1; - directDamage = 0.0; - hasDamageRadius = false; - indirectDamage = 0.0; - damageRadius = 0.0; - radiusDamageType = $DamageType::Default; - kickBackStrength = 0; - bubbleEmitTime = 1.0; - //sound = BloodSplashSound; - explosion = PurpleBiodermExplosion; - //explodeOnMaxBounce = true; - velInheritFactor = 0.5; - baseEmitter[0] = PurpleBiodermBloodEmitter; - - grenadeElasticity = 0.4; - grenadeFriction = 0.2; - armingDelayMS = 100; // was 400 - muzzleVelocity = 0; - drag = 0.1; -}; - - +//------------------------------------------------------------------------------ +// Bioderm Death Effects v3.0 +// Effects by: LuCiD +//============================================================================== + +// see player.cs for functions. +//------------------------------------------------------------------------------ +// Splash Mist +//============================================================================== +datablock ParticleData(BiodermPlayerSplashMist) +{ + dragCoefficient = 2.0; + gravityCoefficient = -0.05; + inheritedVelFactor = 0.0; + constantAcceleration = 0.0; + lifetimeMS = 600; + lifetimeVarianceMS = 100; + useInvAlpha = false; + spinRandomMin = -90.0; + spinRandomMax = 500.0; + textureName = "particleTest"; + colors[0] = "0.1 0.9 0.1 0.5"; + colors[1] = "0.2 0.09 0.05 0.5"; + colors[2] = "0.0 0.4 0.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(BiodermPlayerSplashMistEmitter) +{ + ejectionPeriodMS = 6; + periodVarianceMS = 0; + ejectionVelocity = 3.0; + velocityVariance = 2.0; + ejectionOffset = 0.0; + thetaMin = 85; + thetaMax = 85; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + lifetimeMS = 450; + particles = "BiodermPlayerSplashMist"; +}; + +//------------------------------------------------------------------------------ +// Bioderm Green Pool +//============================================================================== +datablock ShockwaveData(GreenBloodHit) +{ + width = 3.0; + numSegments = 164; + numVertSegments = 35; + velocity = -1.5; + acceleration = 2.0; + lifetimeMS = 800; + height = 0.1; + verticalCurve = 0.5; + + mapToTerrain = false; + renderBottom = true; + orientToNormal = true; + + texture[0] = "special/shockwave4"; + texture[1] = "special/droplet";//"special/gradient"; + texWrap = 8.0; + + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; + + colors[0] = "0.1 0.9 0.1 0.5"; + colors[1] = "0.5 0.06 0.05 0.5"; + colors[2] = "0.0 0.4 0.0 0.0"; +}; + +//------------------------------------------------------------------------------ +// Bioderm Blood +//============================================================================== +datablock ParticleData(BiodermBloodParticle) +{ + dragCoeffiecient = 0.0; + gravityCoefficient = 120.0; // drops quickly + inheritedVelFactor = 0; + + lifetimeMS = 1600; // lasts 2 second + lifetimeVarianceMS = 000; // ...more or less + + textureName = "snowflake8x8";//"particletest"; + + useInvAlpha = true; + spinRandomMin = -30.0; + spinRandomMax = 30.0; + + colors[0] = "0.1 0.9 0.1 0.5"; + colors[1] = "0.2 0.06 0.05 0.5"; + colors[2] = "0.0 0.4 0.0 0.0"; + + sizes[0] = 0.2; + sizes[1] = 0.05; + sizes[2] = 0.06; + + times[0] = 0.0; + times[1] = 0.2; + times[2] = 1.0; +}; + +datablock ParticleEmitterData(BiodermBloodEmitter) +{ + ejectionPeriodMS = 15; + periodVarianceMS = 5; + + ejectionVelocity = 1.25; + velocityVariance = 0.50; + + thetaMin = 0.0; + thetaMax = 90.0; + + particles = "BiodermBloodParticle"; +}; + +//------------------------------------------------------------------------------ +// Bioderm Droplets Particle +//============================================================================== +datablock ParticleData( BiodermDropletsParticle ) +{ + dragCoefficient = 1; + gravityCoefficient = 0.5; + inheritedVelFactor = 0.5; + constantAcceleration = 0.1; + lifetimeMS = 300; + lifetimeVarianceMS = 100; + textureName = "special/droplet"; + colors[0] = "0.1 0.9 0.1 1.0"; + colors[1] = "0.2 0.06 0.05 1.0"; + colors[2] = "0.0 0.4 0.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( BiodermDropletsEmitter ) +{ + ejectionPeriodMS = 7; + periodVarianceMS = 0; + ejectionVelocity = 2; + velocityVariance = 1.0; + ejectionOffset = 0.0; + thetaMin = 60; + thetaMax = 80; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + orientParticles = true; + particles = "BiodermDropletsParticle"; +}; + +//------------------------------------------------------------------------------ +// Bioderm Explosion +//============================================================================== +datablock ExplosionData(BiodermExplosion) +{ + soundProfile = BloodSplashSound; + particleEmitter = BiodermBloodEmitter; + particleDensity = 250; + particleRadius = 1.25; + faceViewer = true; + + emitter[0] = BiodermPlayerSplashMistEmitter; + emitter[1] = BiodermDropletsEmitter; + shockwave = GreenBloodHit; +}; + +datablock GrenadeProjectileData(BiodermBlood) +{ + projectileShapeName = "turret_muzzlepoint.dts"; //Really small and hard to see + emitterDelay = -1; + directDamage = 0.15; + hasDamageRadius = false; + indirectDamage = 0.0; + damageRadius = 0.15; + radiusDamageType = $DamageType::ArmorDeath; + kickBackStrength = 0; + bubbleEmitTime = 1.0; + //sound = BloodSplashSound; + explosion = BiodermExplosion; + //explodeOnMaxBounce = true; + velInheritFactor = 0.5; + baseEmitter[0] = BiodermBloodEmitter; + + grenadeElasticity = 0.4; + grenadeFriction = 0.2; + armingDelayMS = 100; // was 400 + muzzleVelocity = 0; + drag = 0.1; + +}; +//------------------------------------------------------------------------------ +// Purple Bioderm blood +//============================================================================== + +//------------------------------------------------------------------------------ +// Purple Splash Mist +//============================================================================== +datablock ParticleData(PurpleBiodermPlayerSplashMist) +{ + dragCoefficient = 2.0; + gravityCoefficient = -0.05; + inheritedVelFactor = 0.0; + constantAcceleration = 0.0; + lifetimeMS = 600; + lifetimeVarianceMS = 100; + useInvAlpha = false; + spinRandomMin = -90.0; + spinRandomMax = 500.0; + textureName = "particleTest"; + colors[0] = "0.25 0.12 0.40 0.5"; + colors[1] = "0.25 0.12 0.40 0.5"; + colors[2] = "0.4 0.0 0.5 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(PurpleBiodermPlayerSplashMistEmitter) +{ + ejectionPeriodMS = 6; + periodVarianceMS = 0; + ejectionVelocity = 3.0; + velocityVariance = 2.0; + ejectionOffset = 0.0; + thetaMin = 85; + thetaMax = 85; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + lifetimeMS = 450; + particles = "PurpleBiodermPlayerSplashMist"; +}; + +//------------------------------------------------------------------------------ +// Bioderm Purple Pool +//============================================================================== +datablock ShockwaveData(PurpleBloodHit) +{ + width = 3.0; + numSegments = 164; + numVertSegments = 35; + velocity = -1.5; + acceleration = 2.0; + lifetimeMS = 800; + height = 0.1; + verticalCurve = 0.5; + + mapToTerrain = false; + renderBottom = true; + orientToNormal = true; + + texture[0] = "special/shockwave4"; + texture[1] = "special/droplet";//"special/gradient"; + texWrap = 8.0; + + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; + + colors[0] = "0.25 0.12 0.40 0.5"; + colors[1] = "0.25 0.12 0.40 0.5"; + colors[2] = "0.4 0.0 0.5 0.0"; +}; + +//------------------------------------------------------------------------------ +// Purple Bioderm Blood +//============================================================================== +datablock ParticleData(PurpleBiodermBloodParticle) +{ + dragCoeffiecient = 0.0; + gravityCoefficient = 120.0; // drops quickly + inheritedVelFactor = 0; + + lifetimeMS = 1550; // lasts 2 second + lifetimeVarianceMS = 300; // ...more or less + + textureName = "snowflake8x8";//"particletest"; + + useInvAlpha = true; + spinRandomMin = -30.0; + spinRandomMax = 30.0; + + colors[0] = "0.25 0.12 0.40 0.5"; + colors[1] = "0.25 0.12 0.40 0.5"; + colors[2] = "0.4 0.0 0.5 0.0"; + + sizes[0] = 0.2; + sizes[1] = 0.05; + sizes[2] = 0.05; + + times[0] = 0.0; + times[1] = 0.2; + times[2] = 1.0; +}; + +datablock ParticleEmitterData(PurpleBiodermBloodEmitter) +{ + ejectionPeriodMS = 15; + periodVarianceMS = 5; + + ejectionVelocity = 1.25; + velocityVariance = 0.50; + + thetaMin = 0.0; + thetaMax = 90.0; + + particles = "PurpleBiodermBloodParticle"; +}; + +//------------------------------------------------------------------------------ +// purple Bioderm Droplets Particle +//============================================================================== +datablock ParticleData( PurpleBiodermDropletsParticle ) +{ + dragCoefficient = 1; + gravityCoefficient = 0.5; + inheritedVelFactor = 0.5; + constantAcceleration = -0.0; + lifetimeMS = 300; + lifetimeVarianceMS = 100; + textureName = "special/droplet"; + colors[0] = "0.25 0.12 0.40 0.5"; + colors[1] = "0.25 0.12 0.40 0.5"; + colors[2] = "0.4 0.0 0.5 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( PurpleBiodermDropletsEmitter ) +{ + ejectionPeriodMS = 7; + periodVarianceMS = 0; + ejectionVelocity = 2; + velocityVariance = 1.0; + ejectionOffset = 0.0; + thetaMin = 60; + thetaMax = 80; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + orientParticles = true; + particles = "PurpleBiodermDropletsParticle"; +}; + +//------------------------------------------------------------------------------ +// Purple Bioderm Explosion +//============================================================================== +datablock ExplosionData(PurpleBiodermExplosion) +{ + soundProfile = BloodSplashSound; + particleEmitter = PurpleBiodermBloodEmitter; + particleDensity = 250; + particleRadius = 1.25; + faceViewer = true; + + emitter[0] = PurpleBiodermPlayerSplashMistEmitter; + emitter[1] = PurpleBiodermDropletsEmitter; + shockwave = PurpleBloodHit; +}; + +datablock GrenadeProjectileData(PurpleBiodermBlood) +{ + projectileShapeName = "turret_muzzlepoint.dts"; //Really small and hard to see + emitterDelay = -1; + directDamage = 0.0; + hasDamageRadius = false; + indirectDamage = 0.0; + damageRadius = 0.0; + radiusDamageType = $DamageType::Default; + kickBackStrength = 0; + bubbleEmitTime = 1.0; + //sound = BloodSplashSound; + explosion = PurpleBiodermExplosion; + //explodeOnMaxBounce = true; + velInheritFactor = 0.5; + baseEmitter[0] = PurpleBiodermBloodEmitter; + + grenadeElasticity = 0.4; + grenadeFriction = 0.2; + armingDelayMS = 100; // was 400 + muzzleVelocity = 0; + drag = 0.1; +}; + + diff --git a/scripts/modScripts/server/bloodhuman.cs b/scripts/modscripts/server/bloodhuman.cs similarity index 96% rename from scripts/modScripts/server/bloodhuman.cs rename to scripts/modscripts/server/bloodhuman.cs index 2300775..6ba4e61 100644 --- a/scripts/modScripts/server/bloodhuman.cs +++ b/scripts/modscripts/server/bloodhuman.cs @@ -1,213 +1,213 @@ -//------------------------------------------------------------------------------ -// Human Death Effects v3.0 -// Effects By: LuCiD -//============================================================================== - -// see player.cs for functions. -datablock AudioProfile(BloodSplashSound) -{ - filename = "fx/armor/light_LF_water.wav"; - description = AudioClosest3d; - preload = true; - -}; - -//------------------------------------------------------------------------------ -// Splash Mist -//============================================================================== -datablock ParticleData(HumanRedPlayerSplashMist) -{ - dragCoefficient = 2.0; - gravityCoefficient = -0.05; - inheritedVelFactor = 0.0; - constantAcceleration = 0.0; - lifetimeMS = 600; - lifetimeVarianceMS = 100; - useInvAlpha = false; - spinRandomMin = -90.0; - spinRandomMax = 500.0; - textureName = "particleTest"; - colors[0] = "0.9 0.1 0.1 0.5"; - colors[1] = "0.6 0.05 0.05 0.5"; - colors[2] = "0.4 0.0 0.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(HumanRedPlayerSplashMistEmitter) -{ - ejectionPeriodMS = 6; - periodVarianceMS = 1; - ejectionVelocity = 4.0; - velocityVariance = 2.0; - ejectionOffset = 0.0; - thetaMin = 85; - thetaMax = 85; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - lifetimeMS = 450; - particles = "HumanRedPlayerSplashMist"; -}; - -//------------------------------------------------------------------------------ -// Human Red Pool -//============================================================================== -datablock ShockwaveData(RedBloodHit) -{ - width = 3.0; - numSegments = 164; - numVertSegments = 35; - velocity = -1.5; - acceleration = 2.0; - lifetimeMS = 800; - height = 0.1; - verticalCurve = 0.5; - - mapToTerrain = false; - renderBottom = true; - orientToNormal = true; - - texture[0] = "special/shockwave4"; - texture[1] = "special/droplet";//"special/gradient"; - texWrap = 8.0; - - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - - colors[0] = "0.9 0.1 0.1 0.5"; - colors[1] = "0.6 0.05 0.05 0.5"; - colors[2] = "0.4 0.0 0.0 0.0"; -}; - -//------------------------------------------------------------------------------ -// Human Red Blood -//============================================================================== -datablock ParticleData(HumanRedBloodParticle) -{ - dragCoeffiecient = 0.0; - gravityCoefficient = 120.0; - inheritedVelFactor = 0.0; - - lifetimeMS = 1600; - lifetimeVarianceMS = 000; - - textureName = "snowflake8x8";//"particletest"; - - useInvAlpha = true; - spinRandomMin = -30.0; - spinRandomMax = 30.0; - - colors[0] = "0.9 0.1 0.1 0.5"; - colors[1] = "0.6 0.05 0.05 0.5"; - colors[2] = "0.4 0.0 0.0 0.0"; - - sizes[0] = 0.2; - sizes[1] = 0.05; - sizes[2] = 0.06; - - times[0] = 0.0; - times[1] = 0.2; - times[2] = 1.0; -}; - -datablock ParticleEmitterData(HumanRedBloodEmitter) -{ - ejectionPeriodMS = 15; - periodVarianceMS = 5; - - ejectionVelocity = 1.25; - velocityVariance = 0.50; - - thetaMin = 0.0; - thetaMax = 90.0; - - particles = "HumanRedBloodParticle"; -}; - -//------------------------------------------------------------------------------ -// Human Red Droplets Particle -//============================================================================== -datablock ParticleData( HumanRedDropletsParticle ) -{ - dragCoefficient = 1; - gravityCoefficient = 0.5; - inheritedVelFactor = 0.5; - constantAcceleration = 0.1; - lifetimeMS = 300; - lifetimeVarianceMS = 100; - textureName = "special/droplet"; - colors[0] = "0.9 0.1 0.1 1.0"; - colors[1] = "0.6 0.05 0.05 1.0"; - colors[2] = "0.4 0.0 0.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( HumanRedDropletsEmitter ) -{ - ejectionPeriodMS = 7; - periodVarianceMS = 0; - ejectionVelocity = 2; - velocityVariance = 1.0; - ejectionOffset = 0.0; - thetaMin = 60; - thetaMax = 80; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - orientParticles = true; - particles = "HumanRedDropletsParticle"; -}; - -//------------------------------------------------------------------------------ -// Human Red Explosion -//============================================================================== -datablock ExplosionData(HumanRedExplosion) -{ - soundProfile = BloodSplashSound; - particleEmitter = HumanRedBloodEmitter; - particleDensity = 250; - particleRadius = 1.25; - faceViewer = true; - - emitter[0] = HumanRedPlayerSplashMistEmitter; - emitter[1] = HumanRedDropletsEmitter; - shockwave = RedBloodHit; -}; - -datablock GrenadeProjectileData(HumanBlood) -{ - projectileShapeName = "turret_muzzlepoint.dts"; //Really small and hard to see - emitterDelay = -1; - directDamage = 0.0; - hasDamageRadius = false; - indirectDamage = 0.0; - damageRadius = 0.0; - radiusDamageType = $DamageType::Default; - kickBackStrength = 0; - bubbleEmitTime = 1.0; - //sound = BloodSplashSound; - explosion = HumanRedExplosion; - //explodeOnMaxBounce = true; - velInheritFactor = 0.5; - baseEmitter[0] = HumanRedBloodEmitter; - - grenadeElasticity = 0.4; - grenadeFriction = 0.2; - armingDelayMS = 100; // was 400 - muzzleVelocity = 0; - drag = 0.1; - -}; - - +//------------------------------------------------------------------------------ +// Human Death Effects v3.0 +// Effects By: LuCiD +//============================================================================== + +// see player.cs for functions. +datablock AudioProfile(BloodSplashSound) +{ + filename = "fx/armor/light_LF_water.wav"; + description = AudioClosest3d; + preload = true; + +}; + +//------------------------------------------------------------------------------ +// Splash Mist +//============================================================================== +datablock ParticleData(HumanRedPlayerSplashMist) +{ + dragCoefficient = 2.0; + gravityCoefficient = -0.05; + inheritedVelFactor = 0.0; + constantAcceleration = 0.0; + lifetimeMS = 600; + lifetimeVarianceMS = 100; + useInvAlpha = false; + spinRandomMin = -90.0; + spinRandomMax = 500.0; + textureName = "particleTest"; + colors[0] = "0.9 0.1 0.1 0.5"; + colors[1] = "0.6 0.05 0.05 0.5"; + colors[2] = "0.4 0.0 0.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(HumanRedPlayerSplashMistEmitter) +{ + ejectionPeriodMS = 6; + periodVarianceMS = 1; + ejectionVelocity = 4.0; + velocityVariance = 2.0; + ejectionOffset = 0.0; + thetaMin = 85; + thetaMax = 85; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + lifetimeMS = 450; + particles = "HumanRedPlayerSplashMist"; +}; + +//------------------------------------------------------------------------------ +// Human Red Pool +//============================================================================== +datablock ShockwaveData(RedBloodHit) +{ + width = 3.0; + numSegments = 164; + numVertSegments = 35; + velocity = -1.5; + acceleration = 2.0; + lifetimeMS = 800; + height = 0.1; + verticalCurve = 0.5; + + mapToTerrain = false; + renderBottom = true; + orientToNormal = true; + + texture[0] = "special/shockwave4"; + texture[1] = "special/droplet";//"special/gradient"; + texWrap = 8.0; + + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; + + colors[0] = "0.9 0.1 0.1 0.5"; + colors[1] = "0.6 0.05 0.05 0.5"; + colors[2] = "0.4 0.0 0.0 0.0"; +}; + +//------------------------------------------------------------------------------ +// Human Red Blood +//============================================================================== +datablock ParticleData(HumanRedBloodParticle) +{ + dragCoeffiecient = 0.0; + gravityCoefficient = 120.0; + inheritedVelFactor = 0.0; + + lifetimeMS = 1600; + lifetimeVarianceMS = 000; + + textureName = "snowflake8x8";//"particletest"; + + useInvAlpha = true; + spinRandomMin = -30.0; + spinRandomMax = 30.0; + + colors[0] = "0.9 0.1 0.1 0.5"; + colors[1] = "0.6 0.05 0.05 0.5"; + colors[2] = "0.4 0.0 0.0 0.0"; + + sizes[0] = 0.2; + sizes[1] = 0.05; + sizes[2] = 0.06; + + times[0] = 0.0; + times[1] = 0.2; + times[2] = 1.0; +}; + +datablock ParticleEmitterData(HumanRedBloodEmitter) +{ + ejectionPeriodMS = 15; + periodVarianceMS = 5; + + ejectionVelocity = 1.25; + velocityVariance = 0.50; + + thetaMin = 0.0; + thetaMax = 90.0; + + particles = "HumanRedBloodParticle"; +}; + +//------------------------------------------------------------------------------ +// Human Red Droplets Particle +//============================================================================== +datablock ParticleData( HumanRedDropletsParticle ) +{ + dragCoefficient = 1; + gravityCoefficient = 0.5; + inheritedVelFactor = 0.5; + constantAcceleration = 0.1; + lifetimeMS = 300; + lifetimeVarianceMS = 100; + textureName = "special/droplet"; + colors[0] = "0.9 0.1 0.1 1.0"; + colors[1] = "0.6 0.05 0.05 1.0"; + colors[2] = "0.4 0.0 0.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( HumanRedDropletsEmitter ) +{ + ejectionPeriodMS = 7; + periodVarianceMS = 0; + ejectionVelocity = 2; + velocityVariance = 1.0; + ejectionOffset = 0.0; + thetaMin = 60; + thetaMax = 80; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + orientParticles = true; + particles = "HumanRedDropletsParticle"; +}; + +//------------------------------------------------------------------------------ +// Human Red Explosion +//============================================================================== +datablock ExplosionData(HumanRedExplosion) +{ + soundProfile = BloodSplashSound; + particleEmitter = HumanRedBloodEmitter; + particleDensity = 250; + particleRadius = 1.25; + faceViewer = true; + + emitter[0] = HumanRedPlayerSplashMistEmitter; + emitter[1] = HumanRedDropletsEmitter; + shockwave = RedBloodHit; +}; + +datablock GrenadeProjectileData(HumanBlood) +{ + projectileShapeName = "turret_muzzlepoint.dts"; //Really small and hard to see + emitterDelay = -1; + directDamage = 0.0; + hasDamageRadius = false; + indirectDamage = 0.0; + damageRadius = 0.0; + radiusDamageType = $DamageType::Default; + kickBackStrength = 0; + bubbleEmitTime = 1.0; + //sound = BloodSplashSound; + explosion = HumanRedExplosion; + //explodeOnMaxBounce = true; + velInheritFactor = 0.5; + baseEmitter[0] = HumanRedBloodEmitter; + + grenadeElasticity = 0.4; + grenadeFriction = 0.2; + armingDelayMS = 100; // was 400 + muzzleVelocity = 0; + drag = 0.1; + +}; + + diff --git a/scripts/modScripts/server/dataImport.cs b/scripts/modscripts/server/dataImport.cs similarity index 100% rename from scripts/modScripts/server/dataImport.cs rename to scripts/modscripts/server/dataImport.cs diff --git a/scripts/modScripts/server/initialize.cs b/scripts/modscripts/server/initialize.cs similarity index 100% rename from scripts/modScripts/server/initialize.cs rename to scripts/modscripts/server/initialize.cs diff --git a/scripts/modScripts/server/RPG/looting.cs b/scripts/modscripts/server/looting.cs similarity index 100% rename from scripts/modScripts/server/RPG/looting.cs rename to scripts/modscripts/server/looting.cs diff --git a/scripts/modScripts/server/RPG/mining.cs b/scripts/modscripts/server/mining.cs similarity index 100% rename from scripts/modScripts/server/RPG/mining.cs rename to scripts/modscripts/server/mining.cs diff --git a/scripts/modScripts/server/propData.cs b/scripts/modscripts/server/propData.cs similarity index 59% rename from scripts/modScripts/server/propData.cs rename to scripts/modscripts/server/propData.cs index 2e06a9c..bedf311 100644 --- a/scripts/modScripts/server/propData.cs +++ b/scripts/modscripts/server/propData.cs @@ -1,76 +1,44 @@ -//Component: Destructable Props -//Description: Not much to describe.. stuff that blows up or can be broken. - -//---------------------------------------------------------------------------- -// DATABLOCKS -//---------------------------------------------------------------------------- -//datablock StaticShapeData(DetructableSecurityCamera) : StaticShapeDamageProfile -//{ - // className = "SecurityCamera"; - // shapeFile = "SecurityCamera.dts"; - // maxDamage = 2.0; - // destroyedLevel = 2.0; - // disabledLevel = 2.0; - // mass = 1.2; - // elasticity = 0.1; - // friction = 0.9; - // collideable = 1; - // pickupRadius = 1; - // sticky = false; - - // explosion = CameraGrenadeExplosion; - // expDmgRadius = 1.0; - // expDamage = 0.1; - // expImpulse = 200.0; - // dynamicType = $TypeMasks::StaticShapeObjectType; - // deployedObject = true; - // cmdCategory = "Misc"; - // cmdIcon = CMDSensorIcon; - - // targetNameTag = 'Security'; - // targetTypeTag = 'Camera'; - // deployAmbientThread = true; - // debrisShapeName = "debris_generic_small.dts"; - // debris = SmallShapeDebris; - // heatSignature = 0; - // needsPower = true; -//}; - -datablock StaticShapeData(DeployedSpine) : StaticShapeDamageProfile { - className = "spine"; - shapeFile = "Pmiscf.dts"; - - maxDamage = 0.5; - destroyedLevel = 0.5; - disabledLevel = 0.3; - - isShielded = true; - energyPerDamagePoint = 240; - maxEnergy = 50; - rechargeRate = 0.25; - - explosion = HandGrenadeExplosion; - expDmgRadius = 3.0; - expDamage = 0.1; - expImpulse = 200.0; - - dynamicType = $TypeMasks::StaticShapeObjectType; - deployedObject = true; - cmdCategory = "DSupport"; - cmdIcon = CMDSensorIcon; - cmdMiniIconName = "commander/MiniIcons/com_deploymotionsensor"; - targetNameTag = 'Light Support Beam'; - deployAmbientThread = true; - debrisShapeName = "debris_generic_small.dts"; - debris = DeployableDebris; - heatSignature = 0; - needsPower = true; -}; - -//---------------------------------------------------------------------------- -// FUNCTIONS -//---------------------------------------------------------------------------- -function DetructableSecurityCamera::onDestroyed(%this, %obj) -{ - schedule(1000,0,"delete",%obj); -} +//Component: Destructable Props +//Description: Not much to describe.. stuff that blows up or can be broken. + +//---------------------------------------------------------------------------- +// DATABLOCKS +//---------------------------------------------------------------------------- +datablock StaticShapeData(DeployedSpine) : StaticShapeDamageProfile { + className = "spine"; + shapeFile = "Pmiscf.dts"; + + maxDamage = 0.5; + destroyedLevel = 0.5; + disabledLevel = 0.3; + + isShielded = true; + energyPerDamagePoint = 240; + maxEnergy = 50; + rechargeRate = 0.25; + + explosion = HandGrenadeExplosion; + expDmgRadius = 3.0; + expDamage = 0.1; + expImpulse = 200.0; + + dynamicType = $TypeMasks::StaticShapeObjectType; + deployedObject = true; + cmdCategory = "DSupport"; + cmdIcon = CMDSensorIcon; + cmdMiniIconName = "commander/MiniIcons/com_deploymotionsensor"; + targetNameTag = 'Light Support Beam'; + deployAmbientThread = true; + debrisShapeName = "debris_generic_small.dts"; + debris = DeployableDebris; + heatSignature = 0; + needsPower = true; +}; + +//---------------------------------------------------------------------------- +// FUNCTIONS +//---------------------------------------------------------------------------- +function DetructableSecurityCamera::onDestroyed(%this, %obj) +{ + schedule(1000,0,"delete",%obj); +} diff --git a/scripts/modScripts/server/propertyOwning.cs b/scripts/modscripts/server/propertyOwning.cs similarity index 100% rename from scripts/modScripts/server/propertyOwning.cs rename to scripts/modscripts/server/propertyOwning.cs diff --git a/scripts/modScripts/server/serverFunctions.cs b/scripts/modscripts/server/serverFunctions.cs similarity index 100% rename from scripts/modScripts/server/serverFunctions.cs rename to scripts/modscripts/server/serverFunctions.cs diff --git a/scripts/modScripts/server/RPG/serverNetworking.cs b/scripts/modscripts/server/serverNetworking.cs similarity index 100% rename from scripts/modScripts/server/RPG/serverNetworking.cs rename to scripts/modscripts/server/serverNetworking.cs diff --git a/scripts/modScripts/server/torqueExServer.cs b/scripts/modscripts/server/torqueExServer.cs similarity index 74% rename from scripts/modScripts/server/torqueExServer.cs rename to scripts/modscripts/server/torqueExServer.cs index 653157c..b9aa555 100644 --- a/scripts/modScripts/server/torqueExServer.cs +++ b/scripts/modscripts/server/torqueExServer.cs @@ -1,222 +1,294 @@ -//------------------------------------------------------------------------------ -// torqueExServer.cs -// Torque Extensions for Servers -// Copyright (c) 2012 The DarkDragonDX -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -// Name: setVoice -// Argument %client: The client object to change the voice of. -// Argument %voice: The name of the voice to change to -// Argument %voicepitch: The voicepitch to use -// Description: Changes the voice of the targeted client object. -//============================================================================== -function setVoice(%client, %voice, %voicepitch) -{ - freeClientTarget(%client); - %client.voice = %voice; - %client.voicetag = addtaggedstring(%voice); - %client.target = allocClientTarget(%client, %client.name, %client.skin, %client.voiceTag, '_ClientConnection', 0, 0, %client.voicePitch); - - if (IsObject(%client.player)) - %client.player.setTarget(%client.target); - return true; -} - -//------------------------------------------------------------------------------ -// Name: setSkin -// Argument %client: The client object to change the voice of. -// Argument %skin: The skin to change to. -// Description: Changes the skin of the targeted client object. -//============================================================================== -function setSkin(%client, %skin) -{ - freeClientTarget(%client); - %client.skin = addtaggedstring(%skin); - %client.target = allocClientTarget(%client, %client.name, %client.skin, %client.voiceTag, '_ClientConnection', 0, 0, %client.voicePitch); - - // If the client has a player object - if (IsObject(%client.player)) - %client.player.setTarget(%client.target); - return true; -} - -//------------------------------------------------------------------------------ -// Name: setName -// Argument %client: The client object to change the skin of. -// Argument %name: The name to change to. -// Description: Changes the name of the targeted client object. -//============================================================================== -function setName(%client, %name) -{ - freeClientTarget(%client); - %client.namebase = %name; - %client.name = addtaggedstring(%name); - %client.target = allocClientTarget(%client, %client.name, %client.skin, %client.voiceTag, '_ClientConnection', 0, 0, %client.voicePitch); - - if (IsObject(%client.player)) - %client.player.setTarget(%client.target); - - //Update the client in the lobby. - HideClient(%client); - ShowClient(%client); - return true; -} - -//------------------------------------------------------------------------------ -// Name: setTeam -// Argument %client: The client object to change the team of. -// Argument %name: The team to change to. -// Description: Changes the team of the targeted client object. -//============================================================================== -function setTeam(%client,%team) -{ - %client.team = %team; - %client.setSensorGroup(%team); - setTargetSensorGroup(%client.target,%team); - return true; -} - -//------------------------------------------------------------------------------ -// Name: hideClientInLobby -// Argument %client: The client to hide. -// Description: Hides this client object from the lobby only. -// (Doesn't have anything to do with the server list) -//============================================================================== -function hideClientInLobby(%client) -{ - messageAllExcept( %client, -1, 'MsgClientDrop', "", Game.kickClientName, %client ); - return true; -} - -//------------------------------------------------------------------------------ -// Name: showClientInLobby -// Argument %client: The client to show. -// Description: Shows this client object in the lobby only. -// (Doesn't have anything to do with the server list) -//============================================================================== -function showClientInLobby(%client) -{ - messageAllExcept(%client, -1, 'MsgClientJoin', "", %client.name, %client, %client.target, %client.isAIControlled(), %client.isAdmin, %client.isSuperAdmin, %client.isSmurf, %client.Guid); - return true; -} - -//------------------------------------------------------------------------------ -// Name: hideClientInList -// Argument %client: The client to hide. -// Description: Hides the client in the server list only. -// WARNING!!! Running this on actual GameConnections is destructive. The game -// will refuse to update the client anymore until they are reshown. This is -// only known to work on AI's without a problem. -//============================================================================== -function hideClientInList(%client) -{ - if (!IsObject(HiddenClientGroup)) - { - new SimGroup(HiddenClientGroup); - ServerGroup.add(HiddenClientGroup); - } - HiddenClientGroup.add(%client); - return true; -} - -//------------------------------------------------------------------------------ -// Name: showClientInList -// Argument %client: The client to show. -// Description: Shows the client in the server list only. -//============================================================================== -function showClientInList(%client) -{ - ClientGroup.add(%client); - return true; -} - -function ServerCMDCheckHTilt(%client){ return %client; } // CCM-based clients spam fix, for some reason they spam this to the server whenever they strafe. - -// TypeMasks -$TypeMasks::AllObjectType = -1; //Same thing as everything, thanks to Krash123 for telling me this. :) -$TypeMasks::InteractiveObjectType = $TypeMasks::PlayerObjectType | $TypeMasks::VehicleObjectType | $TypeMasks::WaterObjectType | $TypeMasks::ProjectileObjectType | $TypeMasks::ItemObjectType | $TypeMasks::CorpseObjectType; -$TypeMasks::UnInteractiveObjectType = $TypeMasks::StaticObjectType | $TypeMasks::TerrainObjectType | $TypeMasks::InteriorObjectType | $TypeMasks::StaticTSObjectType | $TypeMasks::StaticRenderedObjectType; -$TypeMasks::BaseAssetObjectType = $TypeMasks::ForceFieldObjectType | $TypeMasks::TurretObjectType | $TypeMasks::SensorObjectType | $TypeMasks::StationObjectType | $TypeMasks::GeneratorObjectType; -$TypeMasks::GameSupportObjectType = $TypeMasks::TriggerObjectType | $TypeMasks::MarkerObjectType | $TypeMasks::CameraObjectType | $TypeMasks::VehicleBlockerObjectType | $TypeMasks::PhysicalZoneObjectType; -$TypeMasks::GameContentObjectType = $TypeMasks::ExplosionObjectType | $TypeMasks::CorpseObjectType | $TypeMasks::DebrisObjectType; -$TypeMasks::DefaultLOSObjectType = $TypeMasks::TerrainObjectType | $TypeMasks::InteriorObjectType | $TypeMasks::StaticObjectType; - - -// --- Binding Functions -function GameConnection::setVoice(%this, %voice, %voicepitch) { return setVoice(%this, %voice, %voicepitch); } -function GameConnection::setSkin(%this, %skin) { return setSkin(%this, %skin); } -function GameConnection::setName(%this, %name){ return setName(%this, %name); } -function GameConnection::setTeam(%this, %team){ return setTeam(%this, %team); } -function GameConnection::hideInLobby(%this){ return hideClientInLobby(%this); } -function GameConnection::showInLobby(%this){ return showClientInLobby(%this); } -// function GameConnection::hideClientInList(%this){ return hideClientInList(%this); } -// function GameConnection::showClientInList(%this){ return showClientInList(%this); } - -function AIConnection::setVoice(%this, %voice, %voicepitch) { return setVoice(%this, %voice, %voicepitch); } -function AIConnection::setSkin(%this, %skin) { return setSkin(%this, %skin); } -function AIConnection::setName(%this, %name){ return setName(%this, %name); } -function AIConnection::setTeam(%this, %team){ return setTeam(%this, %team); } -function AIConnection::hide(%this){ return hideClientInLobby(%this); } -function AIConnection::show(%this){ return showClientInLobby(%this); } -function AIConnection::hideClientInList(%this){ return hideClientInList(%this); } -function AIConnection::showClientInList(%this){ return showClientInList(%this); } - -function AIConnection::disengageTasks(%this) -{ - // Don't quite remember exactly what the minimal - // requirements here to get the same effect is, - // but this works fine as it is it seems. - AIUnassignClient(%this); // Have no idea what this does! - %this.stop(); - %this.clearTasks(); // Clear the Behavior Tree - %this.clearStep(); - %this.lastDamageClient = -1; - %this.lastDamageTurret = -1; - %this.shouldEngage = -1; - %this.setEngageTarget(-1); - %this.setTargetObject(-1); - %this.pilotVehicle = false; - %this.defaultTasksAdded = false; - return true; -} - -function Player::setVoice(%this, %voice, %voicepitch) -{ - if (!isObject(%this.Client)) - { - %this.Client = new ScriptObject(); // Glue! - %this.Client.Player = %this; - } - return setVoice(%this.Client, %voice, %voicepitch); -} - -function Player::setSkin(%this, %skin) -{ - if (!isObject(%this.Client)) - { - %this.Client = new ScriptObject(); - %this.Client.Player = %this; - } - return setSkin(%this, %skin); -} - -function Player::setName(%this, %name) -{ - if (!isObject(%this.Client)) - { - %this.Client = new ScriptObject(); - %this.Client.Player = %this; - } - return setName(%this, %name); -} - -function Player::setTeam(%this, %team) -{ - if (!isObject(%this.Client)) - { - %this.Client = new ScriptObject(); - %this.Client.Player = %this; - } - return setTeam(%this, %team); +//------------------------------------------------------------------------------ +// torqueExServer.cs +// Torque Extensions for Servers +// Copyright (c) 2012 Robert MacGregor +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// Name: setVoice +// Argument %client: The client object to change the voice of. +// Argument %voice: The name of the voice to change to +// Argument %voicepitch: The voicepitch to use +// Description: Changes the voice of the targeted client object. +//============================================================================== +function setVoice(%client, %voice, %voicepitch) +{ + freeClientTarget(%client); + %client.voice = %voice; + %client.voicePitch = %voicePitch; + %client.voicetag = addtaggedstring(%voice); + %client.target = allocClientTarget(%client, %client.name, %client.skin, %client.voiceTag, '_ClientConnection', 0, 0, %client.voicePitch); + + if (IsObject(%client.player)) + %client.player.setTarget(%client.target); + return true; +} + +//------------------------------------------------------------------------------ +// Name: setSkin +// Argument %client: The client object to change the voice of. +// Argument %skin: The skin to change to. +// Description: Changes the skin of the targeted client object. +//============================================================================== +function setSkin(%client, %skin) +{ + freeClientTarget(%client); + %client.skin = addtaggedstring(%skin); + %client.target = allocClientTarget(%client, %client.name, %client.skin, %client.voiceTag, '_ClientConnection', 0, 0, %client.voicePitch); + + // If the client has a player object + if (IsObject(%client.player)) + %client.player.setTarget(%client.target); + return true; +} + +//------------------------------------------------------------------------------ +// Name: setName +// Argument %client: The client object to change the skin of. +// Argument %name: The name to change to. +// Description: Changes the name of the targeted client object. +//============================================================================== +function setName(%client, %name, %lobbyUpdate) +{ + freeClientTarget(%client); + %client.namebase = %name; + %client.name = addtaggedstring(%name); + %client.target = allocClientTarget(%client, %client.name, %client.skin, %client.voiceTag, '_ClientConnection', 0, 0, %client.voicePitch); + + if (IsObject(%client.player)) + %client.player.setTarget(%client.target); + + // Update the client in the lobby if we wanted to + if (%lobbyUpdate) + { + hideClientInLobby(%client); + ShowClientInLobby(%client); + } + return true; +} + +//------------------------------------------------------------------------------ +// Name: setTeam +// Argument %client: The client object to change the team of. +// Argument %name: The team to change to. +// Description: Changes the team of the targeted client object. +//============================================================================== +function setTeam(%client,%team) +{ + %client.team = %team; + %client.setSensorGroup(%team); + setTargetSensorGroup(%client.target,%team); + return true; +} + +//------------------------------------------------------------------------------ +// Name: hideClientInLobby +// Argument %client: The client to hide. +// Description: Hides this client object from the lobby only. +// (Doesn't have anything to do with the server list) +//============================================================================== +function hideClientInLobby(%client) +{ + messageAllExcept( %client, -1, 'MsgClientDrop', "", Game.kickClientName, %client ); + return true; +} + +//------------------------------------------------------------------------------ +// Name: showClientInLobby +// Argument %client: The client to show. +// Description: Shows this client object in the lobby only. +// (Doesn't have anything to do with the server list) +//============================================================================== +function showClientInLobby(%client) +{ + messageAllExcept(%client, -1, 'MsgClientJoin', "", %client.name, %client, %client.target, %client.isAIControlled(), %client.isAdmin, %client.isSuperAdmin, %client.isSmurf, %client.Guid); + return true; +} + +//------------------------------------------------------------------------------ +// Name: hideClientInList +// Argument %client: The client to hide. +// Description: Hides the client in the server list only. +// WARNING!!! Running this on actual GameConnections is destructive. The game +// will refuse to update the client anymore until they are reshown. This is +// only known to work on AI's without a problem. +//============================================================================== +function hideClientInList(%client) +{ + if (!IsObject(HiddenClientGroup)) + { + new SimGroup(HiddenClientGroup); + ServerGroup.add(HiddenClientGroup); + } + + if (HiddenClientGroup.isMember(%client)) + return false; + + $HostGamePlayerCount--; + if (%client.isAIControlled()) + $HostGameBotCount--; + + HiddenClientGroup.add(%client); + return true; +} + +function listHiddenPlayers() +{ + for (%i = 0; %i < HiddenClientGroup.getCount(); %i++) + { + %cl = HiddenClientGroup.getObject(%i); + %status = %cl.isAIControlled() ? "Bot" : "Player"; + echo("client: " @ %cl @ " player: " @ %cl.player @ " name: " @ %cl.namebase @ " team: " @ %cl.team @ " status: " @ %status); + } + return true; +} + +//------------------------------------------------------------------------------ +// Name: showClientInList +// Argument %client: The client to show. +// Description: Shows the client in the server list only. +//============================================================================== +function showClientInList(%client) +{ + if (ClientGroup.isMember(%client)) + return false; + + $HostGamePlayerCount++; + if (%client.isAIControlled()) + $HostGameBotCount++; + ClientGroup.add(%client); + return true; +} + +//------------------------------------------------------------------------------ +// Name: plnametocid +// Argument %name: The name of a client. +// Description: Returns the client ID of a player whose name closest matches +// %name. (Does not take the hidden group into consideration) +// Note: This code was pulled from construction, the author is unknown to me. +//============================================================================== +function plnametocid(%name) +{ + %count = ClientGroup.getCount(); //counts total clients + for(%i = 0; %i < %count; %i++) //loops till all clients are accounted for + { + %obj = ClientGroup.getObject(%i); //gets the clientid based on the ordering hes in on the list + %nametest=%obj.namebase; //pointless step but i didnt feel like removing it.... + %nametest=strlwr(%nametest); //make name lowercase + %name=strlwr(%name); //same as above, for the other name + if(strstr(%nametest,%name) != -1) //is all of name test used in name + return %obj; //if so return the clientid and stop the function + } + return 0; //if none fits return 0 and end function +} + +function forceSpawn(%client) +{ + Game.spawnPlayer( %client, false ); + CloseScoreScreen(%client); + return true; +} + +function ServerCMDCheckHTilt(%client){ } // CCM-based clients spam fix, for some reason they spam this to the server whenever they strafe. + +// TypeMasks +$TypeMasks::AllObjectType = -1; //Same thing as everything, thanks to Krash123 for telling me this. :) +$TypeMasks::InteractiveObjectType = $TypeMasks::PlayerObjectType | $TypeMasks::VehicleObjectType | $TypeMasks::WaterObjectType | $TypeMasks::ProjectileObjectType | $TypeMasks::ItemObjectType | $TypeMasks::CorpseObjectType; +$TypeMasks::UnInteractiveObjectType = $TypeMasks::StaticObjectType | $TypeMasks::TerrainObjectType | $TypeMasks::InteriorObjectType | $TypeMasks::StaticTSObjectType | $TypeMasks::StaticRenderedObjectType; +$TypeMasks::BaseAssetObjectType = $TypeMasks::ForceFieldObjectType | $TypeMasks::TurretObjectType | $TypeMasks::SensorObjectType | $TypeMasks::StationObjectType | $TypeMasks::GeneratorObjectType; +$TypeMasks::GameSupportObjectType = $TypeMasks::TriggerObjectType | $TypeMasks::MarkerObjectType | $TypeMasks::CameraObjectType | $TypeMasks::VehicleBlockerObjectType | $TypeMasks::PhysicalZoneObjectType; +$TypeMasks::GameContentObjectType = $TypeMasks::ExplosionObjectType | $TypeMasks::CorpseObjectType | $TypeMasks::DebrisObjectType; +$TypeMasks::DefaultLOSObjectType = $TypeMasks::TerrainObjectType | $TypeMasks::InteriorObjectType | $TypeMasks::StaticObjectType; + + +// --- Binding Functions +function GameConnection::setVoice(%this, %voice, %voicepitch) { return setVoice(%this, %voice, %voicepitch); } +function GameConnection::setSkin(%this, %skin) { return setSkin(%this, %skin); } +function GameConnection::setName(%this, %name){ return setName(%this, %name); } +function GameConnection::setTeam(%this, %team){ return setTeam(%this, %team); } +function GameConnection::hideInLobby(%this){ return hideClientInLobby(%this); } +function GameConnection::showInLobby(%this){ return showClientInLobby(%this); } +function Gameconnection::spawn(%this){ return forceSpawn(%this); } +// function GameConnection::hideClientInList(%this){ return hideClientInList(%this); } +// function GameConnection::showClientInList(%this){ return showClientInList(%this); } + +function AIConnection::setVoice(%this, %voice, %voicepitch) { return setVoice(%this, %voice, %voicepitch); } +function AIConnection::setSkin(%this, %skin) { return setSkin(%this, %skin); } +function AIConnection::setName(%this, %name){ return setName(%this, %name); } +function AIConnection::setTeam(%this, %team){ return setTeam(%this, %team); } +function AIConnection::hide(%this){ return hideClientInLobby(%this); } +function AIConnection::show(%this){ return showClientInLobby(%this); } +function AIConnection::hideClientInList(%this){ return hideClientInList(%this); } +function AIConnection::showClientInList(%this){ return showClientInList(%this); } + +function AIConnection::disengageTasks(%this) +{ + // Don't quite remember exactly what the minimal + // requirements here to get the same effect is, + // but this works fine as it is it seems. + AIUnassignClient(%this); // Have no idea what this does! + %this.stop(); + %this.clearTasks(); // Clear the Behavior Tree + %this.clearStep(); + %this.lastDamageClient = -1; + %this.lastDamageTurret = -1; + %this.shouldEngage = -1; + %this.setEngageTarget(-1); + %this.setTargetObject(-1); + %this.pilotVehicle = false; + %this.defaultTasksAdded = false; + return true; +} + +function Player::setVoice(%this, %voice, %voicepitch) +{ + if (!isObject(%this.Client)) + { + %this.Client = new ScriptObject(); // Glue! + %this.Client.Player = %this; + } + return setVoice(%this.Client, %voice, %voicepitch); +} + +function Player::setSkin(%this, %skin) +{ + if (!isObject(%this.Client)) + { + %this.Client = new ScriptObject(); + %this.Client.Player = %this; + } + return setSkin(%this, %skin); +} + +function Player::setName(%this, %name, %lobbyUpdate) +{ + if (!isObject(%this.Client)) + { + %this.Client = new ScriptObject(); + %this.Client.Player = %this; + } + return setName(%this, %name, %lobbyUpdate); +} + +function Player::setTeam(%this, %team) +{ + if (!isObject(%this.Client)) + { + %this.Client = new ScriptObject(); + %this.Client.Player = %this; + } + return setTeam(%this, %team); +} + +// This package is used to hook several functions that will induce bugs due to usage of this code +package ExOverrides +{ + function fixMe(){} +}; +if (!isActivePackage(ExOverrides)) + activatePackage(ExOverrides); +else +{ + deactivatePackage(ExOverrides); + activatePackage(ExOverrides); } \ No newline at end of file diff --git a/scripts/modScripts/shared/Array.cs b/scripts/modscripts/shared/Array.cs similarity index 84% rename from scripts/modScripts/shared/Array.cs rename to scripts/modscripts/shared/Array.cs index eacc2f6..24ecd1e 100644 --- a/scripts/modScripts/shared/Array.cs +++ b/scripts/modscripts/shared/Array.cs @@ -1,75 +1,83 @@ -//------------------------------------------------------------------------------ -// Array.cs -// Array object you can pass around. -// Copyright (c) 2012 The DarkDragonDX -//============================================================================== - -function ArrayFactory::create(%this, %name) -{ - if (isObject(%name)) - %name = ""; - %object = new ScriptObject(%name) { class = "ArrayObject"; }; - %object.elementCount = 0; - return %object; -} - -function ArrayObject::setElement(%this, %index, %object) -{ - %replaced = false; - if (%this.Element[%index] != "") - %replaced = true; - else - { - %this.elementIndex[%index] = %this.elementCount; - %this.elementIndices[%this.elementCount] = %index; - %this.elementCount++; - } - - %this.Element[%index] = %object; - return %replaced; -} - -function ArrayObject::list(%this) -{ - %list = Array.create(); - for (%i = 0; %i < %this.elementCount; %i++) - %list.setElement(%i, %this.Element[%this.elementIndices[%i]]); - return %list; -} - -function ArrayObject::removeElement(%this, %index) -{ - if (%this.Element[%index] != "") - { - %this.Element[%index] = ""; - for (%i = %this.elementIndex[%index]; %i < %this.elementCount; %i++) - %this.elementIndices[%i] = %this.elementIndices[%i+1]; - %this.elementCount--; - return true; - } - else - return false; - return false; -} - -function ArrayObject::isElement(%this, %index) -{ - if (%this.Element[%index] == "") - return false; - else - return true; - return false; -} - -function ArrayObject::element(%this, %index) -{ - return %this.Element[%index]; -} - -function ArrayObject::count(%this) -{ - return %this.elementCount; -} - -if (!IsObject(Array)) +//------------------------------------------------------------------------------ +// Array.cs +// Array object you can pass around. +// Copyright (c) 2012 Robert MacGregor +//============================================================================== + +function ArrayFactory::create(%this, %name) +{ + if (isObject(%name)) + %name = ""; + %object = new ScriptObject(%name) { class = "ArrayObject"; }; + %object.elementCount = 0; + return %object; +} + +function ArrayObject::setElement(%this, %index, %object) +{ + %replaced = false; + if (%this.Element[%index] != "") + %replaced = true; + else + { + %this.elementIndex[%index] = %this.elementCount; + %this.elementIndices[%this.elementCount] = %index; + %this.elementCount++; + } + + %this.Element[%index] = %object; + return %replaced; +} + +function ArrayObject::list(%this) +{ + %list = Array.create(); + for (%i = 0; %i < %this.elementCount; %i++) + %list.setElement(%i, %this.Element[%this.elementIndices[%i]]); + return %list; +} + +function ArrayObject::removeElement(%this, %index) +{ + if (%this.Element[%index] != "") + { + %this.Element[%index] = ""; + for (%i = %this.elementIndex[%index]; %i < %this.elementCount; %i++) + %this.elementIndices[%i] = %this.elementIndices[%i+1]; + %this.elementCount--; + return true; + } + else + return false; + return false; +} + +function ArrayObject::hasElementValue(%this, %value) +{ + for (%i = 0; %i < %this.elementCount; %i++) + if (%this.Element[%i] == %value) + return true; + return false; +} + +function ArrayObject::isElement(%this, %index) +{ + if (%this.Element[%index] == "") + return false; + else + return true; + return false; +} + +function ArrayObject::element(%this, %index) +{ + return %this.Element[%index]; +} + +function ArrayObject::count(%this) +{ + return %this.elementCount; +} + +if (!IsObject(Array)) new ScriptObject(Array) { class = "ArrayFactory"; }; \ No newline at end of file diff --git a/scripts/modscripts/shared/BasicData.cs b/scripts/modscripts/shared/BasicData.cs new file mode 100644 index 0000000..4699e9c --- /dev/null +++ b/scripts/modscripts/shared/BasicData.cs @@ -0,0 +1,276 @@ +//------------------------------------------------------------------------------ +// basicDataStorage.cs +// Originally written for T2BoL mod back in the day, now is being rewritten +// for the original implementation was pretty crappy. +// Requires: Array.cs +// Copyright (c) 2012 Robert MacGregor +//============================================================================== + +//------------------------------------------------------------------------------ +// Name: BasicDataParser.load +// Argument %file: The file to parse and load into memory. +// Description: This function is the main function of everything; it loads +// %file into memory. +// Return: True if the function succeeded, false if otherwise failed. +//============================================================================== +function BasicDataParser::load(%this, %file) +{ + // Make sure we have our values initialised (math doesn't work right on nonexistent variables!) + if (%this.filesLoaded == "") + %this.filesLoaded = 0; + if (%this.blockEntryCount == "") + %this.blockEntryCount = 0; + if (%this.blockInstances == "") + %this.blockInstances = 0; + + %currentSeconds = formatTimeString("ss"); + // Check to see if the data is valid (returns false if we tried to load a nonexistent file) + if (!isFile(%file)) + { + error("basicDataStorage.cs: Attempted to load non-existent file " @ %file @ "!"); + return false; + } + // Check to see if this file is already loaded + if (%this.isLoaded(%file)) + { + error("basicDataStorage.cs: Attempted to reload data file " @ %file SPC "while it's already in memory! (try unloading or emptying)"); + return false; + } + // Add the file entry to memory (for the file check above) + %this.files[%this.filesLoaded] = %file; + %this.fileIndex[%file] = %this.filesLoaded; + %this.filesLoaded++; + + // Load the file into memory (function is from fileProcessing.cs) + %fileData = strReplace(stripChars(getFileBuffer(%file),"\t"),"\n","\t"); + %lineCount = getFieldCount(%fileData); + + %isProcessingBlock = false; // Used to set processing mode + %currentBlock = 0; + %hadError = false; + // Iterate through all lines + for (%i = 0; %i < %lineCount; %i++) + { + %currentLine = getField(%fileData,%i); + // Check to see if this line contains a block definition or not + %openingBlock = strStr(%currentLine, "["); + %closingBlock = strStr(%currentLine, "]"); + + // If we have a block definition, it should be against left margin + if (%openingBlock == 0 && %closingBlock > 0 && !%isProcessingBlock) + { + %isProcessingBlock = true; + %blockName = getSubStr(%currentLine,%openingBlock+1,%closingBlock-1); + + if (%this.blockInstances[%blockName] == "") + { + %this.blockInstances[%blockName] = 0; + %this.blockEntry[%this.blockEntryCount] = %blockName; + %this.blockEntryCount++; + } + // Create the array to store our block data + %currentBlock = Array.create(); + %currentBlock.Name = %blockName; + %currentBlock.File = %file; + + %this.blocks[%blockName,%this.blockInstances] = %currentBlock; + %this.blockInstances[%blockName]++; + %this.blockInstances++; + continue; + } + // Results in an error + else if (%openingBlock == 0 && %closingBlock > 0 && %isProcessingBlock) + { + error("basicDataStorage.cs: Error loading file "@ %file @ ", block spacing error."); + return false; + } + + // If we're processing the actual block + if (%isProcessingBlock) + { + if (%currentLine $="" || %i == %lineCount) + { + %isProcessingBlock = false; + continue; + } + else + { + %eqPos = strStr(%currentLine,"="); // This is safe since the equals sign should be first. + if (%eqPos == -1) + { + error("basicDataStorage.cs: Unable to read entry for block" SPC %currentBlock.Name @ " in file" SPC %file @ "!"); + %isProcessingBlock = false; + %hadError = true; + continue; + } + // Note: I got lazy here, just don't have semicolons in your data entries.. + %semiPos = strStr(%currentLine,";"); + if (%semiPos == -1 || getSubStrOccurance(%currentLine,";") > 1) + { + error("basicDataStorage.cs: Unable to read entry for block" SPC %currentBlock.Name @ " in file" SPC %file @ "!"); + %isProcessingBlock = false; + %hadError = true; + continue; + } + + %entryName = trim(getSubStr(%currentLine,0,%eqPos-1)); + %entryValue = trim(getSubStr(%currentLine,%eqPos+1, mAbs(%eqPos-%semiPos)-1 )); + %currentBlock.setElement(%entryName,%entryValue); + } + } + + } + + if (!%hadError) + warn("basicDataStorage.cs: Successfully loaded file" SPC %file SPC "in " @ formatTimeString("ss") - %currentSeconds SPC "seconds."); + return !%hadError; +} + +//------------------------------------------------------------------------------ +// Name: BasicDataParser.unload +// Argument %file: The file of who's entries should be unloaded. +// Description: This function is used to unload data by filename -- useful for +// reloading data from specific files. +// Return: True if the function was successful, false if otherwise failed. +//============================================================================== +function BasicDataParser::unload(%this, %file) +{ + if (!%this.isLoaded(%file)) + { + error("basicDataStorage.cs: Attempted to unload non-loaded data file " @ %file @ "!"); + return false; + } + + // Unload any data associated with this file now + %removed = ""; + for (%i = 0; %i < %this.blockEntryCount; %i++) + { + %name = %this.blockEntry[%i]; + for (%h = 0; %h < %this.blockInstances[%name]; %h++) + if (%this.blocks[%name, %h].File $= %file) + { + %this.blocks[%name, %h].delete(); + %this.blocks[%name, %h] = ""; + %this.blockEntry[%i] = ""; + %removed = trim(%removed SPC %i); + + if (%this.blockInstances[%name] == 1) + %this.blockInstances[%name] = ""; + else + %this.blockInstances[%name]--; + } + } + + // Iterate through our block entries and correct the imbalance + for (%i = 0; %i < getWordCount(%removed); %i++) + { + for (%h = i; %h < %this.blockEntryCount; %h++) + %this.blockEntry[%h-%i] = %this.blockEntry[%h+1]; + %this.blockEntryCount--; + } + + // Now remove the file entry + for (%i = %this.fileIndex[%file]; %i < %this.filesLoaded; %i++) + if (%i != %this.filesLoaded-1) + { + %this.files[%i] = %this.files[%i+1]; + %this.fileIndex[%this.files[%i+1]] = %i; + } + else + { + %this.fileIndex[%file] = ""; + %this.files[%i] = ""; + } + + // Decrement the files loaded count and return true + %this.filesLoaded--; + return true; +} + +//------------------------------------------------------------------------------ +// Name: BasicDataParser.count +// Argument %block: The bloick entry to count the occurances of +// Return: The occurances of %block in this parser object. If there is no +// such entry of %block anywhere, false (0) is returned. +//============================================================================== +function BasicDataParser::count(%this, %block) +{ + // Return zero if the block has no entries even registered + if (%this.blockInstances[%block] == "") + return false; + else + // Return the block Instances otherwise + return %this.blockInstances[%block]; + return false; // Shouldn't happen +} + +//------------------------------------------------------------------------------ +// Name: BasicDataParser.empty +// Description: Empties the entire object of any information it may have +// loaded anytime. +// Return: True is always returned from this function. +//============================================================================== +function BasicDataParser::empty(%this) +{ + // Iterate through our block entries and destroy them + for (%i = 0; %i < %this.blockEntryCount; %i++) + { + %name = %this.blockEntry[%i]; + for (%h = 0; %h < %this.blockInstances[%name]; %h++) + { + %this.blocks[%name, %h].delete(); + %this.blocks[%name, %h] = ""; + } + %this.blockInstances[%name] = ""; + %this.blockEntry[%i] = ""; + } + + // Remove the files loaded entries now + for (%i = 0; %i < %this.filesLoaded; %i++) + { + %this.fileIndex[%this.files[%i]] = ""; + %this.files[%i] = ""; + } + + // Reset some variables to 0 and return true + %this.filesLoaded = 0; + %this.blockInstances = 0; + %this.blockEntryCount = 0; + + return true; +} + +//------------------------------------------------------------------------------ +// Name: BasicDataParser.isLoaded +// Argument %file: The file to check the loaded status of. +// Description: Returns if %file is loaded into memory of this object or not. +// Return: A boolean representing the loaded status. +//============================================================================== +function BasicDataParser::isLoaded(%this, %file) +{ + // Check to see if this file is already loaded + for (%i = 0; %i < %this.filesLoaded; %i++) + if (%this.files[%i] $= %file) + return true; + return false; +} + +//------------------------------------------------------------------------------ +// Name: BasicDataParser.get +// Argument %block: The name of the block to return. +// Argument %occurance: The block index we need to return -- if there's +// multiple entries of %block. +// Description: This function is used to retrieve block entries loaded from +// within any of the files this object has parsed. +// Return: An Array (array.cs) containing relevent information to the requested +// block. If there is no such entry of %block, false is returned. +//============================================================================== +function BasicDataParser::get(%this, %block, %occurance) +{ + // Check ti see uf thus block has only once entry -- in which case %occurance is ignored + if (%this.count(%block) == 1) return %this.blocks[%block, 0]; + // Otherwise we use %occurance to return the specific index + else if (%occurance >= 0 && %occurance <= %this.count(%block)) return %this.blocks[%block, %occurance]; + + return false; +} \ No newline at end of file diff --git a/scripts/modscripts/shared/FileFunctions.cs b/scripts/modscripts/shared/FileFunctions.cs new file mode 100644 index 0000000..b77c79a --- /dev/null +++ b/scripts/modscripts/shared/FileFunctions.cs @@ -0,0 +1,80 @@ +// ----------------------------------------------------- +// FileFunctions.cs +// Basic file functions +// Copyright (c) 2012 Robert MacGregor +// ----------------------------------------------------- +function getFileBuffer(%file) +{ + if (!IsFile(%file)) + return -1; + + new FileObject(FileBuffer); + FileBuffer.openForRead(%file); + + while (!FileBuffer.isEOF()) + %buffer = %buffer @ FileBuffer.readLine() @ "\n"; + FileBuffer.detach(); + return %buffer; //Long string. >.> +} + +function getLine(%file, %line) +{ + if (!IsFile(%file)) + return -1; + + new FileObject(FileLine); + FileLine.openForRead(%file); + + for (%i = 0; %i < %line; %i++) + %line = FileLine.readLine(); + FileLine.detach(); + return %line; +} + +function getLine(%file, %line) +{ + if (!IsFile(%file)) + return -1; + + new FileObject(FileLine); + FileLine.openForRead(%file); + + for (%i = 0; %i < %line; %i++) + %line = FileLine.readLine(); + FileLine.detach(); + return %line; +} + +// Returns an unsorted list of the contents of %dir (including folders) +function getDirectory(%dir) +{ + %array = Array.create(); + + %fileCount = 0; + for( %file = findFirstFile( %dir @ "*.*" ); %file !$= ""; %file = findNextFile( %dir @ "*.*" ) ) + { + %file = strReplace(%file, %socket.request, ""); + if (strStr(%file, "/") != -1) + { + %dir = getSubStr(%file, 0, strStr(%file, "/")) @ "/"; + if (!%dirAdded[%dir]) + { + %data = %data @ "" @ %dir @ "
\n"; + %dirAdded[%dir] = true; + } + } + else + %data = %data @ "" @ %file @ "
\n"; + } + return %array; +} + +// ----------------------------------------------------- +// Bound Functions +// ----------------------------------------------------- +function fileObject::Detach(%this) //Detaches fileObject from file & deletes +{ + %this.close(); + %this.delete(); + return %this; +} diff --git a/scripts/modScripts/shared/stringProcessing.cs b/scripts/modscripts/shared/StringFunctions.cs similarity index 90% rename from scripts/modScripts/shared/stringProcessing.cs rename to scripts/modscripts/shared/StringFunctions.cs index 2dc18fd..f147199 100644 --- a/scripts/modScripts/shared/stringProcessing.cs +++ b/scripts/modscripts/shared/StringFunctions.cs @@ -1,196 +1,196 @@ -//------------------------------------------------------------------------------ -// stringProcessing.cs -// String functions -// Copyright (c) 2012 The DarkDragonDX -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -function textToHash(%text) -{ - new fileObject(TextToHash); - TextToHash.openForWrite("Hash.txt"); - TextToHash.writeLine(%text); - TextToHash.detach(); - %hash = getFileCRC("Hash.txt"); - deleteFile("Hash.txt"); - return %hash; -} - -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -function strReverse(%string) -{ - %len = StrLen(%string); - %rstring = ""; - for (%i = 0; %i < %len; %i++) - %rstring = getSubStr(%string,%i,1) @ %rstring; - return %rstring; -} - -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -function subStrInsert(%string,%insert,%slot) -{ - %seg = getSubStr(%string,0,%slot); - %seg = %seg @ %insert; - %string = %seg @ getSubStr(%string,%slot,strLen(%string)); - return %string; -} - -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -function subStrRemove(%string,%slot)//Minimum: 1 -{ - %half2 = getSubStr(%string,%slot,strLen(%string)); - %half1 = getSubStr(%string,0,%slot-1); - return %half1 @ %half2; -} - -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -function strMove(%string,%factor) -{ - %len = GetWordCount(%string); - for (%i = 0; %i < %len; %i++) - { - %sub = getWord(%string,%i); - %move = subStrInsert(%move,%sub,%i); - } - return %move; -} - -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -function subStrMove(%string,%factor) -{ - %len = strLen(%string); - for (%i = 0; %i < %len; %i++) - { - %sub = getSubStr(%string,%i,1); - %move = subStrInsert(%move,%sub,%factor); - } - return %move; -} - -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -function subStrScramble(%string) -{ - %len = strLen(%string); - for (%i = 0; %i < %len; %i++) - { - %sub = getSubStr(%string,%i,1); - %scramble = subStrInsert(%scramble,%sub,getRandom(0,%len)); - } - return %scramble; -} -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -function strSplit(%string) -{ - %count = strLen(%string); - %div = %count / 2; - return getSubStr(%string,0,%div) @ " | " @ getSubStr(%string,%div,%count); -} - -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -function stripSpaces(%string) -{ - return strReplace(%string," ",""); -} - -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -function stripNonNumericCharacters(%string) -{ - %string = strLwr(%string); - return stripChars(%string,"abcdefghijklmnopqrstuvwxyz`~!@#$%^&*()-_=+\|}]{[/?.>,<;:"); -} - -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -function getSubStrOccurance(%string,%search) -{ - %len = strLen(%string); - %srLen = strLen(%search); - %count = 0; - for (%i = 0; %i < %len; %i++) - { - %strSearch = strStr(%string,%search); - if (%strSearch != -1) //It exists somewhere in the string - { - %count++; - %string = getSubStr(%string,%strSearch+%srLen,%len); - } - else - return %count; - } - return %count; -} - -function getSubStrPos(%string,%str,%num) -{ - %len = strLen(%string); - %subC = 0; - for (%i = 0; %i < %len; %i++) - { - %curPos = %i; - %sub = getSubStr(%string,%i,1); - - if (%sub $= %str) - { - %subC++; - if (%subC == %num) - break; - } - } - return %pos; -} - -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -function strWhite(%string, %whiteList, %char) -{ - %charLen = strLen(%char); - for (%i = 0; %i < strLen(%whiteList); %i++) - for (%h = 0; %h < %charLen; %h++) - { - %whiteSeg = getSubStr(%whiteList, %i, %charLen); - - } - return false; -} - -//------------------------------------------------------------------------------ -function getFileNameFromString(%string) -{ - if (strStr(%string, "/") == -1) - return %string; - else - return getSubStr(%string,getSubStrPos(%string,"/",getSubStrOccurance(%string, "/"))+1,strLen(%string)); -} - -//------------------------------------------------------------------------------- -function getFileExtensionFromString(%string) -{ - %file = getFileNameFromString(%string); - %period = strStr(%file,"."); - if (%period == -1) - return false; - else - return getSubStr(%string,getSubStrPos(%string,".",getSubStrOccurance(%string, "."))+1,strLen(%string)); -} - -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +// StringFunctions.cs +// String functions +// Copyright (c) 2012 Robert MacGregor +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +function textToHash(%text) +{ + new fileObject(TextToHash); + TextToHash.openForWrite("Hash.txt"); + TextToHash.writeLine(%text); + TextToHash.detach(); + %hash = getFileCRC("Hash.txt"); + deleteFile("Hash.txt"); + return %hash; +} + +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +function strReverse(%string) +{ + %len = StrLen(%string); + %rstring = ""; + for (%i = 0; %i < %len; %i++) + %rstring = getSubStr(%string,%i,1) @ %rstring; + return %rstring; +} + +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +function subStrInsert(%string,%insert,%slot) +{ + %seg = getSubStr(%string,0,%slot); + %seg = %seg @ %insert; + %string = %seg @ getSubStr(%string,%slot,strLen(%string)); + return %string; +} + +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +function subStrRemove(%string,%slot)//Minimum: 1 +{ + %half2 = getSubStr(%string,%slot,strLen(%string)); + %half1 = getSubStr(%string,0,%slot-1); + return %half1 @ %half2; +} + +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +function strMove(%string,%factor) +{ + %len = GetWordCount(%string); + for (%i = 0; %i < %len; %i++) + { + %sub = getWord(%string,%i); + %move = subStrInsert(%move,%sub,%i); + } + return %move; +} + +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +function subStrMove(%string,%factor) +{ + %len = strLen(%string); + for (%i = 0; %i < %len; %i++) + { + %sub = getSubStr(%string,%i,1); + %move = subStrInsert(%move,%sub,%factor); + } + return %move; +} + +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +function subStrScramble(%string) +{ + %len = strLen(%string); + for (%i = 0; %i < %len; %i++) + { + %sub = getSubStr(%string,%i,1); + %scramble = subStrInsert(%scramble,%sub,getRandom(0,%len)); + } + return %scramble; +} +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +function strSplit(%string) +{ + %count = strLen(%string); + %div = %count / 2; + return getSubStr(%string,0,%div) @ " | " @ getSubStr(%string,%div,%count); +} + +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +function stripSpaces(%string) +{ + return strReplace(%string," ",""); +} + +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +function stripNonNumericCharacters(%string) +{ + %string = strLwr(%string); + return stripChars(%string,"abcdefghijklmnopqrstuvwxyz`~!@#$%^&*()-_=+\|}]{[/?.>,<;:"); +} + +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +function getSubStrOccurances(%string,%search) +{ + %len = strLen(%string); + %srLen = strLen(%search); + %count = 0; + for (%i = 0; %i < %len; %i++) + { + %strSearch = strStr(%string,%search); + if (%strSearch != -1) //It exists somewhere in the string + { + %count++; + %string = getSubStr(%string,%strSearch+%srLen,%len); + } + else + return %count; + } + return %count; +} + +function getSubStrPos(%string,%str,%num) +{ + %len = strLen(%string); + %subC = 0; + for (%i = 0; %i < %len; %i++) + { + %curPos = %i; + %sub = getSubStr(%string,%i,1); + + if (%sub $= %str) + { + if (%subC == %num) + return %i; + %subC++; + } + } + return false; +} + +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +function strWhite(%string, %whiteList, %char) +{ + %charLen = strLen(%char); + for (%i = 0; %i < strLen(%whiteList); %i++) + for (%h = 0; %h < %charLen; %h++) + { + %whiteSeg = getSubStr(%whiteList, %i, %charLen); + + } + return false; +} + +//------------------------------------------------------------------------------ +function getFileNameFromString(%string) +{ + if (strStr(%string, "/") == -1) + return %string; + else + return getSubStr(%string,getSubStrPos(%string, "/", getSubStrOccurances(%string, "/")-1)+1,strLen(%string)); +} + +//------------------------------------------------------------------------------- +function getFileExtensionFromString(%string) +{ + %file = getFileNameFromString(%string); + %period = strStr(%file,"."); + if (%period == -1) + return false; + else + return getSubStr(%file,strStr(%file,".")+1, strLen(%file)); +} + +//------------------------------------------------------------------------------ diff --git a/scripts/modScripts/shared/basicDataStorage.cs b/scripts/modscripts/shared/basicDataStorage.cs similarity index 100% rename from scripts/modScripts/shared/basicDataStorage.cs rename to scripts/modscripts/shared/basicDataStorage.cs diff --git a/scripts/modScripts/shared/fileProcessing.cs b/scripts/modscripts/shared/fileProcessing.cs similarity index 100% rename from scripts/modScripts/shared/fileProcessing.cs rename to scripts/modscripts/shared/fileProcessing.cs diff --git a/scripts/modScripts/shared/initialize.cs b/scripts/modscripts/shared/initialize.cs similarity index 86% rename from scripts/modScripts/shared/initialize.cs rename to scripts/modscripts/shared/initialize.cs index 1acfaca..85b1f79 100644 --- a/scripts/modScripts/shared/initialize.cs +++ b/scripts/modscripts/shared/initialize.cs @@ -3,7 +3,7 @@ // Shared Functions for T2Bol // Copyright (c) 2012 The DarkDragonDX //============================================================================== -exec("scripts/modScripts/shared/stringProcessing.cs"); +exec("scripts/modScripts/shared/StringFunctions.cs"); exec("scripts/modScripts/shared/fileProcessing.cs"); exec("scripts/modScripts/shared/basicDataStorage.cs"); diff --git a/scripts/modScripts/shared/putback/basicDataStorage.cs b/scripts/modscripts/shared/putback/basicDataStorage.cs similarity index 100% rename from scripts/modScripts/shared/putback/basicDataStorage.cs rename to scripts/modscripts/shared/putback/basicDataStorage.cs diff --git a/scripts/mpbTeleporter.cs b/scripts/mpbTeleporter.cs index 6ea83fd..729be61 100644 --- a/scripts/mpbTeleporter.cs +++ b/scripts/mpbTeleporter.cs @@ -1,295 +1,295 @@ -//////////////////////////////////////////////////////////////////////////////// -// Mobile Point Base Teleporter // -// z0dd - ZOD, 4/24/02 // -//////////////////////////////////////////////////////////////////////////////// - -datablock StaticShapeData(MPBTeleporter) : StaticShapeDamageProfile -{ - className = Station; - catagory = "Stations"; - shapeFile = "station_teleport.dts"; - maxDamage = 1.20; - destroyedLevel = 1.20; - disabledLevel = 0.84; - explosion = ShapeExplosion; - expDmgRadius = 10.0; - expDamage = 0.4; - expImpulse = 1500.0; - dynamicType = $TypeMasks::StationObjectType; - isShielded = true; - energyPerDamagePoint = 33; - maxEnergy = 250; - rechargeRate = 0.31; - humSound = StationVehicleHumSound; - // don't let these be damaged in Siege missions - noDamageInSiege = true; - cmdCategory = "Support"; - cmdIcon = CMDVehicleStationIcon; - cmdMiniIconName = "commander/MiniIcons/com_vehicle_pad_inventory"; - targetNameTag = 'MPB'; - targetTypeTag = 'Teleport Station'; - teleporter = 1; -}; - -datablock ParticleData(mpbteleportparticle) -{ - dragCoefficient = 1.5; - gravityCoefficient = 0.2; - inheritedVelFactor = 0.2; - constantAcceleration = 0.0; - lifetimeMS = 1000; - lifetimeVarianceMS = 0; - textureName = "particleTest"; - - colors[0] = "0.06 0.06 0.36 1.0"; - colors[1] = "0.06 0.06 0.36 0.0"; - sizes[0] = 0.65; - sizes[1] = 0.30; -}; - -datablock ParticleEmitterData(MPBTeleportEmitter) -{ - ejectionPeriodMS = 5; - periodVarianceMS = 0; - ejectionVelocity = 1.1; - velocityVariance = 1.0; - ejectionOffset = 2.0; - thetaMin = 0.0; - thetaMax = 10.0; - phiReferenceVel = 0.0; - phiVariance = 360.0; - overrideAdvances = false; - particles = "mpbteleportparticle"; -}; - -function StationVehicle::createTeleporter(%data, %obj, %group) -{ - // %obj = Teleport Object - // %data = Teleport Datablock - // %group = Vehicle Pads Mission Group - - %Teleporter = new StaticShape() { - scale = "1 1 1"; - dataBlock = "MPBTeleporter"; - lockCount = "0"; - homingCount = "0"; - team = %obj.team; - }; - %obj.teleporter = %Teleporter; - %Teleporter.vStation = %obj.pad; - - %trans = %obj.pad.getSlotTransform(0); - %vSPos = getWords(%trans,0,2); - %vRot = getWords(%trans,3,5); - %vAngle = getWord(%trans,6); - %matrix = VectorOrthoBasis(%vRot @ " " @ %vAngle + 0.36); - %yRot = getWords(%matrix, 3, 5); - %pos = vectorAdd(%vSPos, vectorScale(%yRot, -31.5)); - %Teleporter.setTransform(%pos @ " " @ %vRot @ " " @ %vAngle); - - // Add the teleporter to the v-pads mission group for cleanup and power. - %group.add(%Teleporter); - %Teleporter.setPersistent(false); // set the teleporter to not save in the editor. - - // Apparently called to early on mission load done, call it now. - %Teleporter.getDataBlock().gainPower(%Teleporter); - - // Set the sensor group. - if(%Teleporter.getTarget() != -1) - setTargetSensorGroup(%Teleporter.getTarget(), %obj.team); - - // Allow players to use it. - %Teleporter.disabled = 0; -} - -function MPBTeleporter::onCollision(%data, %obj, %col) -{ - if(%col.getDataBlock().className !$= "Armor" || %col.getState() $= "Dead" || %col.teleporting) - return; - - if(isObject(%col)) - { - if(%obj.team == %col.client.team) - { - if(!%obj.isDisabled()) - { - if(%obj.isPowered()) - { - if(isObject(%obj.MPB) && %obj.MPB.fullyDeployed) - { - if(%obj.disabled == 0) - { - %col.lastWeapon = ( %col.getMountedImage($WeaponSlot) == 0 ) ? "" : %col.getMountedImage($WeaponSlot).getName().item; - %col.unmountImage($WeaponSlot); - %pos = %obj.position; - %col.setvelocity("0 0 0"); - %col.setMoveState(true); - %rot = getWords(%col.getTransform(), 3, 6); - %col.setTransform(getWord(%pos,0) @ " " @ getWord(%pos,1) @ " " @ getWord(%pos,2) + 0.6 @ " " @ %rot); - %col.teleporting = 1; - %col.startFade( 1000, 0, true ); - %col.playAudio($PlaySound, StationVehicleAcitvateSound); - - %obj.disabled = 1; // Disable the teleporter to more then one person at a time for a time. - %obj.setThreadDir($ActivateThread, TRUE); - %obj.playThread($ActivateThread, "activate"); - - %data.sparkEmitter(%obj); - %data.schedule(2000, "teleportout", %obj, %col); - %data.schedule(4000, "teleportingDone", %obj, %col); - } - else - messageClient(%col.client, 'MsgTeleportRecharging', '\c2Teleporter is recharging please stand by. ~wfx/powered/nexus_deny.wav'); - } - else - MessageClient(%col.client, "MsgNoMPB", 'MPB is not deployed.'); - } - else - messageClient(%col.client, 'MsgStationNoPower', '\c2Teleporter is not powered.'); - } - else - messageClient(%col.client, 'MsgStationDisabled', '\c2Teleporter is disabled.'); - } - else - messageClient(%col.client, 'MsgStationDenied', '\c2Access Denied -- Wrong team.~wfx/powered/station_denied.wav'); - } - else - return; -} - -function MPBTeleporter::teleportOut(%data, %obj, %player) -{ - if(isObject(%obj.MPB)) - { - %index = -1; - for(%x=0; %x < %obj.MPB.spawnPosCount; %x++) - { - %index = mFloor(getRandom() * %obj.MPB.spawnPosCount); - InitContainerRadiusSearch(%obj.MPB.spawnPos[%index], 2, $TypeMasks::MoveableObjectType); - if(ContainerSearchNext() == 0) - break; - else - %index = -1; - } - if(%index >= 0) - { - %player.setTransform(%obj.MPB.spawnPos[%index] @ " " @ getWords(%obj.MPB.getTransform(), 3, 6)); - } - else - { - messageClient(%player.client, 'MsgTeleFailed', 'No Valid teleporting positions.'); - %player.teleporting = 0; - } - } - else - { - messageClient(%player.client, 'MsgTeleFailed', 'No Valid teleporting positions because MPB was destroyed'); - %player.teleporting = 0; - } - %data.schedule(1000, "teleportIn", %player); -} - -function MPBTeleporter::teleportIn(%data, %player) -{ - %data.sparkEmitter(%player); // z0dd - ZOD, 4/24/02. teleport sparkles - %player.startFade(1000, 0, false ); - %player.playAudio($PlaySound, StationVehicleDeactivateSound); -} - -function MPBTeleporter::reEnable(%data, %obj) -{ - %obj.disabled = 0; -} - -function MPBTeleporter::sparkEmitter(%data, %obj) -{ - if (isObject(%obj.teleportEmitter)) - %obj.teleportEmitter.delete(); - - %obj.teleportEmitter = new ParticleEmissionDummy() { - position = %obj.position; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = defaultEmissionDummy; - emitter = "MPBTeleportEmitter"; - velocity = "1"; - }; - MissionCleanup.add(%obj.teleportEmitter); - %obj.teleportEmitter.schedule(800, "delete"); - - if (isObject(%obj.teleEmitter)) - %obj.teleEmitter.delete(); - - %obj.teleEmitter = new ParticleEmissionDummy() { - position = %obj.position; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = defaultEmissionDummy; - emitter = "FlyerJetEmitter"; - velocity = "1"; - }; - MissionCleanup.add(%obj.teleEmitter); - %obj.teleEmitter.schedule(700, "delete"); -} - -function MPBTeleporter::teleportingDone(%data, %obj, %player) -{ - %player.setMoveState(false); - %player.teleporting = 0; - %player.station = ""; - %data.reEnable(%obj); - if(%player.getMountedImage($WeaponSlot) == 0) - { - if(%player.inv[%player.lastWeapon]) - %player.use(%player.lastWeapon); - else - %player.selectWeaponSlot( 0 ); - } -} - -//------------------------------------------------------------------------------------------ -// Gets called from function MobileBaseVehicle::vehicleDeploy(%data, %obj, %player, %force). -// Passes this information to the MPBTeleporter::teleportOut function. -//------------------------------------------------------------------------------------------ - -function checkSpawnPos(%MPB, %radius) -{ - for(%y = -1; %y < 1; %y += 0.25) - { - %xCount=0; - for(%x = -1; %x < 1; %x += 0.25) - { - $MPBSpawnPos[(%yCount * 8) + %xCount] = %x @ " " @ %y; - %xCount++; - } - %yCount++; - } - %count = -1; - - for(%x = 0; %x < 64; %x++) - { - %pPos = getWords(%MPB.getTransform(), 0, 2); - %pPosX = getWord(%pPos, 0); - %pPosY = getWord(%pPos, 1); - %pPosZ = getWord(%pPos, 2); - - %posX = %pPosX + ( getWord($MPBSpawnPos[%x],0) * %radius); - %posY = %pPosY + (getWord($MPBSpawnPos[%x],1) * %radius); - - %terrHeight = getTerrainHeight(%posX @ " " @ %posY); - - if(mAbs(%terrHeight - %pPosZ) < %radius ) - { - %mask = $TypeMasks::VehicleObjectType | $TypeMasks::MoveableObjectType | - $TypeMasks::StaticShapeObjectType | $TypeMasks::StaticTSObjectType | - $TypeMasks::ForceFieldObjectType | $TypeMasks::ItemObjectType | - $TypeMasks::PlayerObjectType | $TypeMasks::TurretObjectType | - $TypeMasks::InteriorObjectType; - - InitContainerRadiusSearch(%posX @ " " @ %posY @ " " @ %terrHeight, 2, %mask); - if(ContainerSearchNext() == 0) - %MPB.spawnPos[%count++] = %posX @ " " @ %posY @ " " @ %terrHeight; - } - } - %MPB.spawnPosCount = %count; -} +//////////////////////////////////////////////////////////////////////////////// +// Mobile Point Base Teleporter // +// z0dd - ZOD, 4/24/02 // +//////////////////////////////////////////////////////////////////////////////// + +datablock StaticShapeData(MPBTeleporter) : StaticShapeDamageProfile +{ + className = Station; + catagory = "Stations"; + shapeFile = "station_teleport.dts"; + maxDamage = 1.20; + destroyedLevel = 1.20; + disabledLevel = 0.84; + explosion = ShapeExplosion; + expDmgRadius = 10.0; + expDamage = 0.4; + expImpulse = 1500.0; + dynamicType = $TypeMasks::StationObjectType; + isShielded = true; + energyPerDamagePoint = 33; + maxEnergy = 250; + rechargeRate = 0.31; + humSound = StationVehicleHumSound; + // don't let these be damaged in Siege missions + noDamageInSiege = true; + cmdCategory = "Support"; + cmdIcon = CMDVehicleStationIcon; + cmdMiniIconName = "commander/MiniIcons/com_vehicle_pad_inventory"; + targetNameTag = 'MPB'; + targetTypeTag = 'Teleport Station'; + teleporter = 1; +}; + +datablock ParticleData(mpbteleportparticle) +{ + dragCoefficient = 1.5; + gravityCoefficient = 0.2; + inheritedVelFactor = 0.2; + constantAcceleration = 0.0; + lifetimeMS = 1000; + lifetimeVarianceMS = 0; + textureName = "particleTest"; + + colors[0] = "0.06 0.06 0.36 1.0"; + colors[1] = "0.06 0.06 0.36 0.0"; + sizes[0] = 0.65; + sizes[1] = 0.30; +}; + +datablock ParticleEmitterData(MPBTeleportEmitter) +{ + ejectionPeriodMS = 5; + periodVarianceMS = 0; + ejectionVelocity = 1.1; + velocityVariance = 1.0; + ejectionOffset = 2.0; + thetaMin = 0.0; + thetaMax = 10.0; + phiReferenceVel = 0.0; + phiVariance = 360.0; + overrideAdvances = false; + particles = "mpbteleportparticle"; +}; + +function StationVehicle::createTeleporter(%data, %obj, %group) +{ + // %obj = Teleport Object + // %data = Teleport Datablock + // %group = Vehicle Pads Mission Group + + %Teleporter = new StaticShape() { + scale = "1 1 1"; + dataBlock = "MPBTeleporter"; + lockCount = "0"; + homingCount = "0"; + team = %obj.team; + }; + %obj.teleporter = %Teleporter; + %Teleporter.vStation = %obj.pad; + + %trans = %obj.pad.getSlotTransform(0); + %vSPos = getWords(%trans,0,2); + %vRot = getWords(%trans,3,5); + %vAngle = getWord(%trans,6); + %matrix = VectorOrthoBasis(%vRot @ " " @ %vAngle + 0.36); + %yRot = getWords(%matrix, 3, 5); + %pos = vectorAdd(%vSPos, vectorScale(%yRot, -31.5)); + %Teleporter.setTransform(%pos @ " " @ %vRot @ " " @ %vAngle); + + // Add the teleporter to the v-pads mission group for cleanup and power. + %group.add(%Teleporter); + %Teleporter.setPersistent(false); // set the teleporter to not save in the editor. + + // Apparently called to early on mission load done, call it now. + %Teleporter.getDataBlock().gainPower(%Teleporter); + + // Set the sensor group. + if(%Teleporter.getTarget() != -1) + setTargetSensorGroup(%Teleporter.getTarget(), %obj.team); + + // Allow players to use it. + %Teleporter.disabled = 0; +} + +function MPBTeleporter::onCollision(%data, %obj, %col) +{ + if(%col.getDataBlock().className !$= "Armor" || %col.getState() $= "Dead" || %col.teleporting) + return; + + if(isObject(%col)) + { + if(%obj.team == %col.client.team) + { + if(!%obj.isDisabled()) + { + if(%obj.isPowered()) + { + if(isObject(%obj.MPB) && %obj.MPB.fullyDeployed) + { + if(%obj.disabled == 0) + { + %col.lastWeapon = ( %col.getMountedImage($WeaponSlot) == 0 ) ? "" : %col.getMountedImage($WeaponSlot).getName().item; + %col.unmountImage($WeaponSlot); + %pos = %obj.position; + %col.setvelocity("0 0 0"); + %col.setMoveState(true); + %rot = getWords(%col.getTransform(), 3, 6); + %col.setTransform(getWord(%pos,0) @ " " @ getWord(%pos,1) @ " " @ getWord(%pos,2) + 0.6 @ " " @ %rot); + %col.teleporting = 1; + %col.startFade( 1000, 0, true ); + %col.playAudio($PlaySound, StationVehicleAcitvateSound); + + %obj.disabled = 1; // Disable the teleporter to more then one person at a time for a time. + %obj.setThreadDir($ActivateThread, TRUE); + %obj.playThread($ActivateThread, "activate"); + + %data.sparkEmitter(%obj); + %data.schedule(2000, "teleportout", %obj, %col); + %data.schedule(4000, "teleportingDone", %obj, %col); + } + else + messageClient(%col.client, 'MsgTeleportRecharging', '\c2Teleporter is recharging please stand by. ~wfx/powered/nexus_deny.wav'); + } + else + MessageClient(%col.client, "MsgNoMPB", 'MPB is not deployed.'); + } + else + messageClient(%col.client, 'MsgStationNoPower', '\c2Teleporter is not powered.'); + } + else + messageClient(%col.client, 'MsgStationDisabled', '\c2Teleporter is disabled.'); + } + else + messageClient(%col.client, 'MsgStationDenied', '\c2Access Denied -- Wrong team.~wfx/powered/station_denied.wav'); + } + else + return; +} + +function MPBTeleporter::teleportOut(%data, %obj, %player) +{ + if(isObject(%obj.MPB)) + { + %index = -1; + for(%x=0; %x < %obj.MPB.spawnPosCount; %x++) + { + %index = mFloor(getRandom() * %obj.MPB.spawnPosCount); + InitContainerRadiusSearch(%obj.MPB.spawnPos[%index], 2, $TypeMasks::MoveableObjectType); + if(ContainerSearchNext() == 0) + break; + else + %index = -1; + } + if(%index >= 0) + { + %player.setTransform(%obj.MPB.spawnPos[%index] @ " " @ getWords(%obj.MPB.getTransform(), 3, 6)); + } + else + { + messageClient(%player.client, 'MsgTeleFailed', 'No Valid teleporting positions.'); + %player.teleporting = 0; + } + } + else + { + messageClient(%player.client, 'MsgTeleFailed', 'No Valid teleporting positions because MPB was destroyed'); + %player.teleporting = 0; + } + %data.schedule(1000, "teleportIn", %player); +} + +function MPBTeleporter::teleportIn(%data, %player) +{ + %data.sparkEmitter(%player); // z0dd - ZOD, 4/24/02. teleport sparkles + %player.startFade(1000, 0, false ); + %player.playAudio($PlaySound, StationVehicleDeactivateSound); +} + +function MPBTeleporter::reEnable(%data, %obj) +{ + %obj.disabled = 0; +} + +function MPBTeleporter::sparkEmitter(%data, %obj) +{ + if (isObject(%obj.teleportEmitter)) + %obj.teleportEmitter.delete(); + + %obj.teleportEmitter = new ParticleEmissionDummy() { + position = %obj.position; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = defaultEmissionDummy; + emitter = "MPBTeleportEmitter"; + velocity = "1"; + }; + MissionCleanup.add(%obj.teleportEmitter); + %obj.teleportEmitter.schedule(800, "delete"); + + if (isObject(%obj.teleEmitter)) + %obj.teleEmitter.delete(); + + %obj.teleEmitter = new ParticleEmissionDummy() { + position = %obj.position; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = defaultEmissionDummy; + emitter = "FlyerJetEmitter"; + velocity = "1"; + }; + MissionCleanup.add(%obj.teleEmitter); + %obj.teleEmitter.schedule(700, "delete"); +} + +function MPBTeleporter::teleportingDone(%data, %obj, %player) +{ + %player.setMoveState(false); + %player.teleporting = 0; + %player.station = ""; + %data.reEnable(%obj); + if(%player.getMountedImage($WeaponSlot) == 0) + { + if(%player.inv[%player.lastWeapon]) + %player.use(%player.lastWeapon); + else + %player.selectWeaponSlot( 0 ); + } +} + +//------------------------------------------------------------------------------------------ +// Gets called from function MobileBaseVehicle::vehicleDeploy(%data, %obj, %player, %force). +// Passes this information to the MPBTeleporter::teleportOut function. +//------------------------------------------------------------------------------------------ + +function checkSpawnPos(%MPB, %radius) +{ + for(%y = -1; %y < 1; %y += 0.25) + { + %xCount=0; + for(%x = -1; %x < 1; %x += 0.25) + { + $MPBSpawnPos[(%yCount * 8) + %xCount] = %x @ " " @ %y; + %xCount++; + } + %yCount++; + } + %count = -1; + + for(%x = 0; %x < 64; %x++) + { + %pPos = getWords(%MPB.getTransform(), 0, 2); + %pPosX = getWord(%pPos, 0); + %pPosY = getWord(%pPos, 1); + %pPosZ = getWord(%pPos, 2); + + %posX = %pPosX + ( getWord($MPBSpawnPos[%x],0) * %radius); + %posY = %pPosY + (getWord($MPBSpawnPos[%x],1) * %radius); + + %terrHeight = getTerrainHeight(%posX @ " " @ %posY); + + if(mAbs(%terrHeight - %pPosZ) < %radius ) + { + %mask = $TypeMasks::VehicleObjectType | $TypeMasks::MoveableObjectType | + $TypeMasks::StaticShapeObjectType | $TypeMasks::StaticTSObjectType | + $TypeMasks::ForceFieldObjectType | $TypeMasks::ItemObjectType | + $TypeMasks::PlayerObjectType | $TypeMasks::TurretObjectType | + $TypeMasks::InteriorObjectType; + + InitContainerRadiusSearch(%posX @ " " @ %posY @ " " @ %terrHeight, 2, %mask); + if(ContainerSearchNext() == 0) + %MPB.spawnPos[%count++] = %posX @ " " @ %posY @ " " @ %terrHeight; + } + } + %MPB.spawnPosCount = %count; +} diff --git a/scripts/objectiveHud.cs b/scripts/objectiveHud.cs index 8a067e0..019e5d4 100644 --- a/scripts/objectiveHud.cs +++ b/scripts/objectiveHud.cs @@ -1,1528 +1,1528 @@ -// Mission type-dependent objective HUDs - -// TR2 additions -$TR2::Color::CarrierEnemy = "205 0 0 100"; -$TR2::Color::CarrierFriendly = "0 205 0 100"; -$TR2::Color::CarrierNeutral = "190 190 190 100"; -$TR2::DebriefGuiLoaded = 0; - -addMessageCallback('MsgClientReady', setCameraSpeedState); - -function setCameraSpeedState(%msgType, %msgString, %gameType, %a2, %a3, %a4, %a5, %a6) -{ - if( detag(%gameType) $= "TR2Game" ) - { - $_Camera::movementSpeed = $Camera::movementSpeed; - $Camera::movementSpeed = 80; - } - else - { - %val = $_Camera::movementSpeed $= "" ? 40 : $_Camera::movementSpeed; - $Camera::movementSpeed = %val; - } -} - -///// -MISSION START- ////////////////////////////////////////////////////////////// -addMessageCallback('MsgClientReady', clientReadyMSG); - -function clientReadyMSG(%msgType, %msgString, %gameType, %a2, %a3, %a4, %a5, %a6) -{ - clearObjHudMSG(); - setupObjHud(%gameType); -} - -addMessageCallback('MsgClearObjHud', clearObjHudMSG); - -function clearObjHudMSG(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - // clear the separator lines - objectiveHud.setSeparators(""); - objectiveHud.disableHorzSeparator(); - - - //remove everything in the objective Hud - while (objectiveHud.getCount() > 0) - objectiveHud.getObject(0).delete(); -} - -// TR2 Message Callbacks - AO -//----------------------- -// 05-13 removed the team size window -// 05-13 Removed syntax bug in hud (doh!) -// Created separate message type/callback and serverside function for adjusting bonus value -// Scores can now be updated independantly of bons value -// -// NEED TO ADD CODE TO MESSAGE CLIENT THE BONUS VALUE AND TEAM WHEN THEY JOIN!!! - - -addMessageCallback('MsgTR2UpdateBonus', handleTR2UpdateBonus); - - - -addMessageCallback('MsgTR2ObjInit', TR2HudInit); - -function TR2HudInit(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9) -{ - objectiveHud.teamName[1].setValue(detag(%a1)); - objectiveHud.teamName[2].setValue(detag(%a2)); - - objectiveHud.teamScore[1].setValue(detag(%a3)); - objectiveHud.teamScore[2].setValue(detag(%a4)); - - objectiveHud.carrierName.setValue(detag(%a5)); - objectiveHud.carrierHealth.setValue(detag(%a6)); - - TR2BonusObject.doBonus(%a7, $TR2::NeutralColor); -} - -addMessageCallback('MsgTR2SetScore', handleTR2SetScore); - -function handleTR2SetScore(%msgType, %msgString, %team, %score) -{ - %team = detag(%team); - objectiveHud.teamScore[%team].setValue( detag(%score) ); -} -// end TR2 message callbacks - AO - -// REPLACE profile definition in objectiveHud.cs -new GuiControlProfile ("TR2CarrierHealth") -{ - opaque = false; - fillColor = "0 205 0 100"; - border = true; - borderColor = "190 190 190 100"; -}; - -addMessageCallback('MsgTR2FlagStatus', handleTR2FlagStatus); - -function handleTR2FlagStatus(%msgType, %msgString, %location) -{ - objectiveHud.carrierName.setValue(detag(%location)); -} - -addMessageCallback('MsgTR2FlagTaken', handleTR2FlagTaken); - -function handleTR2FlagTaken(%msgType, %msgString, %client, %team, %flagteam, %clientnamebase) -{ - objectiveHud.carrierName.setValue(detag(%client)); -} - -addMessageCallback('MsgTR2FlagDropped', handleTR2FlagDropped); - -function handleTR2FlagDropped(%msgType, %msgString, %client, %team, %flagteam) -{ - objectiveHud.carrierName.setValue("Dropped"); -} - -addMessageCallback('MsgTR2CarrierHealth', handleTR2CarrierHealth); - -function handleTR2CarrierHealth(%msgType, %msgString, %amt, %team) -{ - if( detag(%team) == 1 ) // carrier is on our team - { - objectiveHud.carrierHealth.profile.fillColor = $TR2::Color::CarrierFriendly; - } - else - { - objectiveHud.carrierHealth.profile.fillColor = $TR2::Color::CarrierEnemy; - } - objectiveHud.carrierHealth.setValue(detag(%amt)); -} - -function setupObjHud(%gameType) -{ - if(%gameType $= "PracticeCTFGame" || %gameType $= "CTFPlusGame") - %gameType = "CTFGame"; - - objectiveHud.gameType = %gameType; - - // TR2 additions - if( %gameType $= "TR2Game" ) - { - if( $TR2::DebriefGuiLoaded == 0 ) - { - if( isObject(DB_ChatDlg) ) - DB_ChatDlg.delete(); - if( isObject(DebriefGui) ) - DebriefGui.delete(); - exec("gui/TR2DebriefGui.gui"); - $TR2::DebriefGuiLoaded = 1; - } - } - else - { - if( $TR2::DebriefGuiLoaded == 1 ) - { - if( isObject(DB_ChatDlg) ) - DB_ChatDlg.delete(); - if( isObject(DebriefGui) ) - DebriefGui.delete(); - exec("gui/DebriefGui.gui"); - $TR2::DebriefGuiLoaded = 0; - } - } - - switch$ (%gameType) - { - // Begin TR2 hud stuff - AO - case TR2Game: // | | | < Carrier Name > - // | | | - // set separators - objectiveHud.setSeparators("104 147"); - objectiveHud.enableHorzSeparator(); - - // Team names - objectiveHud.teamName[1] = new GuiTextCtrl() { - profile = "GuiTextObjGoldLeftProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 3"; - extent = "96 16"; - visible = "1"; - }; - objectiveHud.teamName[2] = new GuiTextCtrl() { - profile = "GuiTextObjSilverLeftProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 19"; - extent = "96 16"; - visible = "1"; - }; - // Team scores - objectiveHud.teamScore[1] = new GuiTextCtrl() { - profile = "GuiTextObjGoldCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "108 3"; - extent = "35 16"; - visible = "1"; - }; - objectiveHud.teamScore[2] = new GuiTextCtrl() { - profile = "GuiTextObjSilverCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "108 19"; - extent = "35 16"; - visible = "1"; - }; - - // Bonus - objectiveHud.carrierName = new GuiTextCtrl() { - profile = "GuiTextObjHudCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "151 3"; - extent = "90 16"; - visible = "1"; - text = ""; - }; - objectiveHud.carrierHealth = new GuiProgressCtrl() { - profile = "TR2CarrierHealth"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "159 22"; - extent = "75 10"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - }; - - for(%i = 1; %i <= 2; %i++) - { - objectiveHud.add(objectiveHud.teamScore[%i]); - objectiveHud.add(objectiveHud.teamName[%i]); - } - objectiveHud.add(objectiveHud.carrierName); - objectiveHud.add(objectiveHud.carrierHealth); - - // end TR2 Hud stuff - AO - - case BountyGame: - // set separators - objectiveHud.setSeparators("56 156"); - objectiveHud.disableHorzSeparator(); - - // Your score label ("SCORE") - objectiveHud.scoreLabel = new GuiTextCtrl() { - profile = "GuiTextObjGreenLeftProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 3"; - extent = "50 16"; - visible = "1"; - text = "SCORE"; - }; - // Your score - objectiveHud.yourScore = new GuiTextCtrl() { - profile = "GuiTextObjGreenCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "60 3"; - extent = "90 16"; - visible = "1"; - }; - // Target label ("TARGET") - objectiveHud.targetLabel = new GuiTextCtrl() { - profile = "GuiTextObjGreenLeftProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 19"; - extent = "50 16"; - visible = "1"; - text = "TARGET"; - }; - // your target's name - objectiveHud.yourTarget = new GuiTextCtrl() { - profile = "GuiTextObjGreenCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "60 19"; - extent = "90 16"; - visible = "1"; - }; - - objectiveHud.add(objectiveHud.scoreLabel); - objectiveHud.add(objectiveHud.yourScore); - objectiveHud.add(objectiveHud.targetLabel); - objectiveHud.add(objectiveHud.yourTarget); - - case CnHGame: - // set separators - objectiveHud.setSeparators("96 162 202"); - objectiveHud.enableHorzSeparator(); - - // Team names - objectiveHud.teamName[1] = new GuiTextCtrl() { - profile = "GuiTextObjGreenLeftProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 3"; - extent = "90 16"; - visible = "1"; - }; - objectiveHud.teamName[2] = new GuiTextCtrl() { - profile = "GuiTextObjHudLeftProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 19"; - extent = "90 16"; - visible = "1"; - }; - // Team scores - objectiveHud.teamScore[1] = new GuiTextCtrl() { - profile = "GuiTextObjGreenCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "105 3"; - extent = "50 16"; - visible = "1"; - }; - objectiveHud.teamScore[2] = new GuiTextCtrl() { - profile = "GuiTextObjHudCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "105 19"; - extent = "50 16"; - visible = "1"; - }; - // Hold label ("HOLD") - objectiveHud.holdLabel[1] = new GuiTextCtrl() { - profile = "GuiTextObjGreenCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "165 3"; - extent = "35 16"; - visible = "1"; - text = "HOLD"; - }; - objectiveHud.holdLabel[2] = new GuiTextCtrl() { - profile = "GuiTextObjHudCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "165 19"; - extent = "35 16"; - visible = "1"; - text = "HOLD"; - }; - // number of points held - objectiveHud.numHeld[1] = new GuiTextCtrl() { - profile = "GuiTextObjGreenCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "205 3"; - extent = "30 16"; - visible = "1"; - }; - objectiveHud.numHeld[2] = new GuiTextCtrl() { - profile = "GuiTextObjHudCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "205 19"; - extent = "30 16"; - visible = "1"; - }; - - for(%i = 1; %i <= 2; %i++) - { - objectiveHud.add(objectiveHud.teamName[%i]); - objectiveHud.add(objectiveHud.teamScore[%i]); - objectiveHud.add(objectiveHud.holdLabel[%i]); - objectiveHud.add(objectiveHud.numHeld[%i]); - } - - case CTFGame: - // set separators - objectiveHud.setSeparators("75 100 133"); - objectiveHud.enableHorzSeparator(); - - // Team names - objectiveHud.teamName[1] = new GuiTextCtrl() { - profile = "GuiTextObjGreenLeftProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 3"; - extent = "68 16"; - visible = "1"; - }; - objectiveHud.teamName[2] = new GuiTextCtrl() { - profile = "GuiTextObjHudLeftProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 19"; - extent = "68 16"; - visible = "1"; - }; - // Team scores - objectiveHud.teamScore[1] = new GuiTextCtrl() { - profile = "GuiTextObjGreenCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "78 3"; - extent = "22 16"; - visible = "1"; - }; - objectiveHud.teamScore[2] = new GuiTextCtrl() { - profile = "GuiTextObjHudCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "78 19"; - extent = "22 16"; - visible = "1"; - }; - // Flag label ("FLAG") - objectiveHud.flagLabel[1] = new GuiTextCtrl() { - profile = "GuiTextObjGreenCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "103 3"; - extent = "30 16"; - visible = "1"; - text = "FLAG"; - }; - objectiveHud.flagLabel[2] = new GuiTextCtrl() { - profile = "GuiTextObjHudCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "103 19"; - extent = "30 16"; - visible = "1"; - text = "FLAG"; - }; - // flag location (at base/in field/player carrying it) - objectiveHud.flagLocation[1] = new GuiTextCtrl() { - profile = "GuiTextObjGreenLeftProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "138 3"; - extent = "102 16"; - visible = "1"; - }; - objectiveHud.flagLocation[2] = new GuiTextCtrl() { - profile = "GuiTextObjHudLeftProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "138 19"; - extent = "102 16"; - visible = "1"; - }; - - for(%i = 1; %i <= 2; %i++) - { - objectiveHud.add(objectiveHud.teamName[%i]); - objectiveHud.add(objectiveHud.teamScore[%i]); - objectiveHud.add(objectiveHud.flagLabel[%i]); - objectiveHud.add(objectiveHud.flagLocation[%i]); - } - - case DMGame: - // set separators - objectiveHud.setSeparators("56 96 156"); - objectiveHud.disableHorzSeparator(); - - // Your score label ("SCORE") - objectiveHud.scoreLabel = new GuiTextCtrl() { - profile = "GuiTextObjGreenLeftProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 3"; - extent = "50 16"; - visible = "1"; - text = "SCORE"; - }; - // Your score - objectiveHud.yourScore = new GuiTextCtrl() { - profile = "GuiTextObjGreenCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "60 3"; - extent = "30 16"; - visible = "1"; - }; - // Your kills label ("KILLS") - objectiveHud.killsLabel = new GuiTextCtrl() { - profile = "GuiTextObjGreenLeftProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 19"; - extent = "50 16"; - visible = "1"; - text = "KILLS"; - }; - // Your kills - objectiveHud.yourKills = new GuiTextCtrl() { - profile = "GuiTextObjGreenCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "60 19"; - extent = "30 16"; - visible = "1"; - }; - // Your deaths label ("DEATHS") - objectiveHud.deathsLabel = new GuiTextCtrl() { - profile = "GuiTextObjGreenLeftProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "100 19"; - extent = "50 16"; - visible = "1"; - text = "DEATHS"; - }; - // Your deaths - objectiveHud.yourDeaths = new GuiTextCtrl() { - profile = "GuiTextObjGreenCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "160 19"; - extent = "30 16"; - visible = "1"; - }; - - objectiveHud.add(objectiveHud.scoreLabel); - objectiveHud.add(objectiveHud.yourScore); - objectiveHud.add(objectiveHud.killsLabel); - objectiveHud.add(objectiveHud.yourKills); - objectiveHud.add(objectiveHud.deathsLabel); - objectiveHud.add(objectiveHud.yourDeaths); - - case HuntersGame: - // set separators - objectiveHud.setSeparators("96 132"); - objectiveHud.disableHorzSeparator(); - - // Your score label ("SCORE") - objectiveHud.scoreLabel = new GuiTextCtrl() { - profile = "GuiTextObjGreenLeftProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 3"; - extent = "90 16"; - visible = "1"; - text = "SCORE"; - }; - // Your score - objectiveHud.yourScore = new GuiTextCtrl() { - profile = "GuiTextObjGreenCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "100 3"; - extent = "30 16"; - visible = "1"; - }; - // flags label ("FLAGS") - objectiveHud.flagLabel = new GuiTextCtrl() { - profile = "GuiTextObjGreenLeftProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 19"; - extent = "90 16"; - visible = "1"; - text = "FLAGS"; - }; - // number of flags - objectiveHud.yourFlags = new GuiTextCtrl() { - profile = "GuiTextObjGreenCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "100 19"; - extent = "30 16"; - visible = "1"; - }; - - objectiveHud.add(objectiveHud.scoreLabel); - objectiveHud.add(objectiveHud.yourScore); - objectiveHud.add(objectiveHud.flagLabel); - objectiveHud.add(objectiveHud.yourFlags); - - case RabbitGame: - // set separators - objectiveHud.setSeparators("56 156"); - objectiveHud.disableHorzSeparator(); - - // Your score label ("SCORE") - objectiveHud.scoreLabel = new GuiTextCtrl() { - profile = "GuiTextObjGreenLeftProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 3"; - extent = "50 16"; - visible = "1"; - text = "SCORE"; - }; - // Your score - objectiveHud.yourScore = new GuiTextCtrl() { - profile = "GuiTextObjGreenCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "60 3"; - extent = "90 16"; - visible = "1"; - }; - // Rabbit label ("RABBIT") - objectiveHud.rabbitLabel = new GuiTextCtrl() { - profile = "GuiTextObjGreenLeftProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 19"; - extent = "50 16"; - visible = "1"; - text = "RABBIT"; - }; - // rabbit name - objectiveHud.rabbitName = new GuiTextCtrl() { - profile = "GuiTextObjGreenCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "60 19"; - extent = "90 16"; - visible = "1"; - }; - - objectiveHud.add(objectiveHud.scoreLabel); - objectiveHud.add(objectiveHud.yourScore); - objectiveHud.add(objectiveHud.rabbitLabel); - objectiveHud.add(objectiveHud.rabbitName); - - case SiegeGame: - // set separators - objectiveHud.setSeparators("96 122 177"); - objectiveHud.enableHorzSeparator(); - - // Team names - objectiveHud.teamName[1] = new GuiTextCtrl() { - profile = "GuiTextObjGreenLeftProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 3"; - extent = "90 16"; - visible = "1"; - }; - objectiveHud.teamName[2] = new GuiTextCtrl() { - profile = "GuiTextObjHudLeftProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 19"; - extent = "90 16"; - visible = "1"; - }; - // Team scores - objectiveHud.teamScore[1] = new GuiTextCtrl() { - profile = "GuiTextObjGreenCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "100 3"; - extent = "20 16"; - visible = "1"; - }; - objectiveHud.teamScore[2] = new GuiTextCtrl() { - profile = "GuiTextObjGreenCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "100 19"; - extent = "20 16"; - visible = "1"; - }; - // Role label ("PROTECT" or "DESTROY") - objectiveHud.roleLabel[1] = new GuiTextCtrl() { - profile = "GuiTextObjGreenCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "125 3"; - extent = "50 16"; - visible = "1"; - }; - objectiveHud.roleLabel[2] = new GuiTextCtrl() { - profile = "GuiTextObjHudCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "125 19"; - extent = "50 16"; - visible = "1"; - }; - // number of objectives to protect/destroy - objectiveHud.objectives[1] = new GuiTextCtrl() { - profile = "GuiTextObjGreenCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "180 3"; - extent = "60 16"; - visible = "1"; - }; - objectiveHud.objectives[2] = new GuiTextCtrl() { - profile = "GuiTextObjHudCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "180 19"; - extent = "60 16"; - visible = "1"; - }; - - for(%i = 1; %i <= 2; %i++) - { - objectiveHud.add(objectiveHud.teamName[%i]); - objectiveHud.add(objectiveHud.teamScore[%i]); - objectiveHud.add(objectiveHud.roleLabel[%i]); - objectiveHud.add(objectiveHud.objectives[%i]); - } - - case TeamHuntersGame: - // set separators - objectiveHud.setSeparators("57 83 197"); - objectiveHud.enableHorzSeparator(); - - // flags label ("FLAGS") - objectiveHud.flagLabel = new GuiTextCtrl() { - profile = "GuiTextObjGreenLeftProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 3"; - extent = "50 16"; - visible = "1"; - text = "FLAGS"; - }; - // number of flags - objectiveHud.yourFlags = new GuiTextCtrl() { - profile = "GuiTextObjGreenCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "60 3"; - extent = "20 16"; - visible = "1"; - }; - // team names - objectiveHud.teamName[1] = new GuiTextCtrl() { - profile = "GuiTextObjGreenCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "85 3"; - extent = "110 16"; - visible = "1"; - }; - objectiveHud.teamName[2] = new GuiTextCtrl() { - profile = "GuiTextObjHudCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "85 19"; - extent = "110 16"; - visible = "1"; - }; - // team scores - objectiveHud.teamScore[1] = new GuiTextCtrl() { - profile = "GuiTextObjGreenCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "200 3"; - extent = "40 16"; - visible = "1"; - }; - objectiveHud.teamScore[2] = new GuiTextCtrl() { - profile = "GuiTextObjHudCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "200 19"; - extent = "40 16"; - visible = "1"; - }; - - objectiveHud.add(objectiveHud.flagLabel); - objectiveHud.add(objectiveHud.yourFlags); - for(%i = 1; %i <= 2; %i++) - { - objectiveHud.add(objectiveHud.teamName[%i]); - objectiveHud.add(objectiveHud.teamScore[%i]); - } - - case SinglePlayerGame: - // no separator lines - objectiveHud.setSeparators(""); - objectiveHud.disableHorzSeparator(); - - // two lines to print objectives - objectiveHud.spText[1] = new GuiTextCtrl() { - profile = "GuiTextObjHudLeftProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 3"; - extent = "235 16"; - visible = "1"; - }; - objectiveHud.spText[2] = new GuiTextCtrl() { - profile = "GuiTextObjHudLeftProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 19"; - extent = "235 16"; - visible = "1"; - }; - objectiveHud.add(objectiveHud.spText[1]); - objectiveHud.add(objectiveHud.spText[2]); - // z0dd - ZOD, 9/13/02. New gametype - case JBGame: - // set separators - objectiveHud.setSeparators("64 114 152 202"); - objectiveHud.enableHorzSeparator(); - - // Team names - objectiveHud.teamName[1] = new GuiTextCtrl() { - profile = "GuiTextObjGreenLeftProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 3"; - extent = "60 16"; - visible = "1"; - }; - objectiveHud.teamName[2] = new GuiTextCtrl() { - profile = "GuiTextObjHudLeftProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 19"; - extent = "60 16"; - visible = "1"; - }; - // In Jail ("JAILED") - objectiveHud.inJailLabel[1] = new GuiTextCtrl() { - profile = "GuiTextObjGreenCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "68 3"; - extent = "42 16"; - visible = "1"; - text = "JAILED"; - }; - objectiveHud.inJailLabel[2] = new GuiTextCtrl() { - profile = "GuiTextObjHudCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "68 19"; - extent = "42 16"; - visible = "1"; - text = "JAILED"; - }; - // Players in Jail - objectiveHud.playersJailed[1] = new GuiTextCtrl() { - profile = "GuiTextObjGreenCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "118 3"; - extent = "30 16"; - visible = "1"; - }; - objectiveHud.playersJailed[2] = new GuiTextCtrl() { - profile = "GuiTextObjHudCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "118 19"; - extent = "30 16"; - visible = "1"; - }; - // Score label ("SCORE") - objectiveHud.scoreLabel[1] = new GuiTextCtrl() { - profile = "GuiTextObjGreenCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "156 3"; - extent = "42 16"; - visible = "1"; - text = "SCORE"; - }; - objectiveHud.scoreLabel[2] = new GuiTextCtrl() { - profile = "GuiTextObjHudCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "156 19"; - extent = "42 16"; - visible = "1"; - text = "SCORE"; - }; - // scores - objectiveHud.teamScore[1] = new GuiTextCtrl() { - profile = "GuiTextObjGreenCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "206 3"; - extent = "30 16"; - visible = "1"; - }; - objectiveHud.teamScore[2] = new GuiTextCtrl() { - profile = "GuiTextObjHudCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "206 19"; - extent = "30 16"; - visible = "1"; - }; - for(%i = 1; %i <= 2; %i++) - { - objectiveHud.add(objectiveHud.teamName[%i]); - objectiveHud.add(objectiveHud.inJailLabel[%i]); - objectiveHud.add(objectiveHud.playersJailed[%i]); - objectiveHud.add(objectiveHud.scoreLabel[%i]); - objectiveHud.add(objectiveHud.teamScore[%i]); - } - // z0dd - ZOD, 9/13/02. New gametype - case DnDGame: - // set separators - objectiveHud.setSeparators("75 114 150 210"); - objectiveHud.enableHorzSeparator(); - - // Team names - objectiveHud.teamName[1] = new GuiTextCtrl() { - profile = "GuiTextObjGreenLeftProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 3"; - extent = "68 16"; - visible = "1"; - }; - objectiveHud.teamName[2] = new GuiTextCtrl() { - profile = "GuiTextObjHudLeftProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 19"; - extent = "68 16"; - visible = "1"; - }; - // Label: Scores - objectiveHud.scoreLabel[1] = new GuiTextCtrl() { - profile = "GuiTextObjGreenCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "75 3"; - extent = "42 16"; - visible = "1"; - text = "Score"; - }; - objectiveHud.scoreLabel[2] = new GuiTextCtrl() { - profile = "GuiTextObjHudCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "75 19"; - extent = "42 16"; - visible = "1"; - text = "Score"; - }; - // Team scores - objectiveHud.teamScore[1] = new GuiTextCtrl() { - profile = "GuiTextObjGreenCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "118 3"; - extent = "30 16"; - visible = "1"; - }; - objectiveHud.teamScore[2] = new GuiTextCtrl() { - profile = "GuiTextObjHudCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "118 19"; - extent = "30 16"; - visible = "1"; - }; - // Label: Objectives - objectiveHud.objectivesLabel[1] = new GuiTextCtrl() { - profile = "GuiTextObjGreenCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "158 3"; - extent = "44 16"; - visible = "1"; - text = "Objectives"; - }; - objectiveHud.objectivesLabel[2] = new GuiTextCtrl() { - profile = "GuiTextObjHudCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "158 19"; - extent = "44 16"; - visible = "1"; - text = "Objectives"; - }; - // Team objectives - objectiveHud.objectives[1] = new GuiTextCtrl() { - profile = "GuiTextObjGreenCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "210 3"; - extent = "30 16"; - visible = "1"; - }; - objectiveHud.objectives[2] = new GuiTextCtrl() { - profile = "GuiTextObjHudCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "210 19"; - extent = "30 16"; - visible = "1"; - }; - for(%i = 1; %i <= 2; %i++) - { - objectiveHud.add(objectiveHud.teamName[%i]); - objectiveHud.add(objectiveHud.scoreLabel[%i]); - objectiveHud.add(objectiveHud.teamScore[%i]); - objectiveHud.add(objectiveHud.objectivesLabel[%i]); - objectiveHud.add(objectiveHud.objectives[%i]); - } - } - chatPageDown.setVisible(false); -} - -addMessageCallback('MsgCheckTeamLines', checkTeamLines); - -function checkTeamLines(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - %team = detag(%a1); - - if(%team == 1) - %other = 2; - else if(%team == 2) - %other = 1; - else - return; - - %tY = getWord(objectiveHud.teamName[%team].position, 1); - %oY = getWord(objectiveHud.teamName[%other].position, 1); - - // if player's team is lower on objective hud than other team is, switch them - if(%tY > %oY) - swapTeamLines(); -} - -function swapTeamLines() -{ - // if player's team is on the bottom of the objective hud, swap them so that it's on top - %bLeft = "GuiTextObjHudLeftProfile"; - %bCenter = "GuiTextObjHudCenterProfile"; - %gLeft = "GuiTextObjGreenLeftProfile"; - %gCenter = "GuiTextObjGreenCenterProfile"; - - %teamOneY = getWord(objectiveHud.teamName[1].position, 1); - %teamTwoY = getWord(objectiveHud.teamName[2].position, 1); - - // z0dd - ZOD, 9/13/02. Code streamlining - %newTop = %teamOneY > %teamTwoY ? 1 : 2; - %newBottom = %teamOneY > %teamTwoY ? 2 : 1; - - - // these are present in every team-based mission type - %nameX = firstWord(objectiveHud.teamName[1].position); - objectiveHud.teamName[1].position = %nameX SPC %teamTwoY; - objectiveHud.teamName[2].position = %nameX SPC %teamOneY; - objectiveHud.teamName[%newTop].setProfile(%gLeft); - objectiveHud.teamName[%newBottom].setProfile(%bLeft); - - %scoreX = firstWord(objectiveHud.teamScore[1].position); - objectiveHud.teamScore[1].position = %scoreX SPC %teamTwoY; - objectiveHud.teamScore[2].position = %scoreX SPC %teamOneY; - objectiveHud.teamScore[%newTop].setProfile(%gCenter); - objectiveHud.teamScore[%newBottom].setProfile(%bCenter); - - if(isObject(objectiveHud.flagLocation[1])) - { - // CTF - %locatX = firstWord(objectiveHud.flagLocation[1].position); - objectiveHud.flagLocation[1].position = %locatX SPC %teamTwoY; - objectiveHud.flagLocation[2].position = %locatX SPC %teamOneY; - // swap profiles so top line is green (don't bother with labels) - objectiveHud.flagLocation[%newTop].setProfile(%gLeft); - objectiveHud.flagLocation[%newBottom].setProfile(%bLeft); - } - if(isObject(objectiveHud.numHeld[1])) - { - // CnH - %locatX = firstWord(objectiveHud.numHeld[1].position); - objectiveHud.numHeld[1].position = %locatX SPC %teamTwoY; - objectiveHud.numHeld[2].position = %locatX SPC %teamOneY; - // swap profiles so top line is green (don't bother with labels) - objectiveHud.numHeld[%newTop].setProfile(%gCenter); - objectiveHud.numHeld[%newbottom].setProfile(%bCenter); - } - if(isObject(objectiveHud.objectives[1])) - { - // Siege - %locX = firstWord(objectiveHud.roleLabel[1].position); - objectiveHud.roleLabel[1].position = %locX SPC %teamTwoY; - objectiveHud.roleLabel[2].position = %locX SPC %teamOneY; - %locatX = firstWord(objectiveHud.objectives[1].position); - objectiveHud.objectives[1].position = %locatX SPC %teamTwoY; - objectiveHud.objectives[2].position = %locatX SPC %teamOneY; - // swap profiles so top line is green (don't forget role label) - objectiveHud.roleLabel[%newTop].setProfile(%gCenter); - objectiveHud.roleLabel[%newbottom].setProfile(%bCenter); - objectiveHud.objectives[%newTop].setProfile(%gCenter); - objectiveHud.objectives[%newbottom].setProfile(%bCenter); - } - if(isObject(objectiveHud.playersJailed[1])) // z0dd - ZOD, 9/13/02. New Gametype - { - %jailedX = firstWord(objectiveHud.playersJailed[1].position); - objectiveHud.playersJailed[1].position = %jailedX SPC %teamTwoY; - objectiveHud.playersJailed[2].position = %jailedX SPC %teamOneY; - objectiveHud.playersJailed[%newTop].setProfile(%gCenter); - objectiveHud.playersJailed[%newbottom].setProfile(%bCenter); - } - if (isObject(objectiveHud.objectives[1])) // z0dd - ZOD, 9/13/02. New Gametype - { - %locatX = firstWord(objectiveHud.objectives[1].position); - objectiveHud.objectives[1].position = %locatX SPC %teamTwoY; - objectiveHud.objectives[2].position = %locatX SPC %teamOneY; - objectiveHud.objectives[%newTop].setProfile(%gCenter); - objectiveHud.objectives[%newBottom].setProfile(%bCenter); - } -} - -//----------------------------------------------------------------------------- -//CLOCK HUD Callback -addMessageCallback('MsgSystemClock', setSystemClock); - -function setSystemClock(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - $Hud::TimeLimit = detag(%a1); - %timeLeftMS = detag(%a2); - clockHud.setTime(%timeLeftMS / (60 * 1000)); -} - -//----------------------------------------------------------------------------- -//Generic msg callbacks... - -addMessageCallback('MsgYourScoreIs', YourScoreIs); - -function YourScoreIs(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - if ( isObject( objectiveHud.yourScore ) ) - objectiveHud.yourScore.setValue( detag(%a1) ); -} - -addMessageCallback('MsgTeamScoreIs', teamScoreIs); - -function teamScoreIs(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - %teamNum = detag(%a1); - %score = detag(%a2); - - if(%score $= "") - %score = 0; - - objectiveHud.teamScore[%teamNum].setValue(%score); -} - -addMessageCallback('MsgYourRankIs', yourRankIs); - -function yourRankIs(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - // the rank (+1) adjustment is taken care of server-side... - %rank = detag(%a1); - // no longer displayed in objective hud -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Bounty - Hud Messages -///////////////////////////////////////////////////////////////////////////////////////// - -addMessageCallback('msgBountyTargetIs', bountyTargetIs); - -function bountyTargetIs(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - %hit = detag(%a1); - if(%hit $= "") - %hit = ""; - - objectiveHud.yourTarget.setValue(%hit); -} - -addMessageCallback('msgBountyTargetDropped', bountyTargetDropped); -addMessageCallback('msgBountyTargetEntObs', bountyTargetDropped); - -function bountyTargetDropped(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - objectiveHud.yourTarget.setValue(""); -} - -//addMessageCallback('msgBountyObjRem', bountyObjRem); - -function bountyObjRem(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - %objRem = detag(%a1); - - // this is no longer on the objective hud -} - -///////////////////////////////////////////////////////////////////////////////////////// -// CnH - Hud Messages -///////////////////////////////////////////////////////////////////////////////////////// - -addMessageCallback('MsgCnHAddTeam', cnhAddTeam); - -function cnhAddTeam(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - %teamNum = detag(%a1); - %teamName = detag(%a2); - %score = detag(%a3); - if(%score $= "") - %score = 0; - %sLimit = detag(%a4); - %held = detag(%a5); - - objectiveHud.teamName[%teamNum].setValue(%teamName); - objectiveHud.teamScore[%teamNum].setValue(%score@"/"@%sLimit); - objectiveHud.numHeld[%teamNum].setValue(%held); -} - -addMessageCallback('MsgFlipFlopsHeld', hudFlipFlopsHeld); - -function hudFlipFlopsHeld(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - %teamNum = detag(%a1); - %held = detag(%a2); - - objectiveHud.numHeld[%teamNum].setValue(%held); -} - -addMessageCallback('MsgCnHTeamCap', cnhTeamCap); - -function cnhTeamCap(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - %teamNum = detag(%a4); - %score = detag(%a5); - %sLimit = detag(%a6); - %string = %score @ "/" @ %sLimit; - - objectiveHud.teamScore[%teamNum].setValue(%string); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// CTF - Gui Hud Control -///////////////////////////////////////////////////////////////////////////////////////// - -addMessageCallback('MsgCTFAddTeam', ctfAddTeam); - -function ctfAddTeam(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - %teamNum = detag(%a1); - %teamName = detag(%a2); - %flagStatus = detag(%a3); - %score = detag(%a4); - - objectiveHud.teamName[%teamNum].setValue(%teamName); - objectiveHud.teamScore[%teamNum].setValue(%score); - objectiveHud.flagLocation[%teamNum].setValue(%flagStatus); -} - -addMessageCallback('MsgCTFFlagTaken', ctfFlagTaken); - -function ctfFlagTaken(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - %index = detag(%a3); - %taker = detag(%a4); - - objectiveHud.flagLocation[%index].setValue(%taker); -} - -addMessageCallback('MsgCTFFlagDropped', ctfFlagDropped); - -function ctfFlagDropped(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - %index = detag(%a3); - objectiveHud.flagLocation[%index].setValue(""); -} - -addMessageCallback('MsgCTFFlagCapped', ctfFlagCapped); - -function ctfFlagCapped(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - %index = detag(%a3); - objectiveHud.flagLocation[%index].setValue(""); -} - -addMessageCallback('MsgCTFFlagReturned', ctfFlagReturned); - -function ctfFlagReturned(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - %index = detag(%a3); - objectiveHud.flagLocation[%index].setValue(""); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Deathmatch - Hud Messages -///////////////////////////////////////////////////////////////////////////////////////// - -addMessageCallback('MsgDMPlayerDies', dmPlayerDies); - -function dmPlayerDies(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - %deaths = detag(%a1); - objectiveHud.yourDeaths.setValue(%deaths); -} - -addMessageCallback('MsgDMKill', dmKill); - -function dmKill(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - %kills = detag(%a1); - objectiveHud.yourKills.setValue(%kills); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Hunters - Hud Messages -///////////////////////////////////////////////////////////////////////////////////////// - -addMessageCallback('MsgHuntAddTeam', huntAddTeam); - -function huntAddTeam(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - %teamNum = detag(%a1); - %teamName = detag(%a2); - %score = detag(%a3); - - objectiveHud.teamName[%teamNum].setValue(%teamName); - objectiveHud.teamScore[%teamNum].setValue(%score); -} - -addMessageCallback('MsgHuntGreedStatus', huntGreedStatus); - -function huntGreedStatus(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - %greedStatus = detag(%a1); - %greedAmount = detag(%a2); - // no longer displayed in objective hud -} - -addMessageCallback('MsgHuntHoardStatus', hunthoardStatus); - -function huntHoardStatus(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - $Hud::HoardMode = detag(%a1); - $HUD::TimeLimit = detag(%a2); - %timeLeftMS = detag(%a3); - $HUD::HoardStartTime = detag(%a4); - $HUD::HoardDuration = detag(%a5); - // no longer displayed in objective hud -} - -function updateHoardStatusHUD(%timeLeftMS) -{ - // no longer displayed in objective hud -} - -addMessageCallback('MsgHuntYouHaveFlags', huntYouHaveFlags); - -function huntYouHaveFlags(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - %numFlags = detag(%a1); - objectiveHud.yourFlags.setValue(%numFlags); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Rabbit - Hud Messages -///////////////////////////////////////////////////////////////////////////////////////// - -addMessageCallback('MsgRabbitFlagTaken', rabbitFlagTaken); - -function rabbitFlagTaken(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - %bunny = detag(%a1); - objectiveHud.rabbitName.setValue(%bunny); -} - -addMessageCallback('MsgRabbitFlagDropped', rabbitFlagDropped); - -function rabbitFlagDropped(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - objectiveHud.rabbitName.setValue(""); -} - -addMessageCallback('MsgRabbitFlagReturned', rabbitFlagReturned); - -function rabbitFlagReturned(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - objectiveHud.rabbitName.setValue(""); -} - -addMessageCallback('MsgRabbitFlagStatus', rabbitFlagStatus); - -function rabbitFlagStatus(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - %flagStatus = detag(%a1); - objectiveHud.rabbitName.setValue(%flagStatus); -}///////////////////////////////////////////////////////////////////////////////////////// -// Siege - Hud Messages -///////////////////////////////////////////////////////////////////////////////////////// - -addMessageCallback('MsgSiegeAddTeam', siegeAddTeam); - -function siegeAddTeam(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - %teamNum = detag(%a1); - %teamName = detag(%a2); - if(detag(%a3)) - %role = "CAPTURE"; - else - %role = "PROTECT"; - - objectiveHud.teamName[%teamNum].setValue(%teamName); - objectiveHud.roleLabel[%teamNum].setValue(%role); -} - -addMessageCallback('MsgSiegeRolesSwitched', siegeRolesSwitched); - -function siegeRolesSwitched(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - %newOff = detag(%a2); - %newDef = %newOff == 1 ? 2: 1; - - objectiveHud.roleLabel[%newDef].setValue("PROTECT"); - objectiveHud.roleLabel[%newOff].setValue("CAPTURE"); - //objectiveHud.objectives[%newDef].setValue("1"); - //objectiveHud.objectives[%newOff].setValue("0"); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// DnD - Hud Messages - z0dd - ZOD, 9/13/02. -///////////////////////////////////////////////////////////////////////////////////////// - -function dndAddTeam(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - %teamNum = detag(%a1); - %teamName = detag(%a2); - %score = detag(%a3); - if (%score $= "") - %score = 0; - - %sLimit = detag(%a4); - objectiveHud.teamName[%teamNum].setValue(%teamName); - objectiveHud.objectives[%teamNum].setValue(%sLimit); - objectiveHud.teamScore[%teamNum].setValue(%score); -} - -function dndTeamScores(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - %teamNum = detag(%a1); - %teamName = detag(%a2); - %score = detag(%a3); - if(%score $= "") - %score = 0; - - %sLimit = detag(%a4); - objectiveHud.teamScore[%teamNum].setValue(%score); -} - -addMessageCallback('MsgDnDAddTeam', dndAddTeam); -addMessageCallback('MsgDnDTeamScores', dndTeamScores); - -///////////////////////////////////////////////////////////////////////////////////////// -// Single Player Game - Hud Messages -///////////////////////////////////////////////////////////////////////////////////////// - -//addMessageCallback('MsgSPYourRankIs', spYourRankIs); - -function spYourRankIs(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - //%rank = detag(%a1); - //objectiveHud.data[1,1].setValue(%rank); -} - -addMessageCallback('MsgSPCurrentObjective1', spCurrentObjective1); - -function spCurrentObjective1(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - %obj = detag(%a1); - objectiveHud.spText[1].setValue(%obj); -} - -addMessageCallback('MsgSPCurrentObjective2', spCurrentObjective2); - -function spCurrentObjective2(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - %obj = detag(%a1); - objectiveHud.spText[2].setValue(%obj); -} - -//addMessageCallback('MsgSPCurrentObjective3', spCurrentObjective3); - -//function spCurrentObjective3(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -//{ -// %obj = detag(%a1); -// objectiveHud.data[0,4].setValue(%obj); -//} - -///////////////////////////////////////////////////////////////////////////////////////// -// JB - Hud Messages - z0dd - ZOD, 9/13/02. -///////////////////////////////////////////////////////////////////////////////////////// - -function jbAddTeam(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - %teamNum = detag(%a1); - %teamName = detag(%a2); - %score = detag(%a3); - if(%score $= "") - %score = 0; - - %jailed = detag(%a4); - if(%jailed $= "" || %jailed < 0) - %jailed = 0; - - objectiveHud.teamName[%teamNum].setValue(%teamName); - objectiveHud.playersJailed[%teamNum].setValue(%jailed); - objectiveHud.teamScore[%teamNum].setValue(%score); -} - -function jbRoundHeld(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - %teamNum = detag(%a1); - %score = detag(%a2); - - objectiveHud.teamScore[%teamNum].setValue(%score); -} - -function jbJailed(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - %teamNum = detag(%a4); - %jailed = detag(%a5); - if(%jailed < 0) - %jailed = 0; - - objectiveHud.playersJailed[%teamNum].setValue(%jailed); -} - -addMessageCallback('MsgJBAddTeam', jbAddTeam); -addMessageCallback('MsgJBRoundHeld', jbRoundHeld); +// Mission type-dependent objective HUDs + +// TR2 additions +$TR2::Color::CarrierEnemy = "205 0 0 100"; +$TR2::Color::CarrierFriendly = "0 205 0 100"; +$TR2::Color::CarrierNeutral = "190 190 190 100"; +$TR2::DebriefGuiLoaded = 0; + +addMessageCallback('MsgClientReady', setCameraSpeedState); + +function setCameraSpeedState(%msgType, %msgString, %gameType, %a2, %a3, %a4, %a5, %a6) +{ + if( detag(%gameType) $= "TR2Game" ) + { + $_Camera::movementSpeed = $Camera::movementSpeed; + $Camera::movementSpeed = 80; + } + else + { + %val = $_Camera::movementSpeed $= "" ? 40 : $_Camera::movementSpeed; + $Camera::movementSpeed = %val; + } +} + +///// -MISSION START- ////////////////////////////////////////////////////////////// +addMessageCallback('MsgClientReady', clientReadyMSG); + +function clientReadyMSG(%msgType, %msgString, %gameType, %a2, %a3, %a4, %a5, %a6) +{ + clearObjHudMSG(); + setupObjHud(%gameType); +} + +addMessageCallback('MsgClearObjHud', clearObjHudMSG); + +function clearObjHudMSG(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + // clear the separator lines + objectiveHud.setSeparators(""); + objectiveHud.disableHorzSeparator(); + + + //remove everything in the objective Hud + while (objectiveHud.getCount() > 0) + objectiveHud.getObject(0).delete(); +} + +// TR2 Message Callbacks - AO +//----------------------- +// 05-13 removed the team size window +// 05-13 Removed syntax bug in hud (doh!) +// Created separate message type/callback and serverside function for adjusting bonus value +// Scores can now be updated independantly of bons value +// +// NEED TO ADD CODE TO MESSAGE CLIENT THE BONUS VALUE AND TEAM WHEN THEY JOIN!!! + + +addMessageCallback('MsgTR2UpdateBonus', handleTR2UpdateBonus); + + + +addMessageCallback('MsgTR2ObjInit', TR2HudInit); + +function TR2HudInit(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9) +{ + objectiveHud.teamName[1].setValue(detag(%a1)); + objectiveHud.teamName[2].setValue(detag(%a2)); + + objectiveHud.teamScore[1].setValue(detag(%a3)); + objectiveHud.teamScore[2].setValue(detag(%a4)); + + objectiveHud.carrierName.setValue(detag(%a5)); + objectiveHud.carrierHealth.setValue(detag(%a6)); + + TR2BonusObject.doBonus(%a7, $TR2::NeutralColor); +} + +addMessageCallback('MsgTR2SetScore', handleTR2SetScore); + +function handleTR2SetScore(%msgType, %msgString, %team, %score) +{ + %team = detag(%team); + objectiveHud.teamScore[%team].setValue( detag(%score) ); +} +// end TR2 message callbacks - AO + +// REPLACE profile definition in objectiveHud.cs +new GuiControlProfile ("TR2CarrierHealth") +{ + opaque = false; + fillColor = "0 205 0 100"; + border = true; + borderColor = "190 190 190 100"; +}; + +addMessageCallback('MsgTR2FlagStatus', handleTR2FlagStatus); + +function handleTR2FlagStatus(%msgType, %msgString, %location) +{ + objectiveHud.carrierName.setValue(detag(%location)); +} + +addMessageCallback('MsgTR2FlagTaken', handleTR2FlagTaken); + +function handleTR2FlagTaken(%msgType, %msgString, %client, %team, %flagteam, %clientnamebase) +{ + objectiveHud.carrierName.setValue(detag(%client)); +} + +addMessageCallback('MsgTR2FlagDropped', handleTR2FlagDropped); + +function handleTR2FlagDropped(%msgType, %msgString, %client, %team, %flagteam) +{ + objectiveHud.carrierName.setValue("Dropped"); +} + +addMessageCallback('MsgTR2CarrierHealth', handleTR2CarrierHealth); + +function handleTR2CarrierHealth(%msgType, %msgString, %amt, %team) +{ + if( detag(%team) == 1 ) // carrier is on our team + { + objectiveHud.carrierHealth.profile.fillColor = $TR2::Color::CarrierFriendly; + } + else + { + objectiveHud.carrierHealth.profile.fillColor = $TR2::Color::CarrierEnemy; + } + objectiveHud.carrierHealth.setValue(detag(%amt)); +} + +function setupObjHud(%gameType) +{ + if(%gameType $= "PracticeCTFGame" || %gameType $= "CTFPlusGame") + %gameType = "CTFGame"; + + objectiveHud.gameType = %gameType; + + // TR2 additions + if( %gameType $= "TR2Game" ) + { + if( $TR2::DebriefGuiLoaded == 0 ) + { + if( isObject(DB_ChatDlg) ) + DB_ChatDlg.delete(); + if( isObject(DebriefGui) ) + DebriefGui.delete(); + exec("gui/TR2DebriefGui.gui"); + $TR2::DebriefGuiLoaded = 1; + } + } + else + { + if( $TR2::DebriefGuiLoaded == 1 ) + { + if( isObject(DB_ChatDlg) ) + DB_ChatDlg.delete(); + if( isObject(DebriefGui) ) + DebriefGui.delete(); + exec("gui/DebriefGui.gui"); + $TR2::DebriefGuiLoaded = 0; + } + } + + switch$ (%gameType) + { + // Begin TR2 hud stuff - AO + case TR2Game: // | | | < Carrier Name > + // | | | + // set separators + objectiveHud.setSeparators("104 147"); + objectiveHud.enableHorzSeparator(); + + // Team names + objectiveHud.teamName[1] = new GuiTextCtrl() { + profile = "GuiTextObjGoldLeftProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "4 3"; + extent = "96 16"; + visible = "1"; + }; + objectiveHud.teamName[2] = new GuiTextCtrl() { + profile = "GuiTextObjSilverLeftProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "4 19"; + extent = "96 16"; + visible = "1"; + }; + // Team scores + objectiveHud.teamScore[1] = new GuiTextCtrl() { + profile = "GuiTextObjGoldCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "108 3"; + extent = "35 16"; + visible = "1"; + }; + objectiveHud.teamScore[2] = new GuiTextCtrl() { + profile = "GuiTextObjSilverCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "108 19"; + extent = "35 16"; + visible = "1"; + }; + + // Bonus + objectiveHud.carrierName = new GuiTextCtrl() { + profile = "GuiTextObjHudCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "151 3"; + extent = "90 16"; + visible = "1"; + text = ""; + }; + objectiveHud.carrierHealth = new GuiProgressCtrl() { + profile = "TR2CarrierHealth"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "159 22"; + extent = "75 10"; + minExtent = "8 8"; + visible = "1"; + hideCursor = "0"; + bypassHideCursor = "0"; + helpTag = "0"; + }; + + for(%i = 1; %i <= 2; %i++) + { + objectiveHud.add(objectiveHud.teamScore[%i]); + objectiveHud.add(objectiveHud.teamName[%i]); + } + objectiveHud.add(objectiveHud.carrierName); + objectiveHud.add(objectiveHud.carrierHealth); + + // end TR2 Hud stuff - AO + + case BountyGame: + // set separators + objectiveHud.setSeparators("56 156"); + objectiveHud.disableHorzSeparator(); + + // Your score label ("SCORE") + objectiveHud.scoreLabel = new GuiTextCtrl() { + profile = "GuiTextObjGreenLeftProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "4 3"; + extent = "50 16"; + visible = "1"; + text = "SCORE"; + }; + // Your score + objectiveHud.yourScore = new GuiTextCtrl() { + profile = "GuiTextObjGreenCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "60 3"; + extent = "90 16"; + visible = "1"; + }; + // Target label ("TARGET") + objectiveHud.targetLabel = new GuiTextCtrl() { + profile = "GuiTextObjGreenLeftProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "4 19"; + extent = "50 16"; + visible = "1"; + text = "TARGET"; + }; + // your target's name + objectiveHud.yourTarget = new GuiTextCtrl() { + profile = "GuiTextObjGreenCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "60 19"; + extent = "90 16"; + visible = "1"; + }; + + objectiveHud.add(objectiveHud.scoreLabel); + objectiveHud.add(objectiveHud.yourScore); + objectiveHud.add(objectiveHud.targetLabel); + objectiveHud.add(objectiveHud.yourTarget); + + case CnHGame: + // set separators + objectiveHud.setSeparators("96 162 202"); + objectiveHud.enableHorzSeparator(); + + // Team names + objectiveHud.teamName[1] = new GuiTextCtrl() { + profile = "GuiTextObjGreenLeftProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "4 3"; + extent = "90 16"; + visible = "1"; + }; + objectiveHud.teamName[2] = new GuiTextCtrl() { + profile = "GuiTextObjHudLeftProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "4 19"; + extent = "90 16"; + visible = "1"; + }; + // Team scores + objectiveHud.teamScore[1] = new GuiTextCtrl() { + profile = "GuiTextObjGreenCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "105 3"; + extent = "50 16"; + visible = "1"; + }; + objectiveHud.teamScore[2] = new GuiTextCtrl() { + profile = "GuiTextObjHudCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "105 19"; + extent = "50 16"; + visible = "1"; + }; + // Hold label ("HOLD") + objectiveHud.holdLabel[1] = new GuiTextCtrl() { + profile = "GuiTextObjGreenCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "165 3"; + extent = "35 16"; + visible = "1"; + text = "HOLD"; + }; + objectiveHud.holdLabel[2] = new GuiTextCtrl() { + profile = "GuiTextObjHudCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "165 19"; + extent = "35 16"; + visible = "1"; + text = "HOLD"; + }; + // number of points held + objectiveHud.numHeld[1] = new GuiTextCtrl() { + profile = "GuiTextObjGreenCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "205 3"; + extent = "30 16"; + visible = "1"; + }; + objectiveHud.numHeld[2] = new GuiTextCtrl() { + profile = "GuiTextObjHudCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "205 19"; + extent = "30 16"; + visible = "1"; + }; + + for(%i = 1; %i <= 2; %i++) + { + objectiveHud.add(objectiveHud.teamName[%i]); + objectiveHud.add(objectiveHud.teamScore[%i]); + objectiveHud.add(objectiveHud.holdLabel[%i]); + objectiveHud.add(objectiveHud.numHeld[%i]); + } + + case CTFGame: + // set separators + objectiveHud.setSeparators("75 100 133"); + objectiveHud.enableHorzSeparator(); + + // Team names + objectiveHud.teamName[1] = new GuiTextCtrl() { + profile = "GuiTextObjGreenLeftProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "4 3"; + extent = "68 16"; + visible = "1"; + }; + objectiveHud.teamName[2] = new GuiTextCtrl() { + profile = "GuiTextObjHudLeftProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "4 19"; + extent = "68 16"; + visible = "1"; + }; + // Team scores + objectiveHud.teamScore[1] = new GuiTextCtrl() { + profile = "GuiTextObjGreenCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "78 3"; + extent = "22 16"; + visible = "1"; + }; + objectiveHud.teamScore[2] = new GuiTextCtrl() { + profile = "GuiTextObjHudCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "78 19"; + extent = "22 16"; + visible = "1"; + }; + // Flag label ("FLAG") + objectiveHud.flagLabel[1] = new GuiTextCtrl() { + profile = "GuiTextObjGreenCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "103 3"; + extent = "30 16"; + visible = "1"; + text = "FLAG"; + }; + objectiveHud.flagLabel[2] = new GuiTextCtrl() { + profile = "GuiTextObjHudCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "103 19"; + extent = "30 16"; + visible = "1"; + text = "FLAG"; + }; + // flag location (at base/in field/player carrying it) + objectiveHud.flagLocation[1] = new GuiTextCtrl() { + profile = "GuiTextObjGreenLeftProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "138 3"; + extent = "102 16"; + visible = "1"; + }; + objectiveHud.flagLocation[2] = new GuiTextCtrl() { + profile = "GuiTextObjHudLeftProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "138 19"; + extent = "102 16"; + visible = "1"; + }; + + for(%i = 1; %i <= 2; %i++) + { + objectiveHud.add(objectiveHud.teamName[%i]); + objectiveHud.add(objectiveHud.teamScore[%i]); + objectiveHud.add(objectiveHud.flagLabel[%i]); + objectiveHud.add(objectiveHud.flagLocation[%i]); + } + + case DMGame: + // set separators + objectiveHud.setSeparators("56 96 156"); + objectiveHud.disableHorzSeparator(); + + // Your score label ("SCORE") + objectiveHud.scoreLabel = new GuiTextCtrl() { + profile = "GuiTextObjGreenLeftProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "4 3"; + extent = "50 16"; + visible = "1"; + text = "SCORE"; + }; + // Your score + objectiveHud.yourScore = new GuiTextCtrl() { + profile = "GuiTextObjGreenCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "60 3"; + extent = "30 16"; + visible = "1"; + }; + // Your kills label ("KILLS") + objectiveHud.killsLabel = new GuiTextCtrl() { + profile = "GuiTextObjGreenLeftProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "4 19"; + extent = "50 16"; + visible = "1"; + text = "KILLS"; + }; + // Your kills + objectiveHud.yourKills = new GuiTextCtrl() { + profile = "GuiTextObjGreenCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "60 19"; + extent = "30 16"; + visible = "1"; + }; + // Your deaths label ("DEATHS") + objectiveHud.deathsLabel = new GuiTextCtrl() { + profile = "GuiTextObjGreenLeftProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "100 19"; + extent = "50 16"; + visible = "1"; + text = "DEATHS"; + }; + // Your deaths + objectiveHud.yourDeaths = new GuiTextCtrl() { + profile = "GuiTextObjGreenCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "160 19"; + extent = "30 16"; + visible = "1"; + }; + + objectiveHud.add(objectiveHud.scoreLabel); + objectiveHud.add(objectiveHud.yourScore); + objectiveHud.add(objectiveHud.killsLabel); + objectiveHud.add(objectiveHud.yourKills); + objectiveHud.add(objectiveHud.deathsLabel); + objectiveHud.add(objectiveHud.yourDeaths); + + case HuntersGame: + // set separators + objectiveHud.setSeparators("96 132"); + objectiveHud.disableHorzSeparator(); + + // Your score label ("SCORE") + objectiveHud.scoreLabel = new GuiTextCtrl() { + profile = "GuiTextObjGreenLeftProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "4 3"; + extent = "90 16"; + visible = "1"; + text = "SCORE"; + }; + // Your score + objectiveHud.yourScore = new GuiTextCtrl() { + profile = "GuiTextObjGreenCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "100 3"; + extent = "30 16"; + visible = "1"; + }; + // flags label ("FLAGS") + objectiveHud.flagLabel = new GuiTextCtrl() { + profile = "GuiTextObjGreenLeftProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "4 19"; + extent = "90 16"; + visible = "1"; + text = "FLAGS"; + }; + // number of flags + objectiveHud.yourFlags = new GuiTextCtrl() { + profile = "GuiTextObjGreenCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "100 19"; + extent = "30 16"; + visible = "1"; + }; + + objectiveHud.add(objectiveHud.scoreLabel); + objectiveHud.add(objectiveHud.yourScore); + objectiveHud.add(objectiveHud.flagLabel); + objectiveHud.add(objectiveHud.yourFlags); + + case RabbitGame: + // set separators + objectiveHud.setSeparators("56 156"); + objectiveHud.disableHorzSeparator(); + + // Your score label ("SCORE") + objectiveHud.scoreLabel = new GuiTextCtrl() { + profile = "GuiTextObjGreenLeftProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "4 3"; + extent = "50 16"; + visible = "1"; + text = "SCORE"; + }; + // Your score + objectiveHud.yourScore = new GuiTextCtrl() { + profile = "GuiTextObjGreenCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "60 3"; + extent = "90 16"; + visible = "1"; + }; + // Rabbit label ("RABBIT") + objectiveHud.rabbitLabel = new GuiTextCtrl() { + profile = "GuiTextObjGreenLeftProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "4 19"; + extent = "50 16"; + visible = "1"; + text = "RABBIT"; + }; + // rabbit name + objectiveHud.rabbitName = new GuiTextCtrl() { + profile = "GuiTextObjGreenCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "60 19"; + extent = "90 16"; + visible = "1"; + }; + + objectiveHud.add(objectiveHud.scoreLabel); + objectiveHud.add(objectiveHud.yourScore); + objectiveHud.add(objectiveHud.rabbitLabel); + objectiveHud.add(objectiveHud.rabbitName); + + case SiegeGame: + // set separators + objectiveHud.setSeparators("96 122 177"); + objectiveHud.enableHorzSeparator(); + + // Team names + objectiveHud.teamName[1] = new GuiTextCtrl() { + profile = "GuiTextObjGreenLeftProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "4 3"; + extent = "90 16"; + visible = "1"; + }; + objectiveHud.teamName[2] = new GuiTextCtrl() { + profile = "GuiTextObjHudLeftProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "4 19"; + extent = "90 16"; + visible = "1"; + }; + // Team scores + objectiveHud.teamScore[1] = new GuiTextCtrl() { + profile = "GuiTextObjGreenCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "100 3"; + extent = "20 16"; + visible = "1"; + }; + objectiveHud.teamScore[2] = new GuiTextCtrl() { + profile = "GuiTextObjGreenCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "100 19"; + extent = "20 16"; + visible = "1"; + }; + // Role label ("PROTECT" or "DESTROY") + objectiveHud.roleLabel[1] = new GuiTextCtrl() { + profile = "GuiTextObjGreenCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "125 3"; + extent = "50 16"; + visible = "1"; + }; + objectiveHud.roleLabel[2] = new GuiTextCtrl() { + profile = "GuiTextObjHudCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "125 19"; + extent = "50 16"; + visible = "1"; + }; + // number of objectives to protect/destroy + objectiveHud.objectives[1] = new GuiTextCtrl() { + profile = "GuiTextObjGreenCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "180 3"; + extent = "60 16"; + visible = "1"; + }; + objectiveHud.objectives[2] = new GuiTextCtrl() { + profile = "GuiTextObjHudCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "180 19"; + extent = "60 16"; + visible = "1"; + }; + + for(%i = 1; %i <= 2; %i++) + { + objectiveHud.add(objectiveHud.teamName[%i]); + objectiveHud.add(objectiveHud.teamScore[%i]); + objectiveHud.add(objectiveHud.roleLabel[%i]); + objectiveHud.add(objectiveHud.objectives[%i]); + } + + case TeamHuntersGame: + // set separators + objectiveHud.setSeparators("57 83 197"); + objectiveHud.enableHorzSeparator(); + + // flags label ("FLAGS") + objectiveHud.flagLabel = new GuiTextCtrl() { + profile = "GuiTextObjGreenLeftProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "4 3"; + extent = "50 16"; + visible = "1"; + text = "FLAGS"; + }; + // number of flags + objectiveHud.yourFlags = new GuiTextCtrl() { + profile = "GuiTextObjGreenCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "60 3"; + extent = "20 16"; + visible = "1"; + }; + // team names + objectiveHud.teamName[1] = new GuiTextCtrl() { + profile = "GuiTextObjGreenCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "85 3"; + extent = "110 16"; + visible = "1"; + }; + objectiveHud.teamName[2] = new GuiTextCtrl() { + profile = "GuiTextObjHudCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "85 19"; + extent = "110 16"; + visible = "1"; + }; + // team scores + objectiveHud.teamScore[1] = new GuiTextCtrl() { + profile = "GuiTextObjGreenCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "200 3"; + extent = "40 16"; + visible = "1"; + }; + objectiveHud.teamScore[2] = new GuiTextCtrl() { + profile = "GuiTextObjHudCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "200 19"; + extent = "40 16"; + visible = "1"; + }; + + objectiveHud.add(objectiveHud.flagLabel); + objectiveHud.add(objectiveHud.yourFlags); + for(%i = 1; %i <= 2; %i++) + { + objectiveHud.add(objectiveHud.teamName[%i]); + objectiveHud.add(objectiveHud.teamScore[%i]); + } + + case SinglePlayerGame: + // no separator lines + objectiveHud.setSeparators(""); + objectiveHud.disableHorzSeparator(); + + // two lines to print objectives + objectiveHud.spText[1] = new GuiTextCtrl() { + profile = "GuiTextObjHudLeftProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "4 3"; + extent = "235 16"; + visible = "1"; + }; + objectiveHud.spText[2] = new GuiTextCtrl() { + profile = "GuiTextObjHudLeftProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "4 19"; + extent = "235 16"; + visible = "1"; + }; + objectiveHud.add(objectiveHud.spText[1]); + objectiveHud.add(objectiveHud.spText[2]); + // z0dd - ZOD, 9/13/02. New gametype + case JBGame: + // set separators + objectiveHud.setSeparators("64 114 152 202"); + objectiveHud.enableHorzSeparator(); + + // Team names + objectiveHud.teamName[1] = new GuiTextCtrl() { + profile = "GuiTextObjGreenLeftProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "4 3"; + extent = "60 16"; + visible = "1"; + }; + objectiveHud.teamName[2] = new GuiTextCtrl() { + profile = "GuiTextObjHudLeftProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "4 19"; + extent = "60 16"; + visible = "1"; + }; + // In Jail ("JAILED") + objectiveHud.inJailLabel[1] = new GuiTextCtrl() { + profile = "GuiTextObjGreenCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "68 3"; + extent = "42 16"; + visible = "1"; + text = "JAILED"; + }; + objectiveHud.inJailLabel[2] = new GuiTextCtrl() { + profile = "GuiTextObjHudCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "68 19"; + extent = "42 16"; + visible = "1"; + text = "JAILED"; + }; + // Players in Jail + objectiveHud.playersJailed[1] = new GuiTextCtrl() { + profile = "GuiTextObjGreenCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "118 3"; + extent = "30 16"; + visible = "1"; + }; + objectiveHud.playersJailed[2] = new GuiTextCtrl() { + profile = "GuiTextObjHudCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "118 19"; + extent = "30 16"; + visible = "1"; + }; + // Score label ("SCORE") + objectiveHud.scoreLabel[1] = new GuiTextCtrl() { + profile = "GuiTextObjGreenCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "156 3"; + extent = "42 16"; + visible = "1"; + text = "SCORE"; + }; + objectiveHud.scoreLabel[2] = new GuiTextCtrl() { + profile = "GuiTextObjHudCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "156 19"; + extent = "42 16"; + visible = "1"; + text = "SCORE"; + }; + // scores + objectiveHud.teamScore[1] = new GuiTextCtrl() { + profile = "GuiTextObjGreenCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "206 3"; + extent = "30 16"; + visible = "1"; + }; + objectiveHud.teamScore[2] = new GuiTextCtrl() { + profile = "GuiTextObjHudCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "206 19"; + extent = "30 16"; + visible = "1"; + }; + for(%i = 1; %i <= 2; %i++) + { + objectiveHud.add(objectiveHud.teamName[%i]); + objectiveHud.add(objectiveHud.inJailLabel[%i]); + objectiveHud.add(objectiveHud.playersJailed[%i]); + objectiveHud.add(objectiveHud.scoreLabel[%i]); + objectiveHud.add(objectiveHud.teamScore[%i]); + } + // z0dd - ZOD, 9/13/02. New gametype + case DnDGame: + // set separators + objectiveHud.setSeparators("75 114 150 210"); + objectiveHud.enableHorzSeparator(); + + // Team names + objectiveHud.teamName[1] = new GuiTextCtrl() { + profile = "GuiTextObjGreenLeftProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "4 3"; + extent = "68 16"; + visible = "1"; + }; + objectiveHud.teamName[2] = new GuiTextCtrl() { + profile = "GuiTextObjHudLeftProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "4 19"; + extent = "68 16"; + visible = "1"; + }; + // Label: Scores + objectiveHud.scoreLabel[1] = new GuiTextCtrl() { + profile = "GuiTextObjGreenCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "75 3"; + extent = "42 16"; + visible = "1"; + text = "Score"; + }; + objectiveHud.scoreLabel[2] = new GuiTextCtrl() { + profile = "GuiTextObjHudCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "75 19"; + extent = "42 16"; + visible = "1"; + text = "Score"; + }; + // Team scores + objectiveHud.teamScore[1] = new GuiTextCtrl() { + profile = "GuiTextObjGreenCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "118 3"; + extent = "30 16"; + visible = "1"; + }; + objectiveHud.teamScore[2] = new GuiTextCtrl() { + profile = "GuiTextObjHudCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "118 19"; + extent = "30 16"; + visible = "1"; + }; + // Label: Objectives + objectiveHud.objectivesLabel[1] = new GuiTextCtrl() { + profile = "GuiTextObjGreenCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "158 3"; + extent = "44 16"; + visible = "1"; + text = "Objectives"; + }; + objectiveHud.objectivesLabel[2] = new GuiTextCtrl() { + profile = "GuiTextObjHudCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "158 19"; + extent = "44 16"; + visible = "1"; + text = "Objectives"; + }; + // Team objectives + objectiveHud.objectives[1] = new GuiTextCtrl() { + profile = "GuiTextObjGreenCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "210 3"; + extent = "30 16"; + visible = "1"; + }; + objectiveHud.objectives[2] = new GuiTextCtrl() { + profile = "GuiTextObjHudCenterProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "210 19"; + extent = "30 16"; + visible = "1"; + }; + for(%i = 1; %i <= 2; %i++) + { + objectiveHud.add(objectiveHud.teamName[%i]); + objectiveHud.add(objectiveHud.scoreLabel[%i]); + objectiveHud.add(objectiveHud.teamScore[%i]); + objectiveHud.add(objectiveHud.objectivesLabel[%i]); + objectiveHud.add(objectiveHud.objectives[%i]); + } + } + chatPageDown.setVisible(false); +} + +addMessageCallback('MsgCheckTeamLines', checkTeamLines); + +function checkTeamLines(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + %team = detag(%a1); + + if(%team == 1) + %other = 2; + else if(%team == 2) + %other = 1; + else + return; + + %tY = getWord(objectiveHud.teamName[%team].position, 1); + %oY = getWord(objectiveHud.teamName[%other].position, 1); + + // if player's team is lower on objective hud than other team is, switch them + if(%tY > %oY) + swapTeamLines(); +} + +function swapTeamLines() +{ + // if player's team is on the bottom of the objective hud, swap them so that it's on top + %bLeft = "GuiTextObjHudLeftProfile"; + %bCenter = "GuiTextObjHudCenterProfile"; + %gLeft = "GuiTextObjGreenLeftProfile"; + %gCenter = "GuiTextObjGreenCenterProfile"; + + %teamOneY = getWord(objectiveHud.teamName[1].position, 1); + %teamTwoY = getWord(objectiveHud.teamName[2].position, 1); + + // z0dd - ZOD, 9/13/02. Code streamlining + %newTop = %teamOneY > %teamTwoY ? 1 : 2; + %newBottom = %teamOneY > %teamTwoY ? 2 : 1; + + + // these are present in every team-based mission type + %nameX = firstWord(objectiveHud.teamName[1].position); + objectiveHud.teamName[1].position = %nameX SPC %teamTwoY; + objectiveHud.teamName[2].position = %nameX SPC %teamOneY; + objectiveHud.teamName[%newTop].setProfile(%gLeft); + objectiveHud.teamName[%newBottom].setProfile(%bLeft); + + %scoreX = firstWord(objectiveHud.teamScore[1].position); + objectiveHud.teamScore[1].position = %scoreX SPC %teamTwoY; + objectiveHud.teamScore[2].position = %scoreX SPC %teamOneY; + objectiveHud.teamScore[%newTop].setProfile(%gCenter); + objectiveHud.teamScore[%newBottom].setProfile(%bCenter); + + if(isObject(objectiveHud.flagLocation[1])) + { + // CTF + %locatX = firstWord(objectiveHud.flagLocation[1].position); + objectiveHud.flagLocation[1].position = %locatX SPC %teamTwoY; + objectiveHud.flagLocation[2].position = %locatX SPC %teamOneY; + // swap profiles so top line is green (don't bother with labels) + objectiveHud.flagLocation[%newTop].setProfile(%gLeft); + objectiveHud.flagLocation[%newBottom].setProfile(%bLeft); + } + if(isObject(objectiveHud.numHeld[1])) + { + // CnH + %locatX = firstWord(objectiveHud.numHeld[1].position); + objectiveHud.numHeld[1].position = %locatX SPC %teamTwoY; + objectiveHud.numHeld[2].position = %locatX SPC %teamOneY; + // swap profiles so top line is green (don't bother with labels) + objectiveHud.numHeld[%newTop].setProfile(%gCenter); + objectiveHud.numHeld[%newbottom].setProfile(%bCenter); + } + if(isObject(objectiveHud.objectives[1])) + { + // Siege + %locX = firstWord(objectiveHud.roleLabel[1].position); + objectiveHud.roleLabel[1].position = %locX SPC %teamTwoY; + objectiveHud.roleLabel[2].position = %locX SPC %teamOneY; + %locatX = firstWord(objectiveHud.objectives[1].position); + objectiveHud.objectives[1].position = %locatX SPC %teamTwoY; + objectiveHud.objectives[2].position = %locatX SPC %teamOneY; + // swap profiles so top line is green (don't forget role label) + objectiveHud.roleLabel[%newTop].setProfile(%gCenter); + objectiveHud.roleLabel[%newbottom].setProfile(%bCenter); + objectiveHud.objectives[%newTop].setProfile(%gCenter); + objectiveHud.objectives[%newbottom].setProfile(%bCenter); + } + if(isObject(objectiveHud.playersJailed[1])) // z0dd - ZOD, 9/13/02. New Gametype + { + %jailedX = firstWord(objectiveHud.playersJailed[1].position); + objectiveHud.playersJailed[1].position = %jailedX SPC %teamTwoY; + objectiveHud.playersJailed[2].position = %jailedX SPC %teamOneY; + objectiveHud.playersJailed[%newTop].setProfile(%gCenter); + objectiveHud.playersJailed[%newbottom].setProfile(%bCenter); + } + if (isObject(objectiveHud.objectives[1])) // z0dd - ZOD, 9/13/02. New Gametype + { + %locatX = firstWord(objectiveHud.objectives[1].position); + objectiveHud.objectives[1].position = %locatX SPC %teamTwoY; + objectiveHud.objectives[2].position = %locatX SPC %teamOneY; + objectiveHud.objectives[%newTop].setProfile(%gCenter); + objectiveHud.objectives[%newBottom].setProfile(%bCenter); + } +} + +//----------------------------------------------------------------------------- +//CLOCK HUD Callback +addMessageCallback('MsgSystemClock', setSystemClock); + +function setSystemClock(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + $Hud::TimeLimit = detag(%a1); + %timeLeftMS = detag(%a2); + clockHud.setTime(%timeLeftMS / (60 * 1000)); +} + +//----------------------------------------------------------------------------- +//Generic msg callbacks... + +addMessageCallback('MsgYourScoreIs', YourScoreIs); + +function YourScoreIs(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + if ( isObject( objectiveHud.yourScore ) ) + objectiveHud.yourScore.setValue( detag(%a1) ); +} + +addMessageCallback('MsgTeamScoreIs', teamScoreIs); + +function teamScoreIs(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + %teamNum = detag(%a1); + %score = detag(%a2); + + if(%score $= "") + %score = 0; + + objectiveHud.teamScore[%teamNum].setValue(%score); +} + +addMessageCallback('MsgYourRankIs', yourRankIs); + +function yourRankIs(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + // the rank (+1) adjustment is taken care of server-side... + %rank = detag(%a1); + // no longer displayed in objective hud +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Bounty - Hud Messages +///////////////////////////////////////////////////////////////////////////////////////// + +addMessageCallback('msgBountyTargetIs', bountyTargetIs); + +function bountyTargetIs(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + %hit = detag(%a1); + if(%hit $= "") + %hit = ""; + + objectiveHud.yourTarget.setValue(%hit); +} + +addMessageCallback('msgBountyTargetDropped', bountyTargetDropped); +addMessageCallback('msgBountyTargetEntObs', bountyTargetDropped); + +function bountyTargetDropped(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + objectiveHud.yourTarget.setValue(""); +} + +//addMessageCallback('msgBountyObjRem', bountyObjRem); + +function bountyObjRem(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + %objRem = detag(%a1); + + // this is no longer on the objective hud +} + +///////////////////////////////////////////////////////////////////////////////////////// +// CnH - Hud Messages +///////////////////////////////////////////////////////////////////////////////////////// + +addMessageCallback('MsgCnHAddTeam', cnhAddTeam); + +function cnhAddTeam(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + %teamNum = detag(%a1); + %teamName = detag(%a2); + %score = detag(%a3); + if(%score $= "") + %score = 0; + %sLimit = detag(%a4); + %held = detag(%a5); + + objectiveHud.teamName[%teamNum].setValue(%teamName); + objectiveHud.teamScore[%teamNum].setValue(%score@"/"@%sLimit); + objectiveHud.numHeld[%teamNum].setValue(%held); +} + +addMessageCallback('MsgFlipFlopsHeld', hudFlipFlopsHeld); + +function hudFlipFlopsHeld(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + %teamNum = detag(%a1); + %held = detag(%a2); + + objectiveHud.numHeld[%teamNum].setValue(%held); +} + +addMessageCallback('MsgCnHTeamCap', cnhTeamCap); + +function cnhTeamCap(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + %teamNum = detag(%a4); + %score = detag(%a5); + %sLimit = detag(%a6); + %string = %score @ "/" @ %sLimit; + + objectiveHud.teamScore[%teamNum].setValue(%string); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// CTF - Gui Hud Control +///////////////////////////////////////////////////////////////////////////////////////// + +addMessageCallback('MsgCTFAddTeam', ctfAddTeam); + +function ctfAddTeam(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + %teamNum = detag(%a1); + %teamName = detag(%a2); + %flagStatus = detag(%a3); + %score = detag(%a4); + + objectiveHud.teamName[%teamNum].setValue(%teamName); + objectiveHud.teamScore[%teamNum].setValue(%score); + objectiveHud.flagLocation[%teamNum].setValue(%flagStatus); +} + +addMessageCallback('MsgCTFFlagTaken', ctfFlagTaken); + +function ctfFlagTaken(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + %index = detag(%a3); + %taker = detag(%a4); + + objectiveHud.flagLocation[%index].setValue(%taker); +} + +addMessageCallback('MsgCTFFlagDropped', ctfFlagDropped); + +function ctfFlagDropped(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + %index = detag(%a3); + objectiveHud.flagLocation[%index].setValue(""); +} + +addMessageCallback('MsgCTFFlagCapped', ctfFlagCapped); + +function ctfFlagCapped(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + %index = detag(%a3); + objectiveHud.flagLocation[%index].setValue(""); +} + +addMessageCallback('MsgCTFFlagReturned', ctfFlagReturned); + +function ctfFlagReturned(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + %index = detag(%a3); + objectiveHud.flagLocation[%index].setValue(""); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Deathmatch - Hud Messages +///////////////////////////////////////////////////////////////////////////////////////// + +addMessageCallback('MsgDMPlayerDies', dmPlayerDies); + +function dmPlayerDies(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + %deaths = detag(%a1); + objectiveHud.yourDeaths.setValue(%deaths); +} + +addMessageCallback('MsgDMKill', dmKill); + +function dmKill(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + %kills = detag(%a1); + objectiveHud.yourKills.setValue(%kills); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Hunters - Hud Messages +///////////////////////////////////////////////////////////////////////////////////////// + +addMessageCallback('MsgHuntAddTeam', huntAddTeam); + +function huntAddTeam(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + %teamNum = detag(%a1); + %teamName = detag(%a2); + %score = detag(%a3); + + objectiveHud.teamName[%teamNum].setValue(%teamName); + objectiveHud.teamScore[%teamNum].setValue(%score); +} + +addMessageCallback('MsgHuntGreedStatus', huntGreedStatus); + +function huntGreedStatus(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + %greedStatus = detag(%a1); + %greedAmount = detag(%a2); + // no longer displayed in objective hud +} + +addMessageCallback('MsgHuntHoardStatus', hunthoardStatus); + +function huntHoardStatus(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + $Hud::HoardMode = detag(%a1); + $HUD::TimeLimit = detag(%a2); + %timeLeftMS = detag(%a3); + $HUD::HoardStartTime = detag(%a4); + $HUD::HoardDuration = detag(%a5); + // no longer displayed in objective hud +} + +function updateHoardStatusHUD(%timeLeftMS) +{ + // no longer displayed in objective hud +} + +addMessageCallback('MsgHuntYouHaveFlags', huntYouHaveFlags); + +function huntYouHaveFlags(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + %numFlags = detag(%a1); + objectiveHud.yourFlags.setValue(%numFlags); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Rabbit - Hud Messages +///////////////////////////////////////////////////////////////////////////////////////// + +addMessageCallback('MsgRabbitFlagTaken', rabbitFlagTaken); + +function rabbitFlagTaken(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + %bunny = detag(%a1); + objectiveHud.rabbitName.setValue(%bunny); +} + +addMessageCallback('MsgRabbitFlagDropped', rabbitFlagDropped); + +function rabbitFlagDropped(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + objectiveHud.rabbitName.setValue(""); +} + +addMessageCallback('MsgRabbitFlagReturned', rabbitFlagReturned); + +function rabbitFlagReturned(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + objectiveHud.rabbitName.setValue(""); +} + +addMessageCallback('MsgRabbitFlagStatus', rabbitFlagStatus); + +function rabbitFlagStatus(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + %flagStatus = detag(%a1); + objectiveHud.rabbitName.setValue(%flagStatus); +}///////////////////////////////////////////////////////////////////////////////////////// +// Siege - Hud Messages +///////////////////////////////////////////////////////////////////////////////////////// + +addMessageCallback('MsgSiegeAddTeam', siegeAddTeam); + +function siegeAddTeam(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + %teamNum = detag(%a1); + %teamName = detag(%a2); + if(detag(%a3)) + %role = "CAPTURE"; + else + %role = "PROTECT"; + + objectiveHud.teamName[%teamNum].setValue(%teamName); + objectiveHud.roleLabel[%teamNum].setValue(%role); +} + +addMessageCallback('MsgSiegeRolesSwitched', siegeRolesSwitched); + +function siegeRolesSwitched(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + %newOff = detag(%a2); + %newDef = %newOff == 1 ? 2: 1; + + objectiveHud.roleLabel[%newDef].setValue("PROTECT"); + objectiveHud.roleLabel[%newOff].setValue("CAPTURE"); + //objectiveHud.objectives[%newDef].setValue("1"); + //objectiveHud.objectives[%newOff].setValue("0"); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// DnD - Hud Messages - z0dd - ZOD, 9/13/02. +///////////////////////////////////////////////////////////////////////////////////////// + +function dndAddTeam(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + %teamNum = detag(%a1); + %teamName = detag(%a2); + %score = detag(%a3); + if (%score $= "") + %score = 0; + + %sLimit = detag(%a4); + objectiveHud.teamName[%teamNum].setValue(%teamName); + objectiveHud.objectives[%teamNum].setValue(%sLimit); + objectiveHud.teamScore[%teamNum].setValue(%score); +} + +function dndTeamScores(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + %teamNum = detag(%a1); + %teamName = detag(%a2); + %score = detag(%a3); + if(%score $= "") + %score = 0; + + %sLimit = detag(%a4); + objectiveHud.teamScore[%teamNum].setValue(%score); +} + +addMessageCallback('MsgDnDAddTeam', dndAddTeam); +addMessageCallback('MsgDnDTeamScores', dndTeamScores); + +///////////////////////////////////////////////////////////////////////////////////////// +// Single Player Game - Hud Messages +///////////////////////////////////////////////////////////////////////////////////////// + +//addMessageCallback('MsgSPYourRankIs', spYourRankIs); + +function spYourRankIs(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + //%rank = detag(%a1); + //objectiveHud.data[1,1].setValue(%rank); +} + +addMessageCallback('MsgSPCurrentObjective1', spCurrentObjective1); + +function spCurrentObjective1(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + %obj = detag(%a1); + objectiveHud.spText[1].setValue(%obj); +} + +addMessageCallback('MsgSPCurrentObjective2', spCurrentObjective2); + +function spCurrentObjective2(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + %obj = detag(%a1); + objectiveHud.spText[2].setValue(%obj); +} + +//addMessageCallback('MsgSPCurrentObjective3', spCurrentObjective3); + +//function spCurrentObjective3(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +//{ +// %obj = detag(%a1); +// objectiveHud.data[0,4].setValue(%obj); +//} + +///////////////////////////////////////////////////////////////////////////////////////// +// JB - Hud Messages - z0dd - ZOD, 9/13/02. +///////////////////////////////////////////////////////////////////////////////////////// + +function jbAddTeam(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + %teamNum = detag(%a1); + %teamName = detag(%a2); + %score = detag(%a3); + if(%score $= "") + %score = 0; + + %jailed = detag(%a4); + if(%jailed $= "" || %jailed < 0) + %jailed = 0; + + objectiveHud.teamName[%teamNum].setValue(%teamName); + objectiveHud.playersJailed[%teamNum].setValue(%jailed); + objectiveHud.teamScore[%teamNum].setValue(%score); +} + +function jbRoundHeld(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + %teamNum = detag(%a1); + %score = detag(%a2); + + objectiveHud.teamScore[%teamNum].setValue(%score); +} + +function jbJailed(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) +{ + %teamNum = detag(%a4); + %jailed = detag(%a5); + if(%jailed < 0) + %jailed = 0; + + objectiveHud.playersJailed[%teamNum].setValue(%jailed); +} + +addMessageCallback('MsgJBAddTeam', jbAddTeam); +addMessageCallback('MsgJBRoundHeld', jbRoundHeld); addMessageCallback('MsgJBJailed', jbJailed); \ No newline at end of file diff --git a/scripts/pack.cs b/scripts/pack.cs index f6fcce6..5987c27 100644 --- a/scripts/pack.cs +++ b/scripts/pack.cs @@ -1,92 +1,92 @@ -//---------------------------------------------------------------------------- - -datablock EffectProfile(TurretPackActivateEffect) -{ - effectname = "packs/generic_deploy"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock AudioProfile(TurretPackActivateSound) -{ - filename = "fx/packs/turret_place.wav"; - description = AudioClose3D; - preload = true; - effect = TurretPackActivateEffect; -}; - - -//---------------------------------------------------------------------------- - -function Pack::onCollision(%data, %obj, %col) -{ - // Don't pick up a new pack if you have a satchel charge deployed: - if ( %col.thrownChargeId > 0 ) - return; - - ItemData::onCollision(%data, %obj, %col); -} - -function Pack::onUse(%data,%obj) -{ - if (%obj.getMountedImage($BackpackSlot) != %data.image.getId()) - %obj.mountImage(%data.image,$BackpackSlot); - else - { - // Toggle the image trigger. - %obj.setImageTrigger($BackpackSlot, - !%obj.getImageTrigger($BackpackSlot)); - } -} - -function Pack::onInventory(%data,%obj,%amount) -{ - //only do this for players - if(%obj.getClassName() !$= "Player") - return; - - // Auto-mount the packs on players - if((%oldPack = %obj.getMountedImage($BackpackSlot)) != 0) - %obj.setInventory(%oldPack.item, 0); - if (%amount && %obj.getDatablock().className $= Armor) - { - // if you picked up another pack after you placed a satchel charge but - // before you detonated it, delete the charge - if(%obj.thrownChargeId > 0) - { - %obj.thrownChargeId.delete(); - %obj.thrownChargeId = 0; - } - %obj.mountImage(%data.image,$BackpackSlot); - %obj.client.setBackpackHudItem(%data.getName(), 1); - } - if(%amount == 0 ) - { - if ( %data.getName() $= "SatchelCharge" ) - %obj.client.setBackpackHudItem( "SatchelUnarmed", 1 ); - else - %obj.client.setBackpackHudItem(%data.getName(), 0); - } - ItemData::onInventory(%data,%obj,%amount); -} - -//---------------------------------------------------------------------------- - -// --- Upgrade packs -exec("scripts/packs/ammopack.cs"); -exec("scripts/packs/cloakingpack.cs"); -exec("scripts/packs/energypack.cs"); -exec("scripts/packs/repairpack.cs"); -exec("scripts/packs/shieldpack.cs"); -exec("scripts/packs/satchelCharge.cs"); -exec("scripts/packs/sensorjammerpack.cs"); -exec("scripts/packs/miningTool.cs"); -exec("scripts/packs/c4.cs"); -exec("scripts/packs/buildingconstructor.cs"); - -// --- Turret barrel packs -exec("scripts/packs/aabarrelpack.cs"); -exec("scripts/packs/missilebarrelpack.cs"); -exec("scripts/packs/mortarbarrelpack.cs"); -exec("scripts/packs/plasmabarrelpack.cs"); -exec("scripts/packs/ELFbarrelpack.cs"); +//---------------------------------------------------------------------------- + +datablock EffectProfile(TurretPackActivateEffect) +{ + effectname = "packs/generic_deploy"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock AudioProfile(TurretPackActivateSound) +{ + filename = "fx/packs/turret_place.wav"; + description = AudioClose3D; + preload = true; + effect = TurretPackActivateEffect; +}; + + +//---------------------------------------------------------------------------- + +function Pack::onCollision(%data, %obj, %col) +{ + // Don't pick up a new pack if you have a satchel charge deployed: + if ( %col.thrownChargeId > 0 ) + return; + + ItemData::onCollision(%data, %obj, %col); +} + +function Pack::onUse(%data,%obj) +{ + if (%obj.getMountedImage($BackpackSlot) != %data.image.getId()) + %obj.mountImage(%data.image,$BackpackSlot); + else + { + // Toggle the image trigger. + %obj.setImageTrigger($BackpackSlot, + !%obj.getImageTrigger($BackpackSlot)); + } +} + +function Pack::onInventory(%data,%obj,%amount) +{ + //only do this for players + if(%obj.getClassName() !$= "Player") + return; + + // Auto-mount the packs on players + if((%oldPack = %obj.getMountedImage($BackpackSlot)) != 0) + %obj.setInventory(%oldPack.item, 0); + if (%amount && %obj.getDatablock().className $= Armor) + { + // if you picked up another pack after you placed a satchel charge but + // before you detonated it, delete the charge + if(%obj.thrownChargeId > 0) + { + %obj.thrownChargeId.delete(); + %obj.thrownChargeId = 0; + } + %obj.mountImage(%data.image,$BackpackSlot); + %obj.client.setBackpackHudItem(%data.getName(), 1); + } + if(%amount == 0 ) + { + if ( %data.getName() $= "SatchelCharge" ) + %obj.client.setBackpackHudItem( "SatchelUnarmed", 1 ); + else + %obj.client.setBackpackHudItem(%data.getName(), 0); + } + ItemData::onInventory(%data,%obj,%amount); +} + +//---------------------------------------------------------------------------- + +// --- Upgrade packs +exec("scripts/packs/ammopack.cs"); +exec("scripts/packs/cloakingpack.cs"); +exec("scripts/packs/energypack.cs"); +exec("scripts/packs/repairpack.cs"); +exec("scripts/packs/shieldpack.cs"); +exec("scripts/packs/satchelCharge.cs"); +exec("scripts/packs/sensorjammerpack.cs"); +exec("scripts/packs/miningTool.cs"); +exec("scripts/packs/c4.cs"); +exec("scripts/packs/buildingconstructor.cs"); + +// --- Turret barrel packs +exec("scripts/packs/aabarrelpack.cs"); +exec("scripts/packs/missilebarrelpack.cs"); +exec("scripts/packs/mortarbarrelpack.cs"); +exec("scripts/packs/plasmabarrelpack.cs"); +exec("scripts/packs/ELFbarrelpack.cs"); diff --git a/scripts/packs/ELFbarrelPack.cs b/scripts/packs/ELFbarrelPack.cs index 8a7dbb0..c14625f 100644 --- a/scripts/packs/ELFbarrelPack.cs +++ b/scripts/packs/ELFbarrelPack.cs @@ -1,61 +1,61 @@ -//-------------------------------------------------------------------------- -// -// ELF barrel pack -// -//-------------------------------------------------------------------------- - -datablock ShapeBaseImageData(ELFBarrelPackImage) -{ - mass = 10; // z0dd - ZOD, 7/17/02. Lower mass due to higher gravity. Was 15. - - shapeFile = "pack_barrel_elf.dts"; - item = ELFBarrelPack; - mountPoint = 1; - offset = "0 0 0"; - turretBarrel = "ELFBarrelLarge"; - - stateName[0] = "Idle"; - stateTransitionOnTriggerDown[0] = "Activate"; - - stateName[1] = "Activate"; - stateScript[1] = "onActivate"; - stateTransitionOnTriggerUp[1] = "Deactivate"; - - stateName[2] = "Deactivate"; - stateScript[2] = "onDeactivate"; - stateTransitionOnTimeOut[2] = "Idle"; - - isLarge = true; -}; - -datablock ItemData(ELFBarrelPack) -{ - className = Pack; - catagory = "Packs"; - shapeFile = "pack_barrel_elf.dts"; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - rotate = true; - image = "ELFBarrelPackImage"; - pickUpName = "an ELF barrel pack"; - - computeCRC = true; - -}; - -function ELFBarrelPackImage::onActivate(%data, %obj, %slot) -{ - checkTurretMount(%data, %obj, %slot); -} - -function ELFBarrelPackImage::onDeactivate(%data, %obj, %slot) -{ - %obj.setImageTrigger($BackpackSlot, false); -} - -function ELFBarrelPack::onPickup(%this, %obj, %shape, %amount) -{ - // created to prevent console errors +//-------------------------------------------------------------------------- +// +// ELF barrel pack +// +//-------------------------------------------------------------------------- + +datablock ShapeBaseImageData(ELFBarrelPackImage) +{ + mass = 10; // z0dd - ZOD, 7/17/02. Lower mass due to higher gravity. Was 15. + + shapeFile = "pack_barrel_elf.dts"; + item = ELFBarrelPack; + mountPoint = 1; + offset = "0 0 0"; + turretBarrel = "ELFBarrelLarge"; + + stateName[0] = "Idle"; + stateTransitionOnTriggerDown[0] = "Activate"; + + stateName[1] = "Activate"; + stateScript[1] = "onActivate"; + stateTransitionOnTriggerUp[1] = "Deactivate"; + + stateName[2] = "Deactivate"; + stateScript[2] = "onDeactivate"; + stateTransitionOnTimeOut[2] = "Idle"; + + isLarge = true; +}; + +datablock ItemData(ELFBarrelPack) +{ + className = Pack; + catagory = "Packs"; + shapeFile = "pack_barrel_elf.dts"; + mass = 1; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 2; + rotate = true; + image = "ELFBarrelPackImage"; + pickUpName = "an ELF barrel pack"; + + computeCRC = true; + +}; + +function ELFBarrelPackImage::onActivate(%data, %obj, %slot) +{ + checkTurretMount(%data, %obj, %slot); +} + +function ELFBarrelPackImage::onDeactivate(%data, %obj, %slot) +{ + %obj.setImageTrigger($BackpackSlot, false); +} + +function ELFBarrelPack::onPickup(%this, %obj, %shape, %amount) +{ + // created to prevent console errors } \ No newline at end of file diff --git a/scripts/packs/aabarrelPack.cs b/scripts/packs/aabarrelPack.cs index a1bfcb9..4058de6 100644 --- a/scripts/packs/aabarrelPack.cs +++ b/scripts/packs/aabarrelPack.cs @@ -1,63 +1,63 @@ -//-------------------------------------------------------------------------- -// -// -// -//-------------------------------------------------------------------------- - -datablock ShapeBaseImageData(AABarrelPackImage) -{ - mass = 10; // z0dd - ZOD, 7/17/02. Lower mass due to higher gravity. Was 15. - - shapeFile = "pack_barrel_aa.dts"; - item = AABarrelPack; - mountPoint = 1; - offset = "0 0 0"; - turretBarrel = "AABarrelLarge"; - - stateName[0] = "Idle"; - stateTransitionOnTriggerDown[0] = "Activate"; - - stateName[1] = "Activate"; - stateScript[1] = "onActivate"; - stateTransitionOnTriggerUp[1] = "Deactivate"; - - stateName[2] = "Deactivate"; - stateScript[2] = "onDeactivate"; - stateTransitionOnTimeOut[2] = "Idle"; - - isLarge = true; -}; - -datablock ItemData(AABarrelPack) -{ - className = Pack; - catagory = "Packs"; - shapeFile = "pack_barrel_aa.dts"; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - rotate = true; - image = "AABarrelPackImage"; - pickUpName = "an anti-aircraft barrel pack"; - - computeCRC = true; - -}; - -//AABarrelPackImage.turretBarrel = "AABarrelLarge"; - -function AABarrelPackImage::onActivate(%data, %obj, %slot) -{ - checkTurretMount(%data, %obj, %slot); -} - -function AABarrelPackImage::onDeactivate(%data, %obj, %slot) -{ - %obj.setImageTrigger($BackpackSlot, false); -} - -function AABarrelPack::onPickup(%this, %obj, %shape, %amount) -{ - // created to prevent console errors +//-------------------------------------------------------------------------- +// +// +// +//-------------------------------------------------------------------------- + +datablock ShapeBaseImageData(AABarrelPackImage) +{ + mass = 10; // z0dd - ZOD, 7/17/02. Lower mass due to higher gravity. Was 15. + + shapeFile = "pack_barrel_aa.dts"; + item = AABarrelPack; + mountPoint = 1; + offset = "0 0 0"; + turretBarrel = "AABarrelLarge"; + + stateName[0] = "Idle"; + stateTransitionOnTriggerDown[0] = "Activate"; + + stateName[1] = "Activate"; + stateScript[1] = "onActivate"; + stateTransitionOnTriggerUp[1] = "Deactivate"; + + stateName[2] = "Deactivate"; + stateScript[2] = "onDeactivate"; + stateTransitionOnTimeOut[2] = "Idle"; + + isLarge = true; +}; + +datablock ItemData(AABarrelPack) +{ + className = Pack; + catagory = "Packs"; + shapeFile = "pack_barrel_aa.dts"; + mass = 1; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 2; + rotate = true; + image = "AABarrelPackImage"; + pickUpName = "an anti-aircraft barrel pack"; + + computeCRC = true; + +}; + +//AABarrelPackImage.turretBarrel = "AABarrelLarge"; + +function AABarrelPackImage::onActivate(%data, %obj, %slot) +{ + checkTurretMount(%data, %obj, %slot); +} + +function AABarrelPackImage::onDeactivate(%data, %obj, %slot) +{ + %obj.setImageTrigger($BackpackSlot, false); +} + +function AABarrelPack::onPickup(%this, %obj, %shape, %amount) +{ + // created to prevent console errors } \ No newline at end of file diff --git a/scripts/packs/buildingconstructor.cs b/scripts/packs/buildingconstructor.cs index b724fce..e78e393 100644 --- a/scripts/packs/buildingconstructor.cs +++ b/scripts/packs/buildingconstructor.cs @@ -1,129 +1,129 @@ -//--------------------------------------------------------- -// Deployable Spine, Code by Mostlikely, Prettied by JackTL -//--------------------------------------------------------- - -$TeamDeployableMax[constructorDeployable] = 1; - -datablock ShapeBaseImageData(constructorDeployableImage) { - mass = 1; - emap = true; - shapeFile = "ammo_plasma.dts"; - item = constructorDeployable; - mountPoint = 1; - offset = "0 -0.2 -0.55"; - deployed = DeployedSpine; - heatSignature = 0; - - stateName[0] = "Idle"; - stateTransitionOnTriggerDown[0] = "Activate"; - - stateName[1] = "Activate"; - stateScript[1] = "onActivate"; - stateTransitionOnTriggerUp[1] = "Idle"; - - isLarge = false; - maxDepSlope = 360; - deploySound = ItemPickupSound; - - minDeployDis = 0.1; - maxDeployDis = 50.0; -}; - -datablock ItemData(constructorDeployable) { - className = Pack; - catagory = "Deployables"; - shapeFile = "stackable1s.dts"; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 1; - rotate = true; - image = "constructorDeployableImage"; - pickUpName = "a light support beam pack"; - heatSignature = 0; - emap = true; -}; - -function constructorDeployableImage::testObjectTooClose(%item) { - return ""; -} - -function constructorDeployableImage::testNoTerrainFound(%item) { - // don't check this for non-Landspike turret deployables -} - -function constructorDeployable::onPickup(%this, %obj, %shape, %amount) { - // created to prevent console errors -} - -function constructorDeployableImage::onDeploy(%item, %plyr, %slot) { - //Object - %className = "StaticShape"; - - %grounded = 0; - if (%item.surface.getClassName() $= TerrainBlock) - %grounded = 1; - - %playerVector = vectorNormalize(-1 * getWord(%plyr.getEyeVector(),1) SPC getWord(%plyr.getEyeVector(),0) SPC "0"); - - if (%item.surfaceinher == 0) { - if (vAbs(floorVec(%item.surfaceNrm,100)) $= "0 0 1") - %item.surfaceNrm2 = %playerVector; - else - %item.surfaceNrm2 = vectorNormalize(vectorCross(%item.surfaceNrm,"0 0 1")); - } - - %item.surfaceNrm3 = vectorCross(%item.surfaceNrm,%item.surfaceNrm2); - - %rot = fullRot(%item.surfaceNrm,%item.surfaceNrm2); - %scale = getWords($packSetting["spine",%plyr.packSet],0,2); - %dataBlock = %item.deployed; - - if (%plyr.packSet == 5) { - %space = rayDist(%item.surfacePt SPC %item.surfaceNrm,%scale,$AllObjMask); - if (%space != getWord(%scale,1)) - %type = true; - %scale = getWord(%scale,0) SPC getWord(%scale,0) SPC %space; - } - else if (%plyr.packSet == 6 || %plyr.packSet == 7) { - %mCenter = "0 0 -0.5"; - %pad = pad(%item.surfacePt SPC %item.surfaceNrm SPC %item.surfaceNrm2,%scale,%mCenter); - %scale = getWords(%pad,0,2); - %item.surfacePt = getWords(%pad,3,5); - %rot = getWords(%pad,6,9); - if (%plyr.packSet == 7) { - %scale = vectorMultiply(%scale,1.845 SPC 2 SPC 1.744); // Update dfunctions.cs if changed! - %scaleIsSet = 1; - %item.surfacePt = vectorAdd(%item.surfacePt,vectorScale(%item.surfaceNrm3,0.5)); - %rot = rotAdd(%rot,"1 0 0" SPC $Pi); - %dataBlock = "DeployedWoodSpine"; - } - } - - if (!%scaleIsSet) - %scale = vectorMultiply(%scale,1/4 SPC 1/3 SPC 2); - - //Test pack -- make sure our structure is loaded - exec("data/Game/Structures/SMLCabin.cs"); - build_SMLCabin(%plyr.client,%item.surfacePt,%plyr.client.team); - - // play the deploy sound - serverPlay3D(%item.deploySound, %deplObj.getTransform()); - - %plyr.setInventory("constructorDeployable",0,1); - - return %deplObj; -} - -///////////////////////////////////// - -function constructorDeployableImage::onMount(%data, %obj, %node) { - %obj.hasSpine = true; // set for spinecheck - %obj.packSet = 0; - displayPowerFreq(%obj); -} - -function constructorDeployableImage::onUnmount(%data, %obj, %node) { - %obj.hasSpine = ""; - %obj.packSet = 0; -} +//--------------------------------------------------------- +// Deployable Spine, Code by Mostlikely, Prettied by JackTL +//--------------------------------------------------------- + +$TeamDeployableMax[constructorDeployable] = 1; + +datablock ShapeBaseImageData(constructorDeployableImage) { + mass = 1; + emap = true; + shapeFile = "ammo_plasma.dts"; + item = constructorDeployable; + mountPoint = 1; + offset = "0 -0.2 -0.55"; + deployed = DeployedSpine; + heatSignature = 0; + + stateName[0] = "Idle"; + stateTransitionOnTriggerDown[0] = "Activate"; + + stateName[1] = "Activate"; + stateScript[1] = "onActivate"; + stateTransitionOnTriggerUp[1] = "Idle"; + + isLarge = false; + maxDepSlope = 360; + deploySound = ItemPickupSound; + + minDeployDis = 0.1; + maxDeployDis = 50.0; +}; + +datablock ItemData(constructorDeployable) { + className = Pack; + catagory = "Deployables"; + shapeFile = "stackable1s.dts"; + mass = 1; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 1; + rotate = true; + image = "constructorDeployableImage"; + pickUpName = "a light support beam pack"; + heatSignature = 0; + emap = true; +}; + +function constructorDeployableImage::testObjectTooClose(%item) { + return ""; +} + +function constructorDeployableImage::testNoTerrainFound(%item) { + // don't check this for non-Landspike turret deployables +} + +function constructorDeployable::onPickup(%this, %obj, %shape, %amount) { + // created to prevent console errors +} + +function constructorDeployableImage::onDeploy(%item, %plyr, %slot) { + //Object + %className = "StaticShape"; + + %grounded = 0; + if (%item.surface.getClassName() $= TerrainBlock) + %grounded = 1; + + %playerVector = vectorNormalize(-1 * getWord(%plyr.getEyeVector(),1) SPC getWord(%plyr.getEyeVector(),0) SPC "0"); + + if (%item.surfaceinher == 0) { + if (vAbs(floorVec(%item.surfaceNrm,100)) $= "0 0 1") + %item.surfaceNrm2 = %playerVector; + else + %item.surfaceNrm2 = vectorNormalize(vectorCross(%item.surfaceNrm,"0 0 1")); + } + + %item.surfaceNrm3 = vectorCross(%item.surfaceNrm,%item.surfaceNrm2); + + %rot = fullRot(%item.surfaceNrm,%item.surfaceNrm2); + %scale = getWords($packSetting["spine",%plyr.packSet],0,2); + %dataBlock = %item.deployed; + + if (%plyr.packSet == 5) { + %space = rayDist(%item.surfacePt SPC %item.surfaceNrm,%scale,$AllObjMask); + if (%space != getWord(%scale,1)) + %type = true; + %scale = getWord(%scale,0) SPC getWord(%scale,0) SPC %space; + } + else if (%plyr.packSet == 6 || %plyr.packSet == 7) { + %mCenter = "0 0 -0.5"; + %pad = pad(%item.surfacePt SPC %item.surfaceNrm SPC %item.surfaceNrm2,%scale,%mCenter); + %scale = getWords(%pad,0,2); + %item.surfacePt = getWords(%pad,3,5); + %rot = getWords(%pad,6,9); + if (%plyr.packSet == 7) { + %scale = vectorMultiply(%scale,1.845 SPC 2 SPC 1.744); // Update dfunctions.cs if changed! + %scaleIsSet = 1; + %item.surfacePt = vectorAdd(%item.surfacePt,vectorScale(%item.surfaceNrm3,0.5)); + %rot = rotAdd(%rot,"1 0 0" SPC $Pi); + %dataBlock = "DeployedWoodSpine"; + } + } + + if (!%scaleIsSet) + %scale = vectorMultiply(%scale,1/4 SPC 1/3 SPC 2); + + //Test pack -- make sure our structure is loaded + exec("data/Game/Structures/SMLCabin.cs"); + build_SMLCabin(%plyr.client,%item.surfacePt,%plyr.client.team); + + // play the deploy sound + serverPlay3D(%item.deploySound, %deplObj.getTransform()); + + %plyr.setInventory("constructorDeployable",0,1); + + return %deplObj; +} + +///////////////////////////////////// + +function constructorDeployableImage::onMount(%data, %obj, %node) { + %obj.hasSpine = true; // set for spinecheck + %obj.packSet = 0; + displayPowerFreq(%obj); +} + +function constructorDeployableImage::onUnmount(%data, %obj, %node) { + %obj.hasSpine = ""; + %obj.packSet = 0; +} diff --git a/scripts/packs/c4.cs b/scripts/packs/c4.cs index 10ee741..6e1d962 100644 --- a/scripts/packs/c4.cs +++ b/scripts/packs/c4.cs @@ -1,314 +1,314 @@ -//-------------------------------------------------------------------------- -// C4 -// Used only in Search & Destroy gameMode -// When deployed (must be deploying on an objective) a timer is started -// When the timer runs out, objective goes boom and offence wins -// But the bomb can be defused by defence. - -//-------------------------------------------------------------------------- - -//-------------------------------------------------------------------------- -// Projectile - -//------------------------------------------------------------------------- -// shapebase datablocks -datablock ShapeBaseImageData(C4Image) -{ - shapeFile = "pack_upgrade_satchel.dts"; - item = C4Charge; - mountPoint = 1; - offset = "0 0 0"; - emap = true; -}; - -datablock ItemData(C4Charge) -{ - className = Pack; - catagory = "Packs"; - image = C4Image; - shapeFile = "pack_upgrade_satchel.dts"; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - rotate = true; - pickUpName = "a C4"; - - computeCRC = true; -}; - -datablock StaticShapeData(C4Deployed) : StaticShapeDamageProfile -{ - shapeFile = "pack_upgrade_satchel.dts"; - explosion = SatchelMainExplosion; - underwaterExplosion = UnderwaterSatchelMainExplosion; - armDelay = 2500; - maxDamage = 0.6; - - disabledLevel = 0.5; - destroyedLevel = 0.6; - dynamicType = $TypeMasks::StaticShapeObjectType; - renderWhenDestroyed = false; - - kickBackStrength = 4000; -}; - -//-------------------------------------------------------------------------- - -function C4::onUse(%this, %obj) -{ - %item = new Item() { - dataBlock = SatchelChargeTossed; - rotation = "0 0 1 " @ (getRandom() * 360); - }; - MissionCleanup.add(%item); - // take pack out of inventory and unmount image - %obj.decInventory(SatchelCharge, 1); - %obj.throwObject(%item); - %item.sourceObject = %obj; - - // z0dd - ZOD, 5/16/02. Schedule a check to see if the satchel is at rest but not stuck to anything - %item.checkCount = 0; - %item.velocCheck = %item.getDataBlock().schedule(1000, "checkVelocity", %item); -} - -function initArmSatchelCharge(%satchel) -{ - // "deet deet deet" sound - %satchel.playAudio(1, SatchelChargeActivateSound); - // also need to play "antenna extending" animation - %satchel.playThread(0, "deploy"); - %satchel.playThread(1, "activate"); - - // delay the actual arming until after sound is done playing - schedule( 2200, 0, "armSatchelCharge", %satchel ); -} - -function armSatchelCharge(%satchel) -{ - %satchel.armed = true; - commandToClient( %satchel.sourceObject.client, 'setSatchelArmed' ); -} - -function detonateSatchelCharge(%player) -{ - %satchelCharge = %player.thrownChargeId; - // can't detonate the satchel charge if it isn't armed - if(!%satchelCharge.armed) - return; - - //error("Detonating satchel charge #" @ %satchelCharge @ " for player #" @ %player); - - if(%satchelCharge.getDamageState() !$= Destroyed) - { - %satchelCharge.setDamageState(Destroyed); - %satchelCharge.blowup(); - } - - // Clear the player's HUD: - %player.client.clearBackpackIcon(); -} - -function SatchelChargeThrown::onEnterLiquid(%data, %obj, %coverage, %type) -{ - // lava types - if(%type >=4 && %type <= 6) - { - if(%obj.getDamageState() !$= "Destroyed") - { - %obj.armed = true; - detonateSatchelCharge(%obj.sourceObject); - return; - } - } - - // quickSand - if(%type == 7) - if(isObject(%obj.sourceObject)) - %obj.sourceObject.thrownChargeId = 0; - - Parent::onEnterLiquid(%data, %obj, %coverage, %type); -} - -function SatchelChargeImage::onMount(%data, %obj, %node) -{ - %obj.thrownChargeId = 0; -} - -function SatchelChargeImage::onUnmount(%data, %obj, %node) -{ -} - -function SatchelChargeThrown::onDestroyed(%this, %object, %lastState) -{ - if(%object.kaboom) - return; - else - { - %object.kaboom = true; - - // the "thwart" flag is set if the charge is destroyed with weapons rather - // than detonated. A less damaging explosion, but visually the same scale. - if(%object.thwart) - { - messageClient(%object.sourceObject.client, 'msgSatchelChargeDetonate', "\c2Satchel charge destroyed."); - %dmgRadius = 15; // z0dd - ZOD, 9/27/02. Was 10 - %dmgMod = 0.35; // z0dd - ZOD, 9/27/02. Was 0.3 - %expImpulse = 2000; // z0dd - ZOD, 9/27/02. Was 1000 - %dmgType = $DamageType::Explosion; - } - else - { - messageClient(%object.sourceObject.client, 'msgSatchelChargeDetonate', "\c2Satchel charge detonated!"); - %dmgRadius = 25; // z0dd - ZOD, 9/27/02. Was 20 - %dmgMod = 1.15; // z0dd - ZOD, 9/27/02. Was 1.0 - %expImpulse = 5000; // z0dd - ZOD, 9/27/02. Was 2500 - %dmgType = $DamageType::SatchelCharge; - } - - %object.blowingUp = true; - RadiusExplosion(%object, %object.getPosition(), %dmgRadius, %dmgMod, %expImpulse, %object.sourceObject, %dmgType); - - %object.schedule(1000, "delete"); - } - - // -------------------------------------------------------------------------------- - // z0dd - ZOD, 4/25/02. Satchel bug fix. Prior to fix, clients couldn't pick up - // packs when satchel was destroyed from dmg - if(isObject(%object.sourceObject)) - %object.sourceObject.thrownChargeId = 0; - // -------------------------------------------------------------------------------- -} - -function SatchelChargeThrown::onCollision(%data,%obj,%col) -{ - // Do nothing... -} - -function SatchelChargeThrown::damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType) -{ - if (!%object.blowingUp) - { - %targetObject.damaged += %amount; - - if(%targetObject.damaged >= %targetObject.getDataBlock().maxDamage && - %targetObject.getDamageState() !$= Destroyed) - { - %targetObject.thwart = true; - %targetObject.setDamageState(Destroyed); - %targetObject.blowup(); - - // clear the player's HUD: - %targetObject.sourceObject.client.clearBackPackIcon(); - } - } -} - -function SatchelCharge::onPickup(%this, %obj, %shape, %amount) -{ - // created to prevent console errors -} - -//************************************************************** -// STICKY SATCHEL FUNCTIONS: z0dd - ZOD, 5/16/02 -//************************************************************** - -function SatchelChargeTossed::onEnterLiquid(%data, %obj, %coverage, %type) -{ - // If it lands in lava or quicksand, delete it - if(%type >=4 && %type <= 7) - { - cancel(%obj.velocCheck); - if(isObject(%obj.sourceObject)) - %obj.sourceObject.thrownChargeId = 0; - - %obj.sourceObject.client.clearBackPackIcon(); - %obj.schedule(100, "delete"); - } - else - cancel(%obj.velocCheck); -} - -function SatchelChargeTossed::onLeaveLiquid(%data, %obj, %type) -{ - // On the off chance it passes through to air, reschedule the velocity check - %obj.checkCount = 0; - %obj.velocCheck = %obj.getDataBlock().schedule(1000, "checkVelocity", %obj); -} - -function SatchelChargeTossed::onCollision(%data, %obj, %col) -{ - // Lets keep thing from floating mid air, the check velocity should handle it afterwards - if(%col.getType() & ($TypeMasks::PlayerObjectType | $TypeMasks::VehicleObjectType | $TypeMasks::TurretObjectType)) - { - %vec = (-1.0 + getRandom() * 2.0) SPC (-1.0 + getRandom() * 2.0) SPC getRandom(); - %vec = vectorScale(%vec, 15); - %pos = %col.getWorldBoxCenter(); - %obj.applyImpulse(%pos, %vec); - } -} - -function SatchelChargeTossed::checkVelocity(%data, %item) -{ - %item.checkCount++; - if(VectorLen(%item.getVelocity()) < 0.1) - { - // Satchel has come to rest but not activated, probably on a - // staticshape (station, gen, etc) lets force activation - cancel(%item.velocCheck); - activateSatchel(posFromTransform(%item.getTransform()), rotFromTransform(%item.getTransform()), %item.sourceObject); - %item.schedule(100, "delete"); - } - else if(%item.checkCount >= 6) - { - // satchel's still moving but it's been checked several times, - // probably thrown off face of earth, delete it - cancel(%item.velocCheck); - if(isObject(%item.sourceObject)) - %item.sourceObject.thrownChargeId = 0; - - %item.sourceObject.client.clearBackPackIcon(); - %item.schedule(100, "delete"); - } - else - { - // check back in a little while - %item.velocCheck = %data.schedule(1000, "checkVelocity", %item); - } -} - -function SatchelChargeTossed::onStickyCollision(%data, %obj) -{ - // We have sticky! Lets setup for the actual charge - cancel(%obj.velocCheck); - %pos = %obj.getLastStickyPos(); - %norm = %obj.getLastStickyNormal(); - %intAngle = getTerrainAngle(%norm); - %rotAxis = vectorNormalize(vectorCross(%norm, "0 0 1")); - if (getWord(%norm, 2) == 1 || getWord(%norm, 2) == -1) - %rotAxis = vectorNormalize(vectorCross(%norm, "0 1 0")); - - %rot = %rotAxis @ " " @ %intAngle; - activateSatchel(%pos, %rot, %obj.sourceObject); - %obj.schedule(50, "delete"); -} - -function activateSatchel(%pos, %rot, %source) -{ - // Create the charge and schedule arming - %satchel = new StaticShape() { - dataBlock = SatchelChargeThrown; - sourceObject = %source; - position = %pos; - rotation = %rot; - }; - MissionCleanup.add(%satchel); - %source.thrownChargeId = %satchel; - %satchel.armed = false; - %satchel.damaged = 0.0; - %satchel.thwart = false; - - // arm itself 2.5 seconds after creation - schedule(%satchel.getDatablock().armDelay, %satchel, "initArmSatchelCharge", %satchel); - messageClient(%source.client, 'MsgSatchelChargePlaced', "\c2Satchel charge deployed."); -} +//-------------------------------------------------------------------------- +// C4 +// Used only in Search & Destroy gameMode +// When deployed (must be deploying on an objective) a timer is started +// When the timer runs out, objective goes boom and offence wins +// But the bomb can be defused by defence. + +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +// Projectile + +//------------------------------------------------------------------------- +// shapebase datablocks +datablock ShapeBaseImageData(C4Image) +{ + shapeFile = "pack_upgrade_satchel.dts"; + item = C4Charge; + mountPoint = 1; + offset = "0 0 0"; + emap = true; +}; + +datablock ItemData(C4Charge) +{ + className = Pack; + catagory = "Packs"; + image = C4Image; + shapeFile = "pack_upgrade_satchel.dts"; + mass = 1; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 2; + rotate = true; + pickUpName = "a C4"; + + computeCRC = true; +}; + +datablock StaticShapeData(C4Deployed) : StaticShapeDamageProfile +{ + shapeFile = "pack_upgrade_satchel.dts"; + explosion = SatchelMainExplosion; + underwaterExplosion = UnderwaterSatchelMainExplosion; + armDelay = 2500; + maxDamage = 0.6; + + disabledLevel = 0.5; + destroyedLevel = 0.6; + dynamicType = $TypeMasks::StaticShapeObjectType; + renderWhenDestroyed = false; + + kickBackStrength = 4000; +}; + +//-------------------------------------------------------------------------- + +function C4::onUse(%this, %obj) +{ + %item = new Item() { + dataBlock = SatchelChargeTossed; + rotation = "0 0 1 " @ (getRandom() * 360); + }; + MissionCleanup.add(%item); + // take pack out of inventory and unmount image + %obj.decInventory(SatchelCharge, 1); + %obj.throwObject(%item); + %item.sourceObject = %obj; + + // z0dd - ZOD, 5/16/02. Schedule a check to see if the satchel is at rest but not stuck to anything + %item.checkCount = 0; + %item.velocCheck = %item.getDataBlock().schedule(1000, "checkVelocity", %item); +} + +function initArmSatchelCharge(%satchel) +{ + // "deet deet deet" sound + %satchel.playAudio(1, SatchelChargeActivateSound); + // also need to play "antenna extending" animation + %satchel.playThread(0, "deploy"); + %satchel.playThread(1, "activate"); + + // delay the actual arming until after sound is done playing + schedule( 2200, 0, "armSatchelCharge", %satchel ); +} + +function armSatchelCharge(%satchel) +{ + %satchel.armed = true; + commandToClient( %satchel.sourceObject.client, 'setSatchelArmed' ); +} + +function detonateSatchelCharge(%player) +{ + %satchelCharge = %player.thrownChargeId; + // can't detonate the satchel charge if it isn't armed + if(!%satchelCharge.armed) + return; + + //error("Detonating satchel charge #" @ %satchelCharge @ " for player #" @ %player); + + if(%satchelCharge.getDamageState() !$= Destroyed) + { + %satchelCharge.setDamageState(Destroyed); + %satchelCharge.blowup(); + } + + // Clear the player's HUD: + %player.client.clearBackpackIcon(); +} + +function SatchelChargeThrown::onEnterLiquid(%data, %obj, %coverage, %type) +{ + // lava types + if(%type >=4 && %type <= 6) + { + if(%obj.getDamageState() !$= "Destroyed") + { + %obj.armed = true; + detonateSatchelCharge(%obj.sourceObject); + return; + } + } + + // quickSand + if(%type == 7) + if(isObject(%obj.sourceObject)) + %obj.sourceObject.thrownChargeId = 0; + + Parent::onEnterLiquid(%data, %obj, %coverage, %type); +} + +function SatchelChargeImage::onMount(%data, %obj, %node) +{ + %obj.thrownChargeId = 0; +} + +function SatchelChargeImage::onUnmount(%data, %obj, %node) +{ +} + +function SatchelChargeThrown::onDestroyed(%this, %object, %lastState) +{ + if(%object.kaboom) + return; + else + { + %object.kaboom = true; + + // the "thwart" flag is set if the charge is destroyed with weapons rather + // than detonated. A less damaging explosion, but visually the same scale. + if(%object.thwart) + { + messageClient(%object.sourceObject.client, 'msgSatchelChargeDetonate', "\c2Satchel charge destroyed."); + %dmgRadius = 15; // z0dd - ZOD, 9/27/02. Was 10 + %dmgMod = 0.35; // z0dd - ZOD, 9/27/02. Was 0.3 + %expImpulse = 2000; // z0dd - ZOD, 9/27/02. Was 1000 + %dmgType = $DamageType::Explosion; + } + else + { + messageClient(%object.sourceObject.client, 'msgSatchelChargeDetonate', "\c2Satchel charge detonated!"); + %dmgRadius = 25; // z0dd - ZOD, 9/27/02. Was 20 + %dmgMod = 1.15; // z0dd - ZOD, 9/27/02. Was 1.0 + %expImpulse = 5000; // z0dd - ZOD, 9/27/02. Was 2500 + %dmgType = $DamageType::SatchelCharge; + } + + %object.blowingUp = true; + RadiusExplosion(%object, %object.getPosition(), %dmgRadius, %dmgMod, %expImpulse, %object.sourceObject, %dmgType); + + %object.schedule(1000, "delete"); + } + + // -------------------------------------------------------------------------------- + // z0dd - ZOD, 4/25/02. Satchel bug fix. Prior to fix, clients couldn't pick up + // packs when satchel was destroyed from dmg + if(isObject(%object.sourceObject)) + %object.sourceObject.thrownChargeId = 0; + // -------------------------------------------------------------------------------- +} + +function SatchelChargeThrown::onCollision(%data,%obj,%col) +{ + // Do nothing... +} + +function SatchelChargeThrown::damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType) +{ + if (!%object.blowingUp) + { + %targetObject.damaged += %amount; + + if(%targetObject.damaged >= %targetObject.getDataBlock().maxDamage && + %targetObject.getDamageState() !$= Destroyed) + { + %targetObject.thwart = true; + %targetObject.setDamageState(Destroyed); + %targetObject.blowup(); + + // clear the player's HUD: + %targetObject.sourceObject.client.clearBackPackIcon(); + } + } +} + +function SatchelCharge::onPickup(%this, %obj, %shape, %amount) +{ + // created to prevent console errors +} + +//************************************************************** +// STICKY SATCHEL FUNCTIONS: z0dd - ZOD, 5/16/02 +//************************************************************** + +function SatchelChargeTossed::onEnterLiquid(%data, %obj, %coverage, %type) +{ + // If it lands in lava or quicksand, delete it + if(%type >=4 && %type <= 7) + { + cancel(%obj.velocCheck); + if(isObject(%obj.sourceObject)) + %obj.sourceObject.thrownChargeId = 0; + + %obj.sourceObject.client.clearBackPackIcon(); + %obj.schedule(100, "delete"); + } + else + cancel(%obj.velocCheck); +} + +function SatchelChargeTossed::onLeaveLiquid(%data, %obj, %type) +{ + // On the off chance it passes through to air, reschedule the velocity check + %obj.checkCount = 0; + %obj.velocCheck = %obj.getDataBlock().schedule(1000, "checkVelocity", %obj); +} + +function SatchelChargeTossed::onCollision(%data, %obj, %col) +{ + // Lets keep thing from floating mid air, the check velocity should handle it afterwards + if(%col.getType() & ($TypeMasks::PlayerObjectType | $TypeMasks::VehicleObjectType | $TypeMasks::TurretObjectType)) + { + %vec = (-1.0 + getRandom() * 2.0) SPC (-1.0 + getRandom() * 2.0) SPC getRandom(); + %vec = vectorScale(%vec, 15); + %pos = %col.getWorldBoxCenter(); + %obj.applyImpulse(%pos, %vec); + } +} + +function SatchelChargeTossed::checkVelocity(%data, %item) +{ + %item.checkCount++; + if(VectorLen(%item.getVelocity()) < 0.1) + { + // Satchel has come to rest but not activated, probably on a + // staticshape (station, gen, etc) lets force activation + cancel(%item.velocCheck); + activateSatchel(posFromTransform(%item.getTransform()), rotFromTransform(%item.getTransform()), %item.sourceObject); + %item.schedule(100, "delete"); + } + else if(%item.checkCount >= 6) + { + // satchel's still moving but it's been checked several times, + // probably thrown off face of earth, delete it + cancel(%item.velocCheck); + if(isObject(%item.sourceObject)) + %item.sourceObject.thrownChargeId = 0; + + %item.sourceObject.client.clearBackPackIcon(); + %item.schedule(100, "delete"); + } + else + { + // check back in a little while + %item.velocCheck = %data.schedule(1000, "checkVelocity", %item); + } +} + +function SatchelChargeTossed::onStickyCollision(%data, %obj) +{ + // We have sticky! Lets setup for the actual charge + cancel(%obj.velocCheck); + %pos = %obj.getLastStickyPos(); + %norm = %obj.getLastStickyNormal(); + %intAngle = getTerrainAngle(%norm); + %rotAxis = vectorNormalize(vectorCross(%norm, "0 0 1")); + if (getWord(%norm, 2) == 1 || getWord(%norm, 2) == -1) + %rotAxis = vectorNormalize(vectorCross(%norm, "0 1 0")); + + %rot = %rotAxis @ " " @ %intAngle; + activateSatchel(%pos, %rot, %obj.sourceObject); + %obj.schedule(50, "delete"); +} + +function activateSatchel(%pos, %rot, %source) +{ + // Create the charge and schedule arming + %satchel = new StaticShape() { + dataBlock = SatchelChargeThrown; + sourceObject = %source; + position = %pos; + rotation = %rot; + }; + MissionCleanup.add(%satchel); + %source.thrownChargeId = %satchel; + %satchel.armed = false; + %satchel.damaged = 0.0; + %satchel.thwart = false; + + // arm itself 2.5 seconds after creation + schedule(%satchel.getDatablock().armDelay, %satchel, "initArmSatchelCharge", %satchel); + messageClient(%source.client, 'MsgSatchelChargePlaced', "\c2Satchel charge deployed."); +} diff --git a/scripts/packs/cloakingpack.cs b/scripts/packs/cloakingpack.cs index b9ebab0..bf02f11 100644 --- a/scripts/packs/cloakingpack.cs +++ b/scripts/packs/cloakingpack.cs @@ -1,166 +1,166 @@ -// ------------------------------------------------------------------ -// CLOAKING PACK -// -// When activated, this pack cloaks the user from all visual detection -// by other players and cameras. This is a local effect only (someone standing -// next to the cloaked player will still be visible). Motion sensors will -// still detect a (moving) cloaked player. -// -// When not activated, the pack creates a localized passive sensor dampening -// field. The user will not be visible to any non-motion-detecting sensor. -// -//Only light armors may equip with this item. - -datablock EffectProfile(CloakingPackActivateEffect) -{ - effectname = "packs/cloak_on"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock AudioProfile(CloakingPackActivateSound) -{ - filename = "fx/packs/cloak_on.wav"; - description = CloseLooping3d; - preload = true; - effect = CloakingPackActivateEffect; -}; - -datablock ShapeBaseImageData(CloakingPackImage) -{ - shapeFile = "pack_upgrade_cloaking.dts"; - item = CloakingPack; - mountPoint = 1; - offset = "0 0 0"; - - usesEnergy = true; - minEnergy = 3; - - stateName[0] = "Idle"; - stateTransitionOnTriggerDown[0] = "Activate"; - - stateName[1] = "Activate"; - stateScript[1] = "onActivate"; - stateSequence[1] = "fire"; - stateSound[1] = CloakingPackActivateSound; - stateEnergyDrain[1] = 11.75; // z0dd - ZOD, 4/25/02. Improve cloak pack. Was 12 - stateTransitionOnTriggerUp[1] = "Deactivate"; - stateTransitionOnNoAmmo[1] = "Deactivate"; - - stateName[2] = "Deactivate"; - stateScript[2] = "onDeactivate"; - stateTransitionOnTimeout[2] = "Idle"; -}; - -datablock ItemData(CloakingPack) -{ - className = Pack; - catagory = "Packs"; - shapeFile = "pack_upgrade_cloaking.dts"; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - rotate = true; - image = "CloakingPackImage"; - pickUpName = "a cloaking pack"; - - computeCRC = true; - -}; - -function CloakingPackImage::onMount(%data, %obj, %node) -{ - // player is sensor-invisible while wearing pack (except to motion sensors) - %obj.setPassiveJammed(true); -} - -function CloakingPackImage::onUnmount(%data, %obj, %node) -{ - %obj.setPassiveJammed(false); - %obj.setCloaked(false); - %obj.setImageTrigger(%node, false); -} - -// make player completely invisible to all players/sensors (except motion) -function CloakingPackImage::onActivate(%data, %obj, %slot) -{ - if(%obj.reCloak !$= "") - { - Cancel(%obj.reCloak); - %obj.reCloak = ""; - } - - if(%obj.client.armor $= "Light") - { - // can the player currently cloak (function returns "true" or reason for failure)? - if(%obj.canCloak() $= "true") - { - messageClient(%obj.client, 'MsgCloakingPackOn', '\c2Cloaking pack on.'); - %obj.setCloaked(true); - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - commandToClient( %obj.client, 'setCloakIconOn' ); - } - else - { - // notify player that they cannot cloak - messageClient(%obj.client, 'MsgCloakingPackFailed', '\c2Jamming field prevents cloaking.'); - %obj.setImageTrigger(%slot, false); - } - } - else - { - // hopefully avoid some loopholes - messageClient(%obj.client, 'MsgCloakingPackInvalid', '\c2Cloaking available for light armors only.'); - %obj.setImageTrigger(%slot, false); - } -} - -function CloakingPackImage::onDeactivate(%data, %obj, %slot) -{ - if(%obj.reCloak !$= "") - { - Cancel(%obj.reCloak); - %obj.reCloak = ""; - } - - // if pack is not on then dont bother... - if(%obj.getImageState($BackpackSlot) $= "activate") - messageClient(%obj.client, 'MsgCloakingPackOff', '\c2Cloaking pack off.'); - - %obj.setCloaked(false); - %obj.setImageTrigger(%slot, false); - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - commandToClient( %obj.client, 'setCloakIconOff' ); -} - -function CloakingPack::onPickup(%this, %obj, %shape, %amount) -{ - // created to prevent console errors -} - -function ShapeBaseData::onForceUncloak(%this, %obj, %reason) -{ - // dummy -} - -function Armor::onForceUncloak(%this, %obj, %reason) -{ - %pack = %obj.getMountedImage($BackpackSlot); - if((%pack <= 0) || (%pack.item !$= "CloakingPack")) - return; - - if(%obj.getImageState($BackpackSlot) $= "activate") - { - // cancel recloak thread - if(%obj.reCloak !$= "") - { - Cancel(%obj.reCloak); - %obj.reCloak = ""; - } - - messageClient(%obj.client, 'MsgCloakingPackOff', '\c2Cloaking pack off. Jammed.'); - %obj.setCloaked(false); - %obj.setImageTrigger($BackpackSlot, false); - } +// ------------------------------------------------------------------ +// CLOAKING PACK +// +// When activated, this pack cloaks the user from all visual detection +// by other players and cameras. This is a local effect only (someone standing +// next to the cloaked player will still be visible). Motion sensors will +// still detect a (moving) cloaked player. +// +// When not activated, the pack creates a localized passive sensor dampening +// field. The user will not be visible to any non-motion-detecting sensor. +// +//Only light armors may equip with this item. + +datablock EffectProfile(CloakingPackActivateEffect) +{ + effectname = "packs/cloak_on"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock AudioProfile(CloakingPackActivateSound) +{ + filename = "fx/packs/cloak_on.wav"; + description = CloseLooping3d; + preload = true; + effect = CloakingPackActivateEffect; +}; + +datablock ShapeBaseImageData(CloakingPackImage) +{ + shapeFile = "pack_upgrade_cloaking.dts"; + item = CloakingPack; + mountPoint = 1; + offset = "0 0 0"; + + usesEnergy = true; + minEnergy = 3; + + stateName[0] = "Idle"; + stateTransitionOnTriggerDown[0] = "Activate"; + + stateName[1] = "Activate"; + stateScript[1] = "onActivate"; + stateSequence[1] = "fire"; + stateSound[1] = CloakingPackActivateSound; + stateEnergyDrain[1] = 11.75; // z0dd - ZOD, 4/25/02. Improve cloak pack. Was 12 + stateTransitionOnTriggerUp[1] = "Deactivate"; + stateTransitionOnNoAmmo[1] = "Deactivate"; + + stateName[2] = "Deactivate"; + stateScript[2] = "onDeactivate"; + stateTransitionOnTimeout[2] = "Idle"; +}; + +datablock ItemData(CloakingPack) +{ + className = Pack; + catagory = "Packs"; + shapeFile = "pack_upgrade_cloaking.dts"; + mass = 1; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 2; + rotate = true; + image = "CloakingPackImage"; + pickUpName = "a cloaking pack"; + + computeCRC = true; + +}; + +function CloakingPackImage::onMount(%data, %obj, %node) +{ + // player is sensor-invisible while wearing pack (except to motion sensors) + %obj.setPassiveJammed(true); +} + +function CloakingPackImage::onUnmount(%data, %obj, %node) +{ + %obj.setPassiveJammed(false); + %obj.setCloaked(false); + %obj.setImageTrigger(%node, false); +} + +// make player completely invisible to all players/sensors (except motion) +function CloakingPackImage::onActivate(%data, %obj, %slot) +{ + if(%obj.reCloak !$= "") + { + Cancel(%obj.reCloak); + %obj.reCloak = ""; + } + + if(%obj.client.armor $= "Light") + { + // can the player currently cloak (function returns "true" or reason for failure)? + if(%obj.canCloak() $= "true") + { + messageClient(%obj.client, 'MsgCloakingPackOn', '\c2Cloaking pack on.'); + %obj.setCloaked(true); + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + commandToClient( %obj.client, 'setCloakIconOn' ); + } + else + { + // notify player that they cannot cloak + messageClient(%obj.client, 'MsgCloakingPackFailed', '\c2Jamming field prevents cloaking.'); + %obj.setImageTrigger(%slot, false); + } + } + else + { + // hopefully avoid some loopholes + messageClient(%obj.client, 'MsgCloakingPackInvalid', '\c2Cloaking available for light armors only.'); + %obj.setImageTrigger(%slot, false); + } +} + +function CloakingPackImage::onDeactivate(%data, %obj, %slot) +{ + if(%obj.reCloak !$= "") + { + Cancel(%obj.reCloak); + %obj.reCloak = ""; + } + + // if pack is not on then dont bother... + if(%obj.getImageState($BackpackSlot) $= "activate") + messageClient(%obj.client, 'MsgCloakingPackOff', '\c2Cloaking pack off.'); + + %obj.setCloaked(false); + %obj.setImageTrigger(%slot, false); + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + commandToClient( %obj.client, 'setCloakIconOff' ); +} + +function CloakingPack::onPickup(%this, %obj, %shape, %amount) +{ + // created to prevent console errors +} + +function ShapeBaseData::onForceUncloak(%this, %obj, %reason) +{ + // dummy +} + +function Armor::onForceUncloak(%this, %obj, %reason) +{ + %pack = %obj.getMountedImage($BackpackSlot); + if((%pack <= 0) || (%pack.item !$= "CloakingPack")) + return; + + if(%obj.getImageState($BackpackSlot) $= "activate") + { + // cancel recloak thread + if(%obj.reCloak !$= "") + { + Cancel(%obj.reCloak); + %obj.reCloak = ""; + } + + messageClient(%obj.client, 'MsgCloakingPackOff', '\c2Cloaking pack off. Jammed.'); + %obj.setCloaked(false); + %obj.setImageTrigger($BackpackSlot, false); + } } \ No newline at end of file diff --git a/scripts/packs/miningTool.cs b/scripts/packs/miningTool.cs index 53dda55..2b93f58 100644 --- a/scripts/packs/miningTool.cs +++ b/scripts/packs/miningTool.cs @@ -1,617 +1,617 @@ -//-------------------------------------------------------------------------- -// Mining Tool -// can be used by any armor type -// when activated, gives user a "mining tool" that can be used to -// mine rocks that contain various minerals that can be sold or -// used by miner to build weapons, armor, and other objects. -// -// Note: Although this could've been intergrated into the repair gun -// somehow (technically still repairs), it's been built as a seperate -// pack for "balancing". - -//-------------------------------------------------------------------------- -// Projectile - -datablock RepairProjectileData(MiningBeam) -{ - sound = RepairPackFireSound; - - beamRange = 10; - beamWidth = 0.33; - numSegments = 20; - texRepeat = 0.20; - blurFreq = 10.0; - blurLifetime = 1.0; - cutoffAngle = 25.0; - - textures[0] = "special/ELFBeam"; - textures[1] = "special/BlueImpact"; - -}; - - -//------------------------------------------------------------------------- -// shapebase datablocks - -datablock ShapeBaseImageData(MiningToolImage) -{ - shapeFile = "pack_upgrade_repair.dts"; - item = MiningTool; - mountPoint = 1; - offset = "0 0 0"; - emap = true; - - gun = MiningToolGunImage; - - stateName[0] = "Idle"; - stateTransitionOnTriggerDown[0] = "Activate"; - - stateName[1] = "Activate"; - stateScript[1] = "onActivate"; - stateSequence[1] = "fire"; - stateSound[1] = RepairPackActivateSound; - stateTransitionOnTriggerUp[1] = "Deactivate"; - - stateName[2] = "Deactivate"; - stateScript[2] = "onDeactivate"; - stateTransitionOnTimeout[2] = "Idle"; -}; - -datablock ItemData(MiningTool) -{ - className = Pack; - catagory = "Packs"; - shapeFile = "pack_upgrade_repair.dts"; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - rotate = true; - image = "MiningToolImage"; - pickUpName = "a mining tool"; - - lightOnlyStatic = true; - lightType = "PulsingLight"; - lightColor = "0 0 1 0"; - lightTime = 1200; - lightRadius = 2.5; //It's just a mining tool folks.. - - computeCRC = true; - emap = true; -}; - -//-------------------------------------------------------------------------- -// Mining Gun - -datablock ShapeBaseImageData(MiningToolGunImage) -{ - shapeFile = "weapon_repair.dts"; - offset = "0 0 0"; - - usesEnergy = true; - minEnergy = 3; - cutOffEnergy = 3.1; - emap = true; - - repairFactorPlayer = 0.002; // <--- attention DaveG! - repairFactorObject = 0.004; // <--- attention DaveG! - - stateName[0] = "Activate"; - stateTransitionOnTimeout[0] = "ActivateReady"; - stateTimeoutValue[0] = 0.25; - - stateName[1] = "ActivateReady"; - stateScript[1] = "onActivateReady"; - stateSpinThread[1] = Stop; - stateTransitionOnAmmo[1] = "Ready"; - stateTransitionOnNoAmmo[1] = "ActivateReady"; - - stateName[2] = "Ready"; - stateSpinThread[2] = Stop; - stateTransitionOnNoAmmo[2] = "Deactivate"; - stateTransitionOnTriggerDown[2] = "Validate"; - - stateName[3] = "Validate"; - stateTransitionOnTimeout[3] = "Validate"; - stateTimeoutValue[3] = 0.2; - stateEnergyDrain[3] = 3; - stateSpinThread[3] = SpinUp; - stateScript[3] = "onValidate"; - stateIgnoreLoadedForReady[3] = true; - stateTransitionOnLoaded[3] = "Mine"; - stateTransitionOnNoAmmo[3] = "Deactivate"; - stateTransitionOnTriggerUp[3] = "Deactivate"; - - stateName[4] = "Mine"; - stateSound[4] = RepairPackFireSound; - stateScript[4] = "onMine"; - stateSpinThread[4] = FullSpeed; - stateAllowImageChange[4] = false; - stateSequence[4] = "activate"; - stateFire[4] = true; - stateEnergyDrain[4] = 9; - stateTimeoutValue[4] = 0.2; - stateTransitionOnTimeOut[4] = "Mine"; - stateTransitionOnNoAmmo[4] = "Deactivate"; - stateTransitionOnTriggerUp[4] = "Deactivate"; - stateTransitionOnNotLoaded[4] = "Validate"; - - stateName[5] = "Deactivate"; - stateScript[5] = "onDeactivate"; - stateSpinThread[5] = SpinDown; - stateSequence[5] = "activate"; - stateDirection[5] = false; - stateTimeoutValue[5] = 0.2; - stateTransitionOnTimeout[5] = "ActivateReady"; -}; - -function MiningToolImage::onUnmount(%data, %obj, %node) -{ - // dismount the mining gun if the player had it mounted - // need the extra "if" statement to avoid a console error message - if(%obj.getMountedImage($WeaponSlot)) - if(%obj.getMountedImage($WeaponSlot).getName() $= "MiningToolGunImage") - %obj.unmountImage($WeaponSlot); - // if the player was repairing something when the pack was thrown, stop repairing it - if(%obj.repairing != 0) - stopMining(%obj); -} - -function MiningToolImage::onActivate(%data, %obj, %slot) -{ - // don't activate the pack if player is piloting a vehicle - if(%obj.isPilot()) - { - %obj.setImageTrigger(%slot, false); - return; - } - - if(!isObject(%obj.getMountedImage($WeaponSlot)) || %obj.getMountedImage($WeaponSlot).getName() !$= "MiningToolGunImage") - { - messageClient(%obj.client, 'MsgRepairPackOn', '\c2Mining Tool activated.'); - - // make sure player's arm thread is "look" - %obj.setArmThread(look); - - // mount the repair gun - %obj.mountImage(MiningToolGunImage, $WeaponSlot); - // clientCmdsetRepairReticle found in hud.cs - commandToClient(%obj.client, 'setRepairReticle'); - } -} - -function MiningToolImage::onDeactivate(%data, %obj, %slot) -{ - //called when the player hits the "pack" key again (toggle) - %obj.setImageTrigger(%slot, false); - // if mining gun was mounted, unmount it - if(%obj.getMountedImage($WeaponSlot).getName() $= "MiningToolGunImage") - %obj.unmountImage($WeaponSlot); -} - -function MiningToolGunImage::onMount(%this,%obj,%slot) -{ - %obj.setImageAmmo(%slot,true); - if ( !isDemo() ) - commandToClient( %obj.client, 'setRepairPackIconOn' ); -} - -function MiningToolGunImage::onUnmount(%this,%obj,%slot) -{ - // called when player switches to another weapon - - // stop mining whatever player was mining - if(%obj.repairing) - stopMining(%obj); - - %obj.setImageTrigger(%slot, false); - // "turn off" the mining tool -- player needs to hit the "pack" key to - // activate the mining gun again - %obj.setImageTrigger($BackpackSlot, false); - if ( !isDemo() ) - commandToClient( %obj.client, 'setRepairPackIconOff' ); -} - -function MiningToolGunImage::onActivateReady(%this,%obj,%slot) -{ - %obj.errMsgSent = false; - %obj.selfRepairing = false; - %obj.repairing = 0; - %obj.setImageLoaded(%slot, false); -} - -function MiningToolGunImage::onValidate(%this,%obj,%slot) -{ - // this = miningtoolimage datablock - // obj = player wielding the repair gun - // slot = weapon slot - - if(%obj.getEnergyLevel() <= %this.cutOffEnergy) - { - stopMining(%obj); - return; - } - %repGun = %obj.getMountedImage(%slot); - // muzVec is the vector coming from the mining gun's "muzzle" - %muzVec = %obj.getMuzzleVector(%slot); - // muzNVec = normalized muzVec - %muzNVec = VectorNormalize(%muzVec); - %repairRange = DefaultRepairBeam.beamRange; - // scale muzNVec to the range the mining beam can reach - %muzScaled = VectorScale(%muzNVec, %repairRange); - // muzPoint = the actual point of the gun's "muzzle" - %muzPoint = %obj.getMuzzlePoint(%slot); - // rangeEnd = muzzle point + length of beam - %rangeEnd = VectorAdd(%muzPoint, %muzScaled); - // search for just about anything that can be damaged as well as interiors - %searchMasks = $TypeMasks::StaticShapeObjectType; - // search for objects within the beam's range that fit the masks above - %scanTarg = ContainerRayCast(%muzPoint, %rangeEnd, %searchMasks, %obj); - // screen out interiors - if(%scanTarg && !(%scanTarg.getType() & $TypeMasks::InteriorObjectType)) - { - // a target in range was found - %repTgt = firstWord(%scanTarg); - // is the prospective target damaged? - if(%repTgt.notRepairable) - { - // this is an object that cant be mined at all - // -- mission specific flag set on the object - if(!%obj.errMsgSent) - { - messageClient(%obj.client, 'MsgRepairPackIrrepairable', '\c2Target cannot be mined.', %repTgt); - %obj.errMsgSent = true; - } - // if player was repairing something, stop the repairs -- we're done - if(%obj.repairing) - stopMining(%obj); - } - else if(%repTgt.getDamageLevel()) - { - // yes, it's damaged - if(%repTgt != %obj.repairing) - { - if(isObject(%obj.repairing)) - stopMining(%obj); - - %obj.repairing = %repTgt; - } - // setting imageLoaded to true sends us to repair state (function onRepair) - %obj.setImageLoaded(%slot, true); - } - else - { - // there is a target in range, but it's not damaged - if(!%obj.errMsgSent) - { - // if the target isn't damaged, send a message to that effect only once - messageClient(%obj.client, 'MsgRepairPackNotDamaged', '\c2Target is not damaged.', %repTgt); - %obj.errMsgSent = true; - } - // if player was repairing something, stop the repairs -- we're done - if(%obj.repairing) - stopMining(%obj); - } - } - - //AI hack - too many things influence the aiming, so I'm going to force the repair object for bots only - else if (%obj.client.isAIControlled() && isObject(%obj.client.repairObject)) - { - %repTgt = %obj.client.repairObject; - %repPoint = %repTgt.getAIRepairPoint(); - if (%repPoint $= "0 0 0") - %repPoint = %repTgt.getWorldBoxCenter(); - %repTgtVector = VectorNormalize(VectorSub(%muzPoint, %repPoint)); - %aimVector = VectorNormalize(VectorSub(%muzPoint, %rangeEnd)); - - //if the dot product is very close (ie. we're aiming in the right direction) - if (VectorDot(%repTgtVector, %aimVector) > 0.85) - { - //do an LOS to make sure nothing is in the way... - %scanTarg = ContainerRayCast(%muzPoint, %repPoint, %searchMasks, %obj); - if (firstWord(%scanTarg) == %repTgt) - { - // yes, it's damaged - - if(isObject(%obj.repairing)) - stopMining(%obj); - - %obj.repairing = %repTgt; - // setting imageLoaded to true sends us to repair state (function onRepair) - %obj.setImageLoaded(%slot, true); - } - } - } - else if(%obj.getDamageLevel()) - { - // there is no target in range, but the player is damaged - // check to see if we were repairing something before -- if so, stop repairing old target - if(%obj.repairing != 0) - if(%obj.repairing != %obj) - stopMining(%obj); - if(isObject(%obj.repairing)) - stopMining(%obj); - - %obj.repairing = %obj; - // quick, to onRepair! - %obj.setImageLoaded(%slot, true); - } - else - { - // there is no target in range, and the player isn't damaged - if(!%obj.errMsgSent) - { - // send an error message only once - messageClient(%obj.client, 'MsgRepairPackNoTarget', '\c2No target to mine.'); - %obj.errMsgSent = true; - } - stopMining(%obj); - } -} - -function MiningToolGunImage::onMine(%this,%obj,%slot) -{ - // this = repairgunimage datablock - // obj = player wielding the repair gun - // slot = weapon slot - - if(%obj.getEnergyLevel() <= %this.cutOffEnergy) - { - stopMining(%obj); - return; - } - // reset the flag that indicates an error message has been sent - %obj.errMsgSent = false; - %target = %obj.repairing; - if(!%target) - { - // no target -- whoops! never mind - stopMining(%obj); - } - - else - { - // make sure we still have a target -- more vector fun!!! - %muzVec = %obj.getMuzzleVector(%slot); - %muzNVec = VectorNormalize(%muzVec); - %repairRange = DefaultRepairBeam.beamRange; - %muzScaled = VectorScale(%muzNVec, %repairRange); - %muzPoint = %obj.getMuzzlePoint(%slot); - %rangeEnd = VectorAdd(%muzPoint, %muzScaled); - - %searchMasks = $TypeMasks::StaticShapeObjectType; - - //AI hack to help "fudge" the repairing stuff... - if (%obj.client.isAIControlled() && isObject(%obj.client.repairObject) && %obj.client.repairObject == %obj.repairing) - { - %repTgt = %obj.client.repairObject; - %repPoint = %repTgt.getAIRepairPoint(); - if (%repPoint $= "0 0 0") - %repPoint = %repTgt.getWorldBoxCenter(); - %repTgtVector = VectorNormalize(VectorSub(%muzPoint, %repPoint)); - %aimVector = VectorNormalize(VectorSub(%muzPoint, %rangeEnd)); - - //if the dot product is very close (ie. we're aiming in the right direction) - if (VectorDot(%repTgtVector, %aimVector) > 0.85) - %scanTarg = ContainerRayCast(%muzPoint, %repPoint, %searchMasks, %obj); - } - else - %scanTarg = ContainerRayCast(%muzPoint, %rangeEnd, %searchMasks, %obj); - - if (%scanTarg) - { - %pos = getWords(%scanTarg, 1, 3); - %obstructMask = $TypeMasks::InteriorObjectType | $TypeMasks::TerrainObjectType; - %obstruction = ContainerRayCast(%muzPoint, %pos, %obstructMask, %obj); - if (%obstruction) - %scanTarg = "0"; - } - - if(%scanTarg) - { - // there's still a target out there - %repTgt = firstWord(%scanTarg); - - if (%repTgt.mineral $= "") - { - messageClient(%obj.client, 'MsgMineFail',"\c2Rock is empty as of now. Check back later."); - %obj.errMsgSent = true; - stopMining(%obj); - return; - } - - // is the target damaged? - if(%repTgt.getDamageLevel()) - { - %obj.client.collected = %obj.client.collected + %obj.getRepairRate() + MiningToolGunImage.repairFactorPlayer; - %obj.client.units[%obj.repairing.mineral] = %obj.client.units[%obj.repairing.mineral] + %obj.client.collected; - if(%repTgt != %obj.repairing) - { - // the target is not the same as the one we were just repairing - // stop repairing old target, start repairing new target - stopRepairing(%obj); - if(isObject(%obj.repairing)) - stopRepairing(%obj); - - %obj.repairing = %repTgt; - // extract the name of what player is repairing based on what it is - // if it's a player, it's the player's name (duh) - // if it's an object, look for a nametag - // if object has no nametag, just say what it is (e.g. generatorLarge) - if(%repTgt.getClassName() $= Player) - %tgtName = getTaggedString(%repTgt.client.name); - else if(%repTgt.getGameName() !$= "") - %tgtName = %repTgt.getGameName(); - else - %tgtName = %repTgt.getDatablock().getName(); - messageClient(%obj.client, 'MsgRepairPackRepairingObj', '\c2Mining rock.. (%3)', %tgtName, %repTgt, %repTgt.mineral); - startMining(%obj, false); - } - else - { - // it's the same target as last time - // changed to fix "2 players can't repair same object" bug - if(%obj.repairProjectile == 0) - { - if(%repTgt.getClassName() $= Player) - %tgtName = getTaggedString(%repTgt.client.name); - else if(%repTgt.getGameName() !$= "") - %tgtName = %repTgt.getGameName(); - else - %tgtName = %repTgt.getDatablock().getName(); - messageClient(%obj.client, 'MsgRepairPackRepairingObj', '\c2Mining Rock.. (%3)', %tgtName, %repTgt, %repTgt.mineral); - startMining(%obj, false); - } - } - } - else - { - %rateOfRepair = %this.repairFactorObject; - if(%repTgt.getClassName() $= Player) - { - %tgtName = getTaggedString(%repTgt.client.name); - %rateOfRepair = %this.repairFactorPlayer; - } - else if(%repTgt.getGameName() !$= "") - %tgtName = %repTgt.getGameName(); - else - %tgtName = %repTgt.getDatablock().getName(); - if(%repTgt != %obj.repairing) - { - // it isn't the same object we were repairing previously - messageClient(%obj.client, 'MsgRepairPackNotDamaged', '\c2%1 is not damaged.', %tgtName); - } - else - { - // same target, but not damaged -- we must be done - messageClient(%obj.client, 'MsgRepairPackDone', '\c2Rock ran out of minerals.'); - stopMining(%obj); //Push this through to make sure client gets minerals.. - Game.objectRepaired(%repTgt, %tgtName); - } - %obj.errMsgSent = true; - stopMining(%obj); - } - } - else - { - // whoops, we lost our target - messageClient(%obj.client, 'MsgRepairPackLostTarget', '\c2No target to mine.'); - stopMining(%obj); - } - } - } - - -function MiningToolGunImage::onDeactivate(%this,%obj,%slot) -{ - stopMining(%obj); -} - -function stopMining(%player) -{ - // %player = the player who was using the repair pack - - if(%player.selfRepairing) - { - // there is no projectile for self-repairing - %player.setRepairRate(%player.getRepairRate() - %player.repairingRate); - %player.selfRepairing = false; - } - else if(%player.repairing > 0) - { - // player was repairing something else - //if(%player.repairing.beingRepaired > 0) - //{ - // don't decrement this stuff if it's already at 0 -- though it shouldn't be - //%player.repairing.beingRepaired--; - %player.repairing.setRepairRate(%player.repairing.getRepairRate() - %player.repairingRate); - //} - if(%player.repairProjectile > 0) - { - // is there a repair projectile? delete it - %player.repairProjectile.delete(); - %player.repairProjectile = 0; - } - } - - if (!%player.errMsgSent && isObject(%player.repairing) && %player.repairing.mineral !$= "") //Ok, player stopped mining. Give the player his/her WTF they mined. - { - %client = %player.client; - %mineral = %player.repairing.mineral; - %collected = %player.client.collected; - %total = %client.units[%mineral]; - %obj = %player.repairing; - - messageClient(%player.client,'msgMiningCollect','\c2Collected %1 units of %2. You now have %3 units of %2.',%collected,%mineral,%total); - } - - %player.client.collected = 0; - %player.repairing = 0; - %player.repairingRate = 0; - %player.setImageTrigger($WeaponSlot, false); - %player.setImageLoaded($WeaponSlot, false); -} - -function startMining(%player, %self) -{ - // %player = the player who was using the repair pack - // %self = boolean -- is player repairing him/herself? - - if(%self) - { - // one repair, hold the projectile - %player.setRepairRate(%player.getRepairRate() + MiningToolGunImage.repairFactorPlayer); - %player.selfRepairing = true; - %player.repairingRate = MiningToolGunImage.repairFactorPlayer; - } - else - { - //if(%player.repairing.beingRepaired $= "") - // %player.repairing.beingRepaired = 1; - //else - // %player.repairing.beingRepaired++; - - //AI hack... - if (%player.client.isAIControlled() && %player.client.repairObject == %player.repairing) - { - %initialPosition = %player.getMuzzlePoint($WeaponSlot); - %initialDirection = VectorSub(%initialPosition, %player.repairing.getWorldBoxCenter()); - } - else - { - %initialDirection = %player.getMuzzleVector($WeaponSlot); - %initialPosition = %player.getMuzzlePoint($WeaponSlot); - } - if(%player.repairing.getClassName() $= Player) - %repRate = RepairGunImage.repairFactorPlayer; - else - %repRate = RepairGunImage.repairFactorObject; - %player.repairing.setRepairRate(%player.repairing.getRepairRate() + %repRate); - - %player.repairingRate = %repRate; - %player.repairProjectile = new RepairProjectile() { - dataBlock = MiningBeam; - initialDirection = %initialDirection; - initialPosition = %initialPosition; - sourceObject = %player; - sourceSlot = $WeaponSlot; - targetObject = %player.repairing; - }; - // ---------------------------------------------------- - // z0dd - ZOD, 5/27/02. Fix lingering projectile bug - if(isObject(%player.lastProjectile)) - %player.lastProjectile.delete(); - - %player.HP = %player.repairing.getDamageLevel(); //Is used when player stops 'mining' - - %player.lastProjectile = %player.repairProjectile; - // End z0dd - ZOD - // ---------------------------------------------------- - MissionCleanup.add(%player.repairProjectile); - } -} - -function MiningTool::onPickup(%this, %obj, %shape, %amount) -{ - // created to prevent console errors -} +//-------------------------------------------------------------------------- +// Mining Tool +// can be used by any armor type +// when activated, gives user a "mining tool" that can be used to +// mine rocks that contain various minerals that can be sold or +// used by miner to build weapons, armor, and other objects. +// +// Note: Although this could've been intergrated into the repair gun +// somehow (technically still repairs), it's been built as a seperate +// pack for "balancing". + +//-------------------------------------------------------------------------- +// Projectile + +datablock RepairProjectileData(MiningBeam) +{ + sound = RepairPackFireSound; + + beamRange = 10; + beamWidth = 0.33; + numSegments = 20; + texRepeat = 0.20; + blurFreq = 10.0; + blurLifetime = 1.0; + cutoffAngle = 25.0; + + textures[0] = "special/ELFBeam"; + textures[1] = "special/BlueImpact"; + +}; + + +//------------------------------------------------------------------------- +// shapebase datablocks + +datablock ShapeBaseImageData(MiningToolImage) +{ + shapeFile = "pack_upgrade_repair.dts"; + item = MiningTool; + mountPoint = 1; + offset = "0 0 0"; + emap = true; + + gun = MiningToolGunImage; + + stateName[0] = "Idle"; + stateTransitionOnTriggerDown[0] = "Activate"; + + stateName[1] = "Activate"; + stateScript[1] = "onActivate"; + stateSequence[1] = "fire"; + stateSound[1] = RepairPackActivateSound; + stateTransitionOnTriggerUp[1] = "Deactivate"; + + stateName[2] = "Deactivate"; + stateScript[2] = "onDeactivate"; + stateTransitionOnTimeout[2] = "Idle"; +}; + +datablock ItemData(MiningTool) +{ + className = Pack; + catagory = "Packs"; + shapeFile = "pack_upgrade_repair.dts"; + mass = 1; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 2; + rotate = true; + image = "MiningToolImage"; + pickUpName = "a mining tool"; + + lightOnlyStatic = true; + lightType = "PulsingLight"; + lightColor = "0 0 1 0"; + lightTime = 1200; + lightRadius = 2.5; //It's just a mining tool folks.. + + computeCRC = true; + emap = true; +}; + +//-------------------------------------------------------------------------- +// Mining Gun + +datablock ShapeBaseImageData(MiningToolGunImage) +{ + shapeFile = "weapon_repair.dts"; + offset = "0 0 0"; + + usesEnergy = true; + minEnergy = 3; + cutOffEnergy = 3.1; + emap = true; + + repairFactorPlayer = 0.002; // <--- attention DaveG! + repairFactorObject = 0.004; // <--- attention DaveG! + + stateName[0] = "Activate"; + stateTransitionOnTimeout[0] = "ActivateReady"; + stateTimeoutValue[0] = 0.25; + + stateName[1] = "ActivateReady"; + stateScript[1] = "onActivateReady"; + stateSpinThread[1] = Stop; + stateTransitionOnAmmo[1] = "Ready"; + stateTransitionOnNoAmmo[1] = "ActivateReady"; + + stateName[2] = "Ready"; + stateSpinThread[2] = Stop; + stateTransitionOnNoAmmo[2] = "Deactivate"; + stateTransitionOnTriggerDown[2] = "Validate"; + + stateName[3] = "Validate"; + stateTransitionOnTimeout[3] = "Validate"; + stateTimeoutValue[3] = 0.2; + stateEnergyDrain[3] = 3; + stateSpinThread[3] = SpinUp; + stateScript[3] = "onValidate"; + stateIgnoreLoadedForReady[3] = true; + stateTransitionOnLoaded[3] = "Mine"; + stateTransitionOnNoAmmo[3] = "Deactivate"; + stateTransitionOnTriggerUp[3] = "Deactivate"; + + stateName[4] = "Mine"; + stateSound[4] = RepairPackFireSound; + stateScript[4] = "onMine"; + stateSpinThread[4] = FullSpeed; + stateAllowImageChange[4] = false; + stateSequence[4] = "activate"; + stateFire[4] = true; + stateEnergyDrain[4] = 9; + stateTimeoutValue[4] = 0.2; + stateTransitionOnTimeOut[4] = "Mine"; + stateTransitionOnNoAmmo[4] = "Deactivate"; + stateTransitionOnTriggerUp[4] = "Deactivate"; + stateTransitionOnNotLoaded[4] = "Validate"; + + stateName[5] = "Deactivate"; + stateScript[5] = "onDeactivate"; + stateSpinThread[5] = SpinDown; + stateSequence[5] = "activate"; + stateDirection[5] = false; + stateTimeoutValue[5] = 0.2; + stateTransitionOnTimeout[5] = "ActivateReady"; +}; + +function MiningToolImage::onUnmount(%data, %obj, %node) +{ + // dismount the mining gun if the player had it mounted + // need the extra "if" statement to avoid a console error message + if(%obj.getMountedImage($WeaponSlot)) + if(%obj.getMountedImage($WeaponSlot).getName() $= "MiningToolGunImage") + %obj.unmountImage($WeaponSlot); + // if the player was repairing something when the pack was thrown, stop repairing it + if(%obj.repairing != 0) + stopMining(%obj); +} + +function MiningToolImage::onActivate(%data, %obj, %slot) +{ + // don't activate the pack if player is piloting a vehicle + if(%obj.isPilot()) + { + %obj.setImageTrigger(%slot, false); + return; + } + + if(!isObject(%obj.getMountedImage($WeaponSlot)) || %obj.getMountedImage($WeaponSlot).getName() !$= "MiningToolGunImage") + { + messageClient(%obj.client, 'MsgRepairPackOn', '\c2Mining Tool activated.'); + + // make sure player's arm thread is "look" + %obj.setArmThread(look); + + // mount the repair gun + %obj.mountImage(MiningToolGunImage, $WeaponSlot); + // clientCmdsetRepairReticle found in hud.cs + commandToClient(%obj.client, 'setRepairReticle'); + } +} + +function MiningToolImage::onDeactivate(%data, %obj, %slot) +{ + //called when the player hits the "pack" key again (toggle) + %obj.setImageTrigger(%slot, false); + // if mining gun was mounted, unmount it + if(%obj.getMountedImage($WeaponSlot).getName() $= "MiningToolGunImage") + %obj.unmountImage($WeaponSlot); +} + +function MiningToolGunImage::onMount(%this,%obj,%slot) +{ + %obj.setImageAmmo(%slot,true); + if ( !isDemo() ) + commandToClient( %obj.client, 'setRepairPackIconOn' ); +} + +function MiningToolGunImage::onUnmount(%this,%obj,%slot) +{ + // called when player switches to another weapon + + // stop mining whatever player was mining + if(%obj.repairing) + stopMining(%obj); + + %obj.setImageTrigger(%slot, false); + // "turn off" the mining tool -- player needs to hit the "pack" key to + // activate the mining gun again + %obj.setImageTrigger($BackpackSlot, false); + if ( !isDemo() ) + commandToClient( %obj.client, 'setRepairPackIconOff' ); +} + +function MiningToolGunImage::onActivateReady(%this,%obj,%slot) +{ + %obj.errMsgSent = false; + %obj.selfRepairing = false; + %obj.repairing = 0; + %obj.setImageLoaded(%slot, false); +} + +function MiningToolGunImage::onValidate(%this,%obj,%slot) +{ + // this = miningtoolimage datablock + // obj = player wielding the repair gun + // slot = weapon slot + + if(%obj.getEnergyLevel() <= %this.cutOffEnergy) + { + stopMining(%obj); + return; + } + %repGun = %obj.getMountedImage(%slot); + // muzVec is the vector coming from the mining gun's "muzzle" + %muzVec = %obj.getMuzzleVector(%slot); + // muzNVec = normalized muzVec + %muzNVec = VectorNormalize(%muzVec); + %repairRange = DefaultRepairBeam.beamRange; + // scale muzNVec to the range the mining beam can reach + %muzScaled = VectorScale(%muzNVec, %repairRange); + // muzPoint = the actual point of the gun's "muzzle" + %muzPoint = %obj.getMuzzlePoint(%slot); + // rangeEnd = muzzle point + length of beam + %rangeEnd = VectorAdd(%muzPoint, %muzScaled); + // search for just about anything that can be damaged as well as interiors + %searchMasks = $TypeMasks::StaticShapeObjectType; + // search for objects within the beam's range that fit the masks above + %scanTarg = ContainerRayCast(%muzPoint, %rangeEnd, %searchMasks, %obj); + // screen out interiors + if(%scanTarg && !(%scanTarg.getType() & $TypeMasks::InteriorObjectType)) + { + // a target in range was found + %repTgt = firstWord(%scanTarg); + // is the prospective target damaged? + if(%repTgt.notRepairable) + { + // this is an object that cant be mined at all + // -- mission specific flag set on the object + if(!%obj.errMsgSent) + { + messageClient(%obj.client, 'MsgRepairPackIrrepairable', '\c2Target cannot be mined.', %repTgt); + %obj.errMsgSent = true; + } + // if player was repairing something, stop the repairs -- we're done + if(%obj.repairing) + stopMining(%obj); + } + else if(%repTgt.getDamageLevel()) + { + // yes, it's damaged + if(%repTgt != %obj.repairing) + { + if(isObject(%obj.repairing)) + stopMining(%obj); + + %obj.repairing = %repTgt; + } + // setting imageLoaded to true sends us to repair state (function onRepair) + %obj.setImageLoaded(%slot, true); + } + else + { + // there is a target in range, but it's not damaged + if(!%obj.errMsgSent) + { + // if the target isn't damaged, send a message to that effect only once + messageClient(%obj.client, 'MsgRepairPackNotDamaged', '\c2Target is not damaged.', %repTgt); + %obj.errMsgSent = true; + } + // if player was repairing something, stop the repairs -- we're done + if(%obj.repairing) + stopMining(%obj); + } + } + + //AI hack - too many things influence the aiming, so I'm going to force the repair object for bots only + else if (%obj.client.isAIControlled() && isObject(%obj.client.repairObject)) + { + %repTgt = %obj.client.repairObject; + %repPoint = %repTgt.getAIRepairPoint(); + if (%repPoint $= "0 0 0") + %repPoint = %repTgt.getWorldBoxCenter(); + %repTgtVector = VectorNormalize(VectorSub(%muzPoint, %repPoint)); + %aimVector = VectorNormalize(VectorSub(%muzPoint, %rangeEnd)); + + //if the dot product is very close (ie. we're aiming in the right direction) + if (VectorDot(%repTgtVector, %aimVector) > 0.85) + { + //do an LOS to make sure nothing is in the way... + %scanTarg = ContainerRayCast(%muzPoint, %repPoint, %searchMasks, %obj); + if (firstWord(%scanTarg) == %repTgt) + { + // yes, it's damaged + + if(isObject(%obj.repairing)) + stopMining(%obj); + + %obj.repairing = %repTgt; + // setting imageLoaded to true sends us to repair state (function onRepair) + %obj.setImageLoaded(%slot, true); + } + } + } + else if(%obj.getDamageLevel()) + { + // there is no target in range, but the player is damaged + // check to see if we were repairing something before -- if so, stop repairing old target + if(%obj.repairing != 0) + if(%obj.repairing != %obj) + stopMining(%obj); + if(isObject(%obj.repairing)) + stopMining(%obj); + + %obj.repairing = %obj; + // quick, to onRepair! + %obj.setImageLoaded(%slot, true); + } + else + { + // there is no target in range, and the player isn't damaged + if(!%obj.errMsgSent) + { + // send an error message only once + messageClient(%obj.client, 'MsgRepairPackNoTarget', '\c2No target to mine.'); + %obj.errMsgSent = true; + } + stopMining(%obj); + } +} + +function MiningToolGunImage::onMine(%this,%obj,%slot) +{ + // this = repairgunimage datablock + // obj = player wielding the repair gun + // slot = weapon slot + + if(%obj.getEnergyLevel() <= %this.cutOffEnergy) + { + stopMining(%obj); + return; + } + // reset the flag that indicates an error message has been sent + %obj.errMsgSent = false; + %target = %obj.repairing; + if(!%target) + { + // no target -- whoops! never mind + stopMining(%obj); + } + + else + { + // make sure we still have a target -- more vector fun!!! + %muzVec = %obj.getMuzzleVector(%slot); + %muzNVec = VectorNormalize(%muzVec); + %repairRange = DefaultRepairBeam.beamRange; + %muzScaled = VectorScale(%muzNVec, %repairRange); + %muzPoint = %obj.getMuzzlePoint(%slot); + %rangeEnd = VectorAdd(%muzPoint, %muzScaled); + + %searchMasks = $TypeMasks::StaticShapeObjectType; + + //AI hack to help "fudge" the repairing stuff... + if (%obj.client.isAIControlled() && isObject(%obj.client.repairObject) && %obj.client.repairObject == %obj.repairing) + { + %repTgt = %obj.client.repairObject; + %repPoint = %repTgt.getAIRepairPoint(); + if (%repPoint $= "0 0 0") + %repPoint = %repTgt.getWorldBoxCenter(); + %repTgtVector = VectorNormalize(VectorSub(%muzPoint, %repPoint)); + %aimVector = VectorNormalize(VectorSub(%muzPoint, %rangeEnd)); + + //if the dot product is very close (ie. we're aiming in the right direction) + if (VectorDot(%repTgtVector, %aimVector) > 0.85) + %scanTarg = ContainerRayCast(%muzPoint, %repPoint, %searchMasks, %obj); + } + else + %scanTarg = ContainerRayCast(%muzPoint, %rangeEnd, %searchMasks, %obj); + + if (%scanTarg) + { + %pos = getWords(%scanTarg, 1, 3); + %obstructMask = $TypeMasks::InteriorObjectType | $TypeMasks::TerrainObjectType; + %obstruction = ContainerRayCast(%muzPoint, %pos, %obstructMask, %obj); + if (%obstruction) + %scanTarg = "0"; + } + + if(%scanTarg) + { + // there's still a target out there + %repTgt = firstWord(%scanTarg); + + if (%repTgt.mineral $= "") + { + messageClient(%obj.client, 'MsgMineFail',"\c2Rock is empty as of now. Check back later."); + %obj.errMsgSent = true; + stopMining(%obj); + return; + } + + // is the target damaged? + if(%repTgt.getDamageLevel()) + { + %obj.client.collected = %obj.client.collected + %obj.getRepairRate() + MiningToolGunImage.repairFactorPlayer; + %obj.client.units[%obj.repairing.mineral] = %obj.client.units[%obj.repairing.mineral] + %obj.client.collected; + if(%repTgt != %obj.repairing) + { + // the target is not the same as the one we were just repairing + // stop repairing old target, start repairing new target + stopRepairing(%obj); + if(isObject(%obj.repairing)) + stopRepairing(%obj); + + %obj.repairing = %repTgt; + // extract the name of what player is repairing based on what it is + // if it's a player, it's the player's name (duh) + // if it's an object, look for a nametag + // if object has no nametag, just say what it is (e.g. generatorLarge) + if(%repTgt.getClassName() $= Player) + %tgtName = getTaggedString(%repTgt.client.name); + else if(%repTgt.getGameName() !$= "") + %tgtName = %repTgt.getGameName(); + else + %tgtName = %repTgt.getDatablock().getName(); + messageClient(%obj.client, 'MsgRepairPackRepairingObj', '\c2Mining rock.. (%3)', %tgtName, %repTgt, %repTgt.mineral); + startMining(%obj, false); + } + else + { + // it's the same target as last time + // changed to fix "2 players can't repair same object" bug + if(%obj.repairProjectile == 0) + { + if(%repTgt.getClassName() $= Player) + %tgtName = getTaggedString(%repTgt.client.name); + else if(%repTgt.getGameName() !$= "") + %tgtName = %repTgt.getGameName(); + else + %tgtName = %repTgt.getDatablock().getName(); + messageClient(%obj.client, 'MsgRepairPackRepairingObj', '\c2Mining Rock.. (%3)', %tgtName, %repTgt, %repTgt.mineral); + startMining(%obj, false); + } + } + } + else + { + %rateOfRepair = %this.repairFactorObject; + if(%repTgt.getClassName() $= Player) + { + %tgtName = getTaggedString(%repTgt.client.name); + %rateOfRepair = %this.repairFactorPlayer; + } + else if(%repTgt.getGameName() !$= "") + %tgtName = %repTgt.getGameName(); + else + %tgtName = %repTgt.getDatablock().getName(); + if(%repTgt != %obj.repairing) + { + // it isn't the same object we were repairing previously + messageClient(%obj.client, 'MsgRepairPackNotDamaged', '\c2%1 is not damaged.', %tgtName); + } + else + { + // same target, but not damaged -- we must be done + messageClient(%obj.client, 'MsgRepairPackDone', '\c2Rock ran out of minerals.'); + stopMining(%obj); //Push this through to make sure client gets minerals.. + Game.objectRepaired(%repTgt, %tgtName); + } + %obj.errMsgSent = true; + stopMining(%obj); + } + } + else + { + // whoops, we lost our target + messageClient(%obj.client, 'MsgRepairPackLostTarget', '\c2No target to mine.'); + stopMining(%obj); + } + } + } + + +function MiningToolGunImage::onDeactivate(%this,%obj,%slot) +{ + stopMining(%obj); +} + +function stopMining(%player) +{ + // %player = the player who was using the repair pack + + if(%player.selfRepairing) + { + // there is no projectile for self-repairing + %player.setRepairRate(%player.getRepairRate() - %player.repairingRate); + %player.selfRepairing = false; + } + else if(%player.repairing > 0) + { + // player was repairing something else + //if(%player.repairing.beingRepaired > 0) + //{ + // don't decrement this stuff if it's already at 0 -- though it shouldn't be + //%player.repairing.beingRepaired--; + %player.repairing.setRepairRate(%player.repairing.getRepairRate() - %player.repairingRate); + //} + if(%player.repairProjectile > 0) + { + // is there a repair projectile? delete it + %player.repairProjectile.delete(); + %player.repairProjectile = 0; + } + } + + if (!%player.errMsgSent && isObject(%player.repairing) && %player.repairing.mineral !$= "") //Ok, player stopped mining. Give the player his/her WTF they mined. + { + %client = %player.client; + %mineral = %player.repairing.mineral; + %collected = %player.client.collected; + %total = %client.units[%mineral]; + %obj = %player.repairing; + + messageClient(%player.client,'msgMiningCollect','\c2Collected %1 units of %2. You now have %3 units of %2.',%collected,%mineral,%total); + } + + %player.client.collected = 0; + %player.repairing = 0; + %player.repairingRate = 0; + %player.setImageTrigger($WeaponSlot, false); + %player.setImageLoaded($WeaponSlot, false); +} + +function startMining(%player, %self) +{ + // %player = the player who was using the repair pack + // %self = boolean -- is player repairing him/herself? + + if(%self) + { + // one repair, hold the projectile + %player.setRepairRate(%player.getRepairRate() + MiningToolGunImage.repairFactorPlayer); + %player.selfRepairing = true; + %player.repairingRate = MiningToolGunImage.repairFactorPlayer; + } + else + { + //if(%player.repairing.beingRepaired $= "") + // %player.repairing.beingRepaired = 1; + //else + // %player.repairing.beingRepaired++; + + //AI hack... + if (%player.client.isAIControlled() && %player.client.repairObject == %player.repairing) + { + %initialPosition = %player.getMuzzlePoint($WeaponSlot); + %initialDirection = VectorSub(%initialPosition, %player.repairing.getWorldBoxCenter()); + } + else + { + %initialDirection = %player.getMuzzleVector($WeaponSlot); + %initialPosition = %player.getMuzzlePoint($WeaponSlot); + } + if(%player.repairing.getClassName() $= Player) + %repRate = RepairGunImage.repairFactorPlayer; + else + %repRate = RepairGunImage.repairFactorObject; + %player.repairing.setRepairRate(%player.repairing.getRepairRate() + %repRate); + + %player.repairingRate = %repRate; + %player.repairProjectile = new RepairProjectile() { + dataBlock = MiningBeam; + initialDirection = %initialDirection; + initialPosition = %initialPosition; + sourceObject = %player; + sourceSlot = $WeaponSlot; + targetObject = %player.repairing; + }; + // ---------------------------------------------------- + // z0dd - ZOD, 5/27/02. Fix lingering projectile bug + if(isObject(%player.lastProjectile)) + %player.lastProjectile.delete(); + + %player.HP = %player.repairing.getDamageLevel(); //Is used when player stops 'mining' + + %player.lastProjectile = %player.repairProjectile; + // End z0dd - ZOD + // ---------------------------------------------------- + MissionCleanup.add(%player.repairProjectile); + } +} + +function MiningTool::onPickup(%this, %obj, %shape, %amount) +{ + // created to prevent console errors +} diff --git a/scripts/packs/missilebarrelPack.cs b/scripts/packs/missilebarrelPack.cs index b768c70..0621658 100644 --- a/scripts/packs/missilebarrelPack.cs +++ b/scripts/packs/missilebarrelPack.cs @@ -1,65 +1,65 @@ -//-------------------------------------------------------------------------- -// -// -// -//-------------------------------------------------------------------------- - -datablock ShapeBaseImageData(MissileBarrelPackImage) -{ - mass = 10; // z0dd - ZOD, 7/17/02. Lower mass due to higher gravity. Was 15. - - className = TurretPack; - - shapeFile = "pack_barrel_missile.dts"; - item = MissileBarrelPack; - mountPoint = 1; - offset = "0 0 0"; - turretBarrel = "MissileBarrelLarge"; - - stateName[0] = "Idle"; - stateTransitionOnTriggerDown[0] = "Activate"; - - stateName[1] = "Activate"; - stateScript[1] = "onActivate"; - stateTransitionOnTriggerUp[1] = "Deactivate"; - - stateName[2] = "Deactivate"; - stateScript[2] = "onDeactivate"; - stateTransitionOnTimeOut[2] = "Idle"; - - isLarge = true; -}; - -datablock ItemData(MissileBarrelPack) -{ - className = Pack; - catagory = "Packs"; - shapeFile = "pack_barrel_missile.dts"; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - rotate = true; - image = "MissileBarrelPackImage"; - pickUpName = "a missile barrel pack"; - - computeCRC = true; - -}; - -//MissileBarrelPackImage.turretBarrel = "MissileBarrelLarge"; - -function MissileBarrelPackImage::onActivate(%data, %obj, %slot) -{ - checkTurretMount(%data, %obj, %slot); -} - -function MissileBarrelPackImage::onDeactivate(%data, %obj, %slot) -{ - %obj.setImageTrigger($BackpackSlot, false); -} - -function MissileBarrelPack::onPickup(%this, %obj, %shape, %amount) -{ - // created to prevent console errors +//-------------------------------------------------------------------------- +// +// +// +//-------------------------------------------------------------------------- + +datablock ShapeBaseImageData(MissileBarrelPackImage) +{ + mass = 10; // z0dd - ZOD, 7/17/02. Lower mass due to higher gravity. Was 15. + + className = TurretPack; + + shapeFile = "pack_barrel_missile.dts"; + item = MissileBarrelPack; + mountPoint = 1; + offset = "0 0 0"; + turretBarrel = "MissileBarrelLarge"; + + stateName[0] = "Idle"; + stateTransitionOnTriggerDown[0] = "Activate"; + + stateName[1] = "Activate"; + stateScript[1] = "onActivate"; + stateTransitionOnTriggerUp[1] = "Deactivate"; + + stateName[2] = "Deactivate"; + stateScript[2] = "onDeactivate"; + stateTransitionOnTimeOut[2] = "Idle"; + + isLarge = true; +}; + +datablock ItemData(MissileBarrelPack) +{ + className = Pack; + catagory = "Packs"; + shapeFile = "pack_barrel_missile.dts"; + mass = 1; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 2; + rotate = true; + image = "MissileBarrelPackImage"; + pickUpName = "a missile barrel pack"; + + computeCRC = true; + +}; + +//MissileBarrelPackImage.turretBarrel = "MissileBarrelLarge"; + +function MissileBarrelPackImage::onActivate(%data, %obj, %slot) +{ + checkTurretMount(%data, %obj, %slot); +} + +function MissileBarrelPackImage::onDeactivate(%data, %obj, %slot) +{ + %obj.setImageTrigger($BackpackSlot, false); +} + +function MissileBarrelPack::onPickup(%this, %obj, %shape, %amount) +{ + // created to prevent console errors } \ No newline at end of file diff --git a/scripts/packs/mortarBarrelPack.cs b/scripts/packs/mortarBarrelPack.cs index f3c89e2..12528e5 100644 --- a/scripts/packs/mortarBarrelPack.cs +++ b/scripts/packs/mortarBarrelPack.cs @@ -1,63 +1,63 @@ -//-------------------------------------------------------------------------- -// -// -// -//-------------------------------------------------------------------------- - -datablock ShapeBaseImageData(MortarBarrelPackImage) -{ - mass = 10; // z0dd - ZOD, 7/17/02. Lower mass due to higher gravity. Was 15. - - className = TurretPack; - - shapeFile = "pack_barrel_mortar.dts"; - item = MortarBarrelPack; - mountPoint = 1; - offset = "0 0 0"; - turretBarrel = "MortarBarrelLarge"; - - stateName[0] = "Idle"; - stateTransitionOnTriggerDown[0] = "Activate"; - - stateName[1] = "Activate"; - stateScript[1] = "onActivate"; - stateTransitionOnTriggerUp[1] = "Deactivate"; - - stateName[2] = "Deactivate"; - stateScript[2] = "onDeactivate"; - stateTransitionOnTimeOut[2] = "Idle"; - - isLarge = true; -}; - -datablock ItemData(MortarBarrelPack) -{ - className = Pack; - catagory = "Packs"; - shapeFile = "pack_barrel_mortar.dts"; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - rotate = true; - image = "MortarBarrelPackImage"; - pickUpName = "a mortar barrel pack"; - - computeCRC = true; - -}; - -function MortarBarrelPackImage::onActivate(%data, %obj, %slot) -{ - checkTurretMount(%data, %obj, %slot); -} - -function MortarBarrelPackImage::onDeactivate(%data, %obj, %slot) -{ - %obj.setImageTrigger($BackpackSlot, false); -} - -function MortarBarrelPack::onPickup(%this, %obj, %shape, %amount) -{ - // created to prevent console errors +//-------------------------------------------------------------------------- +// +// +// +//-------------------------------------------------------------------------- + +datablock ShapeBaseImageData(MortarBarrelPackImage) +{ + mass = 10; // z0dd - ZOD, 7/17/02. Lower mass due to higher gravity. Was 15. + + className = TurretPack; + + shapeFile = "pack_barrel_mortar.dts"; + item = MortarBarrelPack; + mountPoint = 1; + offset = "0 0 0"; + turretBarrel = "MortarBarrelLarge"; + + stateName[0] = "Idle"; + stateTransitionOnTriggerDown[0] = "Activate"; + + stateName[1] = "Activate"; + stateScript[1] = "onActivate"; + stateTransitionOnTriggerUp[1] = "Deactivate"; + + stateName[2] = "Deactivate"; + stateScript[2] = "onDeactivate"; + stateTransitionOnTimeOut[2] = "Idle"; + + isLarge = true; +}; + +datablock ItemData(MortarBarrelPack) +{ + className = Pack; + catagory = "Packs"; + shapeFile = "pack_barrel_mortar.dts"; + mass = 1; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 2; + rotate = true; + image = "MortarBarrelPackImage"; + pickUpName = "a mortar barrel pack"; + + computeCRC = true; + +}; + +function MortarBarrelPackImage::onActivate(%data, %obj, %slot) +{ + checkTurretMount(%data, %obj, %slot); +} + +function MortarBarrelPackImage::onDeactivate(%data, %obj, %slot) +{ + %obj.setImageTrigger($BackpackSlot, false); +} + +function MortarBarrelPack::onPickup(%this, %obj, %shape, %amount) +{ + // created to prevent console errors } \ No newline at end of file diff --git a/scripts/packs/plasmabarrelPack.cs b/scripts/packs/plasmabarrelPack.cs index f6af241..a7527f5 100644 --- a/scripts/packs/plasmabarrelPack.cs +++ b/scripts/packs/plasmabarrelPack.cs @@ -1,61 +1,61 @@ -//-------------------------------------------------------------------------- -// -// Plasma barrel pack -// -//-------------------------------------------------------------------------- - -datablock ShapeBaseImageData(PlasmaBarrelPackImage) -{ - mass = 10; // z0dd - ZOD, 7/17/02. Lower mass due to higher gravity. Was 15. - - shapeFile = "pack_barrel_fusion.dts"; - item = PlasmaBarrelPack; - mountPoint = 1; - offset = "0 0 0"; - turretBarrel = "PlasmaBarrelLarge"; - - stateName[0] = "Idle"; - stateTransitionOnTriggerDown[0] = "Activate"; - - stateName[1] = "Activate"; - stateScript[1] = "onActivate"; - stateTransitionOnTriggerUp[1] = "Deactivate"; - - stateName[2] = "Deactivate"; - stateScript[2] = "onDeactivate"; - stateTransitionOnTimeOut[2] = "Idle"; - - isLarge = true; -}; - -datablock ItemData(PlasmaBarrelPack) -{ - className = Pack; - catagory = "Packs"; - shapeFile = "pack_barrel_fusion.dts"; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - rotate = true; - image = "PlasmaBarrelPackImage"; - pickUpName = "a plasma barrel pack"; - - computeCRC = true; - -}; - -function PlasmaBarrelPackImage::onActivate(%data, %obj, %slot) -{ - checkTurretMount(%data, %obj, %slot); -} - -function PlasmaBarrelPackImage::onDeactivate(%data, %obj, %slot) -{ - %obj.setImageTrigger($BackpackSlot, false); -} - -function PlasmaBarrelPack::onPickup(%this, %obj, %shape, %amount) -{ - // created to prevent console errors +//-------------------------------------------------------------------------- +// +// Plasma barrel pack +// +//-------------------------------------------------------------------------- + +datablock ShapeBaseImageData(PlasmaBarrelPackImage) +{ + mass = 10; // z0dd - ZOD, 7/17/02. Lower mass due to higher gravity. Was 15. + + shapeFile = "pack_barrel_fusion.dts"; + item = PlasmaBarrelPack; + mountPoint = 1; + offset = "0 0 0"; + turretBarrel = "PlasmaBarrelLarge"; + + stateName[0] = "Idle"; + stateTransitionOnTriggerDown[0] = "Activate"; + + stateName[1] = "Activate"; + stateScript[1] = "onActivate"; + stateTransitionOnTriggerUp[1] = "Deactivate"; + + stateName[2] = "Deactivate"; + stateScript[2] = "onDeactivate"; + stateTransitionOnTimeOut[2] = "Idle"; + + isLarge = true; +}; + +datablock ItemData(PlasmaBarrelPack) +{ + className = Pack; + catagory = "Packs"; + shapeFile = "pack_barrel_fusion.dts"; + mass = 1; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 2; + rotate = true; + image = "PlasmaBarrelPackImage"; + pickUpName = "a plasma barrel pack"; + + computeCRC = true; + +}; + +function PlasmaBarrelPackImage::onActivate(%data, %obj, %slot) +{ + checkTurretMount(%data, %obj, %slot); +} + +function PlasmaBarrelPackImage::onDeactivate(%data, %obj, %slot) +{ + %obj.setImageTrigger($BackpackSlot, false); +} + +function PlasmaBarrelPack::onPickup(%this, %obj, %shape, %amount) +{ + // created to prevent console errors } \ No newline at end of file diff --git a/scripts/packs/repairpack.cs b/scripts/packs/repairpack.cs index 2762f40..4a2ad39 100644 --- a/scripts/packs/repairpack.cs +++ b/scripts/packs/repairpack.cs @@ -1,643 +1,643 @@ -//-------------------------------------------------------------------------- -// Repair Pack -// can be used by any armor type -// when activated, gives user a "repair gun" that can be used to -// repair a damaged object or player. If there is no target in -// range for the repair gun, the user is repaired. - -//-------------------------------------------------------------------------- -// Sounds & feedback effects - -datablock EffectProfile(RepairPackActivateEffect) -{ - effectname = "packs/packs.repairPackOn"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(RepairPackFireEffect) -{ - effectname = "packs/repair_use"; - minDistance = 2.5; - maxDistance = 5.0; -}; - -datablock AudioProfile(RepairPackActivateSound) -{ - filename = "fx/packs/packs.repairPackOn.wav"; - description = AudioClosest3d; - preload = true; - effect = RepairPackActivateEffect; -}; - -datablock AudioProfile(RepairPackFireSound) -{ - filename = "fx/packs/repair_use.wav"; - description = CloseLooping3d; - preload = true; - effect = RepairPackFireEffect; -}; - -//-------------------------------------------------------------------------- -// Projectile - -datablock RepairProjectileData(DefaultRepairBeam) -{ - sound = RepairPackFireSound; - - beamRange = 10; - beamWidth = 0.15; - numSegments = 20; - texRepeat = 0.20; - blurFreq = 10.0; - blurLifetime = 1.0; - cutoffAngle = 25.0; - - textures[0] = "special/redbump2"; - textures[1] = "special/redflare"; - -}; - - -//------------------------------------------------------------------------- -// shapebase datablocks - -datablock ShapeBaseImageData(RepairPackImage) -{ - shapeFile = "pack_upgrade_repair.dts"; - item = RepairPack; - mountPoint = 1; - offset = "0 0 0"; - emap = true; - - gun = RepairGunImage; - - stateName[0] = "Idle"; - stateTransitionOnTriggerDown[0] = "Activate"; - - stateName[1] = "Activate"; - stateScript[1] = "onActivate"; - stateSequence[1] = "fire"; - stateSound[1] = RepairPackActivateSound; - stateTransitionOnTriggerUp[1] = "Deactivate"; - - stateName[2] = "Deactivate"; - stateScript[2] = "onDeactivate"; - stateTransitionOnTimeout[2] = "Idle"; -}; - -datablock ItemData(RepairPack) -{ - className = Pack; - catagory = "Packs"; - shapeFile = "pack_upgrade_repair.dts"; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - rotate = true; - image = "RepairPackImage"; - pickUpName = "a repair pack"; - - lightOnlyStatic = true; - lightType = "PulsingLight"; - lightColor = "1 0 0 1"; - lightTime = 1200; - lightRadius = 4; - - computeCRC = true; - emap = true; -}; - -//-------------------------------------------------------------------------- -// Repair Gun - -datablock ShapeBaseImageData(RepairGunImage) -{ - shapeFile = "weapon_repair.dts"; - offset = "0 0 0"; - - usesEnergy = true; - minEnergy = 3; - cutOffEnergy = 3.1; - emap = true; - - repairFactorPlayer = 0.002; // <--- attention DaveG! - repairFactorObject = 0.005; // <--- attention DaveG! // z0dd - ZOD, 7/20/02. was 0.004 - - stateName[0] = "Activate"; - stateTransitionOnTimeout[0] = "ActivateReady"; - stateTimeoutValue[0] = 0.25; - - stateName[1] = "ActivateReady"; - stateScript[1] = "onActivateReady"; - stateSpinThread[1] = Stop; - stateTransitionOnAmmo[1] = "Ready"; - stateTransitionOnNoAmmo[1] = "ActivateReady"; - - stateName[2] = "Ready"; - stateSpinThread[2] = Stop; - stateTransitionOnNoAmmo[2] = "Deactivate"; - stateTransitionOnTriggerDown[2] = "Validate"; - - stateName[3] = "Validate"; - stateTransitionOnTimeout[3] = "Validate"; - stateTimeoutValue[3] = 0.2; - stateEnergyDrain[3] = 3; - stateSpinThread[3] = SpinUp; - stateScript[3] = "onValidate"; - stateIgnoreLoadedForReady[3] = true; - stateTransitionOnLoaded[3] = "Repair"; - stateTransitionOnNoAmmo[3] = "Deactivate"; - stateTransitionOnTriggerUp[3] = "Deactivate"; - - stateName[4] = "Repair"; - stateSound[4] = RepairPackFireSound; - stateScript[4] = "onRepair"; - stateSpinThread[4] = FullSpeed; - stateAllowImageChange[4] = false; - stateSequence[4] = "activate"; - stateFire[4] = true; - stateEnergyDrain[4] = 9; - stateTimeoutValue[4] = 0.2; - stateTransitionOnTimeOut[4] = "Repair"; - stateTransitionOnNoAmmo[4] = "Deactivate"; - stateTransitionOnTriggerUp[4] = "Deactivate"; - stateTransitionOnNotLoaded[4] = "Validate"; - - stateName[5] = "Deactivate"; - stateScript[5] = "onDeactivate"; - stateSpinThread[5] = SpinDown; - stateSequence[5] = "activate"; - stateDirection[5] = false; - stateTimeoutValue[5] = 0.2; - stateTransitionOnTimeout[5] = "ActivateReady"; -}; - -function RepairPackImage::onUnmount(%data, %obj, %node) -{ - // dismount the repair gun if the player had it mounted - // need the extra "if" statement to avoid a console error message - if(%obj.getMountedImage($WeaponSlot)) - if(%obj.getMountedImage($WeaponSlot).getName() $= "RepairGunImage") - %obj.unmountImage($WeaponSlot); - // if the player was repairing something when the pack was thrown, stop repairing it - if(%obj.repairing != 0) - stopRepairing(%obj); -} - -function RepairPackImage::onActivate(%data, %obj, %slot) -{ - // don't activate the pack if player is piloting a vehicle - if(%obj.isPilot()) - { - %obj.setImageTrigger(%slot, false); - return; - } - - if(!isObject(%obj.getMountedImage($WeaponSlot)) || %obj.getMountedImage($WeaponSlot).getName() !$= "RepairGunImage") - { - messageClient(%obj.client, 'MsgRepairPackOn', '\c2Repair pack activated.'); - - // make sure player's arm thread is "look" - %obj.setArmThread(look); - - // mount the repair gun - %obj.mountImage(RepairGunImage, $WeaponSlot); - // clientCmdsetRepairReticle found in hud.cs - commandToClient(%obj.client, 'setRepairReticle'); - } -} - -function RepairPackImage::onDeactivate(%data, %obj, %slot) -{ - //called when the player hits the "pack" key again (toggle) - %obj.setImageTrigger(%slot, false); - // if repair gun was mounted, unmount it - if(%obj.getMountedImage($WeaponSlot).getName() $= "RepairGunImage") - %obj.unmountImage($WeaponSlot); -} - -function RepairGunImage::onMount(%this,%obj,%slot) -{ - %obj.setImageAmmo(%slot,true); - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - commandToClient( %obj.client, 'setRepairPackIconOn' ); -} - -function RepairGunImage::onUnmount(%this,%obj,%slot) -{ - // called when player switches to another weapon - - // stop repairing whatever player was repairing - if(%obj.repairing) - stopRepairing(%obj); - - %obj.setImageTrigger(%slot, false); - // "turn off" the repair pack -- player needs to hit the "pack" key to - // activate the repair gun again - %obj.setImageTrigger($BackpackSlot, false); - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - commandToClient( %obj.client, 'setRepairPackIconOff' ); -} - -function RepairGunImage::onActivateReady(%this,%obj,%slot) -{ - %obj.errMsgSent = false; - %obj.selfRepairing = false; - %obj.repairing = 0; - %obj.setImageLoaded(%slot, false); -} - -function RepairGunImage::onValidate(%this,%obj,%slot) -{ - // this = repairgunimage datablock - // obj = player wielding the repair gun - // slot = weapon slot - - if(%obj.getEnergyLevel() <= %this.cutOffEnergy) - { - stopRepairing(%obj); - return; - } - %repGun = %obj.getMountedImage(%slot); - // muzVec is the vector coming from the repair gun's "muzzle" - %muzVec = %obj.getMuzzleVector(%slot); - // muzNVec = normalized muzVec - %muzNVec = VectorNormalize(%muzVec); - %repairRange = DefaultRepairBeam.beamRange; - // scale muzNVec to the range the repair beam can reach - %muzScaled = VectorScale(%muzNVec, %repairRange); - // muzPoint = the actual point of the gun's "muzzle" - %muzPoint = %obj.getMuzzlePoint(%slot); - // rangeEnd = muzzle point + length of beam - %rangeEnd = VectorAdd(%muzPoint, %muzScaled); - // search for just about anything that can be damaged as well as interiors - %searchMasks = $TypeMasks::PlayerObjectType | $TypeMasks::VehicleObjectType | - $TypeMasks::StaticShapeObjectType | $TypeMasks::TurretObjectType | $TypeMasks::InteriorObjectType; - // search for objects within the beam's range that fit the masks above - %scanTarg = ContainerRayCast(%muzPoint, %rangeEnd, %searchMasks, %obj); - // screen out interiors - if(%scanTarg && !(%scanTarg.getType() & $TypeMasks::InteriorObjectType)) - { - // a target in range was found - %repTgt = firstWord(%scanTarg); - // is the prospective target damaged? - if(%repTgt.notRepairable) - { - // this is an object that cant be repaired at all - // -- mission specific flag set on the object - if(!%obj.errMsgSent) - { - messageClient(%obj.client, 'MsgRepairPackIrrepairable', '\c2Target is not repairable.', %repTgt); - %obj.errMsgSent = true; - } - // if player was repairing something, stop the repairs -- we're done - if(%obj.repairing) - stopRepairing(%obj); - } - else if(%repTgt.getDamageLevel()) - { - // yes, it's damaged - if(%repTgt != %obj.repairing) - { - if(isObject(%obj.repairing)) - stopRepairing(%obj); - - %obj.repairing = %repTgt; - } - // setting imageLoaded to true sends us to repair state (function onRepair) - %obj.setImageLoaded(%slot, true); - } - else - { - // there is a target in range, but it's not damaged - if(!%obj.errMsgSent) - { - // if the target isn't damaged, send a message to that effect only once - messageClient(%obj.client, 'MsgRepairPackNotDamaged', '\c2Target is not damaged.', %repTgt); - %obj.errMsgSent = true; - } - // if player was repairing something, stop the repairs -- we're done - if(%obj.repairing) - stopRepairing(%obj); - } - } - - //AI hack - too many things influence the aiming, so I'm going to force the repair object for bots only - else if (%obj.client.isAIControlled() && isObject(%obj.client.repairObject)) - { - %repTgt = %obj.client.repairObject; - %repPoint = %repTgt.getAIRepairPoint(); - if (%repPoint $= "0 0 0") - %repPoint = %repTgt.getWorldBoxCenter(); - %repTgtVector = VectorNormalize(VectorSub(%muzPoint, %repPoint)); - %aimVector = VectorNormalize(VectorSub(%muzPoint, %rangeEnd)); - - //if the dot product is very close (ie. we're aiming in the right direction) - if (VectorDot(%repTgtVector, %aimVector) > 0.85) - { - //do an LOS to make sure nothing is in the way... - %scanTarg = ContainerRayCast(%muzPoint, %repPoint, %searchMasks, %obj); - if (firstWord(%scanTarg) == %repTgt) - { - // yes, it's damaged - - if(isObject(%obj.repairing)) - stopRepairing(%obj); - - %obj.repairing = %repTgt; - // setting imageLoaded to true sends us to repair state (function onRepair) - %obj.setImageLoaded(%slot, true); - } - } - } - else if(%obj.getDamageLevel()) - { - // there is no target in range, but the player is damaged - // check to see if we were repairing something before -- if so, stop repairing old target - if(%obj.repairing != 0) - if(%obj.repairing != %obj) - stopRepairing(%obj); - if(isObject(%obj.repairing)) - stopRepairing(%obj); - - %obj.repairing = %obj; - // quick, to onRepair! - %obj.setImageLoaded(%slot, true); - } - else - { - // there is no target in range, and the player isn't damaged - if(!%obj.errMsgSent) - { - // send an error message only once - messageClient(%obj.client, 'MsgRepairPackNoTarget', '\c2No target to repair.'); - %obj.errMsgSent = true; - } - stopRepairing(%obj); - } -} - -function RepairGunImage::onRepair(%this,%obj,%slot) -{ - // this = repairgunimage datablock - // obj = player wielding the repair gun - // slot = weapon slot - - if(%obj.getEnergyLevel() <= %this.cutOffEnergy) - { - stopRepairing(%obj); - return; - } - // reset the flag that indicates an error message has been sent - %obj.errMsgSent = false; - %target = %obj.repairing; - if(!%target) - { - // no target -- whoops! never mind - stopRepairing(%obj); - } - else - { - %target.repairedBy = %obj.client; //keep track of who last repaired this item - if(%obj.repairing == %obj) - { - // player is self-repairing - if(%obj.getDamageLevel()) - { - if(!%obj.selfRepairing) - { - // no need for a projectile, just send a message and up the repair rate - messageClient(%obj.client, 'MsgRepairPackPlayerSelfRepair', '\c2Repairing self.'); - %obj.selfRepairing = true; - startRepairing(%obj, true); - } - } - else - { - messageClient(%obj.client, 'MsgRepairPackSelfDone', '\c2Repairs completed on self.'); - stopRepairing(%obj); - %obj.errMsgSent = true; - } - } - else - { - // make sure we still have a target -- more vector fun!!! - %muzVec = %obj.getMuzzleVector(%slot); - %muzNVec = VectorNormalize(%muzVec); - %repairRange = DefaultRepairBeam.beamRange; - %muzScaled = VectorScale(%muzNVec, %repairRange); - %muzPoint = %obj.getMuzzlePoint(%slot); - %rangeEnd = VectorAdd(%muzPoint, %muzScaled); - - %searchMasks = $TypeMasks::PlayerObjectType | $TypeMasks::VehicleObjectType | - $TypeMasks::StaticShapeObjectType | $TypeMasks::TurretObjectType; - - //AI hack to help "fudge" the repairing stuff... - if (%obj.client.isAIControlled() && isObject(%obj.client.repairObject) && %obj.client.repairObject == %obj.repairing) - { - %repTgt = %obj.client.repairObject; - %repPoint = %repTgt.getAIRepairPoint(); - if (%repPoint $= "0 0 0") - %repPoint = %repTgt.getWorldBoxCenter(); - %repTgtVector = VectorNormalize(VectorSub(%muzPoint, %repPoint)); - %aimVector = VectorNormalize(VectorSub(%muzPoint, %rangeEnd)); - - //if the dot product is very close (ie. we're aiming in the right direction) - if (VectorDot(%repTgtVector, %aimVector) > 0.85) - %scanTarg = ContainerRayCast(%muzPoint, %repPoint, %searchMasks, %obj); - } - else - %scanTarg = ContainerRayCast(%muzPoint, %rangeEnd, %searchMasks, %obj); - - if (%scanTarg) - { - %pos = getWords(%scanTarg, 1, 3); - %obstructMask = $TypeMasks::InteriorObjectType | $TypeMasks::TerrainObjectType; - %obstruction = ContainerRayCast(%muzPoint, %pos, %obstructMask, %obj); - if (%obstruction) - %scanTarg = "0"; - } - - if(%scanTarg) - { - // there's still a target out there - %repTgt = firstWord(%scanTarg); - // is the target damaged? - if(%repTgt.getDamageLevel()) - { - if(%repTgt != %obj.repairing) - { - // the target is not the same as the one we were just repairing - // stop repairing old target, start repairing new target - stopRepairing(%obj); - if(isObject(%obj.repairing)) - stopRepairing(%obj); - - %obj.repairing = %repTgt; - // extract the name of what player is repairing based on what it is - // if it's a player, it's the player's name (duh) - // if it's an object, look for a nametag - // if object has no nametag, just say what it is (e.g. generatorLarge) - if(%repTgt.getClassName() $= Player) - %tgtName = getTaggedString(%repTgt.client.name); - else if(%repTgt.getGameName() !$= "") - %tgtName = %repTgt.getGameName(); - else - %tgtName = %repTgt.getDatablock().getName(); - messageClient(%obj.client, 'MsgRepairPackRepairingObj', '\c2Repairing %1.', %tgtName, %repTgt); - startRepairing(%obj, false); - } - else - { - // it's the same target as last time - // changed to fix "2 players can't repair same object" bug - if(%obj.repairProjectile == 0) - { - if(%repTgt.getClassName() $= Player) - %tgtName = getTaggedString(%repTgt.client.name); - else if(%repTgt.getGameName() !$= "") - %tgtName = %repTgt.getGameName(); - else - %tgtName = %repTgt.getDatablock().getName(); - messageClient(%obj.client, 'MsgRepairPackRepairingObj', '\c2Repairing %1.', %tgtName, %repTgt); - startRepairing(%obj, false); - } - } - } - else - { - %rateOfRepair = %this.repairFactorObject; - if(%repTgt.getClassName() $= Player) - { - %tgtName = getTaggedString(%repTgt.client.name); - %rateOfRepair = %this.repairFactorPlayer; - } - else if(%repTgt.getGameName() !$= "") - %tgtName = %repTgt.getGameName(); - else - %tgtName = %repTgt.getDatablock().getName(); - if(%repTgt != %obj.repairing) - { - // it isn't the same object we were repairing previously - messageClient(%obj.client, 'MsgRepairPackNotDamaged', '\c2%1 is not damaged.', %tgtName); - } - else - { - // same target, but not damaged -- we must be done - messageClient(%obj.client, 'MsgRepairPackDone', '\c2Repairs completed.'); - Game.objectRepaired(%repTgt, %tgtName); - } - %obj.errMsgSent = true; - stopRepairing(%obj); - } - } - else - { - // whoops, we lost our target - messageClient(%obj.client, 'MsgRepairPackLostTarget', '\c2Repair target no longer in range.'); - stopRepairing(%obj); - } - } - } -} - -function RepairGunImage::onDeactivate(%this,%obj,%slot) -{ - stopRepairing(%obj); -} - -function stopRepairing(%player) -{ - // %player = the player who was using the repair pack - - if(%player.selfRepairing) - { - // there is no projectile for self-repairing - %player.setRepairRate(%player.getRepairRate() - %player.repairingRate); - %player.selfRepairing = false; - } - else if(%player.repairing > 0) - { - // player was repairing something else - //if(%player.repairing.beingRepaired > 0) - //{ - // don't decrement this stuff if it's already at 0 -- though it shouldn't be - //%player.repairing.beingRepaired--; - %player.repairing.setRepairRate(%player.repairing.getRepairRate() - %player.repairingRate); - //} - if(%player.repairProjectile > 0) - { - // is there a repair projectile? delete it - %player.repairProjectile.delete(); - %player.repairProjectile = 0; - } - } - %player.repairing = 0; - %player.repairingRate = 0; - %player.setImageTrigger($WeaponSlot, false); - %player.setImageLoaded($WeaponSlot, false); -} - -function startRepairing(%player, %self) -{ - // %player = the player who was using the repair pack - // %self = boolean -- is player repairing him/herself? - - if(%self) - { - // one repair, hold the projectile - %player.setRepairRate(%player.getRepairRate() + RepairGunImage.repairFactorPlayer); - %player.selfRepairing = true; - %player.repairingRate = RepairGunImage.repairFactorPlayer; - } - else - { - //if(%player.repairing.beingRepaired $= "") - // %player.repairing.beingRepaired = 1; - //else - // %player.repairing.beingRepaired++; - - //AI hack... - if (%player.client.isAIControlled() && %player.client.repairObject == %player.repairing) - { - %initialPosition = %player.getMuzzlePoint($WeaponSlot); - %initialDirection = VectorSub(%initialPosition, %player.repairing.getWorldBoxCenter()); - } - else - { - %initialDirection = %player.getMuzzleVector($WeaponSlot); - %initialPosition = %player.getMuzzlePoint($WeaponSlot); - } - if(%player.repairing.getClassName() $= Player) - %repRate = RepairGunImage.repairFactorPlayer; - else - %repRate = RepairGunImage.repairFactorObject; - %player.repairing.setRepairRate(%player.repairing.getRepairRate() + %repRate); - - %player.repairingRate = %repRate; - %player.repairProjectile = new RepairProjectile() { - dataBlock = DefaultRepairBeam; - initialDirection = %initialDirection; - initialPosition = %initialPosition; - sourceObject = %player; - sourceSlot = $WeaponSlot; - targetObject = %player.repairing; - }; - // ---------------------------------------------------- - // z0dd - ZOD, 5/27/02. Fix lingering projectile bug - if(isObject(%player.lastProjectile)) - %player.lastProjectile.delete(); - - %player.lastProjectile = %player.repairProjectile; - // End z0dd - ZOD - // ---------------------------------------------------- - MissionCleanup.add(%player.repairProjectile); - } -} - -function RepairPack::onPickup(%this, %obj, %shape, %amount) -{ - // created to prevent console errors +//-------------------------------------------------------------------------- +// Repair Pack +// can be used by any armor type +// when activated, gives user a "repair gun" that can be used to +// repair a damaged object or player. If there is no target in +// range for the repair gun, the user is repaired. + +//-------------------------------------------------------------------------- +// Sounds & feedback effects + +datablock EffectProfile(RepairPackActivateEffect) +{ + effectname = "packs/packs.repairPackOn"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock EffectProfile(RepairPackFireEffect) +{ + effectname = "packs/repair_use"; + minDistance = 2.5; + maxDistance = 5.0; +}; + +datablock AudioProfile(RepairPackActivateSound) +{ + filename = "fx/packs/packs.repairPackOn.wav"; + description = AudioClosest3d; + preload = true; + effect = RepairPackActivateEffect; +}; + +datablock AudioProfile(RepairPackFireSound) +{ + filename = "fx/packs/repair_use.wav"; + description = CloseLooping3d; + preload = true; + effect = RepairPackFireEffect; +}; + +//-------------------------------------------------------------------------- +// Projectile + +datablock RepairProjectileData(DefaultRepairBeam) +{ + sound = RepairPackFireSound; + + beamRange = 10; + beamWidth = 0.15; + numSegments = 20; + texRepeat = 0.20; + blurFreq = 10.0; + blurLifetime = 1.0; + cutoffAngle = 25.0; + + textures[0] = "special/redbump2"; + textures[1] = "special/redflare"; + +}; + + +//------------------------------------------------------------------------- +// shapebase datablocks + +datablock ShapeBaseImageData(RepairPackImage) +{ + shapeFile = "pack_upgrade_repair.dts"; + item = RepairPack; + mountPoint = 1; + offset = "0 0 0"; + emap = true; + + gun = RepairGunImage; + + stateName[0] = "Idle"; + stateTransitionOnTriggerDown[0] = "Activate"; + + stateName[1] = "Activate"; + stateScript[1] = "onActivate"; + stateSequence[1] = "fire"; + stateSound[1] = RepairPackActivateSound; + stateTransitionOnTriggerUp[1] = "Deactivate"; + + stateName[2] = "Deactivate"; + stateScript[2] = "onDeactivate"; + stateTransitionOnTimeout[2] = "Idle"; +}; + +datablock ItemData(RepairPack) +{ + className = Pack; + catagory = "Packs"; + shapeFile = "pack_upgrade_repair.dts"; + mass = 1; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 2; + rotate = true; + image = "RepairPackImage"; + pickUpName = "a repair pack"; + + lightOnlyStatic = true; + lightType = "PulsingLight"; + lightColor = "1 0 0 1"; + lightTime = 1200; + lightRadius = 4; + + computeCRC = true; + emap = true; +}; + +//-------------------------------------------------------------------------- +// Repair Gun + +datablock ShapeBaseImageData(RepairGunImage) +{ + shapeFile = "weapon_repair.dts"; + offset = "0 0 0"; + + usesEnergy = true; + minEnergy = 3; + cutOffEnergy = 3.1; + emap = true; + + repairFactorPlayer = 0.002; // <--- attention DaveG! + repairFactorObject = 0.005; // <--- attention DaveG! // z0dd - ZOD, 7/20/02. was 0.004 + + stateName[0] = "Activate"; + stateTransitionOnTimeout[0] = "ActivateReady"; + stateTimeoutValue[0] = 0.25; + + stateName[1] = "ActivateReady"; + stateScript[1] = "onActivateReady"; + stateSpinThread[1] = Stop; + stateTransitionOnAmmo[1] = "Ready"; + stateTransitionOnNoAmmo[1] = "ActivateReady"; + + stateName[2] = "Ready"; + stateSpinThread[2] = Stop; + stateTransitionOnNoAmmo[2] = "Deactivate"; + stateTransitionOnTriggerDown[2] = "Validate"; + + stateName[3] = "Validate"; + stateTransitionOnTimeout[3] = "Validate"; + stateTimeoutValue[3] = 0.2; + stateEnergyDrain[3] = 3; + stateSpinThread[3] = SpinUp; + stateScript[3] = "onValidate"; + stateIgnoreLoadedForReady[3] = true; + stateTransitionOnLoaded[3] = "Repair"; + stateTransitionOnNoAmmo[3] = "Deactivate"; + stateTransitionOnTriggerUp[3] = "Deactivate"; + + stateName[4] = "Repair"; + stateSound[4] = RepairPackFireSound; + stateScript[4] = "onRepair"; + stateSpinThread[4] = FullSpeed; + stateAllowImageChange[4] = false; + stateSequence[4] = "activate"; + stateFire[4] = true; + stateEnergyDrain[4] = 9; + stateTimeoutValue[4] = 0.2; + stateTransitionOnTimeOut[4] = "Repair"; + stateTransitionOnNoAmmo[4] = "Deactivate"; + stateTransitionOnTriggerUp[4] = "Deactivate"; + stateTransitionOnNotLoaded[4] = "Validate"; + + stateName[5] = "Deactivate"; + stateScript[5] = "onDeactivate"; + stateSpinThread[5] = SpinDown; + stateSequence[5] = "activate"; + stateDirection[5] = false; + stateTimeoutValue[5] = 0.2; + stateTransitionOnTimeout[5] = "ActivateReady"; +}; + +function RepairPackImage::onUnmount(%data, %obj, %node) +{ + // dismount the repair gun if the player had it mounted + // need the extra "if" statement to avoid a console error message + if(%obj.getMountedImage($WeaponSlot)) + if(%obj.getMountedImage($WeaponSlot).getName() $= "RepairGunImage") + %obj.unmountImage($WeaponSlot); + // if the player was repairing something when the pack was thrown, stop repairing it + if(%obj.repairing != 0) + stopRepairing(%obj); +} + +function RepairPackImage::onActivate(%data, %obj, %slot) +{ + // don't activate the pack if player is piloting a vehicle + if(%obj.isPilot()) + { + %obj.setImageTrigger(%slot, false); + return; + } + + if(!isObject(%obj.getMountedImage($WeaponSlot)) || %obj.getMountedImage($WeaponSlot).getName() !$= "RepairGunImage") + { + messageClient(%obj.client, 'MsgRepairPackOn', '\c2Repair pack activated.'); + + // make sure player's arm thread is "look" + %obj.setArmThread(look); + + // mount the repair gun + %obj.mountImage(RepairGunImage, $WeaponSlot); + // clientCmdsetRepairReticle found in hud.cs + commandToClient(%obj.client, 'setRepairReticle'); + } +} + +function RepairPackImage::onDeactivate(%data, %obj, %slot) +{ + //called when the player hits the "pack" key again (toggle) + %obj.setImageTrigger(%slot, false); + // if repair gun was mounted, unmount it + if(%obj.getMountedImage($WeaponSlot).getName() $= "RepairGunImage") + %obj.unmountImage($WeaponSlot); +} + +function RepairGunImage::onMount(%this,%obj,%slot) +{ + %obj.setImageAmmo(%slot,true); + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + commandToClient( %obj.client, 'setRepairPackIconOn' ); +} + +function RepairGunImage::onUnmount(%this,%obj,%slot) +{ + // called when player switches to another weapon + + // stop repairing whatever player was repairing + if(%obj.repairing) + stopRepairing(%obj); + + %obj.setImageTrigger(%slot, false); + // "turn off" the repair pack -- player needs to hit the "pack" key to + // activate the repair gun again + %obj.setImageTrigger($BackpackSlot, false); + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + commandToClient( %obj.client, 'setRepairPackIconOff' ); +} + +function RepairGunImage::onActivateReady(%this,%obj,%slot) +{ + %obj.errMsgSent = false; + %obj.selfRepairing = false; + %obj.repairing = 0; + %obj.setImageLoaded(%slot, false); +} + +function RepairGunImage::onValidate(%this,%obj,%slot) +{ + // this = repairgunimage datablock + // obj = player wielding the repair gun + // slot = weapon slot + + if(%obj.getEnergyLevel() <= %this.cutOffEnergy) + { + stopRepairing(%obj); + return; + } + %repGun = %obj.getMountedImage(%slot); + // muzVec is the vector coming from the repair gun's "muzzle" + %muzVec = %obj.getMuzzleVector(%slot); + // muzNVec = normalized muzVec + %muzNVec = VectorNormalize(%muzVec); + %repairRange = DefaultRepairBeam.beamRange; + // scale muzNVec to the range the repair beam can reach + %muzScaled = VectorScale(%muzNVec, %repairRange); + // muzPoint = the actual point of the gun's "muzzle" + %muzPoint = %obj.getMuzzlePoint(%slot); + // rangeEnd = muzzle point + length of beam + %rangeEnd = VectorAdd(%muzPoint, %muzScaled); + // search for just about anything that can be damaged as well as interiors + %searchMasks = $TypeMasks::PlayerObjectType | $TypeMasks::VehicleObjectType | + $TypeMasks::StaticShapeObjectType | $TypeMasks::TurretObjectType | $TypeMasks::InteriorObjectType; + // search for objects within the beam's range that fit the masks above + %scanTarg = ContainerRayCast(%muzPoint, %rangeEnd, %searchMasks, %obj); + // screen out interiors + if(%scanTarg && !(%scanTarg.getType() & $TypeMasks::InteriorObjectType)) + { + // a target in range was found + %repTgt = firstWord(%scanTarg); + // is the prospective target damaged? + if(%repTgt.notRepairable) + { + // this is an object that cant be repaired at all + // -- mission specific flag set on the object + if(!%obj.errMsgSent) + { + messageClient(%obj.client, 'MsgRepairPackIrrepairable', '\c2Target is not repairable.', %repTgt); + %obj.errMsgSent = true; + } + // if player was repairing something, stop the repairs -- we're done + if(%obj.repairing) + stopRepairing(%obj); + } + else if(%repTgt.getDamageLevel()) + { + // yes, it's damaged + if(%repTgt != %obj.repairing) + { + if(isObject(%obj.repairing)) + stopRepairing(%obj); + + %obj.repairing = %repTgt; + } + // setting imageLoaded to true sends us to repair state (function onRepair) + %obj.setImageLoaded(%slot, true); + } + else + { + // there is a target in range, but it's not damaged + if(!%obj.errMsgSent) + { + // if the target isn't damaged, send a message to that effect only once + messageClient(%obj.client, 'MsgRepairPackNotDamaged', '\c2Target is not damaged.', %repTgt); + %obj.errMsgSent = true; + } + // if player was repairing something, stop the repairs -- we're done + if(%obj.repairing) + stopRepairing(%obj); + } + } + + //AI hack - too many things influence the aiming, so I'm going to force the repair object for bots only + else if (%obj.client.isAIControlled() && isObject(%obj.client.repairObject)) + { + %repTgt = %obj.client.repairObject; + %repPoint = %repTgt.getAIRepairPoint(); + if (%repPoint $= "0 0 0") + %repPoint = %repTgt.getWorldBoxCenter(); + %repTgtVector = VectorNormalize(VectorSub(%muzPoint, %repPoint)); + %aimVector = VectorNormalize(VectorSub(%muzPoint, %rangeEnd)); + + //if the dot product is very close (ie. we're aiming in the right direction) + if (VectorDot(%repTgtVector, %aimVector) > 0.85) + { + //do an LOS to make sure nothing is in the way... + %scanTarg = ContainerRayCast(%muzPoint, %repPoint, %searchMasks, %obj); + if (firstWord(%scanTarg) == %repTgt) + { + // yes, it's damaged + + if(isObject(%obj.repairing)) + stopRepairing(%obj); + + %obj.repairing = %repTgt; + // setting imageLoaded to true sends us to repair state (function onRepair) + %obj.setImageLoaded(%slot, true); + } + } + } + else if(%obj.getDamageLevel()) + { + // there is no target in range, but the player is damaged + // check to see if we were repairing something before -- if so, stop repairing old target + if(%obj.repairing != 0) + if(%obj.repairing != %obj) + stopRepairing(%obj); + if(isObject(%obj.repairing)) + stopRepairing(%obj); + + %obj.repairing = %obj; + // quick, to onRepair! + %obj.setImageLoaded(%slot, true); + } + else + { + // there is no target in range, and the player isn't damaged + if(!%obj.errMsgSent) + { + // send an error message only once + messageClient(%obj.client, 'MsgRepairPackNoTarget', '\c2No target to repair.'); + %obj.errMsgSent = true; + } + stopRepairing(%obj); + } +} + +function RepairGunImage::onRepair(%this,%obj,%slot) +{ + // this = repairgunimage datablock + // obj = player wielding the repair gun + // slot = weapon slot + + if(%obj.getEnergyLevel() <= %this.cutOffEnergy) + { + stopRepairing(%obj); + return; + } + // reset the flag that indicates an error message has been sent + %obj.errMsgSent = false; + %target = %obj.repairing; + if(!%target) + { + // no target -- whoops! never mind + stopRepairing(%obj); + } + else + { + %target.repairedBy = %obj.client; //keep track of who last repaired this item + if(%obj.repairing == %obj) + { + // player is self-repairing + if(%obj.getDamageLevel()) + { + if(!%obj.selfRepairing) + { + // no need for a projectile, just send a message and up the repair rate + messageClient(%obj.client, 'MsgRepairPackPlayerSelfRepair', '\c2Repairing self.'); + %obj.selfRepairing = true; + startRepairing(%obj, true); + } + } + else + { + messageClient(%obj.client, 'MsgRepairPackSelfDone', '\c2Repairs completed on self.'); + stopRepairing(%obj); + %obj.errMsgSent = true; + } + } + else + { + // make sure we still have a target -- more vector fun!!! + %muzVec = %obj.getMuzzleVector(%slot); + %muzNVec = VectorNormalize(%muzVec); + %repairRange = DefaultRepairBeam.beamRange; + %muzScaled = VectorScale(%muzNVec, %repairRange); + %muzPoint = %obj.getMuzzlePoint(%slot); + %rangeEnd = VectorAdd(%muzPoint, %muzScaled); + + %searchMasks = $TypeMasks::PlayerObjectType | $TypeMasks::VehicleObjectType | + $TypeMasks::StaticShapeObjectType | $TypeMasks::TurretObjectType; + + //AI hack to help "fudge" the repairing stuff... + if (%obj.client.isAIControlled() && isObject(%obj.client.repairObject) && %obj.client.repairObject == %obj.repairing) + { + %repTgt = %obj.client.repairObject; + %repPoint = %repTgt.getAIRepairPoint(); + if (%repPoint $= "0 0 0") + %repPoint = %repTgt.getWorldBoxCenter(); + %repTgtVector = VectorNormalize(VectorSub(%muzPoint, %repPoint)); + %aimVector = VectorNormalize(VectorSub(%muzPoint, %rangeEnd)); + + //if the dot product is very close (ie. we're aiming in the right direction) + if (VectorDot(%repTgtVector, %aimVector) > 0.85) + %scanTarg = ContainerRayCast(%muzPoint, %repPoint, %searchMasks, %obj); + } + else + %scanTarg = ContainerRayCast(%muzPoint, %rangeEnd, %searchMasks, %obj); + + if (%scanTarg) + { + %pos = getWords(%scanTarg, 1, 3); + %obstructMask = $TypeMasks::InteriorObjectType | $TypeMasks::TerrainObjectType; + %obstruction = ContainerRayCast(%muzPoint, %pos, %obstructMask, %obj); + if (%obstruction) + %scanTarg = "0"; + } + + if(%scanTarg) + { + // there's still a target out there + %repTgt = firstWord(%scanTarg); + // is the target damaged? + if(%repTgt.getDamageLevel()) + { + if(%repTgt != %obj.repairing) + { + // the target is not the same as the one we were just repairing + // stop repairing old target, start repairing new target + stopRepairing(%obj); + if(isObject(%obj.repairing)) + stopRepairing(%obj); + + %obj.repairing = %repTgt; + // extract the name of what player is repairing based on what it is + // if it's a player, it's the player's name (duh) + // if it's an object, look for a nametag + // if object has no nametag, just say what it is (e.g. generatorLarge) + if(%repTgt.getClassName() $= Player) + %tgtName = getTaggedString(%repTgt.client.name); + else if(%repTgt.getGameName() !$= "") + %tgtName = %repTgt.getGameName(); + else + %tgtName = %repTgt.getDatablock().getName(); + messageClient(%obj.client, 'MsgRepairPackRepairingObj', '\c2Repairing %1.', %tgtName, %repTgt); + startRepairing(%obj, false); + } + else + { + // it's the same target as last time + // changed to fix "2 players can't repair same object" bug + if(%obj.repairProjectile == 0) + { + if(%repTgt.getClassName() $= Player) + %tgtName = getTaggedString(%repTgt.client.name); + else if(%repTgt.getGameName() !$= "") + %tgtName = %repTgt.getGameName(); + else + %tgtName = %repTgt.getDatablock().getName(); + messageClient(%obj.client, 'MsgRepairPackRepairingObj', '\c2Repairing %1.', %tgtName, %repTgt); + startRepairing(%obj, false); + } + } + } + else + { + %rateOfRepair = %this.repairFactorObject; + if(%repTgt.getClassName() $= Player) + { + %tgtName = getTaggedString(%repTgt.client.name); + %rateOfRepair = %this.repairFactorPlayer; + } + else if(%repTgt.getGameName() !$= "") + %tgtName = %repTgt.getGameName(); + else + %tgtName = %repTgt.getDatablock().getName(); + if(%repTgt != %obj.repairing) + { + // it isn't the same object we were repairing previously + messageClient(%obj.client, 'MsgRepairPackNotDamaged', '\c2%1 is not damaged.', %tgtName); + } + else + { + // same target, but not damaged -- we must be done + messageClient(%obj.client, 'MsgRepairPackDone', '\c2Repairs completed.'); + Game.objectRepaired(%repTgt, %tgtName); + } + %obj.errMsgSent = true; + stopRepairing(%obj); + } + } + else + { + // whoops, we lost our target + messageClient(%obj.client, 'MsgRepairPackLostTarget', '\c2Repair target no longer in range.'); + stopRepairing(%obj); + } + } + } +} + +function RepairGunImage::onDeactivate(%this,%obj,%slot) +{ + stopRepairing(%obj); +} + +function stopRepairing(%player) +{ + // %player = the player who was using the repair pack + + if(%player.selfRepairing) + { + // there is no projectile for self-repairing + %player.setRepairRate(%player.getRepairRate() - %player.repairingRate); + %player.selfRepairing = false; + } + else if(%player.repairing > 0) + { + // player was repairing something else + //if(%player.repairing.beingRepaired > 0) + //{ + // don't decrement this stuff if it's already at 0 -- though it shouldn't be + //%player.repairing.beingRepaired--; + %player.repairing.setRepairRate(%player.repairing.getRepairRate() - %player.repairingRate); + //} + if(%player.repairProjectile > 0) + { + // is there a repair projectile? delete it + %player.repairProjectile.delete(); + %player.repairProjectile = 0; + } + } + %player.repairing = 0; + %player.repairingRate = 0; + %player.setImageTrigger($WeaponSlot, false); + %player.setImageLoaded($WeaponSlot, false); +} + +function startRepairing(%player, %self) +{ + // %player = the player who was using the repair pack + // %self = boolean -- is player repairing him/herself? + + if(%self) + { + // one repair, hold the projectile + %player.setRepairRate(%player.getRepairRate() + RepairGunImage.repairFactorPlayer); + %player.selfRepairing = true; + %player.repairingRate = RepairGunImage.repairFactorPlayer; + } + else + { + //if(%player.repairing.beingRepaired $= "") + // %player.repairing.beingRepaired = 1; + //else + // %player.repairing.beingRepaired++; + + //AI hack... + if (%player.client.isAIControlled() && %player.client.repairObject == %player.repairing) + { + %initialPosition = %player.getMuzzlePoint($WeaponSlot); + %initialDirection = VectorSub(%initialPosition, %player.repairing.getWorldBoxCenter()); + } + else + { + %initialDirection = %player.getMuzzleVector($WeaponSlot); + %initialPosition = %player.getMuzzlePoint($WeaponSlot); + } + if(%player.repairing.getClassName() $= Player) + %repRate = RepairGunImage.repairFactorPlayer; + else + %repRate = RepairGunImage.repairFactorObject; + %player.repairing.setRepairRate(%player.repairing.getRepairRate() + %repRate); + + %player.repairingRate = %repRate; + %player.repairProjectile = new RepairProjectile() { + dataBlock = DefaultRepairBeam; + initialDirection = %initialDirection; + initialPosition = %initialPosition; + sourceObject = %player; + sourceSlot = $WeaponSlot; + targetObject = %player.repairing; + }; + // ---------------------------------------------------- + // z0dd - ZOD, 5/27/02. Fix lingering projectile bug + if(isObject(%player.lastProjectile)) + %player.lastProjectile.delete(); + + %player.lastProjectile = %player.repairProjectile; + // End z0dd - ZOD + // ---------------------------------------------------- + MissionCleanup.add(%player.repairProjectile); + } +} + +function RepairPack::onPickup(%this, %obj, %shape, %amount) +{ + // created to prevent console errors } \ No newline at end of file diff --git a/scripts/packs/satchelCharge.cs b/scripts/packs/satchelCharge.cs index 28ded35..46d4ca8 100644 --- a/scripts/packs/satchelCharge.cs +++ b/scripts/packs/satchelCharge.cs @@ -1,843 +1,843 @@ -//-------------------------------------------------------------------------- -// Satchel Charge pack -// can be used by any armor type -// when activated, throws the pack -- when activated again (before -// picking up another pack), detonates with a BIG explosion. - -//-------------------------------------------------------------------------- -// Sounds - -datablock EffectProfile(SatchelChargeActivateEffect) -{ - effectname = "packs/satchel_pack_activate"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(SatchelChargeExplosionEffect) -{ - effectname = "packs/satchel_pack_detonate"; - minDistance = 2.5; - maxDistance = 5.0; -}; - -datablock EffectProfile(SatchelChargePreExplosionEffect) -{ - effectname = "explosions/explosion.xpl03"; - minDistance = 10.0; - maxDistance = 30.0; -}; - -datablock AudioProfile(SatchelChargeActivateSound) -{ - filename = "fx/packs/satchel_pack_activate.wav"; - description = AudioClose3d; - preload = true; - effect = SatchelChargeActivateEffect; -}; - -datablock AudioProfile(SatchelChargeExplosionSound) -{ - filename = "fx/packs/satchel_pack_detonate.wav"; - description = AudioBIGExplosion3d; - preload = true; - effect = SatchelChargeExplosionEffect; -}; - -datablock AudioProfile(SatchelChargePreExplosionSound) -{ - filename = "fx/explosions/explosion.xpl03.wav"; - description = AudioBIGExplosion3d; - preload = true; - effect = SatchelChargePreExplosionEffect; -}; - -datablock AudioProfile(UnderwaterSatchelChargeExplosionSound) -{ - filename = "fx/weapons/mortar_explode_UW.wav"; - description = AudioBIGExplosion3d; - preload = true; - effect = SatchelChargeExplosionEffect; -}; - -//---------------------------------------------------------------------------- -// Satchel Debris -//---------------------------------------------------------------------------- -datablock ParticleData( SDebrisSmokeParticle ) -{ - dragCoeffiecient = 1.0; - gravityCoefficient = 0.0; - inheritedVelFactor = 0.2; - - lifetimeMS = 1000; - lifetimeVarianceMS = 100; - - textureName = "particleTest"; - - useInvAlpha = true; - - spinRandomMin = -60.0; - spinRandomMax = 60.0; - - colors[0] = "0.4 0.4 0.4 1.0"; - colors[1] = "0.3 0.3 0.3 0.5"; - colors[2] = "0.0 0.0 0.0 0.0"; - sizes[0] = 0.0; - sizes[1] = 2.0; - sizes[2] = 3.0; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData( SDebrisSmokeEmitter ) -{ - ejectionPeriodMS = 7; - periodVarianceMS = 1; - - ejectionVelocity = 1.0; // A little oomph at the back end - velocityVariance = 0.2; - - thetaMin = 0.0; - thetaMax = 40.0; - - particles = "SDebrisSmokeParticle"; -}; - - -datablock DebrisData( SatchelDebris ) -{ - emitters[0] = SDebrisSmokeEmitter; - - explodeOnMaxBounce = true; - - elasticity = 0.4; - friction = 0.2; - - lifetime = 0.3; - lifetimeVariance = 0.02; -}; - -//---------------------------------------------------------------------------- -// Bubbles -//---------------------------------------------------------------------------- -datablock ParticleData(SatchelBubbleParticle) -{ - dragCoefficient = 0.0; - gravityCoefficient = -0.25; - inheritedVelFactor = 0.0; - constantAcceleration = 0.0; - lifetimeMS = 1500; - lifetimeVarianceMS = 600; - useInvAlpha = false; - textureName = "special/bubbles"; - - spinRandomMin = -100.0; - spinRandomMax = 100.0; - - colors[0] = "0.7 0.8 1.0 0.0"; - colors[1] = "0.7 0.8 1.0 0.4"; - colors[2] = "0.7 0.8 1.0 0.0"; - sizes[0] = 2.0; - sizes[1] = 2.0; - sizes[2] = 2.0; - times[0] = 0.0; - times[1] = 0.8; - times[2] = 1.0; -}; - -datablock ParticleEmitterData(SatchelBubbleEmitter) -{ - ejectionPeriodMS = 10; - periodVarianceMS = 0; - ejectionVelocity = 1.0; - ejectionOffset = 7.0; - velocityVariance = 0.5; - thetaMin = 0; - thetaMax = 80; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - particles = "MortarExplosionBubbleParticle"; -}; - -//-------------------------------------------------------------------------- -// Satchel Explosion Particle effects -//-------------------------------------- -datablock ParticleData(SatchelExplosionSmoke) -{ - dragCoeffiecient = 0.4; - gravityCoefficient = -0.0; // rises slowly - inheritedVelFactor = 0.025; - - lifetimeMS = 2000; - lifetimeVarianceMS = 0; - - textureName = "particleTest"; - - useInvAlpha = true; - spinRandomMin = -200.0; - spinRandomMax = 200.0; - - textureName = "special/Smoke/smoke_001"; - - colors[0] = "1.0 0.7 0.0 1.0"; - colors[1] = "0.2 0.2 0.2 0.5"; - colors[2] = "0.0 0.0 0.0 0.0"; - sizes[0] = 7.0; - sizes[1] = 17.0; - sizes[2] = 2.0; - times[0] = 0.0; - times[1] = 0.4; - times[2] = 1.0; -}; - -datablock ParticleEmitterData(SatchelExplosionSmokeEmitter) -{ - ejectionPeriodMS = 10; - periodVarianceMS = 0; - - ejectionVelocity = 14.25; - velocityVariance = 2.25; - - thetaMin = 0.0; - thetaMax = 180.0; - - lifetimeMS = 200; - - particles = "SatchelExplosionSmoke"; -}; - -datablock ParticleData(UnderwaterSatchelExplosionSmoke) -{ - dragCoeffiecient = 105.0; - gravityCoefficient = -0.0; - inheritedVelFactor = 0.025; - - constantAcceleration = -1.0; - - lifetimeMS = 1500; - lifetimeVarianceMS = 0; - - textureName = "particleTest"; - - useInvAlpha = false; - spinRandomMin = -200.0; - spinRandomMax = 200.0; - - textureName = "special/Smoke/smoke_001"; - - colors[0] = "0.4 0.4 1.0 1.0"; - colors[1] = "0.4 0.4 1.0 0.5"; - colors[2] = "0.0 0.0 0.0 0.0"; - sizes[0] = 7.0; - sizes[1] = 17.0; - sizes[2] = 2.0; - times[0] = 0.0; - times[1] = 0.2; - times[2] = 1.0; -}; - -datablock ParticleEmitterData(UnderwaterSatchelExplosionSmokeEmitter) -{ - ejectionPeriodMS = 10; - periodVarianceMS = 0; - - ejectionVelocity = 14.25; - velocityVariance = 2.25; - - thetaMin = 0.0; - thetaMax = 180.0; - - lifetimeMS = 200; - - particles = "UnderwaterSatchelExplosionSmoke"; -}; - - -datablock ParticleData(SatchelSparks) -{ - dragCoefficient = 1; - gravityCoefficient = 0.0; - inheritedVelFactor = 0.2; - constantAcceleration = 0.0; - lifetimeMS = 500; - lifetimeVarianceMS = 150; - textureName = "special/bigSpark"; - colors[0] = "0.56 0.36 0.26 1.0"; - colors[1] = "0.56 0.36 0.26 1.0"; - colors[2] = "1.0 0.36 0.26 0.0"; - sizes[0] = 0.5; - sizes[1] = 0.5; - sizes[2] = 0.75; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - -}; - -datablock ParticleEmitterData(SatchelSparksEmitter) -{ - ejectionPeriodMS = 1; - periodVarianceMS = 0; - ejectionVelocity = 40; - velocityVariance = 20.0; - ejectionOffset = 0.0; - thetaMin = 0; - thetaMax = 180; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - orientParticles = true; - lifetimeMS = 200; - particles = "SatchelSparks"; -}; - -datablock ParticleData(UnderwaterSatchelSparks) -{ - dragCoefficient = 1; - gravityCoefficient = 0.0; - inheritedVelFactor = 0.2; - constantAcceleration = 0.0; - lifetimeMS = 500; - lifetimeVarianceMS = 350; - textureName = "special/underwaterSpark"; - colors[0] = "0.6 0.6 1.0 1.0"; - colors[1] = "0.6 0.6 1.0 1.0"; - colors[2] = "0.6 0.6 1.0 0.0"; - sizes[0] = 0.5; - sizes[1] = 0.5; - sizes[2] = 0.75; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - -}; - -datablock ParticleEmitterData(UnderwaterSatchelSparksEmitter) -{ - ejectionPeriodMS = 2; - periodVarianceMS = 0; - ejectionVelocity = 30; - velocityVariance = 5.0; - ejectionOffset = 0.0; - thetaMin = 0; - thetaMax = 70; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - orientParticles = true; - lifetimeMS = 100; - particles = "UnderwaterSatchelSparks"; -}; - - -//--------------------------------------------------------------------------- -// Explosion -//--------------------------------------------------------------------------- - -datablock ExplosionData(SatchelSubExplosion) -{ - explosionShape = "disc_explosion.dts"; - faceViewer = true; - explosionScale = "0.5 0.5 0.5"; - - debris = SatchelDebris; - debrisThetaMin = 10; - debrisThetaMax = 80; - debrisNum = 8; - debrisVelocity = 60.0; - debrisVelocityVariance = 15.0; - - lifetimeMS = 1000; - delayMS = 0; - - emitter[0] = SatchelExplosionSmokeEmitter; - emitter[1] = SatchelSparksEmitter; - - offset = 0.0; - - playSpeed = 1.5; - - sizes[0] = "1.5 1.5 1.5"; - sizes[1] = "3.0 3.0 3.0"; - times[0] = 0.0; - times[1] = 1.0; -}; - -datablock ExplosionData(SatchelSubExplosion2) -{ - explosionShape = "disc_explosion.dts"; - faceViewer = true; - explosionScale = "0.7 0.7 0.7"; - - debris = SatchelDebris; - debrisThetaMin = 10; - debrisThetaMax = 170; - debrisNum = 8; - debrisVelocity = 60.0; - debrisVelocityVariance = 15.0; - - lifetimeMS = 1000; - delayMS = 50; - - emitter[0] = SatchelExplosionSmokeEmitter; - emitter[1] = SatchelSparksEmitter; - - offset = 9.0; - - playSpeed = 1.5; - - sizes[0] = "1.5 1.5 1.5"; - sizes[1] = "1.5 1.5 1.5"; - times[0] = 0.0; - times[1] = 1.0; -}; - -datablock ExplosionData(SatchelSubExplosion3) -{ - explosionShape = "disc_explosion.dts"; - faceViewer = true; - explosionScale = "1.0 1.0 1.0"; - - debris = SatchelDebris; - debrisThetaMin = 10; - debrisThetaMax = 170; - debrisNum = 8; - debrisVelocity = 60.0; - debrisVelocityVariance = 15.0; - - lifetimeMS = 2000; - delayMS = 100; - - emitter[0] = SatchelExplosionSmokeEmitter; - emitter[1] = SatchelSparksEmitter; - - offset = 9.0; - - playSpeed = 2.5; - - sizes[0] = "1.0 1.0 1.0"; - sizes[1] = "1.0 1.0 1.0"; - times[0] = 0.0; - times[1] = 1.0; -}; - -datablock ExplosionData(SatchelMainExplosion) -{ - soundProfile = SatchelChargePreExplosionSound; - - subExplosion[0] = SatchelSubExplosion; - subExplosion[1] = SatchelSubExplosion2; - subExplosion[2] = SatchelSubExplosion3; -}; - -//--------------------------------------------------------------------------- -// Underwater Explosion -//--------------------------------------------------------------------------- - -datablock ExplosionData(UnderwaterSatchelSubExplosion) -{ - explosionShape = "disc_explosion.dts"; - faceViewer = true; - explosionScale = "0.5 0.5 0.5"; - - - lifetimeMS = 1000; - delayMS = 0; - - emitter[0] = UnderwaterSatchelExplosionSmokeEmitter; - emitter[1] = UnderwaterSatchelSparksEmitter; - emitter[2] = SatchelBubbleEmitter; - - offset = 0.0; - - playSpeed = 0.75; - - sizes[0] = "1.5 1.5 1.5"; - sizes[1] = "2.5 2.5 2.5"; - sizes[2] = "2.0 2.0 2.0"; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ExplosionData(UnderwaterSatchelSubExplosion2) -{ - explosionShape = "disc_explosion.dts"; - faceViewer = true; - explosionScale = "0.7 0.7 0.7"; - - - lifetimeMS = 1000; - delayMS = 50; - - emitter[0] = UnderwaterSatchelExplosionSmokeEmitter; - emitter[1] = UnderwaterSatchelSparksEmitter; - emitter[2] = SatchelBubbleEmitter; - - offset = 9.0; - - playSpeed = 0.75; - - sizes[0] = "1.5 1.5 1.5"; - sizes[1] = "1.0 1.0 1.0"; - sizes[2] = "0.75 0.75 0.75"; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ExplosionData(UnderwaterSatchelSubExplosion3) -{ - explosionShape = "disc_explosion.dts"; - faceViewer = true; - explosionScale = "1.0 1.0 1.0"; - - - lifetimeMS = 2000; - delayMS = 100; - - emitter[0] = UnderwaterSatchelExplosionSmokeEmitter; - emitter[1] = UnderwaterSatchelSparksEmitter; - emitter[2] = SatchelBubbleEmitter; - - offset = 9.0; - - playSpeed = 1.25; - - sizes[0] = "1.0 1.0 1.0"; - sizes[1] = "1.0 1.0 1.0"; - sizes[2] = "0.5 0.5 0.5"; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ExplosionData(UnderwaterSatchelMainExplosion) -{ - soundProfile = UnderwaterSatchelChargeExplosionSound; - - subExplosion[0] = UnderwaterSatchelSubExplosion; - subExplosion[1] = UnderwaterSatchelSubExplosion2; - subExplosion[2] = UnderwaterSatchelSubExplosion3; -}; - - -//-------------------------------------------------------------------------- -// Projectile - -//------------------------------------------------------------------------- -// shapebase datablocks -datablock ShapeBaseImageData(SatchelChargeImage) -{ - shapeFile = "pack_upgrade_satchel.dts"; - item = SatchelCharge; - mountPoint = 1; - offset = "0 0 0"; - emap = true; -}; - -datablock ItemData(SatchelCharge) -{ - className = Pack; - catagory = "Packs"; - image = SatchelChargeImage; - shapeFile = "pack_upgrade_satchel.dts"; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - rotate = true; - pickUpName = "a satchel charge pack"; - - computeCRC = true; -}; - -datablock ItemData(SatchelChargeTossed) -{ - shapeFile = "pack_upgrade_satchel.dts"; - mass = 1.2; - elasticity = 0.1; - friction = 0.9; - rotate = false; - pickupRadius = 0; - noTimeout = true; - sticky = true; -}; - -datablock StaticShapeData(SatchelChargeThrown) : StaticShapeDamageProfile -{ - shapeFile = "pack_upgrade_satchel.dts"; - explosion = SatchelMainExplosion; - underwaterExplosion = UnderwaterSatchelMainExplosion; - armDelay = 2500; - maxDamage = 0.6; - - disabledLevel = 0.5; - destroyedLevel = 0.6; - dynamicType = $TypeMasks::StaticShapeObjectType; - renderWhenDestroyed = false; - - kickBackStrength = 4000; -}; - -//-------------------------------------------------------------------------- - -function SatchelCharge::onUse(%this, %obj) -{ - %item = new Item() { - dataBlock = SatchelChargeTossed; - rotation = "0 0 1 " @ (getRandom() * 360); - }; - MissionCleanup.add(%item); - // take pack out of inventory and unmount image - %obj.decInventory(SatchelCharge, 1); - %obj.throwObject(%item); - %item.sourceObject = %obj; - - // z0dd - ZOD, 5/16/02. Schedule a check to see if the satchel is at rest but not stuck to anything - %item.checkCount = 0; - %item.velocCheck = %item.getDataBlock().schedule(1000, "checkVelocity", %item); -} - -function initArmSatchelCharge(%satchel) -{ - // "deet deet deet" sound - %satchel.playAudio(1, SatchelChargeActivateSound); - // also need to play "antenna extending" animation - %satchel.playThread(0, "deploy"); - %satchel.playThread(1, "activate"); - - // delay the actual arming until after sound is done playing - schedule( 2200, 0, "armSatchelCharge", %satchel ); -} - -function armSatchelCharge(%satchel) -{ - %satchel.armed = true; - commandToClient( %satchel.sourceObject.client, 'setSatchelArmed' ); -} - -function detonateSatchelCharge(%player) -{ - %satchelCharge = %player.thrownChargeId; - // can't detonate the satchel charge if it isn't armed - if(!%satchelCharge.armed) - return; - - //error("Detonating satchel charge #" @ %satchelCharge @ " for player #" @ %player); - - if(%satchelCharge.getDamageState() !$= Destroyed) - { - %satchelCharge.setDamageState(Destroyed); - %satchelCharge.blowup(); - } - - // Clear the player's HUD: - %player.client.clearBackpackIcon(); -} - -function SatchelChargeThrown::onEnterLiquid(%data, %obj, %coverage, %type) -{ - // lava types - if(%type >=4 && %type <= 6) - { - if(%obj.getDamageState() !$= "Destroyed") - { - %obj.armed = true; - detonateSatchelCharge(%obj.sourceObject); - return; - } - } - - // quickSand - if(%type == 7) - if(isObject(%obj.sourceObject)) - %obj.sourceObject.thrownChargeId = 0; - - Parent::onEnterLiquid(%data, %obj, %coverage, %type); -} - -function SatchelChargeImage::onMount(%data, %obj, %node) -{ - %obj.thrownChargeId = 0; -} - -function SatchelChargeImage::onUnmount(%data, %obj, %node) -{ -} - -function SatchelChargeThrown::onDestroyed(%this, %object, %lastState) -{ - if(%object.kaboom) - return; - else - { - %object.kaboom = true; - - // the "thwart" flag is set if the charge is destroyed with weapons rather - // than detonated. A less damaging explosion, but visually the same scale. - if(%object.thwart) - { - messageClient(%object.sourceObject.client, 'msgSatchelChargeDetonate', "\c2Satchel charge destroyed."); - %dmgRadius = 15; // z0dd - ZOD, 9/27/02. Was 10 - %dmgMod = 0.35; // z0dd - ZOD, 9/27/02. Was 0.3 - %expImpulse = 2000; // z0dd - ZOD, 9/27/02. Was 1000 - %dmgType = $DamageType::Explosion; - } - else - { - messageClient(%object.sourceObject.client, 'msgSatchelChargeDetonate', "\c2Satchel charge detonated!"); - %dmgRadius = 25; // z0dd - ZOD, 9/27/02. Was 20 - %dmgMod = 1.15; // z0dd - ZOD, 9/27/02. Was 1.0 - %expImpulse = 5000; // z0dd - ZOD, 9/27/02. Was 2500 - %dmgType = $DamageType::SatchelCharge; - } - - %object.blowingUp = true; - RadiusExplosion(%object, %object.getPosition(), %dmgRadius, %dmgMod, %expImpulse, %object.sourceObject, %dmgType); - - %object.schedule(1000, "delete"); - } - - // -------------------------------------------------------------------------------- - // z0dd - ZOD, 4/25/02. Satchel bug fix. Prior to fix, clients couldn't pick up - // packs when satchel was destroyed from dmg - if(isObject(%object.sourceObject)) - %object.sourceObject.thrownChargeId = 0; - // -------------------------------------------------------------------------------- -} - -function SatchelChargeThrown::onCollision(%data,%obj,%col) -{ - // Do nothing... -} - -function SatchelChargeThrown::damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType) -{ - if (!%object.blowingUp) - { - %targetObject.damaged += %amount; - - if(%targetObject.damaged >= %targetObject.getDataBlock().maxDamage && - %targetObject.getDamageState() !$= Destroyed) - { - %targetObject.thwart = true; - %targetObject.setDamageState(Destroyed); - %targetObject.blowup(); - - // clear the player's HUD: - %targetObject.sourceObject.client.clearBackPackIcon(); - } - } -} - -function SatchelCharge::onPickup(%this, %obj, %shape, %amount) -{ - // created to prevent console errors -} - -//************************************************************** -// STICKY SATCHEL FUNCTIONS: z0dd - ZOD, 5/16/02 -//************************************************************** - -function SatchelChargeTossed::onEnterLiquid(%data, %obj, %coverage, %type) -{ - // If it lands in lava or quicksand, delete it - if(%type >=4 && %type <= 7) - { - cancel(%obj.velocCheck); - if(isObject(%obj.sourceObject)) - %obj.sourceObject.thrownChargeId = 0; - - %obj.sourceObject.client.clearBackPackIcon(); - %obj.schedule(100, "delete"); - } - else - cancel(%obj.velocCheck); -} - -function SatchelChargeTossed::onLeaveLiquid(%data, %obj, %type) -{ - // On the off chance it passes through to air, reschedule the velocity check - %obj.checkCount = 0; - %obj.velocCheck = %obj.getDataBlock().schedule(1000, "checkVelocity", %obj); -} - -function SatchelChargeTossed::onCollision(%data, %obj, %col) -{ - // Lets keep thing from floating mid air, the check velocity should handle it afterwards - if(%col.getType() & ($TypeMasks::PlayerObjectType | $TypeMasks::VehicleObjectType | $TypeMasks::TurretObjectType)) - { - %vec = (-1.0 + getRandom() * 2.0) SPC (-1.0 + getRandom() * 2.0) SPC getRandom(); - %vec = vectorScale(%vec, 15); - %pos = %col.getWorldBoxCenter(); - %obj.applyImpulse(%pos, %vec); - } -} - -function SatchelChargeTossed::checkVelocity(%data, %item) -{ - %item.checkCount++; - if(VectorLen(%item.getVelocity()) < 0.1) - { - // Satchel has come to rest but not activated, probably on a - // staticshape (station, gen, etc) lets force activation - cancel(%item.velocCheck); - activateSatchel(posFromTransform(%item.getTransform()), rotFromTransform(%item.getTransform()), %item.sourceObject); - %item.schedule(100, "delete"); - } - else if(%item.checkCount >= 6) - { - // satchel's still moving but it's been checked several times, - // probably thrown off face of earth, delete it - cancel(%item.velocCheck); - if(isObject(%item.sourceObject)) - %item.sourceObject.thrownChargeId = 0; - - %item.sourceObject.client.clearBackPackIcon(); - %item.schedule(100, "delete"); - } - else - { - // check back in a little while - %item.velocCheck = %data.schedule(1000, "checkVelocity", %item); - } -} - -function SatchelChargeTossed::onStickyCollision(%data, %obj) -{ - // We have sticky! Lets setup for the actual charge - cancel(%obj.velocCheck); - %pos = %obj.getLastStickyPos(); - %norm = %obj.getLastStickyNormal(); - %intAngle = getTerrainAngle(%norm); - %rotAxis = vectorNormalize(vectorCross(%norm, "0 0 1")); - if (getWord(%norm, 2) == 1 || getWord(%norm, 2) == -1) - %rotAxis = vectorNormalize(vectorCross(%norm, "0 1 0")); - - %rot = %rotAxis @ " " @ %intAngle; - activateSatchel(%pos, %rot, %obj.sourceObject); - %obj.schedule(50, "delete"); -} - -function activateSatchel(%pos, %rot, %source) -{ - // Create the charge and schedule arming - %satchel = new StaticShape() { - dataBlock = SatchelChargeThrown; - sourceObject = %source; - position = %pos; - rotation = %rot; - }; - MissionCleanup.add(%satchel); - %source.thrownChargeId = %satchel; - %satchel.armed = false; - %satchel.damaged = 0.0; - %satchel.thwart = false; - - // arm itself 2.5 seconds after creation - schedule(%satchel.getDatablock().armDelay, %satchel, "initArmSatchelCharge", %satchel); - messageClient(%source.client, 'MsgSatchelChargePlaced', "\c2Satchel charge deployed."); -} +//-------------------------------------------------------------------------- +// Satchel Charge pack +// can be used by any armor type +// when activated, throws the pack -- when activated again (before +// picking up another pack), detonates with a BIG explosion. + +//-------------------------------------------------------------------------- +// Sounds + +datablock EffectProfile(SatchelChargeActivateEffect) +{ + effectname = "packs/satchel_pack_activate"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock EffectProfile(SatchelChargeExplosionEffect) +{ + effectname = "packs/satchel_pack_detonate"; + minDistance = 2.5; + maxDistance = 5.0; +}; + +datablock EffectProfile(SatchelChargePreExplosionEffect) +{ + effectname = "explosions/explosion.xpl03"; + minDistance = 10.0; + maxDistance = 30.0; +}; + +datablock AudioProfile(SatchelChargeActivateSound) +{ + filename = "fx/packs/satchel_pack_activate.wav"; + description = AudioClose3d; + preload = true; + effect = SatchelChargeActivateEffect; +}; + +datablock AudioProfile(SatchelChargeExplosionSound) +{ + filename = "fx/packs/satchel_pack_detonate.wav"; + description = AudioBIGExplosion3d; + preload = true; + effect = SatchelChargeExplosionEffect; +}; + +datablock AudioProfile(SatchelChargePreExplosionSound) +{ + filename = "fx/explosions/explosion.xpl03.wav"; + description = AudioBIGExplosion3d; + preload = true; + effect = SatchelChargePreExplosionEffect; +}; + +datablock AudioProfile(UnderwaterSatchelChargeExplosionSound) +{ + filename = "fx/weapons/mortar_explode_UW.wav"; + description = AudioBIGExplosion3d; + preload = true; + effect = SatchelChargeExplosionEffect; +}; + +//---------------------------------------------------------------------------- +// Satchel Debris +//---------------------------------------------------------------------------- +datablock ParticleData( SDebrisSmokeParticle ) +{ + dragCoeffiecient = 1.0; + gravityCoefficient = 0.0; + inheritedVelFactor = 0.2; + + lifetimeMS = 1000; + lifetimeVarianceMS = 100; + + textureName = "particleTest"; + + useInvAlpha = true; + + spinRandomMin = -60.0; + spinRandomMax = 60.0; + + colors[0] = "0.4 0.4 0.4 1.0"; + colors[1] = "0.3 0.3 0.3 0.5"; + colors[2] = "0.0 0.0 0.0 0.0"; + sizes[0] = 0.0; + sizes[1] = 2.0; + sizes[2] = 3.0; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; +}; + +datablock ParticleEmitterData( SDebrisSmokeEmitter ) +{ + ejectionPeriodMS = 7; + periodVarianceMS = 1; + + ejectionVelocity = 1.0; // A little oomph at the back end + velocityVariance = 0.2; + + thetaMin = 0.0; + thetaMax = 40.0; + + particles = "SDebrisSmokeParticle"; +}; + + +datablock DebrisData( SatchelDebris ) +{ + emitters[0] = SDebrisSmokeEmitter; + + explodeOnMaxBounce = true; + + elasticity = 0.4; + friction = 0.2; + + lifetime = 0.3; + lifetimeVariance = 0.02; +}; + +//---------------------------------------------------------------------------- +// Bubbles +//---------------------------------------------------------------------------- +datablock ParticleData(SatchelBubbleParticle) +{ + dragCoefficient = 0.0; + gravityCoefficient = -0.25; + inheritedVelFactor = 0.0; + constantAcceleration = 0.0; + lifetimeMS = 1500; + lifetimeVarianceMS = 600; + useInvAlpha = false; + textureName = "special/bubbles"; + + spinRandomMin = -100.0; + spinRandomMax = 100.0; + + colors[0] = "0.7 0.8 1.0 0.0"; + colors[1] = "0.7 0.8 1.0 0.4"; + colors[2] = "0.7 0.8 1.0 0.0"; + sizes[0] = 2.0; + sizes[1] = 2.0; + sizes[2] = 2.0; + times[0] = 0.0; + times[1] = 0.8; + times[2] = 1.0; +}; + +datablock ParticleEmitterData(SatchelBubbleEmitter) +{ + ejectionPeriodMS = 10; + periodVarianceMS = 0; + ejectionVelocity = 1.0; + ejectionOffset = 7.0; + velocityVariance = 0.5; + thetaMin = 0; + thetaMax = 80; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + particles = "MortarExplosionBubbleParticle"; +}; + +//-------------------------------------------------------------------------- +// Satchel Explosion Particle effects +//-------------------------------------- +datablock ParticleData(SatchelExplosionSmoke) +{ + dragCoeffiecient = 0.4; + gravityCoefficient = -0.0; // rises slowly + inheritedVelFactor = 0.025; + + lifetimeMS = 2000; + lifetimeVarianceMS = 0; + + textureName = "particleTest"; + + useInvAlpha = true; + spinRandomMin = -200.0; + spinRandomMax = 200.0; + + textureName = "special/Smoke/smoke_001"; + + colors[0] = "1.0 0.7 0.0 1.0"; + colors[1] = "0.2 0.2 0.2 0.5"; + colors[2] = "0.0 0.0 0.0 0.0"; + sizes[0] = 7.0; + sizes[1] = 17.0; + sizes[2] = 2.0; + times[0] = 0.0; + times[1] = 0.4; + times[2] = 1.0; +}; + +datablock ParticleEmitterData(SatchelExplosionSmokeEmitter) +{ + ejectionPeriodMS = 10; + periodVarianceMS = 0; + + ejectionVelocity = 14.25; + velocityVariance = 2.25; + + thetaMin = 0.0; + thetaMax = 180.0; + + lifetimeMS = 200; + + particles = "SatchelExplosionSmoke"; +}; + +datablock ParticleData(UnderwaterSatchelExplosionSmoke) +{ + dragCoeffiecient = 105.0; + gravityCoefficient = -0.0; + inheritedVelFactor = 0.025; + + constantAcceleration = -1.0; + + lifetimeMS = 1500; + lifetimeVarianceMS = 0; + + textureName = "particleTest"; + + useInvAlpha = false; + spinRandomMin = -200.0; + spinRandomMax = 200.0; + + textureName = "special/Smoke/smoke_001"; + + colors[0] = "0.4 0.4 1.0 1.0"; + colors[1] = "0.4 0.4 1.0 0.5"; + colors[2] = "0.0 0.0 0.0 0.0"; + sizes[0] = 7.0; + sizes[1] = 17.0; + sizes[2] = 2.0; + times[0] = 0.0; + times[1] = 0.2; + times[2] = 1.0; +}; + +datablock ParticleEmitterData(UnderwaterSatchelExplosionSmokeEmitter) +{ + ejectionPeriodMS = 10; + periodVarianceMS = 0; + + ejectionVelocity = 14.25; + velocityVariance = 2.25; + + thetaMin = 0.0; + thetaMax = 180.0; + + lifetimeMS = 200; + + particles = "UnderwaterSatchelExplosionSmoke"; +}; + + +datablock ParticleData(SatchelSparks) +{ + dragCoefficient = 1; + gravityCoefficient = 0.0; + inheritedVelFactor = 0.2; + constantAcceleration = 0.0; + lifetimeMS = 500; + lifetimeVarianceMS = 150; + textureName = "special/bigSpark"; + colors[0] = "0.56 0.36 0.26 1.0"; + colors[1] = "0.56 0.36 0.26 1.0"; + colors[2] = "1.0 0.36 0.26 0.0"; + sizes[0] = 0.5; + sizes[1] = 0.5; + sizes[2] = 0.75; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; + +}; + +datablock ParticleEmitterData(SatchelSparksEmitter) +{ + ejectionPeriodMS = 1; + periodVarianceMS = 0; + ejectionVelocity = 40; + velocityVariance = 20.0; + ejectionOffset = 0.0; + thetaMin = 0; + thetaMax = 180; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + orientParticles = true; + lifetimeMS = 200; + particles = "SatchelSparks"; +}; + +datablock ParticleData(UnderwaterSatchelSparks) +{ + dragCoefficient = 1; + gravityCoefficient = 0.0; + inheritedVelFactor = 0.2; + constantAcceleration = 0.0; + lifetimeMS = 500; + lifetimeVarianceMS = 350; + textureName = "special/underwaterSpark"; + colors[0] = "0.6 0.6 1.0 1.0"; + colors[1] = "0.6 0.6 1.0 1.0"; + colors[2] = "0.6 0.6 1.0 0.0"; + sizes[0] = 0.5; + sizes[1] = 0.5; + sizes[2] = 0.75; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; + +}; + +datablock ParticleEmitterData(UnderwaterSatchelSparksEmitter) +{ + ejectionPeriodMS = 2; + periodVarianceMS = 0; + ejectionVelocity = 30; + velocityVariance = 5.0; + ejectionOffset = 0.0; + thetaMin = 0; + thetaMax = 70; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + orientParticles = true; + lifetimeMS = 100; + particles = "UnderwaterSatchelSparks"; +}; + + +//--------------------------------------------------------------------------- +// Explosion +//--------------------------------------------------------------------------- + +datablock ExplosionData(SatchelSubExplosion) +{ + explosionShape = "disc_explosion.dts"; + faceViewer = true; + explosionScale = "0.5 0.5 0.5"; + + debris = SatchelDebris; + debrisThetaMin = 10; + debrisThetaMax = 80; + debrisNum = 8; + debrisVelocity = 60.0; + debrisVelocityVariance = 15.0; + + lifetimeMS = 1000; + delayMS = 0; + + emitter[0] = SatchelExplosionSmokeEmitter; + emitter[1] = SatchelSparksEmitter; + + offset = 0.0; + + playSpeed = 1.5; + + sizes[0] = "1.5 1.5 1.5"; + sizes[1] = "3.0 3.0 3.0"; + times[0] = 0.0; + times[1] = 1.0; +}; + +datablock ExplosionData(SatchelSubExplosion2) +{ + explosionShape = "disc_explosion.dts"; + faceViewer = true; + explosionScale = "0.7 0.7 0.7"; + + debris = SatchelDebris; + debrisThetaMin = 10; + debrisThetaMax = 170; + debrisNum = 8; + debrisVelocity = 60.0; + debrisVelocityVariance = 15.0; + + lifetimeMS = 1000; + delayMS = 50; + + emitter[0] = SatchelExplosionSmokeEmitter; + emitter[1] = SatchelSparksEmitter; + + offset = 9.0; + + playSpeed = 1.5; + + sizes[0] = "1.5 1.5 1.5"; + sizes[1] = "1.5 1.5 1.5"; + times[0] = 0.0; + times[1] = 1.0; +}; + +datablock ExplosionData(SatchelSubExplosion3) +{ + explosionShape = "disc_explosion.dts"; + faceViewer = true; + explosionScale = "1.0 1.0 1.0"; + + debris = SatchelDebris; + debrisThetaMin = 10; + debrisThetaMax = 170; + debrisNum = 8; + debrisVelocity = 60.0; + debrisVelocityVariance = 15.0; + + lifetimeMS = 2000; + delayMS = 100; + + emitter[0] = SatchelExplosionSmokeEmitter; + emitter[1] = SatchelSparksEmitter; + + offset = 9.0; + + playSpeed = 2.5; + + sizes[0] = "1.0 1.0 1.0"; + sizes[1] = "1.0 1.0 1.0"; + times[0] = 0.0; + times[1] = 1.0; +}; + +datablock ExplosionData(SatchelMainExplosion) +{ + soundProfile = SatchelChargePreExplosionSound; + + subExplosion[0] = SatchelSubExplosion; + subExplosion[1] = SatchelSubExplosion2; + subExplosion[2] = SatchelSubExplosion3; +}; + +//--------------------------------------------------------------------------- +// Underwater Explosion +//--------------------------------------------------------------------------- + +datablock ExplosionData(UnderwaterSatchelSubExplosion) +{ + explosionShape = "disc_explosion.dts"; + faceViewer = true; + explosionScale = "0.5 0.5 0.5"; + + + lifetimeMS = 1000; + delayMS = 0; + + emitter[0] = UnderwaterSatchelExplosionSmokeEmitter; + emitter[1] = UnderwaterSatchelSparksEmitter; + emitter[2] = SatchelBubbleEmitter; + + offset = 0.0; + + playSpeed = 0.75; + + sizes[0] = "1.5 1.5 1.5"; + sizes[1] = "2.5 2.5 2.5"; + sizes[2] = "2.0 2.0 2.0"; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; +}; + +datablock ExplosionData(UnderwaterSatchelSubExplosion2) +{ + explosionShape = "disc_explosion.dts"; + faceViewer = true; + explosionScale = "0.7 0.7 0.7"; + + + lifetimeMS = 1000; + delayMS = 50; + + emitter[0] = UnderwaterSatchelExplosionSmokeEmitter; + emitter[1] = UnderwaterSatchelSparksEmitter; + emitter[2] = SatchelBubbleEmitter; + + offset = 9.0; + + playSpeed = 0.75; + + sizes[0] = "1.5 1.5 1.5"; + sizes[1] = "1.0 1.0 1.0"; + sizes[2] = "0.75 0.75 0.75"; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; +}; + +datablock ExplosionData(UnderwaterSatchelSubExplosion3) +{ + explosionShape = "disc_explosion.dts"; + faceViewer = true; + explosionScale = "1.0 1.0 1.0"; + + + lifetimeMS = 2000; + delayMS = 100; + + emitter[0] = UnderwaterSatchelExplosionSmokeEmitter; + emitter[1] = UnderwaterSatchelSparksEmitter; + emitter[2] = SatchelBubbleEmitter; + + offset = 9.0; + + playSpeed = 1.25; + + sizes[0] = "1.0 1.0 1.0"; + sizes[1] = "1.0 1.0 1.0"; + sizes[2] = "0.5 0.5 0.5"; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; +}; + +datablock ExplosionData(UnderwaterSatchelMainExplosion) +{ + soundProfile = UnderwaterSatchelChargeExplosionSound; + + subExplosion[0] = UnderwaterSatchelSubExplosion; + subExplosion[1] = UnderwaterSatchelSubExplosion2; + subExplosion[2] = UnderwaterSatchelSubExplosion3; +}; + + +//-------------------------------------------------------------------------- +// Projectile + +//------------------------------------------------------------------------- +// shapebase datablocks +datablock ShapeBaseImageData(SatchelChargeImage) +{ + shapeFile = "pack_upgrade_satchel.dts"; + item = SatchelCharge; + mountPoint = 1; + offset = "0 0 0"; + emap = true; +}; + +datablock ItemData(SatchelCharge) +{ + className = Pack; + catagory = "Packs"; + image = SatchelChargeImage; + shapeFile = "pack_upgrade_satchel.dts"; + mass = 1; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 2; + rotate = true; + pickUpName = "a satchel charge pack"; + + computeCRC = true; +}; + +datablock ItemData(SatchelChargeTossed) +{ + shapeFile = "pack_upgrade_satchel.dts"; + mass = 1.2; + elasticity = 0.1; + friction = 0.9; + rotate = false; + pickupRadius = 0; + noTimeout = true; + sticky = true; +}; + +datablock StaticShapeData(SatchelChargeThrown) : StaticShapeDamageProfile +{ + shapeFile = "pack_upgrade_satchel.dts"; + explosion = SatchelMainExplosion; + underwaterExplosion = UnderwaterSatchelMainExplosion; + armDelay = 2500; + maxDamage = 0.6; + + disabledLevel = 0.5; + destroyedLevel = 0.6; + dynamicType = $TypeMasks::StaticShapeObjectType; + renderWhenDestroyed = false; + + kickBackStrength = 4000; +}; + +//-------------------------------------------------------------------------- + +function SatchelCharge::onUse(%this, %obj) +{ + %item = new Item() { + dataBlock = SatchelChargeTossed; + rotation = "0 0 1 " @ (getRandom() * 360); + }; + MissionCleanup.add(%item); + // take pack out of inventory and unmount image + %obj.decInventory(SatchelCharge, 1); + %obj.throwObject(%item); + %item.sourceObject = %obj; + + // z0dd - ZOD, 5/16/02. Schedule a check to see if the satchel is at rest but not stuck to anything + %item.checkCount = 0; + %item.velocCheck = %item.getDataBlock().schedule(1000, "checkVelocity", %item); +} + +function initArmSatchelCharge(%satchel) +{ + // "deet deet deet" sound + %satchel.playAudio(1, SatchelChargeActivateSound); + // also need to play "antenna extending" animation + %satchel.playThread(0, "deploy"); + %satchel.playThread(1, "activate"); + + // delay the actual arming until after sound is done playing + schedule( 2200, 0, "armSatchelCharge", %satchel ); +} + +function armSatchelCharge(%satchel) +{ + %satchel.armed = true; + commandToClient( %satchel.sourceObject.client, 'setSatchelArmed' ); +} + +function detonateSatchelCharge(%player) +{ + %satchelCharge = %player.thrownChargeId; + // can't detonate the satchel charge if it isn't armed + if(!%satchelCharge.armed) + return; + + //error("Detonating satchel charge #" @ %satchelCharge @ " for player #" @ %player); + + if(%satchelCharge.getDamageState() !$= Destroyed) + { + %satchelCharge.setDamageState(Destroyed); + %satchelCharge.blowup(); + } + + // Clear the player's HUD: + %player.client.clearBackpackIcon(); +} + +function SatchelChargeThrown::onEnterLiquid(%data, %obj, %coverage, %type) +{ + // lava types + if(%type >=4 && %type <= 6) + { + if(%obj.getDamageState() !$= "Destroyed") + { + %obj.armed = true; + detonateSatchelCharge(%obj.sourceObject); + return; + } + } + + // quickSand + if(%type == 7) + if(isObject(%obj.sourceObject)) + %obj.sourceObject.thrownChargeId = 0; + + Parent::onEnterLiquid(%data, %obj, %coverage, %type); +} + +function SatchelChargeImage::onMount(%data, %obj, %node) +{ + %obj.thrownChargeId = 0; +} + +function SatchelChargeImage::onUnmount(%data, %obj, %node) +{ +} + +function SatchelChargeThrown::onDestroyed(%this, %object, %lastState) +{ + if(%object.kaboom) + return; + else + { + %object.kaboom = true; + + // the "thwart" flag is set if the charge is destroyed with weapons rather + // than detonated. A less damaging explosion, but visually the same scale. + if(%object.thwart) + { + messageClient(%object.sourceObject.client, 'msgSatchelChargeDetonate', "\c2Satchel charge destroyed."); + %dmgRadius = 15; // z0dd - ZOD, 9/27/02. Was 10 + %dmgMod = 0.35; // z0dd - ZOD, 9/27/02. Was 0.3 + %expImpulse = 2000; // z0dd - ZOD, 9/27/02. Was 1000 + %dmgType = $DamageType::Explosion; + } + else + { + messageClient(%object.sourceObject.client, 'msgSatchelChargeDetonate', "\c2Satchel charge detonated!"); + %dmgRadius = 25; // z0dd - ZOD, 9/27/02. Was 20 + %dmgMod = 1.15; // z0dd - ZOD, 9/27/02. Was 1.0 + %expImpulse = 5000; // z0dd - ZOD, 9/27/02. Was 2500 + %dmgType = $DamageType::SatchelCharge; + } + + %object.blowingUp = true; + RadiusExplosion(%object, %object.getPosition(), %dmgRadius, %dmgMod, %expImpulse, %object.sourceObject, %dmgType); + + %object.schedule(1000, "delete"); + } + + // -------------------------------------------------------------------------------- + // z0dd - ZOD, 4/25/02. Satchel bug fix. Prior to fix, clients couldn't pick up + // packs when satchel was destroyed from dmg + if(isObject(%object.sourceObject)) + %object.sourceObject.thrownChargeId = 0; + // -------------------------------------------------------------------------------- +} + +function SatchelChargeThrown::onCollision(%data,%obj,%col) +{ + // Do nothing... +} + +function SatchelChargeThrown::damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType) +{ + if (!%object.blowingUp) + { + %targetObject.damaged += %amount; + + if(%targetObject.damaged >= %targetObject.getDataBlock().maxDamage && + %targetObject.getDamageState() !$= Destroyed) + { + %targetObject.thwart = true; + %targetObject.setDamageState(Destroyed); + %targetObject.blowup(); + + // clear the player's HUD: + %targetObject.sourceObject.client.clearBackPackIcon(); + } + } +} + +function SatchelCharge::onPickup(%this, %obj, %shape, %amount) +{ + // created to prevent console errors +} + +//************************************************************** +// STICKY SATCHEL FUNCTIONS: z0dd - ZOD, 5/16/02 +//************************************************************** + +function SatchelChargeTossed::onEnterLiquid(%data, %obj, %coverage, %type) +{ + // If it lands in lava or quicksand, delete it + if(%type >=4 && %type <= 7) + { + cancel(%obj.velocCheck); + if(isObject(%obj.sourceObject)) + %obj.sourceObject.thrownChargeId = 0; + + %obj.sourceObject.client.clearBackPackIcon(); + %obj.schedule(100, "delete"); + } + else + cancel(%obj.velocCheck); +} + +function SatchelChargeTossed::onLeaveLiquid(%data, %obj, %type) +{ + // On the off chance it passes through to air, reschedule the velocity check + %obj.checkCount = 0; + %obj.velocCheck = %obj.getDataBlock().schedule(1000, "checkVelocity", %obj); +} + +function SatchelChargeTossed::onCollision(%data, %obj, %col) +{ + // Lets keep thing from floating mid air, the check velocity should handle it afterwards + if(%col.getType() & ($TypeMasks::PlayerObjectType | $TypeMasks::VehicleObjectType | $TypeMasks::TurretObjectType)) + { + %vec = (-1.0 + getRandom() * 2.0) SPC (-1.0 + getRandom() * 2.0) SPC getRandom(); + %vec = vectorScale(%vec, 15); + %pos = %col.getWorldBoxCenter(); + %obj.applyImpulse(%pos, %vec); + } +} + +function SatchelChargeTossed::checkVelocity(%data, %item) +{ + %item.checkCount++; + if(VectorLen(%item.getVelocity()) < 0.1) + { + // Satchel has come to rest but not activated, probably on a + // staticshape (station, gen, etc) lets force activation + cancel(%item.velocCheck); + activateSatchel(posFromTransform(%item.getTransform()), rotFromTransform(%item.getTransform()), %item.sourceObject); + %item.schedule(100, "delete"); + } + else if(%item.checkCount >= 6) + { + // satchel's still moving but it's been checked several times, + // probably thrown off face of earth, delete it + cancel(%item.velocCheck); + if(isObject(%item.sourceObject)) + %item.sourceObject.thrownChargeId = 0; + + %item.sourceObject.client.clearBackPackIcon(); + %item.schedule(100, "delete"); + } + else + { + // check back in a little while + %item.velocCheck = %data.schedule(1000, "checkVelocity", %item); + } +} + +function SatchelChargeTossed::onStickyCollision(%data, %obj) +{ + // We have sticky! Lets setup for the actual charge + cancel(%obj.velocCheck); + %pos = %obj.getLastStickyPos(); + %norm = %obj.getLastStickyNormal(); + %intAngle = getTerrainAngle(%norm); + %rotAxis = vectorNormalize(vectorCross(%norm, "0 0 1")); + if (getWord(%norm, 2) == 1 || getWord(%norm, 2) == -1) + %rotAxis = vectorNormalize(vectorCross(%norm, "0 1 0")); + + %rot = %rotAxis @ " " @ %intAngle; + activateSatchel(%pos, %rot, %obj.sourceObject); + %obj.schedule(50, "delete"); +} + +function activateSatchel(%pos, %rot, %source) +{ + // Create the charge and schedule arming + %satchel = new StaticShape() { + dataBlock = SatchelChargeThrown; + sourceObject = %source; + position = %pos; + rotation = %rot; + }; + MissionCleanup.add(%satchel); + %source.thrownChargeId = %satchel; + %satchel.armed = false; + %satchel.damaged = 0.0; + %satchel.thwart = false; + + // arm itself 2.5 seconds after creation + schedule(%satchel.getDatablock().armDelay, %satchel, "initArmSatchelCharge", %satchel); + messageClient(%source.client, 'MsgSatchelChargePlaced', "\c2Satchel charge deployed."); +} diff --git a/scripts/packs/sensorjammerpack.cs b/scripts/packs/sensorjammerpack.cs index 7e52c99..447e542 100644 --- a/scripts/packs/sensorjammerpack.cs +++ b/scripts/packs/sensorjammerpack.cs @@ -1,146 +1,146 @@ -// ------------------------------------------------------------------ -// SENSOR JAMMER PACK -// -// When activated, the sensor jammer pack emits a sensor-jamming field of -// 20m radius. Any players within this field are completely invisible to -// all sensors, turrets and cameras. -// -// When not activated, the pack has no effect. -// -datablock EffectProfile(SensorJammerPackActivateEffect) -{ - effectname = "packs/cloak_on"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock AudioProfile(SensorJammerActivateSound) -{ - filename = "fx/packs/sensorjammerpack_on.wav"; - description = ClosestLooping3d; - preload = true; - effect = SensorJammerPackActivateEffect; -}; - -datablock ShapeBaseImageData(SensorJammerPackImage) -{ - shapeFile = "pack_upgrade_sensorjammer.dts"; - item = SensorJammerPack; - mountPoint = 1; - offset = "0 0 0"; - - usesEnergy = true; - minEnergy = 3; - - stateName[0] = "Idle"; - stateTransitionOnTriggerDown[0] = "Activate"; - - stateName[1] = "Activate"; - stateScript[1] = "onActivate"; - stateSequence[1] = "fire"; - stateSound[1] = SensorJammerActivateSound; - stateEnergyDrain[1] = 10.5; - stateTransitionOnTriggerUp[1] = "Deactivate"; - stateTransitionOnNoAmmo[1] = "Deactivate"; - - stateName[2] = "Deactivate"; - stateScript[2] = "onDeactivate"; - stateTransitionOnTimeout[2] = "Idle"; -}; - -datablock ItemData(SensorJammerPack) -{ - className = Pack; - catagory = "Packs"; - shapeFile = "pack_upgrade_sensorjammer.dts"; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - rotate = true; - image = "SensorJammerPackImage"; - pickUpName = "a sensor jammer pack"; - - computeCRC = true; -}; - -datablock SensorData(JammerSensorObjectPassive) -{ - // same detection info as 'PlayerObject' sensorData - detects = true; - detectsUsingLOS = true; - detectsPassiveJammed = true; - detectRadius = 2000; - detectionPings = false; - detectsFOVOnly = true; - detectFOVPercent = 1.3; - useObjectFOV = true; - - jams = true; - jamsOnlyGroup = true; - jamsUsingLOS = true; - jamRadius = 0; -}; - -datablock SensorData(JammerSensorObjectActive) -{ - // same detection info as 'PlayerObject' sensorData - detects = true; - detectsUsingLOS = true; - detectsPassiveJammed = true; - detectRadius = 2000; - detectionPings = false; - detectsFOVOnly = true; - detectFOVPercent = 1.3; - useObjectFOV = true; - - jams = true; - jamsOnlyGroup = true; - jamsUsingLOS = true; - jamRadius = 30; -}; - -function SensorJammerPackImage::onMount(%data, %obj, %slot) -{ - setTargetSensorData(%obj.client.target, JammerSensorObjectPassive); -} - -function SensorJammerPackImage::onUnmount(%data, %obj, %slot) -{ - setTargetSensorData(%obj.client.target, PlayerSensor); - %obj.setImageTrigger(%slot, false); -} - -function SensorJammerPackImage::onActivate(%data, %obj, %slot) -{ - messageClient(%obj.client, 'MsgSensorJammerPackOn', '\c2Sensor jammer pack on.'); - setTargetSensorData(%obj.client.target, JammerSensorObjectActive); - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - commandToClient( %obj.client, 'setSenJamIconOn' ); - - %obj.setJammerFX( true ); -} - -function SensorJammerPackImage::onDeactivate(%data, %obj, %slot) -{ - messageClient(%obj.client, 'MsgSensorJammerPackOff', '\c2Sensor jammer pack off.'); - %obj.setImageTrigger(%slot, false); - - // ---------------------------------------------------------------------- - // z0dd - ZOD, 4/25/02. This function is actually getting called AFTER - // ::onUnmount. We must check to see what the players current sensor data - // is, then if it is NOT PlayerSensor, set to passive jam, bug fix. - if(getTargetSensorData(%obj.client.target).getName() !$= "PlayerSensor") - setTargetSensorData(%obj.client.target, JammerSensorObjectPassive); - // ---------------------------------------------------------------------- - - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - commandToClient( %obj.client, 'setSenJamIconOff' ); - - %obj.setJammerFX( false ); -} - -function SensorJammerPack::onPickup(%this, %obj, %shape, %amount) -{ - // created to prevent console errors -} +// ------------------------------------------------------------------ +// SENSOR JAMMER PACK +// +// When activated, the sensor jammer pack emits a sensor-jamming field of +// 20m radius. Any players within this field are completely invisible to +// all sensors, turrets and cameras. +// +// When not activated, the pack has no effect. +// +datablock EffectProfile(SensorJammerPackActivateEffect) +{ + effectname = "packs/cloak_on"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock AudioProfile(SensorJammerActivateSound) +{ + filename = "fx/packs/sensorjammerpack_on.wav"; + description = ClosestLooping3d; + preload = true; + effect = SensorJammerPackActivateEffect; +}; + +datablock ShapeBaseImageData(SensorJammerPackImage) +{ + shapeFile = "pack_upgrade_sensorjammer.dts"; + item = SensorJammerPack; + mountPoint = 1; + offset = "0 0 0"; + + usesEnergy = true; + minEnergy = 3; + + stateName[0] = "Idle"; + stateTransitionOnTriggerDown[0] = "Activate"; + + stateName[1] = "Activate"; + stateScript[1] = "onActivate"; + stateSequence[1] = "fire"; + stateSound[1] = SensorJammerActivateSound; + stateEnergyDrain[1] = 10.5; + stateTransitionOnTriggerUp[1] = "Deactivate"; + stateTransitionOnNoAmmo[1] = "Deactivate"; + + stateName[2] = "Deactivate"; + stateScript[2] = "onDeactivate"; + stateTransitionOnTimeout[2] = "Idle"; +}; + +datablock ItemData(SensorJammerPack) +{ + className = Pack; + catagory = "Packs"; + shapeFile = "pack_upgrade_sensorjammer.dts"; + mass = 1; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 2; + rotate = true; + image = "SensorJammerPackImage"; + pickUpName = "a sensor jammer pack"; + + computeCRC = true; +}; + +datablock SensorData(JammerSensorObjectPassive) +{ + // same detection info as 'PlayerObject' sensorData + detects = true; + detectsUsingLOS = true; + detectsPassiveJammed = true; + detectRadius = 2000; + detectionPings = false; + detectsFOVOnly = true; + detectFOVPercent = 1.3; + useObjectFOV = true; + + jams = true; + jamsOnlyGroup = true; + jamsUsingLOS = true; + jamRadius = 0; +}; + +datablock SensorData(JammerSensorObjectActive) +{ + // same detection info as 'PlayerObject' sensorData + detects = true; + detectsUsingLOS = true; + detectsPassiveJammed = true; + detectRadius = 2000; + detectionPings = false; + detectsFOVOnly = true; + detectFOVPercent = 1.3; + useObjectFOV = true; + + jams = true; + jamsOnlyGroup = true; + jamsUsingLOS = true; + jamRadius = 30; +}; + +function SensorJammerPackImage::onMount(%data, %obj, %slot) +{ + setTargetSensorData(%obj.client.target, JammerSensorObjectPassive); +} + +function SensorJammerPackImage::onUnmount(%data, %obj, %slot) +{ + setTargetSensorData(%obj.client.target, PlayerSensor); + %obj.setImageTrigger(%slot, false); +} + +function SensorJammerPackImage::onActivate(%data, %obj, %slot) +{ + messageClient(%obj.client, 'MsgSensorJammerPackOn', '\c2Sensor jammer pack on.'); + setTargetSensorData(%obj.client.target, JammerSensorObjectActive); + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + commandToClient( %obj.client, 'setSenJamIconOn' ); + + %obj.setJammerFX( true ); +} + +function SensorJammerPackImage::onDeactivate(%data, %obj, %slot) +{ + messageClient(%obj.client, 'MsgSensorJammerPackOff', '\c2Sensor jammer pack off.'); + %obj.setImageTrigger(%slot, false); + + // ---------------------------------------------------------------------- + // z0dd - ZOD, 4/25/02. This function is actually getting called AFTER + // ::onUnmount. We must check to see what the players current sensor data + // is, then if it is NOT PlayerSensor, set to passive jam, bug fix. + if(getTargetSensorData(%obj.client.target).getName() !$= "PlayerSensor") + setTargetSensorData(%obj.client.target, JammerSensorObjectPassive); + // ---------------------------------------------------------------------- + + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + commandToClient( %obj.client, 'setSenJamIconOff' ); + + %obj.setJammerFX( false ); +} + +function SensorJammerPack::onPickup(%this, %obj, %shape, %amount) +{ + // created to prevent console errors +} diff --git a/scripts/player.cs b/scripts/player.cs index 6ef978f..8f712cb 100644 --- a/scripts/player.cs +++ b/scripts/player.cs @@ -1,3743 +1,3514 @@ -$InvincibleTime = 6; -// Load dts shapes and merge animations -exec("scripts/light_male.cs"); -exec("scripts/medium_male.cs"); -exec("scripts/heavy_male.cs"); -exec("scripts/light_female.cs"); -exec("scripts/medium_female.cs"); -exec("scripts/bioderm_light.cs"); -exec("scripts/bioderm_medium.cs"); -exec("scripts/bioderm_heavy.cs"); - -$CorpseTimeoutValue = 22 * 1000; - -//Damage Rate for entering Liquid -$DamageLava = 0.0325; -$DamageHotLava = 0.0325; -$DamageCrustyLava = 0.0325; - -$PlayerDeathAnim::TorsoFrontFallForward = 1; -$PlayerDeathAnim::TorsoFrontFallBack = 2; -$PlayerDeathAnim::TorsoBackFallForward = 3; -$PlayerDeathAnim::TorsoLeftSpinDeath = 4; -$PlayerDeathAnim::TorsoRightSpinDeath = 5; -$PlayerDeathAnim::LegsLeftGimp = 6; -$PlayerDeathAnim::LegsRightGimp = 7; -$PlayerDeathAnim::TorsoBackFallForward = 8; -$PlayerDeathAnim::HeadFrontDirect = 9; -$PlayerDeathAnim::HeadBackFallForward = 10; -$PlayerDeathAnim::ExplosionBlowBack = 11; - -datablock SensorData(PlayerSensor) -{ - detects = true; - detectsUsingLOS = true; - detectsPassiveJammed = true; - detectRadius = 2000; - detectionPings = false; - detectsFOVOnly = true; - detectFOVPercent = 1.3; - useObjectFOV = true; -}; - -//---------------------------------------------------------------------------- - -datablock EffectProfile(ArmorJetEffect) -{ - effectname = "armor/thrust"; - minDistance = 5.0; - maxDistance = 10.0; -}; - -datablock EffectProfile(ImpactSoftEffect) -{ - effectname = "armor/light_land_soft"; - minDistance = 5.0; - maxDistance = 10.0; -}; - -datablock EffectProfile(ImpactHardEffect) -{ - effectname = "armor/light_land_hard"; - minDistance = 5.0; - maxDistance = 10.0; -}; - -datablock EffectProfile(ImpactMetalEffect) -{ - effectname = "armor/light_land_metal"; - minDistance = 5.0; - maxDistance = 10.0; -}; - -datablock EffectProfile(ImpactSnowEffect) -{ - effectname = "armor/light_land_snow"; - minDistance = 5.0; - maxDistance = 10.0; -}; - -datablock EffectProfile(CorpseLootingEffect) -{ - effectname = "weapons/generic_switch"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(MountVehicleEffect) -{ - effectname = "vehicles/mount_dis"; - minDistance = 5; - maxDistance = 20; -}; - -datablock EffectProfile(UnmountVehicleEffect) -{ - effectname = "weapons/generic_switch"; - minDistance = 5; - maxDistance = 20; -}; - -datablock EffectProfile(GenericPainEffect) -{ - effectname = "misc/generic_pain"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(GenericDeathEffect) -{ - effectname = "misc/generic_death"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(ImpactHeavyWaterEasyEffect) -{ - effectname = "armor/general_water_smallsplash"; - minDistance = 5; - maxDistance = 15; -}; - -datablock EffectProfile(ImpactHeavyMediumWaterEffect) -{ - effectname = "armor/general_water_medsplash"; - minDistance = 5; - maxDistance = 15; -}; - -datablock EffectProfile(ImpactHeavyWaterHardEffect) -{ - effectname = "armor/general_water_bigsplash"; - minDistance = 5; - maxDistance = 15; -}; - -//---------------------------------------------------------------------------- -//datablock AudioProfile( DeathCrySound ) -//{ -// fileName = ""; -// description = AudioClose3d; -// preload = true; -//}; -// -//datablock AudioProfile( PainCrySound ) -//{ -// fileName = ""; -// description = AudioClose3d; -// preload = true; -//}; - -datablock AudioProfile(ArmorJetSound) -{ - filename = "fx/armor/thrust.wav"; - description = CloseLooping3d; - preload = true; - effect = ArmorJetEffect; -}; - -datablock AudioProfile(ArmorWetJetSound) -{ - filename = "fx/armor/thrust_uw.wav"; - description = CloseLooping3d; - preload = true; - effect = ArmorJetEffect; -}; - -datablock AudioProfile(MountVehicleSound) -{ - filename = "fx/vehicles/mount_dis.wav"; - description = AudioClose3d; - preload = true; - effect = MountVehicleEffect; -}; - -datablock AudioProfile(UnmountVehicleSound) -{ - filename = "fx/vehicles/mount.wav"; - description = AudioClose3d; - preload = true; - effect = UnmountVehicleEffect; -}; - -datablock AudioProfile(CorpseLootingSound) -{ - fileName = "fx/weapons/generic_switch.wav"; - description = AudioClosest3d; - preload = true; - effect = CorpseLootingEffect; -}; - -datablock AudioProfile(ArmorMoveBubblesSound) -{ - filename = "fx/armor/bubbletrail2.wav"; - description = CloseLooping3d; - preload = true; -}; - -datablock AudioProfile(WaterBreathMaleSound) -{ - filename = "fx/armor/breath_uw.wav"; - description = ClosestLooping3d; - preload = true; -}; - -datablock AudioProfile(WaterBreathFemaleSound) -{ - filename = "fx/armor/breath_fem_uw.wav"; - description = ClosestLooping3d; - preload = true; -}; - -datablock AudioProfile(waterBreathBiodermSound) -{ - filename = "fx/armor/breath_bio_uw.wav"; - description = ClosestLooping3d; - preload = true; -}; - -datablock AudioProfile(SkiAllSoftSound) -{ - filename = "fx/armor/ski_soft.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(SkiAllHardSound) -{ - filename = "fx/armor/ski_soft.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(SkiAllMetalSound) -{ - filename = "fx/armor/ski_soft.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(SkiAllSnowSound) -{ - filename = "fx/armor/ski_soft.wav"; - description = AudioClosest3d; - preload = true; -}; - -//SOUNDS ----- LIGHT ARMOR-------- -datablock AudioProfile(LFootLightSoftSound) -{ - filename = "fx/armor/light_LF_soft.wav"; - description = AudioClosest3d; - preload = true; -}; - -datablock AudioProfile(RFootLightSoftSound) -{ - filename = "fx/armor/light_RF_soft.wav"; - description = AudioClosest3d; - preload = true; -}; - -datablock AudioProfile(LFootLightHardSound) -{ - filename = "fx/armor/light_LF_hard.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(RFootLightHardSound) -{ - filename = "fx/armor/light_RF_hard.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(LFootLightMetalSound) -{ - filename = "fx/armor/light_LF_metal.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(RFootLightMetalSound) -{ - filename = "fx/armor/light_RF_metal.wav"; - description = AudioClose3d; - preload = true; -}; -datablock AudioProfile(LFootLightSnowSound) -{ - filename = "fx/armor/light_LF_snow.wav"; - description = AudioClosest3d; - preload = true; -}; - -datablock AudioProfile(RFootLightSnowSound) -{ - filename = "fx/armor/light_RF_snow.wav"; - description = AudioClosest3d; - preload = true; -}; - -datablock AudioProfile(LFootLightShallowSplashSound) -{ - filename = "fx/armor/light_LF_water.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(RFootLightShallowSplashSound) -{ - filename = "fx/armor/light_RF_water.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(LFootLightWadingSound) -{ - filename = "fx/armor/light_LF_wade.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(RFootLightWadingSound) -{ - filename = "fx/armor/light_RF_wade.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(LFootLightUnderwaterSound) -{ - filename = "fx/armor/light_LF_uw.wav"; - description = AudioClosest3d; - preload = true; -}; - -datablock AudioProfile(RFootLightUnderwaterSound) -{ - filename = "fx/armor/light_RF_uw.wav"; - description = AudioClosest3d; - preload = true; -}; - -datablock AudioProfile(LFootLightBubblesSound) -{ - filename = "fx/armor/light_LF_bubbles.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(RFootLightBubblesSound) -{ - filename = "fx/armor/light_RF_bubbles.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(ImpactLightSoftSound) -{ - filename = "fx/armor/light_land_soft.wav"; - description = AudioClose3d; - preload = true; - effect = ImpactSoftEffect; -}; - -datablock AudioProfile(ImpactLightHardSound) -{ - filename = "fx/armor/light_land_hard.wav"; - description = AudioClose3d; - preload = true; - effect = ImpactHardEffect; -}; - -datablock AudioProfile(ImpactLightMetalSound) -{ - filename = "fx/armor/light_land_metal.wav"; - description = AudioClose3d; - preload = true; - effect = ImpactMetalEffect; -}; - -datablock AudioProfile(ImpactLightSnowSound) -{ - filename = "fx/armor/light_land_snow.wav"; - description = AudioClosest3d; - preload = true; - effect = ImpactSnowEffect; -}; - -datablock AudioProfile(ImpactLightWaterEasySound) -{ - filename = "fx/armor/general_water_smallsplash2.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(ImpactLightWaterMediumSound) -{ - filename = "fx/armor/general_water_medsplash.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(ImpactLightWaterHardSound) -{ - filename = "fx/armor/general_water_bigsplash.wav"; - description = AudioDefault3d; - preload = true; -}; - -datablock AudioProfile(ExitingWaterLightSound) -{ - filename = "fx/armor/general_water_exit2.wav"; - description = AudioClose3d; - preload = true; -}; - -//SOUNDS ----- Medium ARMOR-------- -datablock AudioProfile(LFootMediumSoftSound) -{ - filename = "fx/armor/med_LF_soft.wav"; - description = AudioClosest3d; - preload = true; -}; - -datablock AudioProfile(RFootMediumSoftSound) -{ - filename = "fx/armor/med_RF_soft.wav"; - description = AudioClosest3d; - preload = true; -}; - -datablock AudioProfile(LFootMediumHardSound) -{ - filename = "fx/armor/med_LF_hard.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(RFootMediumHardSound) -{ - filename = "fx/armor/med_RF_hard.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(LFootMediumMetalSound) -{ - filename = "fx/armor/med_LF_metal.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(RFootMediumMetalSound) -{ - filename = "fx/armor/med_RF_metal.wav"; - description = AudioClose3d; - preload = true; -}; -datablock AudioProfile(LFootMediumSnowSound) -{ - filename = "fx/armor/med_LF_snow.wav"; - description = AudioClosest3d; - preload = true; -}; - -datablock AudioProfile(RFootMediumSnowSound) -{ - filename = "fx/armor/med_RF_snow.wav"; - description = AudioClosest3d; - preload = true; -}; - -datablock AudioProfile(LFootMediumShallowSplashSound) -{ - filename = "fx/armor/med_LF_water.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(RFootMediumShallowSplashSound) -{ - filename = "fx/armor/med_RF_water.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(LFootMediumWadingSound) -{ - filename = "fx/armor/med_LF_uw.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(RFootMediumWadingSound) -{ - filename = "fx/armor/med_RF_uw.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(LFootMediumUnderwaterSound) -{ - filename = "fx/armor/med_LF_uw.wav"; - description = AudioClosest3d; - preload = true; -}; - -datablock AudioProfile(RFootMediumUnderwaterSound) -{ - filename = "fx/armor/med_RF_uw.wav"; - description = AudioClosest3d; - preload = true; -}; - -datablock AudioProfile(LFootMediumBubblesSound) -{ - filename = "fx/armor/light_LF_bubbles.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(RFootMediumBubblesSound) -{ - filename = "fx/armor/light_RF_bubbles.wav"; - description = AudioClose3d; - preload = true; -}; -datablock AudioProfile(ImpactMediumSoftSound) -{ - filename = "fx/armor/med_land_soft.wav"; - description = AudioClosest3d; - preload = true; - effect = ImpactSoftEffect; -}; - -datablock AudioProfile(ImpactMediumHardSound) -{ - filename = "fx/armor/med_land_hard.wav"; - description = AudioClose3d; - preload = true; - effect = ImpactHardEffect; -}; - -datablock AudioProfile(ImpactMediumMetalSound) -{ - filename = "fx/armor/med_land_metal.wav"; - description = AudioClose3d; - preload = true; - effect = ImpactMetalEffect; -}; - -datablock AudioProfile(ImpactMediumSnowSound) -{ - filename = "fx/armor/med_land_snow.wav"; - description = AudioClosest3d; - preload = true; - effect = ImpactSnowEffect; -}; - -datablock AudioProfile(ImpactMediumWaterEasySound) -{ - filename = "fx/armor/general_water_smallsplash.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(ImpactMediumWaterMediumSound) -{ - filename = "fx/armor/general_water_medsplash.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(ImpactMediumWaterHardSound) -{ - filename = "fx/armor/general_water_bigsplash.wav"; - description = AudioDefault3d; - preload = true; -}; - -datablock AudioProfile(ExitingWaterMediumSound) -{ - filename = "fx/armor/general_water_exit.wav"; - description = AudioClose3d; - preload = true; -}; - -//SOUNDS ----- HEAVY ARMOR-------- -datablock AudioProfile(LFootHeavySoftSound) -{ - filename = "fx/armor/heavy_LF_soft.wav"; - description = AudioClosest3d; - preload = true; -}; - -datablock AudioProfile(RFootHeavySoftSound) -{ - filename = "fx/armor/heavy_RF_soft.wav"; - description = AudioClosest3d; - preload = true; -}; - -datablock AudioProfile(LFootHeavyHardSound) -{ - filename = "fx/armor/heavy_LF_hard.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(RFootHeavyHardSound) -{ - filename = "fx/armor/heavy_RF_hard.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(LFootHeavyMetalSound) -{ - filename = "fx/armor/heavy_LF_metal.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(RFootHeavyMetalSound) -{ - filename = "fx/armor/heavy_RF_metal.wav"; - description = AudioClose3d; - preload = true; -}; -datablock AudioProfile(LFootHeavySnowSound) -{ - filename = "fx/armor/heavy_LF_snow.wav"; - description = AudioClosest3d; - preload = true; -}; - -datablock AudioProfile(RFootHeavySnowSound) -{ - filename = "fx/armor/heavy_RF_snow.wav"; - description = AudioClosest3d; - preload = true; -}; - -datablock AudioProfile(LFootHeavyShallowSplashSound) -{ - filename = "fx/armor/heavy_LF_water.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(RFootHeavyShallowSplashSound) -{ - filename = "fx/armor/heavy_RF_water.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(LFootHeavyWadingSound) -{ - filename = "fx/armor/heavy_LF_uw.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(RFootHeavyWadingSound) -{ - filename = "fx/armor/heavy_RF_uw.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(LFootHeavyUnderwaterSound) -{ - filename = "fx/armor/heavy_LF_uw.wav"; - description = AudioClosest3d; - preload = true; -}; - -datablock AudioProfile(RFootHeavyUnderwaterSound) -{ - filename = "fx/armor/heavy_RF_uw.wav"; - description = AudioClosest3d; - preload = true; -}; - -datablock AudioProfile(LFootHeavyBubblesSound) -{ - filename = "fx/armor/light_LF_bubbles.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(RFootHeavyBubblesSound) -{ - filename = "fx/armor/light_RF_bubbles.wav"; - description = AudioClose3d; - preload = true; -}; -datablock AudioProfile(ImpactHeavySoftSound) -{ - filename = "fx/armor/heavy_land_soft.wav"; - description = AudioClose3d; - preload = true; - effect = ImpactSoftEffect; -}; - -datablock AudioProfile(ImpactHeavyHardSound) -{ - filename = "fx/armor/heavy_land_hard.wav"; - description = AudioClose3d; - preload = true; - effect = ImpactHardEffect; -}; - -datablock AudioProfile(ImpactHeavyMetalSound) -{ - filename = "fx/armor/heavy_land_metal.wav"; - description = AudioClose3d; - preload = true; - effect = ImpactMetalEffect; -}; - -datablock AudioProfile(ImpactHeavySnowSound) -{ - filename = "fx/armor/heavy_land_snow.wav"; - description = AudioClosest3d; - preload = true; - effect = ImpactSnowEffect; -}; - -datablock AudioProfile(ImpactHeavyWaterEasySound) -{ - filename = "fx/armor/general_water_smallsplash.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(ImpactHeavyWaterMediumSound) -{ - filename = "fx/armor/general_water_medsplash.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(ImpactHeavyWaterHardSound) -{ - filename = "fx/armor/general_water_bigsplash.wav"; - description = AudioDefault3d; - preload = true; -}; - -datablock AudioProfile(ExitingWaterHeavySound) -{ - filename = "fx/armor/general_water_exit2.wav"; - description = AudioClose3d; - 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 = "particleTest"; - colors[0] = "0.7 0.8 1.0 1.0"; - colors[1] = "0.7 0.8 1.0 0.5"; - colors[2] = "0.7 0.8 1.0 0.0"; - sizes[0] = 0.5; - sizes[1] = 0.5; - sizes[2] = 0.8; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData(PlayerSplashMistEmitter) -{ - ejectionPeriodMS = 5; - periodVarianceMS = 0; - ejectionVelocity = 3.0; - velocityVariance = 2.0; - ejectionOffset = 0.0; - thetaMin = 85; - thetaMax = 85; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - lifetimeMS = 250; - particles = "PlayerSplashMist"; -}; - - -datablock ParticleData(PlayerBubbleParticle) -{ - dragCoefficient = 0.0; - gravityCoefficient = -0.50; - inheritedVelFactor = 0.0; - constantAcceleration = 0.0; - lifetimeMS = 400; - lifetimeVarianceMS = 100; - useInvAlpha = false; - textureName = "special/bubbles"; - 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; - overrideAdvances = false; - particles = "PlayerBubbleParticle"; -}; - -datablock ParticleData(PlayerFoamParticle) -{ - dragCoefficient = 2.0; - gravityCoefficient = -0.05; - inheritedVelFactor = 0.0; - constantAcceleration = 0.0; - lifetimeMS = 400; - lifetimeVarianceMS = 100; - useInvAlpha = false; - spinRandomMin = -90.0; - spinRandomMax = 500.0; - textureName = "particleTest"; - colors[0] = "0.7 0.8 1.0 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; - overrideAdvances = false; - particles = "PlayerFoamParticle"; -}; - - -datablock ParticleData( PlayerFoamDropletsParticle ) -{ - dragCoefficient = 1; - gravityCoefficient = 0.2; - inheritedVelFactor = 0.2; - constantAcceleration = -0.0; - lifetimeMS = 600; - lifetimeVarianceMS = 0; - textureName = "special/droplet"; - colors[0] = "0.7 0.8 1.0 1.0"; - colors[1] = "0.7 0.8 1.0 0.5"; - colors[2] = "0.7 0.8 1.0 0.0"; - sizes[0] = 0.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; - overrideAdvances = false; - orientParticles = true; - particles = "PlayerFoamDropletsParticle"; -}; - - - -datablock ParticleData( PlayerSplashParticle ) -{ - dragCoefficient = 1; - gravityCoefficient = 0.2; - inheritedVelFactor = 0.2; - constantAcceleration = -0.0; - lifetimeMS = 600; - lifetimeVarianceMS = 0; - textureName = "special/droplet"; - colors[0] = "0.7 0.8 1.0 1.0"; - colors[1] = "0.7 0.8 1.0 0.5"; - colors[2] = "0.7 0.8 1.0 0.0"; - sizes[0] = 0.5; - sizes[1] = 0.5; - sizes[2] = 0.5; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData( PlayerSplashEmitter ) -{ - ejectionPeriodMS = 1; - periodVarianceMS = 0; - ejectionVelocity = 3; - velocityVariance = 1.0; - ejectionOffset = 0.0; - thetaMin = 60; - thetaMax = 80; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - orientParticles = true; - lifetimeMS = 100; - particles = "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 = "special/water2"; - - 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; -}; - -//---------------------------------------------------------------------------- -// Jet data -//---------------------------------------------------------------------------- -datablock ParticleData(HumanArmorJetParticle) -{ - dragCoefficient = 0.0; - gravityCoefficient = 0; - inheritedVelFactor = 0.2; - constantAcceleration = 0.0; - lifetimeMS = 100; - lifetimeVarianceMS = 0; - textureName = "particleTest"; - colors[0] = "0.32 0.47 0.47 1.0"; - colors[1] = "0.32 0.47 0.47 0"; - sizes[0] = 0.40; - sizes[1] = 0.15; -}; - -datablock ParticleEmitterData(HumanArmorJetEmitter) -{ - ejectionPeriodMS = 3; - periodVarianceMS = 0; - ejectionVelocity = 3; - velocityVariance = 2.9; - ejectionOffset = 0.0; - thetaMin = 0; - thetaMax = 5; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - particles = "HumanArmorJetParticle"; -}; - -datablock JetEffectData(HumanArmorJetEffect) -{ - texture = "special/jetExhaust02"; - coolColor = "0.0 0.0 1.0 1.0"; - hotColor = "0.2 0.4 0.7 1.0"; - activateTime = 0.2; - deactivateTime = 0.05; - length = 0.75; - width = 0.2; - speed = -15; - stretch = 2.0; - yOffset = 0.2; -}; - -datablock JetEffectData(HumanMediumArmorJetEffect) -{ - texture = "special/jetExhaust02"; - coolColor = "0.0 0.0 1.0 1.0"; - hotColor = "0.2 0.4 0.7 1.0"; - activateTime = 0.2; - deactivateTime = 0.05; - length = 0.75; - width = 0.2; - speed = -15; - stretch = 2.0; - yOffset = 0.4; -}; - -datablock JetEffectData(HumanLightFemaleArmorJetEffect) -{ - texture = "special/jetExhaust02"; - coolColor = "0.0 0.0 1.0 1.0"; - hotColor = "0.2 0.4 0.7 1.0"; - activateTime = 0.2; - deactivateTime = 0.05; - length = 0.75; - width = 0.2; - speed = -15; - stretch = 2.0; - yOffset = 0.2; -}; - -datablock JetEffectData(BiodermArmorJetEffect) -{ - texture = "special/jetExhaust02"; - coolColor = "0.0 0.0 1.0 1.0"; - hotColor = "0.8 0.6 0.2 1.0"; - activateTime = 0.2; - deactivateTime = 0.05; - length = 0.75; - width = 0.2; - speed = -15; - stretch = 2.0; - yOffset = 0.0; -}; - -//---------------------------------------------------------------------------- -// Foot puffs -//---------------------------------------------------------------------------- -datablock ParticleData(LightPuff) -{ - dragCoefficient = 2.0; - gravityCoefficient = -0.01; - inheritedVelFactor = 0.0; - constantAcceleration = 0.0; - lifetimeMS = 500; - lifetimeVarianceMS = 100; - useInvAlpha = true; - spinRandomMin = -35.0; - spinRandomMax = 35.0; - textureName = "particleTest"; - colors[0] = "0.46 0.36 0.26 0.4"; - colors[1] = "0.46 0.46 0.36 0.0"; - sizes[0] = 0.4; - sizes[1] = 1.0; -}; - -datablock ParticleEmitterData(LightPuffEmitter) -{ - ejectionPeriodMS = 35; - periodVarianceMS = 10; - ejectionVelocity = 0.1; - velocityVariance = 0.05; - ejectionOffset = 0.0; - thetaMin = 5; - thetaMax = 20; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = 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; - textureName = "particleTest"; - colors[0] = "0.46 0.36 0.26 0.0"; - colors[1] = "0.46 0.46 0.36 0.4"; - colors[2] = "0.46 0.46 0.36 0.0"; - sizes[0] = 0.2; - sizes[1] = 0.6; - sizes[2] = 1.0; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData(LiftoffDustEmitter) -{ - ejectionPeriodMS = 5; - periodVarianceMS = 0; - ejectionVelocity = 2.0; - velocityVariance = 0.0; - ejectionOffset = 0.0; - thetaMin = 90; - thetaMax = 90; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - useEmitterColors = true; - particles = "LiftoffDust"; -}; - -//---------------------------------------------------------------------------- - -datablock ParticleData(BiodermArmorJetParticle) : HumanArmorJetParticle -{ - colors[0] = "0.50 0.48 0.36 1.0"; - colors[1] = "0.50 0.48 0.36 0"; -}; - -datablock ParticleEmitterData(BiodermArmorJetEmitter) : HumanArmorJetEmitter -{ - particles = "BiodermArmorJetParticle"; -}; - - -//---------------------------------------------------------------------------- -datablock DecalData(LightMaleFootprint) -{ - sizeX = 0.125; - sizeY = 0.25; - textureName = "special/footprints/L_male"; -}; - -datablock DebrisData( PlayerDebris ) -{ - explodeOnMaxBounce = false; - - elasticity = 0.35; - friction = 0.5; - - lifetime = 4.0; - lifetimeVariance = 0.0; - - minSpinSpeed = 60; - maxSpinSpeed = 600; - - numBounces = 5; - bounceVariance = 0; - - staticOnMaxBounce = true; - gravModifier = 1.0; - - useRadiusMass = true; - baseRadius = 1; - - velocity = 18.0; - velocityVariance = 12.0; -}; - -datablock DebrisData( HumanRedPlayerDebris ) //Omfg, blood. -{ - explodeOnMaxBounce = false; - - elasticity = 0.35; - friction = 0.5; - - lifetime = 4.0; - lifetimeVariance = 0.0; - - emitters[0] = HumanRedBloodEmitter; - emitters[1] = HumanRedPlayerSplashMistEmitter; - emitters[2] = HumanRedDropletsEmitter; - - minSpinSpeed = 60; - maxSpinSpeed = 900; - - numBounces = 15; - bounceVariance = 0; - - staticOnMaxBounce = true; - gravModifier = 1.0; - - useRadiusMass = true; - baseRadius = 1; - - velocity = 18.0; - velocityVariance = 12.0; - -}; - -datablock DebrisData( BiodermPlayerDebris ) //Green Blood! -{ - explodeOnMaxBounce = false; - - elasticity = 0.35; - friction = 0.5; - - lifetime = 4.0; - lifetimeVariance = 0.0; - - emitters[0] = BiodermBloodEmitter; - emitters[1] = BiodermPlayerSplashMistEmitter; - emitters[2] = PurpleBiodermDropletsEmitter; - - minSpinSpeed = 60; - maxSpinSpeed = 900; - - numBounces = 15; - bounceVariance = 0; - - staticOnMaxBounce = true; - gravModifier = 1.0; - - useRadiusMass = true; - baseRadius = 1; - - velocity = 18.0; - velocityVariance = 12.0; - -}; - -// z0dd - ZOD, 4/21/02. Altered most of these properties -datablock PlayerData(LightMaleHumanArmor) : LightPlayerDamageProfile -{ - emap = true; - - className = Armor; - shapeFile = "light_male.dts"; - cameraMaxDist = 3; - computeCRC = true; - - canObserve = true; - cmdCategory = "Clients"; - cmdIcon = CMDPlayerIcon; - cmdMiniIconName = "commander/MiniIcons/com_player_grey"; - - hudImageNameFriendly[0] = "gui/hud_playertriangle"; - hudImageNameEnemy[0] = "gui/hud_playertriangle_enemy"; - hudRenderModulated[0] = true; - - hudImageNameFriendly[1] = "commander/MiniIcons/com_flag_grey"; - hudImageNameEnemy[1] = "commander/MiniIcons/com_flag_grey"; - hudRenderModulated[1] = true; - hudRenderAlways[1] = true; - hudRenderCenter[1] = true; - hudRenderDistance[1] = true; - - hudImageNameFriendly[2] = "commander/MiniIcons/com_flag_grey"; - hudImageNameEnemy[2] = "commander/MiniIcons/com_flag_grey"; - hudRenderModulated[2] = true; - hudRenderAlways[2] = true; - hudRenderCenter[2] = true; - hudRenderDistance[2] = true; - - cameraDefaultFov = 90.0; - cameraMinFov = 5.0; - cameraMaxFov = 120.0; - - debrisShapeName = "debris_player.dts"; - debris = HumanRedPlayerDebris; - - aiAvoidThis = true; - - minLookAngle = -1.5; - maxLookAngle = 1.5; - maxFreelookAngle = 3.0; - - mass = 90; - drag = 0.134; - maxdrag = 0.3; - density = 19; - maxDamage = 0.66; - maxEnergy = 60; - repairRate = 0.0033; - energyPerDamagePoint = 75.0; // shield energy required to block one point of damage - - rechargeRate = 0.256; - jetForce = 37.28 * 90; - underwaterJetForce = 28.00 * 90 * 1.5; - underwaterVertJetFactor = 1.5; - jetEnergyDrain = 0.90; - underwaterJetEnergyDrain = 0.7; - minJetEnergy = 3; - maxJetHorizontalPercentage = 0.6; - - runForce = 55.20 * 90; - runEnergyDrain = 0; - minRunEnergy = 0; - maxForwardSpeed = 15; - maxBackwardSpeed = 13; - maxSideSpeed = 13; - - maxUnderwaterForwardSpeed = 13; - maxUnderwaterBackwardSpeed = 11; - maxUnderwaterSideSpeed = 11; - - jumpForce = 8.34 * 90; - jumpEnergyDrain = 0; - minJumpEnergy = 0; - jumpDelay = 0; - - recoverDelay = 8; - recoverRunForceScale = 1.4; - - minImpactSpeed = 45; - speedDamageScale = 0.0022; - - jetSound = ArmorJetSound; - wetJetSound = ArmorJetSound; - jetEmitter = HumanArmorJetEmitter; - jetEffect = HumanArmorJetEffect; - - boundingBox = "1.2 1.2 2.3"; - pickupRadius = 0.75; - - // damage location details - boxNormalHeadPercentage = 0.83; - boxNormalTorsoPercentage = 0.49; - boxHeadLeftPercentage = 0; - boxHeadRightPercentage = 1; - boxHeadBackPercentage = 0; - boxHeadFrontPercentage = 1; - - //Foot Prints - decalData = LightMaleFootprint; - decalOffset = 0.25; - - footPuffEmitter = LightPuffEmitter; - footPuffNumParts = 15; - footPuffRadius = 0.25; - - dustEmitter = LiftoffDustEmitter; - - splash = PlayerSplash; - splashVelocity = 4.0; - splashAngle = 67.0; - splashFreqMod = 300.0; - splashVelEpsilon = 0.60; - bubbleEmitTime = 0.4; - splashEmitter[0] = PlayerFoamDropletsEmitter; - splashEmitter[1] = PlayerFoamEmitter; - splashEmitter[2] = PlayerBubbleEmitter; - mediumSplashSoundVelocity = 10.0; - hardSplashSoundVelocity = 20.0; - exitSplashSoundVelocity = 5.0; - - // Controls over slope of runnable/jumpable surfaces - runSurfaceAngle = 70; - jumpSurfaceAngle = 80; - - minJumpSpeed = 20; - maxJumpSpeed = 30; - - noFrictionOnSki = true; - horizMaxSpeed = 500; - horizResistSpeed = 48.74; - horizResistFactor = 0; - maxJetForwardSpeed = 30; - - upMaxSpeed = 52; - upResistSpeed = 20.89; - upResistFactor = 0.35; - - // heat inc'ers and dec'ers - heatDecayPerSec = 1.0 / 4.0; // takes 4 seconds to clear heat sig. - heatIncreasePerSec = 1.0 / 3.0; // takes 3.0 seconds of constant jet to get full heat sig. - - footstepSplashHeight = 0.35; - //Footstep Sounds - LFootSoftSound = LFootLightSoftSound; - RFootSoftSound = RFootLightSoftSound; - LFootHardSound = LFootLightHardSound; - RFootHardSound = RFootLightHardSound; - LFootMetalSound = LFootLightMetalSound; - RFootMetalSound = RFootLightMetalSound; - LFootSnowSound = LFootLightSnowSound; - RFootSnowSound = RFootLightSnowSound; - LFootShallowSound = LFootLightShallowSplashSound; - RFootShallowSound = RFootLightShallowSplashSound; - LFootWadingSound = LFootLightWadingSound; - RFootWadingSound = RFootLightWadingSound; - LFootUnderwaterSound = LFootLightUnderwaterSound; - RFootUnderwaterSound = RFootLightUnderwaterSound; - LFootBubblesSound = LFootLightBubblesSound; - RFootBubblesSound = RFootLightBubblesSound; - movingBubblesSound = ArmorMoveBubblesSound; - waterBreathSound = WaterBreathMaleSound; - - impactSoftSound = ImpactLightSoftSound; - impactHardSound = ImpactLightHardSound; - impactMetalSound = ImpactLightMetalSound; - impactSnowSound = ImpactLightSnowSound; - - skiSoftSound = SkiAllSoftSound; - skiHardSound = SkiAllHardSound; - skiMetalSound = SkiAllMetalSound; - skiSnowSound = SkiAllSnowSound; - - impactWaterEasy = ImpactLightWaterEasySound; - impactWaterMedium = ImpactLightWaterMediumSound; - impactWaterHard = ImpactLightWaterHardSound; - - groundImpactMinSpeed = 14.0; - groundImpactShakeFreq = "3.0 3.0 3.0"; - groundImpactShakeAmp = "1.0 1.0 1.0"; - groundImpactShakeDuration = 0.6; - groundImpactShakeFalloff = 10.0; - - exitingWater = ExitingWaterLightSound; - - maxWeapons = 3; // Max number of different weapons the player can have - maxGrenades = 1; // Max number of different grenades the player can have - maxMines = 1; // Max number of different mines the player can have - - // Inventory restrictions - max[RepairKit] = 1; - max[Mine] = 3; - max[Grenade] = 5; - max[Blaster] = 1; - max[Plasma] = 1; - max[PlasmaAmmo] = 20; - max[Disc] = 1; - max[DiscAmmo] = 15; - max[SniperRifle] = 1; - max[GrenadeLauncher] = 1; - max[GrenadeLauncherAmmo]= 10; - max[Mortar] = 0; - max[MortarAmmo] = 0; - max[MissileLauncher] = 0; - max[MissileLauncherAmmo]= 0; - max[Chaingun] = 1; - max[ChaingunAmmo] = 100; - max[RepairGun] = 1; - max[CloakingPack] = 1; - max[SensorJammerPack] = 1; - max[EnergyPack] = 1; - max[RepairPack] = 1; - max[ShieldPack] = 1; - max[AmmoPack] = 1; - max[SatchelCharge] = 1; - max[MortarBarrelPack] = 0; - max[MissileBarrelPack] = 0; - max[AABarrelPack] = 0; - max[PlasmaBarrelPack] = 0; - max[ELFBarrelPack] = 0; - max[InventoryDeployable]= 0; - max[MotionSensorDeployable] = 1; - max[PulseSensorDeployable] = 1; - max[TurretOutdoorDeployable] = 0; - max[TurretIndoorDeployable] = 0; - max[FlashGrenade] = 5; - max[ConcussionGrenade] = 5; - max[FlareGrenade] = 5; - max[TargetingLaser] = 1; - max[ELFGun] = 1; - max[R700] = 1; - max[ShockLance] = 1; - max[CameraGrenade] = 2; - max[Beacon] = 3; - max[Lootbag] = 1; - max[MiningTool] = 1; - max[C4Charge] = 1; - max[Flamer] = 0; //Just in case - - observeParameters = "0.5 4.5 4.5"; - shieldEffectScale = "0.7 0.7 1.0"; -}; - -//---------------------------------------------------------------------------- - -datablock DecalData(MediumMaleFootprint) -{ - sizeX = 0.125; - sizeY = 0.25; - textureName = "special/footprints/M_male"; -}; - -// z0dd - ZOD, 4/21/02. Altered most of these properties -datablock PlayerData(MediumMaleHumanArmor) : MediumPlayerDamageProfile -{ - emap = true; - - className = Armor; - shapeFile = "medium_male.dts"; - cameraMaxDist = 3; - computeCRC = true; - - canObserve = true; - cmdCategory = "Clients"; - cmdIcon = CMDPlayerIcon; - cmdMiniIconName = "commander/MiniIcons/com_player_grey"; - - hudImageNameFriendly[0] = "gui/hud_playertriangle"; - hudImageNameEnemy[0] = "gui/hud_playertriangle_enemy"; - hudRenderModulated[0] = true; - - hudImageNameFriendly[1] = "commander/MiniIcons/com_flag_grey"; - hudImageNameEnemy[1] = "commander/MiniIcons/com_flag_grey"; - hudRenderModulated[1] = true; - hudRenderAlways[1] = true; - hudRenderCenter[1] = true; - hudRenderDistance[1] = true; - - hudImageNameFriendly[2] = "commander/MiniIcons/com_flag_grey"; - hudImageNameEnemy[2] = "commander/MiniIcons/com_flag_grey"; - hudRenderModulated[2] = true; - hudRenderAlways[2] = true; - hudRenderCenter[2] = true; - hudRenderDistance[2] = true; - - cameraDefaultFov = 90.0; - cameraMinFov = 5.0; - cameraMaxFov = 120.0; - - debrisShapeName = "debris_player.dts"; - debris = HumanRedPlayerDebris; - - aiAvoidThis = true; - - minLookAngle = -1.5; - maxLookAngle = 1.5; - maxFreelookAngle = 3.0; - - mass = 130; - drag = 0.2; - maxdrag = 0.4; - density = 20; - maxDamage = 1.1; - maxEnergy = 80; - repairRate = 0.0033; - energyPerDamagePoint = 75.0; // shield energy required to block one point of damage - - rechargeRate = 0.256; - jetForce = 33.79 * 130; - underwaterJetForce = 27.00 * 130 * 1.5; - underwaterVertJetFactor = 1.5; - jetEnergyDrain = 1.1; - underwaterJetEnergyDrain = 0.65; - minJetEnergy = 3; - maxJetHorizontalPercentage = 0.5; - - runForce = 46 * 130; - runEnergyDrain = 0; - minRunEnergy = 0; - maxForwardSpeed = 12; - maxBackwardSpeed = 10; - maxSideSpeed = 10; - - maxUnderwaterForwardSpeed = 10; - maxUnderwaterBackwardSpeed = 8; - maxUnderwaterSideSpeed = 8; - - recoverDelay = 8; - recoverRunForceScale = 0.8; - - // heat inc'ers and dec'ers - heatDecayPerSec = 1.0 / 4.0; // takes 4 seconds to clear heat sig. - heatIncreasePerSec = 1.0 / 3.0; // takes 3.0 seconds of constant jet to get full heat sig. - - jumpForce = 8.5 * 130; - jumpEnergyDrain = 0; - minJumpEnergy = 0; - jumpDelay = 0; - - // Controls over slope of runnable/jumpable surfaces - runSurfaceAngle = 70; - jumpSurfaceAngle = 80; - - minJumpSpeed = 15; - maxJumpSpeed = 25; - - noFrictionOnSki = true; - horizMaxSpeed = 500; - horizResistSpeed = 41.78; - horizResistFactor = 0; - maxJetForwardSpeed = 25; - - upMaxSpeed = 52; - upResistSpeed = 20.89; - upResistFactor = 0.23; - - minImpactSpeed = 45; - speedDamageScale = 0.0023; - - jetSound = ArmorJetSound; - wetJetSound = ArmorWetJetSound; - - jetEmitter = HumanArmorJetEmitter; - jetEffect = HumanMediumArmorJetEffect; - - boundingBox = "1.45 1.45 2.4"; - pickupRadius = 0.75; - - // damage location details - boxNormalHeadPercentage = 0.83; - boxNormalTorsoPercentage = 0.49; - boxHeadLeftPercentage = 0; - boxHeadRightPercentage = 1; - boxHeadBackPercentage = 0; - boxHeadFrontPercentage = 1; - - //Foot Prints - decalData = MediumMaleFootprint; - decalOffset = 0.35; - - footPuffEmitter = LightPuffEmitter; - footPuffNumParts = 15; - footPuffRadius = 0.25; - - dustEmitter = LiftoffDustEmitter; - - splash = PlayerSplash; - splashVelocity = 4.0; - splashAngle = 67.0; - splashFreqMod = 300.0; - splashVelEpsilon = 0.60; - bubbleEmitTime = 0.4; - splashEmitter[0] = PlayerFoamDropletsEmitter; - splashEmitter[1] = PlayerFoamEmitter; - splashEmitter[2] = PlayerBubbleEmitter; - mediumSplashSoundVelocity = 10.0; - hardSplashSoundVelocity = 20.0; - exitSplashSoundVelocity = 5.0; - - footstepSplashHeight = 0.35; - //Footstep Sounds - LFootSoftSound = LFootMediumSoftSound; - RFootSoftSound = RFootMediumSoftSound; - LFootHardSound = LFootMediumHardSound; - RFootHardSound = RFootMediumHardSound; - LFootMetalSound = LFootMediumMetalSound; - RFootMetalSound = RFootMediumMetalSound; - LFootSnowSound = LFootMediumSnowSound; - RFootSnowSound = RFootMediumSnowSound; - LFootShallowSound = LFootMediumShallowSplashSound; - RFootShallowSound = RFootMediumShallowSplashSound; - LFootWadingSound = LFootMediumWadingSound; - RFootWadingSound = RFootMediumWadingSound; - LFootUnderwaterSound = LFootMediumUnderwaterSound; - RFootUnderwaterSound = RFootMediumUnderwaterSound; - LFootBubblesSound = LFootMediumBubblesSound; - RFootBubblesSound = RFootMediumBubblesSound; - movingBubblesSound = ArmorMoveBubblesSound; - waterBreathSound = WaterBreathMaleSound; - - impactSoftSound = ImpactMediumSoftSound; - impactHardSound = ImpactMediumHardSound; - impactMetalSound = ImpactMediumMetalSound; - impactSnowSound = ImpactMediumSnowSound; - - skiSoftSound = SkiAllSoftSound; - skiHardSound = SkiAllHardSound; - skiMetalSound = SkiAllMetalSound; - skiSnowSound = SkiAllSnowSound; - - impactWaterEasy = ImpactMediumWaterEasySound; - impactWaterMedium = ImpactMediumWaterMediumSound; - impactWaterHard = ImpactMediumWaterHardSound; - - groundImpactMinSpeed = 13.0; - groundImpactShakeFreq = "3.5 3.5 3.5"; - groundImpactShakeAmp = "1.0 1.0 1.0"; - groundImpactShakeDuration = 0.7; - groundImpactShakeFalloff = 10.0; - - exitingWater = ExitingWaterMediumSound; - - maxWeapons = 4; // Max number of different weapons the player can have - maxGrenades = 1; // Max number of different grenades the player can have - maxMines = 1; // Max number of different mines the player can have - - // Inventory restrictions - max[RepairKit] = 1; - max[Mine] = 3; - max[Grenade] = 6; - max[Blaster] = 1; - max[Plasma] = 1; - max[PlasmaAmmo] = 40; - max[Disc] = 1; - max[DiscAmmo] = 15; - max[SniperRifle] = 0; - max[GrenadeLauncher] = 1; - max[GrenadeLauncherAmmo]= 15; // z0dd - ZOD, 9/28/02. Was 12 - max[Mortar] = 0; - max[MortarAmmo] = 0; - max[MissileLauncher] = 1; - max[MissileLauncherAmmo]= 4; - max[Chaingun] = 1; - max[ChaingunAmmo] = 150; - max[RepairGun] = 1; - max[CloakingPack] = 0; - max[SensorJammerPack] = 1; - max[EnergyPack] = 1; - max[RepairPack] = 1; - max[ShieldPack] = 1; - max[AmmoPack] = 1; - max[SatchelCharge] = 1; - max[MortarBarrelPack] = 1; - max[MissileBarrelPack] = 1; - max[AABarrelPack] = 1; - max[PlasmaBarrelPack] = 1; - max[ELFBarrelPack] = 1; - max[InventoryDeployable]= 1; - max[MotionSensorDeployable] = 1; - max[PulseSensorDeployable] = 1; - max[TurretOutdoorDeployable] = 1; - max[TurretIndoorDeployable] = 1; - max[FlashGrenade] = 6; - max[ConcussionGrenade] = 6; - max[FlareGrenade] = 6; - max[TargetingLaser] = 1; - max[ELFGun] = 1; - max[ShockLance] = 1; - max[CameraGrenade] = 3; - max[Beacon] = 3; - max[Lootbag] = 1; - max[MiningTool] = 1; - max[C4Charge] = 1; - max[Flamer] = 0; - - observeParameters = "0.5 4.5 4.5"; - - shieldEffectScale = "0.7 0.7 1.0"; -}; - -//---------------------------------------------------------------------------- -datablock DecalData(HeavyMaleFootprint) -{ - sizeX = 0.25; - sizeY = 0.5; - textureName = "special/footprints/H_male"; -}; - -// z0dd - ZOD, 4/21/02. Altered most of these properties -datablock PlayerData(HeavyMaleHumanArmor) : HeavyPlayerDamageProfile -{ - emap = true; - - className = Armor; - shapeFile = "heavy_male.dts"; - cameraMaxDist = 3; - computeCRC = true; - - canObserve = true; - cmdCategory = "Clients"; - cmdIcon = CMDPlayerIcon; - cmdMiniIconName = "commander/MiniIcons/com_player_grey"; - - hudImageNameFriendly[0] = "gui/hud_playertriangle"; - hudImageNameEnemy[0] = "gui/hud_playertriangle_enemy"; - hudRenderModulated[0] = true; - - hudImageNameFriendly[1] = "commander/MiniIcons/com_flag_grey"; - hudImageNameEnemy[1] = "commander/MiniIcons/com_flag_grey"; - hudRenderModulated[1] = true; - hudRenderAlways[1] = true; - hudRenderCenter[1] = true; - hudRenderDistance[1] = true; - - hudImageNameFriendly[2] = "commander/MiniIcons/com_flag_grey"; - hudImageNameEnemy[2] = "commander/MiniIcons/com_flag_grey"; - hudRenderModulated[2] = true; - hudRenderAlways[2] = true; - hudRenderCenter[2] = true; - hudRenderDistance[2] = true; - - cameraDefaultFov = 90.0; - cameraMinFov = 5.0; - cameraMaxFov = 120.0; - - debrisShapeName = "debris_player.dts"; - debris = HumanRedPlayerDebris; - - aiAvoidThis = true; - - minLookAngle = -1.5; - maxLookAngle = 1.5; - maxFreelookAngle = 3.0; - - mass = 180; - drag = 0.23; - maxdrag = 0.5; - density = 27; - maxDamage = 1.32; - maxEnergy = 110; - repairRate = 0.0033; - energyPerDamagePoint = 54.0; // shield energy required to block one point of damage - - rechargeRate = 0.256; - jetForce = 29.58 * 180; - underwaterJetForce = 25.25 * 180 * 1.5; - underwaterVertJetFactor = 1.5; - jetEnergyDrain = 1.25; - underwaterJetEnergyDrain = 0.65; - minJetEnergy = 3; - maxJetHorizontalPercentage = 0.3; - - runForce = 40.25 * 180; - runEnergyDrain = 0; - minRunEnergy = 0; - maxForwardSpeed = 7.5; - maxBackwardSpeed = 5; - maxSideSpeed = 5; - - maxUnderwaterForwardSpeed = 5; - maxUnderwaterBackwardSpeed = 3; - maxUnderwaterSideSpeed = 3; - - recoverDelay = 8; - recoverRunForceScale = 0.2; - - jumpForce = 8.35 * 180; - jumpEnergyDrain = 0; - minJumpEnergy = 0; - jumpDelay = 0; - - // heat inc'ers and dec'ers - heatDecayPerSec = 1.0 / 4.0; // takes 4 seconds to clear heat sig. - heatIncreasePerSec = 1.0 / 3.0; // takes 3.0 seconds of constant jet to get full heat sig. - - // Controls over slope of runnable/jumpable surfaces - runSurfaceAngle = 70; - jumpSurfaceAngle = 75; - - minJumpSpeed = 20; - maxJumpSpeed = 30; - - noFrictionOnSki = true; - horizMaxSpeed = 500; - horizResistSpeed = 34.81; - horizResistFactor = 0; - maxJetForwardSpeed = 20; - - upMaxSpeed = 52; - upResistSpeed = 20.89; - upResistFactor = 0.18; - - minImpactSpeed = 45; - speedDamageScale = 0.0030; - - jetSound = ArmorJetSound; - wetJetSound = ArmorJetSound; - jetEmitter = HumanArmorJetEmitter; - - boundingBox = "1.63 1.63 2.6"; - pickupRadius = 0.75; - - // damage location details - boxNormalHeadPercentage = 0.83; - boxNormalTorsoPercentage = 0.49; - boxHeadLeftPercentage = 0; - boxHeadRightPercentage = 1; - boxHeadBackPercentage = 0; - boxHeadFrontPercentage = 1; - - //Foot Prints - decalData = HeavyMaleFootprint; - decalOffset = 0.4; - - footPuffEmitter = LightPuffEmitter; - footPuffNumParts = 15; - footPuffRadius = 0.25; - - dustEmitter = LiftoffDustEmitter; - - splash = PlayerSplash; - splashVelocity = 4.0; - splashAngle = 67.0; - splashFreqMod = 300.0; - splashVelEpsilon = 0.60; - bubbleEmitTime = 0.4; - splashEmitter[0] = PlayerFoamDropletsEmitter; - splashEmitter[1] = PlayerFoamEmitter; - splashEmitter[2] = PlayerBubbleEmitter; - mediumSplashSoundVelocity = 10.0; - hardSplashSoundVelocity = 20.0; - exitSplashSoundVelocity = 5.0; - - footstepSplashHeight = 0.35; - //Footstep Sounds - LFootSoftSound = LFootHeavySoftSound; - RFootSoftSound = RFootHeavySoftSound; - LFootHardSound = LFootHeavyHardSound; - RFootHardSound = RFootHeavyHardSound; - LFootMetalSound = LFootHeavyMetalSound; - RFootMetalSound = RFootHeavyMetalSound; - LFootSnowSound = LFootHeavySnowSound; - RFootSnowSound = RFootHeavySnowSound; - LFootShallowSound = LFootHeavyShallowSplashSound; - RFootShallowSound = RFootHeavyShallowSplashSound; - LFootWadingSound = LFootHeavyWadingSound; - RFootWadingSound = RFootHeavyWadingSound; - LFootUnderwaterSound = LFootHeavyUnderwaterSound; - RFootUnderwaterSound = RFootHeavyUnderwaterSound; - LFootBubblesSound = LFootHeavyBubblesSound; - RFootBubblesSound = RFootHeavyBubblesSound; - movingBubblesSound = ArmorMoveBubblesSound; - waterBreathSound = WaterBreathMaleSound; - - impactSoftSound = ImpactHeavySoftSound; - impactHardSound = ImpactHeavyHardSound; - impactMetalSound = ImpactHeavyMetalSound; - impactSnowSound = ImpactHeavySnowSound; - - skiSoftSound = SkiAllSoftSound; - skiHardSound = SkiAllHardSound; - skiMetalSound = SkiAllMetalSound; - skiSnowSound = SkiAllSnowSound; - - impactWaterEasy = ImpactHeavyWaterEasySound; - impactWaterMedium = ImpactHeavyWaterMediumSound; - impactWaterHard = ImpactHeavyWaterHardSound; - - groundImpactMinSpeed = 11.0; - groundImpactShakeFreq = "4.0 4.0 4.0"; - groundImpactShakeAmp = "1.0 1.0 1.0"; - groundImpactShakeDuration = 0.8; - groundImpactShakeFalloff = 10.0; - - exitingWater = ExitingWaterHeavySound; - - maxWeapons = 5; // Max number of different weapons the player can have - maxGrenades = 1; // Max number of different grenades the player can have - maxMines = 1; // Max number of different mines the player can have - - // Inventory restrictions - max[RepairKit] = 1; - max[Mine] = 3; - max[Grenade] = 8; - max[Blaster] = 1; - max[Plasma] = 1; - max[PlasmaAmmo] = 50; - max[Disc] = 1; - max[DiscAmmo] = 15; - max[SniperRifle] = 0; - max[GrenadeLauncher] = 1; - max[GrenadeLauncherAmmo]= 15; - max[Mortar] = 1; - max[MortarAmmo] = 10; - max[MissileLauncher] = 1; - max[MissileLauncherAmmo]= 8; - max[Chaingun] = 1; - max[ChaingunAmmo] = 200; - max[RepairGun] = 1; - max[CloakingPack] = 0; - max[SensorJammerPack] = 1; - max[EnergyPack] = 1; - max[RepairPack] = 1; - max[ShieldPack] = 1; - max[AmmoPack] = 1; - max[SatchelCharge] = 1; - max[MortarBarrelPack] = 1; - max[MissileBarrelPack] = 1; - max[AABarrelPack] = 1; - max[PlasmaBarrelPack] = 1; - max[ELFBarrelPack] = 1; - max[InventoryDeployable]= 1; - max[MotionSensorDeployable] = 1; - max[PulseSensorDeployable] = 1; - max[TurretOutdoorDeployable] = 1; - max[TurretIndoorDeployable] = 1; - max[FlashGrenade] = 8; - max[ConcussionGrenade] = 8; - max[FlareGrenade] = 8; - max[TargetingLaser] = 1; - max[ELFGun] = 1; - max[ShockLance] = 1; - max[CameraGrenade] = 3; - max[Beacon] = 3; - max[Lootbag] = 1; - max[MiningTool] = 1; - max[C4Charge] = 1; - max[Flamer] = 0; - - observeParameters = "0.5 4.5 4.5"; - - shieldEffectScale = "0.7 0.7 1.0"; -}; - -//---------------------------------------------------------------------------- -datablock PlayerData(LightFemaleHumanArmor) : LightMaleHumanArmor -{ - shapeFile = "light_female.dts"; - waterBreathSound = WaterBreathFemaleSound; - jetEffect = HumanMediumArmorJetEffect; -}; - -//---------------------------------------------------------------------------- -datablock PlayerData(MediumFemaleHumanArmor) : MediumMaleHumanArmor -{ - shapeFile = "medium_female.dts"; - waterBreathSound = WaterBreathFemaleSound; - jetEffect = HumanArmorJetEffect; -}; - -//---------------------------------------------------------------------------- -datablock PlayerData(HeavyFemaleHumanArmor) : HeavyMaleHumanArmor -{ - shapeFile = "heavy_male.dts"; - waterBreathSound = WaterBreathFemaleSound; -}; - -//---------------------------------------------------------------------------- -datablock DecalData(LightBiodermFootprint) -{ - sizeX = 0.25; - sizeY = 0.25; - textureName = "special/footprints/L_bioderm"; -}; - -datablock PlayerData(LightMaleBiodermArmor) : LightMaleHumanArmor -{ - shapeFile = "bioderm_light.dts"; - jetEmitter = BiodermArmorJetEmitter; - jetEffect = BiodermArmorJetEffect; - - - debrisShapeName = "bio_player_debris.dts"; - debris = BiodermPlayerDebris; - - //Foot Prints - decalData = LightBiodermFootprint; - decalOffset = 0.3; - - waterBreathSound = WaterBreathBiodermSound; -}; - -//TODO: Balance out the Draakan armors -datablock PlayerData(LightADraakanArmor) : LightMaleHumanArmor -{ - shapeFile = "bioderm_light.dts"; - jetEmitter = BiodermArmorJetEmitter; - jetEffect = BiodermArmorJetEffect; - - - debrisShapeName = "bio_player_debris.dts"; - debris = BiodermPlayerDebris; - - max[Flamer] = 1; - - //All the values from here and down (all Draakan armors) was severely unbalanced - - damageScale[$DamageType::Flame] = 0.2; - damageScale[$DamageType::Ground] = 0.37; //Was 0.07 - damageScale[$DamageType::Lava] = 0.1; //Was 0.01 - - - //Foot Prints - decalData = LightBiodermFootprint; - decalOffset = 0.3; - //Movement - runForce = 40.25 * 120; //Was 150 - runEnergyDrain = 0; - minRunEnergy = 0; - maxForwardSpeed = 20; - maxBackwardSpeed = 15.8; - maxSideSpeed = 9.9; - - maxUnderwaterForwardSpeed = 5; - maxUnderwaterBackwardSpeed = 3; - maxUnderwaterSideSpeed = 3; - - recoverDelay = 8; - recoverRunForceScale = 0.2; - - jumpForce = 8.35 * 135; //Was 160 - jumpEnergyDrain = 0; - minJumpEnergy = 0; - jumpDelay = 0; - - waterBreathSound = WaterBreathBiodermSound; -}; - -datablock PlayerData(LightBDraakanArmor) : LightMaleHumanArmor -{ - shapeFile = "bioderm_light.dts"; - jetEmitter = BiodermArmorJetEmitter; - jetEffect = BiodermArmorJetEffect; - - - debrisShapeName = "bio_player_debris.dts"; - debris = BiodermPlayerDebris; - - max[Flamer] = 1; - - damageScale[$DamageType::Flame] = 0; - damageScale[$DamageType::Ground] = 0.06; - damageScale[$DamageType::Lava] = 0.009; - - runForce = 40.25 * 180; - runEnergyDrain = 0; - minRunEnergy = 0; - maxForwardSpeed = 18.7; - maxBackwardSpeed = 13.2; - maxSideSpeed = 7.7; - - maxUnderwaterForwardSpeed = 5; - maxUnderwaterBackwardSpeed = 3; - maxUnderwaterSideSpeed = 3; - - recoverDelay = 8; - recoverRunForceScale = 0.2; - - jumpForce = 8.35 * 200; - jumpEnergyDrain = 0; - minJumpEnergy = 0; - jumpDelay = 0; - - - //Foot Prints - decalData = LightBiodermFootprint; - decalOffset = 0.3; - - waterBreathSound = WaterBreathBiodermSound; -}; - -datablock PlayerData(LightCDraakanArmor) : LightMaleHumanArmor -{ - shapeFile = "bioderm_light.dts"; - jetEmitter = BiodermArmorJetEmitter; - jetEffect = BiodermArmorJetEffect; - - - debrisShapeName = "bio_player_debris.dts"; - debris = BiodermPlayerDebris; - - max[Flamer] = 1; - - damageScale[$DamageType::Flame] = 0; - damageScale[$DamageType::Ground] = 0.06; - damageScale[$DamageType::Lava] = 0.009; - - runForce = 40.25 * 180; - runEnergyDrain = 0; - minRunEnergy = 0; - maxForwardSpeed = 18.7; - maxBackwardSpeed = 13.2; - maxSideSpeed = 7.7; - - maxUnderwaterForwardSpeed = 5; - maxUnderwaterBackwardSpeed = 3; - maxUnderwaterSideSpeed = 3; - - recoverDelay = 8; - recoverRunForceScale = 0.2; - - jumpForce = 8.35 * 200; - jumpEnergyDrain = 0; - minJumpEnergy = 0; - jumpDelay = 0; - - //Foot Prints - decalData = LightBiodermFootprint; - decalOffset = 0.3; - - waterBreathSound = WaterBreathBiodermSound; -}; - -datablock PlayerData(LightMaleCriollosArmor) : LightMaleHumanArmor -{ - shapeFile = "bioderm_light.dts"; - jetEmitter = BiodermArmorJetEmitter; - jetEffect = BiodermArmorJetEffect; - - - debrisShapeName = "bio_player_debris.dts"; - debris = BiodermPlayerDebris; - - - //Foot Prints - decalData = LightBiodermFootprint; - decalOffset = 0.3; - - waterBreathSound = WaterBreathBiodermSound; -}; - - -//---------------------------------------------------------------------------- -datablock DecalData(MediumBiodermFootprint) -{ - sizeX = 0.25; - sizeY = 0.25; - textureName = "special/footprints/M_bioderm"; -}; - -datablock PlayerData(MediumMaleBiodermArmor) : MediumMaleHumanArmor -{ - shapeFile = "bioderm_medium.dts"; - jetEmitter = BiodermArmorJetEmitter; - jetEffect = BiodermArmorJetEffect; - - debrisShapeName = "bio_player_debris.dts"; - debris = BiodermPlayerDebris; - - //Foot Prints - decalData = MediumBiodermFootprint; - decalOffset = 0.35; - - waterBreathSound = WaterBreathBiodermSound; -}; - -datablock PlayerData(MediumADraakanArmor) : MediumMaleHumanArmor -{ - emap = false; - - shapeFile = "bioderm_medium.dts"; - jetEmitter = BiodermArmorJetEmitter; - - damageScale[$DamageType::Flame] = 0; - damageScale[$DamageType::Ground] = 0.06; - damageScale[$DamageType::Lava] = 0.009; - - runForce = 40.25 * 180; - runEnergyDrain = 0; - minRunEnergy = 0; - maxForwardSpeed = 18.7; - maxBackwardSpeed = 13.2; - maxSideSpeed = 7.7; - - maxUnderwaterForwardSpeed = 5; - maxUnderwaterBackwardSpeed = 3; - maxUnderwaterSideSpeed = 3; - - recoverDelay = 8; - recoverRunForceScale = 0.2; - - jumpForce = 8.35 * 200; - jumpEnergyDrain = 0; - minJumpEnergy = 0; - jumpDelay = 0; - - debrisShapeName = "bio_player_debris.dts"; - debris = BiodermPlayerDebris; - - //Foot Prints - decalData = HeavyBiodermFootprint; - decalOffset = 0.4; - - waterBreathSound = WaterBreathBiodermSound; -}; - -datablock PlayerData(MediumBDraakanArmor) : MediumMaleHumanArmor -{ - emap = false; - - shapeFile = "bioderm_medium.dts"; - jetEmitter = BiodermArmorJetEmitter; - - damageScale[$DamageType::Flame] = 0; - damageScale[$DamageType::Ground] = 0.06; - damageScale[$DamageType::Lava] = 0.009; - - runForce = 40.25 * 180; - runEnergyDrain = 0; - minRunEnergy = 0; - maxForwardSpeed = 18.7; - maxBackwardSpeed = 13.2; - maxSideSpeed = 7.7; - - maxUnderwaterForwardSpeed = 5; - maxUnderwaterBackwardSpeed = 3; - maxUnderwaterSideSpeed = 3; - - recoverDelay = 8; - recoverRunForceScale = 0.2; - - jumpForce = 8.35 * 200; - jumpEnergyDrain = 0; - minJumpEnergy = 0; - jumpDelay = 0; - - - debrisShapeName = "bio_player_debris.dts"; - debris = BiodermPlayerDebris; - - //Foot Prints - decalData = HeavyBiodermFootprint; - decalOffset = 0.4; - - waterBreathSound = WaterBreathBiodermSound; -}; - -datablock PlayerData(MediumCDraakanArmor) : MediumMaleHumanArmor -{ - emap = false; - - shapeFile = "bioderm_medium.dts"; - jetEmitter = BiodermArmorJetEmitter; - - damageScale[$DamageType::Flame] = 0; - damageScale[$DamageType::Ground] = 0.06; - damageScale[$DamageType::Lava] = 0.009; - - runForce = 40.25 * 180; - runEnergyDrain = 0; - minRunEnergy = 0; - maxForwardSpeed = 18.7; - maxBackwardSpeed = 13.2; - maxSideSpeed = 7.7; - - maxUnderwaterForwardSpeed = 5; - maxUnderwaterBackwardSpeed = 3; - maxUnderwaterSideSpeed = 3; - - recoverDelay = 8; - recoverRunForceScale = 0.2; - - jumpForce = 8.35 * 200; - jumpEnergyDrain = 0; - minJumpEnergy = 0; - jumpDelay = 0; - - - debrisShapeName = "bio_player_debris.dts"; - debris = BiodermPlayerDebris; - - //Foot Prints - decalData = HeavyBiodermFootprint; - decalOffset = 0.4; - - waterBreathSound = WaterBreathBiodermSound; -}; - -datablock PlayerData(MediumMaleCriollosArmor) : MediumMaleHumanArmor -{ - emap = false; - - shapeFile = "bioderm_medium.dts"; - jetEmitter = BiodermArmorJetEmitter; - - debrisShapeName = "bio_player_debris.dts"; - debris = BiodermPlayerDebris; - - //Foot Prints - decalData = HeavyBiodermFootprint; - decalOffset = 0.4; - - waterBreathSound = WaterBreathBiodermSound; -}; - -//---------------------------------------------------------------------------- -datablock DecalData(HeavyBiodermFootprint) -{ - sizeX = 0.25; - sizeY = 0.5; - textureName = "special/footprints/H_bioderm"; -}; - -datablock PlayerData(HeavyMaleBiodermArmor) : HeavyMaleHumanArmor -{ - emap = false; - - shapeFile = "bioderm_heavy.dts"; - jetEmitter = BiodermArmorJetEmitter; - - debrisShapeName = "bio_player_debris.dts"; - debris = BiodermPlayerDebris; - - //Foot Prints - decalData = HeavyBiodermFootprint; - decalOffset = 0.4; - - waterBreathSound = WaterBreathBiodermSound; -}; - -datablock PlayerData(HeavyADraakanArmor) : HeavyMaleHumanArmor -{ - shapeFile = "bioderm_heavy.dts"; - debrisShapeName = "bio_player_debris.dts"; - debris = BiodermPlayerDebris; - - damageScale[$DamageType::Flame] = 0; - damageScale[$DamageType::Ground] = 0.06; - damageScale[$DamageType::Lava] = 0.009; - - runForce = 40.25 * 180; - runEnergyDrain = 0; - minRunEnergy = 0; - maxForwardSpeed = 18.7; - maxBackwardSpeed = 13.2; - maxSideSpeed = 7.7; - - maxUnderwaterForwardSpeed = 5; - maxUnderwaterBackwardSpeed = 3; - maxUnderwaterSideSpeed = 3; - - recoverDelay = 8; - recoverRunForceScale = 0.2; - - jumpForce = 8.35 * 200; - jumpEnergyDrain = 0; - minJumpEnergy = 0; - jumpDelay = 0; - -}; - -datablock PlayerData(HeavyBDraakanArmor) : HeavyMaleHumanArmor -{ - shapeFile = "bioderm_heavy.dts"; - debrisShapeName = "bio_player_debris.dts"; - debris = BiodermPlayerDebris; - - damageScale[$DamageType::Flame] = 0; - damageScale[$DamageType::Ground] = 0.06; - damageScale[$DamageType::Lava] = 0.009; - - runForce = 40.25 * 180; - runEnergyDrain = 0; - minRunEnergy = 0; - maxForwardSpeed = 18.7; - maxBackwardSpeed = 13.2; - maxSideSpeed = 7.7; - - maxUnderwaterForwardSpeed = 5; - maxUnderwaterBackwardSpeed = 3; - maxUnderwaterSideSpeed = 3; - - recoverDelay = 8; - recoverRunForceScale = 0.2; - - jumpForce = 8.35 * 200; - jumpEnergyDrain = 0; - minJumpEnergy = 0; - jumpDelay = 0; - -}; - -datablock PlayerData(HeavyCDraakanArmor) : HeavyMaleHumanArmor -{ -shapeFile = "bioderm_heavy.dts"; -debrisShapeName = "bio_player_debris.dts"; -debris = BiodermPlayerDebris; - - damageScale[$DamageType::Flame] = 0; - damageScale[$DamageType::Ground] = 0.06; - damageScale[$DamageType::Lava] = 0.009; - - runForce = 40.25 * 180; - runEnergyDrain = 0; - minRunEnergy = 0; - maxForwardSpeed = 18.7; - maxBackwardSpeed = 13.2; - maxSideSpeed = 7.7; - - maxUnderwaterForwardSpeed = 5; - maxUnderwaterBackwardSpeed = 3; - maxUnderwaterSideSpeed = 3; - - recoverDelay = 8; - recoverRunForceScale = 0.2; - - jumpForce = 8.35 * 200; - jumpEnergyDrain = 0; - minJumpEnergy = 0; - jumpDelay = 0; - -}; - -datablock PlayerData(HeavyMaleCriollosArmor) : HeavyMaleHumanArmor -{ -shapeFile = "bioderm_heavy.dts"; -debrisShapeName = "bio_player_debris.dts"; -debris = BiodermPlayerDebris; -}; - -//---------------------------------------------------------------------------- - -function Armor::onAdd(%data,%obj) -{ - Parent::onAdd(%data, %obj); - // Vehicle timeout - %obj.mountVehicle = true; - - // Default dynamic armor stats - %obj.setRechargeRate(%data.rechargeRate); - %obj.setRepairRate(0); - - %obj.setSelfPowered(); -} - -function Armor::onRemove(%this, %obj) -{ - //Frohny asked me to remove this - all players are deleted now on mission cycle... - //if(%obj.getState() !$= "Dead") - //{ - // error("ERROR PLAYER REMOVED WITHOUT DEATH - TRACE:"); - // trace(1); - // schedule(0,0,trace,0); - //} - - if (%obj.client.player == %obj) - %obj.client.player = 0; -} - -function Armor::onNewDataBlock(%this,%obj) -{ -} - -//------------------------------------------------------------------------------------- -// z0dd - ZOD, 4-15-02. Allow respawn switching during tourney wait. Function rewrite. -function Armor::onDisabled(%this,%obj,%state) -{ - if($MatchStarted) - { - %obj.startFade( 1000, $CorpseTimeoutValue - 1000, true ); - %obj.schedule( $CorpseTimeoutValue, "delete" ); - } - else - { - %obj.schedule( 150, "delete" ); - } -} -//------------------------------------------------------------------------------------- - -function Armor::shouldApplyImpulse(%data, %obj) -{ - return true; -} - -$wasFirstPerson = true; - -function Armor::onMount(%this,%obj,%vehicle,%node) -{ - if (%node == 0) - { - // Node 0 is the pilot's pos. - %obj.setTransform("0 0 0 0 0 1 0"); - %obj.setActionThread(%vehicle.getDatablock().mountPose[%node],true,true); - - if(!%obj.inStation) - %obj.lastWeapon = (%obj.getMountedImage($WeaponSlot) == 0 ) ? "" : %obj.getMountedImage($WeaponSlot).getName().item; - - %obj.unmountImage($WeaponSlot); - - if(!%obj.client.isAIControlled()) - { - %obj.setControlObject(%vehicle); - %obj.client.setObjectActiveImage(%vehicle, 2); - } - - //E3 respawn... - - if(%obj == %obj.lastVehicle.lastPilot && %obj.lastVehicle != %vehicle) - { - schedule(15000, %obj.lastVehicle,"vehicleAbandonTimeOut", %obj.lastVehicle); - %obj.lastVehicle.lastPilot = ""; - } - if(%vehicle.lastPilot !$= "" && %vehicle == %vehicle.lastPilot.lastVehicle) - %vehicle.lastPilot.lastVehicle = ""; - - %vehicle.abandon = false; - %vehicle.lastPilot = %obj; - %obj.lastVehicle = %vehicle; - - // update the vehicle's team - if((%vehicle.getTarget() != -1) && %vehicle.getDatablock().cantTeamSwitch $= "") - { - setTargetSensorGroup(%vehicle.getTarget(), %obj.client.getSensorGroup()); - if( %vehicle.turretObject > 0 ) - setTargetSensorGroup(%vehicle.turretObject.getTarget(), %obj.client.getSensorGroup()); - } - - // Send a message to the client so they can decide if they want to change view or not: - commandToClient( %obj.client, 'VehicleMount' ); - - } - else - { - // tailgunner/passenger positions - if(%vehicle.getDataBlock().mountPose[%node] !$= "") - %obj.setActionThread(%vehicle.getDatablock().mountPose[%node]); - else - %obj.setActionThread("root", true); - } - // z0dd - ZOD, 6/27/02. announce to any other passengers that you've boarded - if(%vehicle.getDatablock().numMountPoints > 1) - { - %nodeName = findNodeName(%vehicle, %node); // function in vehicle.cs - for(%i = 0; %i < %vehicle.getDatablock().numMountPoints; %i++) - { - if (%vehicle.getMountNodeObject(%i) > 0) - { - if(%vehicle.getMountNodeObject(%i).client != %obj.client) - { - %team = (%obj.team == %vehicle.getMountNodeObject(%i).client.team ? 'Teammate' : 'Enemy'); - messageClient( %vehicle.getMountNodeObject(%i).client, 'MsgShowPassenger', '\c2%3: \c3%1\c2 has boarded in the \c3%2\c2 position.', %obj.client.name, %nodeName, %team ); - } - commandToClient( %vehicle.getMountNodeObject(%i).client, 'showPassenger', %node, true); - } - } - } - //make sure they don't have any packs active -// if ( %obj.getImageState( $BackpackSlot ) $= "activate") -// %obj.use("Backpack"); - if ( %obj.getImageTrigger( $BackpackSlot ) ) - %obj.setImageTrigger( $BackpackSlot, false ); - - //AI hooks - %obj.client.vehicleMounted = %vehicle; - AIVehicleMounted(%vehicle); - if(%obj.client.isAIControlled()) - %this.AIonMount(%obj, %vehicle, %node); -} - - -function Armor::onUnmount( %this, %obj, %vehicle, %node ) -{ - if ( %node == 0 ) - { - commandToClient( %obj.client, 'VehicleDismount' ); - commandToClient(%obj.client, 'removeReticle'); - - if(%obj.inv[%obj.lastWeapon]) - %obj.use(%obj.lastWeapon); - - if(%obj.getMountedImage($WeaponSlot) == 0) - %obj.selectWeaponSlot( 0 ); - - //Inform gunner position when pilot leaves... - //if(%vehicle.getDataBlock().showPilotInfo !$= "") - // if((%gunner = %vehicle.getMountNodeObject(1)) != 0) - // commandToClient(%gunner.client, 'PilotInfo', "PILOT EJECTED", 6, 1); - } - // z0dd - ZOD, 6/27/02. announce to any other passengers that you've left - if(%vehicle.getDatablock().numMountPoints > 1) - { - %nodeName = findNodeName(%vehicle, %node); // function in vehicle.cs - for(%i = 0; %i < %vehicle.getDatablock().numMountPoints; %i++) - { - if (%vehicle.getMountNodeObject(%i) > 0) - { - if(%vehicle.getMountNodeObject(%i).client != %obj.client) - { - %team = (%obj.team == %vehicle.getMountNodeObject(%i).client.team ? 'Teammate' : 'Enemy'); - messageClient( %vehicle.getMountNodeObject(%i).client, 'MsgShowPassenger', '\c2%3: \c3%1\c2 has ejected from the \c3%2\c2 position.', %obj.client.name, %nodeName, %team ); - } - commandToClient( %vehicle.getMountNodeObject(%i).client, 'showPassenger', %node, false); - } - } - } - //AI hooks - %obj.client.vehicleMounted = ""; - if(%obj.client.isAIControlled()) - %this.AIonUnMount(%obj, %vehicle, %node); -} - -$ammoType[0] = "PlasmaAmmo"; -$ammoType[1] = "DiscAmmo"; -$ammoType[2] = "GrenadeLauncherAmmo"; -$ammoType[3] = "MortarAmmo"; -$ammoType[4] = "MissileLauncherAmmo"; -$ammoType[5] = "ChaingunAmmo"; -// ------------------------------------- -// z0dd - ZOD, 9/13/02. For TR2 weapons -$ammoType[6] = "TR2DiscAmmo"; -$ammoType[7] = "TR2GrenadeLauncherAmmo"; -$ammoType[8] = "TR2ChaingunAmmo"; -$ammoType[9] = "TR2MortarAmmo"; -// ------------------------------------- - -function Armor::onCollision(%this,%obj,%col,%forceVehicleNode) -{ - if (%obj.getState() $= "Dead") - return; - - %dataBlock = %col.getDataBlock(); - %className = %dataBlock.className; - %client = %obj.client; - // player collided with a vehicle - %node = -1; - if (%forceVehicleNode !$= "" || (%className $= WheeledVehicleData || %className $= FlyingVehicleData || %className $= HoverVehicleData) && - %obj.mountVehicle && %obj.getState() $= "Move" && %col.mountable && !%obj.inStation && %col.getDamageState() !$= "Destroyed") { - - //if the player is an AI, he should snap to the mount points in node order, - //to ensure they mount the turret before the passenger seat, regardless of where they collide... - if (%obj.client.isAIControlled()) - { - %transform = %col.getTransform(); - - //either the AI is *required* to pilot, or they'll pick the first available passenger seat - if (%client.pilotVehicle) - { - //make sure the bot is in light armor - if (%client.player.getArmorSize() $= "Light") - { - //make sure the pilot seat is empty - if (!%col.getMountNodeObject(0)) - %node = 0; - } - } - else - %node = findAIEmptySeat(%col, %obj); - } - else - %node = findEmptySeat(%col, %obj, %forceVehicleNode); - - //now mount the player in the vehicle - if(%node >= 0) - { - // players can't be pilots, bombardiers or turreteers if they have - // "large" packs -- stations, turrets, turret barrels - if(hasLargePack(%obj)) { - // check to see if attempting to enter a "sitting" node - if(nodeIsSitting(%datablock, %node)) { - // send the player a message -- can't sit here with large pack - if(!%obj.noSitMessage) - { - %obj.noSitMessage = true; - %obj.schedule(2000, "resetSitMessage"); - messageClient(%obj.client, 'MsgCantSitHere', '\c2Pack too large, can\'t occupy this seat.~wfx/misc/misc.error.wav'); - } - return; - } - } - if(%col.noEnemyControl && %obj.team != %col.team) - return; - - commandToClient(%obj.client,'SetDefaultVehicleKeys', true); - //If pilot or passenger then bind a few extra keys - if(%node == 0) - commandToClient(%obj.client,'SetPilotVehicleKeys', true); - else - commandToClient(%obj.client,'SetPassengerVehicleKeys', true); - - if(!%obj.inStation) - %col.lastWeapon = ( %col.getMountedImage($WeaponSlot) == 0 ) ? "" : %col.getMountedImage($WeaponSlot).getName().item; - else - %col.lastWeapon = %obj.lastWeapon; - - %col.mountObject(%obj,%node); - %col.playAudio(0, MountVehicleSound); - %obj.mVehicle = %col; - - // if player is repairing something, stop it - if(%obj.repairing) - stopRepairing(%obj); - - //this will setup the huds as well... - %dataBlock.playerMounted(%col,%obj, %node); - } - } - else if (%className $= "Armor") { - // player has collided with another player - if(%col.getState() $= "Dead") { - %gotSomething = false; - // it's corpse-looting time! - // weapons -- don't pick up more than you are allowed to carry! - for(%i = 0; ( %obj.weaponCount < %obj.getDatablock().maxWeapons ) && $InvWeapon[%i] !$= ""; %i++) - { - %weap = $NameToInv[$InvWeapon[%i]]; - if ( %col.hasInventory( %weap ) ) - { - if ( %obj.incInventory(%weap, 1) > 0 ) - { - %col.decInventory(%weap, 1); - %gotSomething = true; - messageClient(%obj.client, 'MsgItemPickup', '\c0You picked up %1.', %weap.pickUpName); - } - } - } - // targeting laser: - if ( %col.hasInventory( "TargetingLaser" ) ) - { - if ( %obj.incInventory( "TargetingLaser", 1 ) > 0 ) - { - %col.decInventory( "TargetingLaser", 1 ); - %gotSomething = true; - messageClient( %obj.client, 'MsgItemPickup', '\c0You picked up a targeting laser.' ); - } - } - // ammo - for(%j = 0; $ammoType[%j] !$= ""; %j++) - { - %ammoAmt = %col.inv[$ammoType[%j]]; - if(%ammoAmt) - { - // incInventory returns the amount of stuff successfully grabbed - %grabAmt = %obj.incInventory($ammoType[%j], %ammoAmt); - if(%grabAmt > 0) - { - %col.decInventory($ammoType[%j], %grabAmt); - %gotSomething = true; - messageClient(%obj.client, 'MsgItemPickup', '\c0You picked up %1.', $ammoType[%j].pickUpName); - %obj.client.setWeaponsHudAmmo($ammoType[%j], %obj.getInventory($ammoType[%j])); - } - } - } - // figure out what type, if any, grenades the (live) player has - %playerGrenType = "None"; - for(%x = 0; $InvGrenade[%x] !$= ""; %x++) { - %gren = $NameToInv[$InvGrenade[%x]]; - %playerGrenAmt = %obj.inv[%gren]; - if(%playerGrenAmt > 0) - { - %playerGrenType = %gren; - break; - } - } - // grenades - for(%k = 0; $InvGrenade[%k] !$= ""; %k++) - { - %gren = $NameToInv[$InvGrenade[%k]]; - %corpseGrenAmt = %col.inv[%gren]; - // does the corpse hold any of this grenade type? - if(%corpseGrenAmt) - { - // can the player pick up this grenade type? - if((%playerGrenType $= "None") || (%playerGrenType $= %gren)) - { - %taken = %obj.incInventory(%gren, %corpseGrenAmt); - if(%taken > 0) - { - %col.decInventory(%gren, %taken); - %gotSomething = true; - messageClient(%obj.client, 'MsgItemPickup', '\c0You picked up %1.', %gren.pickUpName); - %obj.client.setInventoryHudAmount(%gren, %obj.getInventory(%gren)); - } - } - break; - } - } - // figure out what type, if any, mines the (live) player has - %playerMineType = "None"; - for(%y = 0; $InvMine[%y] !$= ""; %y++) - { - %mType = $NameToInv[$InvMine[%y]]; - %playerMineAmt = %obj.inv[%mType]; - if(%playerMineAmt > 0) - { - %playerMineType = %mType; - break; - } - } - // mines - for(%l = 0; $InvMine[%l] !$= ""; %l++) - { - %mine = $NameToInv[$InvMine[%l]]; - %mineAmt = %col.inv[%mine]; - if(%mineAmt) { - if((%playerMineType $= "None") || (%playerMineType $= %mine)) - { - %grabbed = %obj.incInventory(%mine, %mineAmt); - if(%grabbed > 0) - { - %col.decInventory(%mine, %grabbed); - %gotSomething = true; - messageClient(%obj.client, 'MsgItemPickup', '\c0You picked up %1.', %mine.pickUpName); - %obj.client.setInventoryHudAmount(%mine, %obj.getInventory(%mine)); - } - } - break; - } - } - // beacons - %beacAmt = %col.inv[Beacon]; - if(%beacAmt) - { - %bTaken = %obj.incInventory(Beacon, %beacAmt); - if(%bTaken > 0) - { - %col.decInventory(Beacon, %bTaken); - %gotSomething = true; - messageClient(%obj.client, 'MsgItemPickup', '\c0You picked up %1.', Beacon.pickUpName); - %obj.client.setInventoryHudAmount(Beacon, %obj.getInventory(Beacon)); - } - } - // repair kit - %rkAmt = %col.inv[RepairKit]; - if(%rkAmt) - { - %rkTaken = %obj.incInventory(RepairKit, %rkAmt); - if(%rkTaken > 0) - { - %col.decInventory(RepairKit, %rkTaken); - %gotSomething = true; - messageClient(%obj.client, 'MsgItemPickup', '\c0You picked up %1.', RepairKit.pickUpName); - %obj.client.setInventoryHudAmount(RepairKit, %obj.getInventory(RepairKit)); - } - } - } - if(%gotSomething) - %col.playAudio(0, CorpseLootingSound); - } -} - -// ------------------------------------------------------------ -// z0dd - ZOD, 9/27/02. Delay on grabbing flag after tossing it -function Player::resetFlagTossWait(%this) -{ - %this.flagTossWait = false; -} -// ------------------------------------------------------------ - -function Player::resetSitMessage(%obj) -{ - %obj.noSitMessage = false; -} - -function Player::setInvincible(%this, %val) -{ - %this.invincible = %val; -} - -function Player::causedRecentDamage(%this, %val) -{ - %this.causedRecentDamage = %val; -} - -function hasLargePack(%player) -{ - %pack = %player.getMountedImage($BackpackSlot); - if(%pack.isLarge) - return true; - else - return false; -} - -function nodeIsSitting(%vehDBlock, %node) -{ - // pilot == always a "sitting" node - if(%node == 0) - return true; - else { - switch$ (%vehDBlock.getName()) - { - // note: for assault tank -- both nodes are sitting - // for any single-user vehicle -- pilot node is sitting - case "BomberFlyer": - // bombardier == sitting; tailgunner == not sitting - if(%node == 1) - return true; - else - return false; - case "HAPCFlyer": - // only the pilot node is sitting - return false; - default: - return true; - } - } -} - -//---------------------------------------------------------------------------- -function Player::setMountVehicle(%this, %val) -{ - %this.mountVehicle = %val; -} - -function Armor::doDismount(%this, %obj, %forced) -{ - // This function is called by player.cc when the jump trigger - // is true while mounted - if (!%obj.isMounted()) - return; - - if(isObject(%obj.getObjectMount().shield)) - %obj.getObjectMount().shield.delete(); - - commandToClient(%obj.client,'SetDefaultVehicleKeys', false); - - // Position above dismount point - - %pos = getWords(%obj.getTransform(), 0, 2); - %oldPos = %pos; - %vec[0] = " 0 0 1"; - %vec[1] = " 0 0 1"; - %vec[2] = " 0 0 -1"; - %vec[3] = " 1 0 0"; - %vec[4] = "-1 0 0"; - %numAttempts = 5; - %success = -1; - %impulseVec = "0 0 0"; - if (%obj.getObjectMount().getDatablock().hasDismountOverrides() == true) - { - %vec[0] = %obj.getObjectMount().getDatablock().getDismountOverride(%obj.getObjectMount(), %obj); - %vec[0] = MatrixMulVector(%obj.getObjectMount().getTransform(), %vec[0]); - } - else - { - %vec[0] = MatrixMulVector( %obj.getTransform(), %vec[0]); - } - - %pos = "0 0 0"; - for (%i = 0; %i < %numAttempts; %i++) - { - %pos = VectorAdd(%oldPos, VectorScale(%vec[%i], 5)); // z0dd - ZOD, 4/24/02. More ejection clearance. 5 was 3 - if (%obj.checkDismountPoint(%oldPos, %pos)) - { - %success = %i; - %impulseVec = %vec[%i]; - break; - } - } - if (%forced && %success == -1) - { - %pos = %oldPos; - } - - // hide the dashboard HUD and delete elements based on node - commandToClient(%obj.client, 'setHudMode', 'Standard', "", 0); - // Unmount and control body - if(%obj.vehicleTurret) - %obj.vehicleTurret.getDataBlock().playerDismount(%obj.vehicleTurret); - %obj.unmount(); - if(%obj.mVehicle) - %obj.mVehicle.getDataBlock().playerDismounted(%obj.mVehicle, %obj); - - // bots don't change their control objects when in vehicles - if(!%obj.client.isAIControlled()) - { - %vehicle = %obj.getControlObject(); - %obj.setControlObject(0); - } - - %obj.mountVehicle = false; - %obj.schedule(1500, "setMountVehicle", true); // z0dd - ZOD, 3/29/02. Reduce time between being able to mount vehicles . Was 4000 - - // Position above dismount point - %obj.setTransform(%pos); - %obj.playAudio(0, UnmountVehicleSound); - %obj.applyImpulse(%pos, VectorScale(%impulseVec, %obj.getDataBlock().mass * 3)); - %obj.setPilot(false); - %obj.vehicleTurret = ""; - - // ----------------------------------------------------- - // z0dd - ZOD, 4/8/02. Set player velocity when ejecting - %vel = %obj.getVelocity(); - %vec = vectorDot(%vel, vectorNormalize(%vel)); - if(%vec > 50) - { - %scale = 50 / %vec; - %obj.setVelocity(VectorScale(%vel, %scale)); - } - // ----------------------------------------------------- -} - -function resetObserveFollow( %client, %dismount ) -{ - if( %dismount ) - { - if( !isObject( %client.player ) ) - return; - - for( %i = 0; %i < %client.observeCount; %i++ ) - { - %client.observers[%i].camera.setOrbitMode( %client.player, %client.player.getTransform(), 0.5, 4.5, 4.5); - } - } - else - { - if( !%client.player.isMounted() ) - return; - - // grab the vehicle... - %mount = %client.player.getObjectMount(); - if( %mount.getDataBlock().observeParameters $= "" ) - %params = %client.player.getTransform(); - else - %params = %mount.getDataBlock().observeParameters; - - for( %i = 0; %i < %client.observeCount; %i++ ) - { - %client.observers[%i].camera.setOrbitMode(%mount, %mount.getTransform(), getWord( %params, 0 ), getWord( %params, 1 ), getWord( %params, 2 )); - } - } -} - - -//---------------------------------------------------------------------------- - -function Player::scriptKill(%player, %damageType) -{ - %player.scriptKilled = 1; - %player.setInvincible(false); - %player.damage(0, %player.getPosition(), 10000, %damageType); -} - -function Armor::damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType, %momVec, %mineSC) -{ -//error("Armor::damageObject( "@%data@", "@%targetObject@", "@%sourceObject@", "@%position@", "@%amount@", "@%damageType@", "@%momVec@" )"); - if(%targetObject.invincible || %targetObject.getState() $= "Dead") - return; - - //---------------------------------------------------------------- - // z0dd - ZOD, 6/09/02. Check to see if this vehicle is destroyed, - // if it is do no damage. Fixes vehicle ghosting bug. We do not - // check for isObject here, destroyed objects fail it even though - // they exist as objects, go figure. - if(%damageType == $DamageType::Impact) - if(%sourceObject.getDamageState() $= "Destroyed") - return; - - if (%targetObject.isMounted() && %targetObject.scriptKilled $= "") - { - %mount = %targetObject.getObjectMount(); - if(%mount.team == %targetObject.team) - { - %found = -1; - for (%i = 0; %i < %mount.getDataBlock().numMountPoints; %i++) - { - if (%mount.getMountNodeObject(%i) == %targetObject) - { - %found = %i; - break; - } - } - - if (%found != -1) - { - if (%mount.getDataBlock().isProtectedMountPoint[%found]) - { - %mount.getDataBlock().damageObject(%mount, %sourceObject, %position, %amount, %damageType); - return; - } - } - } - } - - %targetClient = %targetObject.getOwnerClient(); - if(isObject(%mineSC)) - %sourceClient = %mineSC; - else - %sourceClient = isObject(%sourceObject) ? %sourceObject.getOwnerClient() : 0; - - %targetTeam = %targetClient.team; - - //if the source object is a player object, player's don't have sensor groups - // if it's a turret, get the sensor group of the target - // if its a vehicle (of any type) use the sensor group - if (%sourceClient) - %sourceTeam = %sourceClient.getSensorGroup(); - else if(%damageType == $DamageType::Suicide) - %sourceTeam = 0; - //-------------------------------------------------------------------------------------------------------------------- - // z0dd - ZOD, 4/8/02. Check to see if this turret has a valid owner, if not clear the variable. - else if(isObject(%sourceObject) && %sourceObject.getClassName() $= "Turret") - { - %sourceTeam = getTargetSensorGroup(%sourceObject.getTarget()); - if(%sourceObject.owner !$="" && (%sourceObject.owner.team != %sourceObject.team || !isObject(%sourceObject.owner))) - { - %sourceObject.owner = ""; - } - } - //-------------------------------------------------------------------------------------------------------------------- - else if( isObject(%sourceObject) && - ( %sourceObject.getClassName() $= "FlyingVehicle" || %sourceObject.getClassName() $= "WheeledVehicle" || %sourceObject.getClassName() $= "HoverVehicle")) - %sourceTeam = getTargetSensorGroup(%sourceObject.getTarget()); - else - { - if (isObject(%sourceObject) && %sourceObject.getTarget() >= 0 ) - { - %sourceTeam = getTargetSensorGroup(%sourceObject.getTarget()); - } - else - { - %sourceTeam = -1; - } - } - - // if teamdamage is off, and both parties are on the same team - // (but are not the same person), apply no damage - if(!$teamDamage && (%targetClient != %sourceClient) && (%targetTeam == %sourceTeam)) - return; - - if(%targetObject.isShielded && %damageType != $DamageType::Blaster) - %amount = %data.checkShields(%targetObject, %position, %amount, %damageType); - - if(%amount == 0) - return; - - // Set the damage flash - %damageScale = %data.damageScale[%damageType]; - if(%damageScale !$= "") - %amount *= %damageScale; - - %flash = %targetObject.getDamageFlash() + (%amount * 2); - if (%flash > 0.75) - %flash = 0.75; - - %previousDamage = %targetObject.getDamagePercent(); - %targetObject.setDamageFlash(%flash); - %targetObject.applyDamage(%amount); - Game.onClientDamaged(%targetClient, %sourceClient, %damageType, %sourceObject); - - %targetClient.lastDamagedBy = %damagingClient; - %targetClient.lastDamaged = getSimTime(); - - //now call the "onKilled" function if the client was... you know... - if(%targetObject.getState() $= "Dead") - { - // where did this guy get it? - %damLoc = %targetObject.getDamageLocation(%position); - - // should this guy be blown apart? - if( %damageType == $DamageType::Explosion || - %damageType == $DamageType::TankMortar || - %damageType == $DamageType::Mortar || - %damageType == $DamageType::MortarTurret || - %damageType == $DamageType::BomberBombs || - %damageType == $DamageType::SatchelCharge || - %damageType == $DamageType::Missile ) - { - if( %previousDamage >= 0.35 ) // only if <= 35 percent damage remaining - { - %targetObject.setMomentumVector(%momVec); - %targetObject.blowup(); - } - } - - // this should be funny... - if( %damageType == $DamageType::VehicleSpawn ) - { - %targetObject.setMomentumVector("0 0 1"); - %targetObject.blowup(); - } - - // If we were killed, max out the flash - %targetObject.setDamageFlash(0.75); - - %damLoc = %targetObject.getDamageLocation(%position); - Game.onClientKilled(%targetClient, %sourceClient, %damageType, %sourceObject, %damLoc); - - if ( %amount > 0.1 ) - { - if( %targetObject.station $= "" && %targetObject.isCloaked() ) - { - %targetObject.setCloaked( false ); - %targetObject.reCloak = %targetObject.schedule( 500, "setCloaked", true ); - } - - playPain( %targetObject ); - } - } -} - -function Armor::onImpact(%data, %playerObject, %collidedObject, %vec, %vecLen) -{ - %data.damageObject(%playerObject, 0, VectorAdd(%playerObject.getPosition(),%vec), - %vecLen * %data.speedDamageScale, $DamageType::Ground); -} - -function Armor::applyConcussion( %this, %dist, %radius, %sourceObject, %targetObject ) -{ - %percentage = 1 - ( %dist / %radius ); - %random = getRandom(); - - if( %sourceObject == %targetObject ) - { - %flagChance = 1.0; - %itemChance = 1.0; - } - else - { - %flagChance = 0.7; - %itemChance = 0.7; - } - - %probabilityFlag = %flagChance * %percentage; - %probabilityItem = %itemChance * %percentage; - - if( %random <= %probabilityFlag ) - { - Game.applyConcussion( %targetObject ); - } - - if( %random <= %probabilityItem ) - { - %player = %targetObject; - %numWeapons = 0; - - // blaster 0 - // plasma 1 - // chain 2 - // disc 3 - // grenade 4 - // snipe 5 - // elf 6 - // mortar 7 - - //get our inventory - if( %weaps[0] = %player.getInventory("Blaster") > 0 ) %numWeapons++; - if( %weaps[1] = %player.getInventory("Plasma") > 0 ) %numWeapons++; - if( %weaps[2] = %player.getInventory("Chaingun") > 0 ) %numWeapons++; - if( %weaps[3] = %player.getInventory("Disc") > 0 ) %numWeapons++; - if( %weaps[4] = %player.getInventory("GrenadeLauncher") > 0 ) %numWeapons++; - if( %weaps[5] = %player.getInventory("SniperRifle") > 0 ) %numWeapons++; - if( %weaps[6] = %player.getInventory("ELFGun") > 0 ) %numWeapons++; - if( %weaps[7] = %player.getInventory("Mortar") > 0 ) %numWeapons++; - - %foundWeapon = false; - %attempts = 0; - - if( %numWeapons > 0 ) - { - while( !%foundWeapon ) - { - %rand = mFloor( getRandom() * 8 ); - if( %weaps[ %rand ] ) - { - %foundWeapon = true; - - switch ( %rand ) - { - case 0: - %player.use("Blaster"); - case 1: - %player.use("Plasma"); - case 2: - %player.use("Chaingun"); - case 3: - %player.use("Disc"); - case 4: - %player.use("GrenadeLauncher"); - case 5: - %player.use("SniperRifle"); - case 6: - %player.use("ElfGun"); - case 7: - %player.use("Mortar"); - } - - %image = %player.getMountedImage( $WeaponSlot ); - %player.throw( %image.item ); - %player.client.setWeaponsHudItem( %image.item, 0, 0 ); - %player.throwPack(); - } - else - { - %attempts++; - if( %attempts > 10 ) - %foundWeapon = true; - } - } - } - else - { - %targetObject.throwPack(); - %targetObject.throwWeapon(); - } - } -} - -//---------------------------------------------------------------------------- - -$DeathCry[1] = 'avo.deathCry_01'; -$DeathCry[2] = 'avo.deathCry_02'; -$PainCry[1] = 'avo.grunt'; -$PainCry[2] = 'avo.pain'; - -function playDeathCry( %obj ) -{ - %client = %obj.client; - %random = getRandom(1) + 1; - %desc = AudioClosest3d; - - playTargetAudio( %client.target, $DeathCry[%random], %desc, false ); -} - -function playPain( %obj ) -{ - %client = %obj.client; - %random = getRandom(1) + 1; - %desc = AudioClosest3d; - - playTargetAudio( %client.target, $PainCry[%random], %desc, false); -} - -//---------------------------------------------------------------------------- - -//$DefaultPlayerArmor = LightMaleHumanArmor; -$DefaultPlayerArmor = Light; - -function Player::setArmor(%this,%size) -{ - // Takes size as "Light","Medium", "Heavy" - %client = %this.client; - if (%client.race $= "Bioderm") - // Only have male bioderms. - %armor = %size @ "Male" @ %client.race @ Armor; - else - %armor = %size @ %client.sex @ %client.race @ Armor; - //echo("Player::armor: " @ %armor); - %this.setDataBlock(%armor); - %client.armor = %size; -} - -function getDamagePercent(%maxDmg, %dmgLvl) -{ - return (%dmgLvl / %maxDmg); -} - -function Player::getArmorSize(%this) -{ - // return size as "Light","Medium", "Heavy" - %dataBlock = %this.getDataBlock().getName(); - if (getSubStr(%dataBlock, 0, 5) $= "Light") - return "Light"; - else if (getSubStr(%dataBlock, 0, 6) $= "Medium") - return "Medium"; - else if (getSubStr(%dataBlock, 0, 5) $= "Heavy") - return "Heavy"; - else - return "Unknown"; -} - -function Player::pickup(%this,%obj,%amount) -{ - %data = %obj.getDataBlock(); - %client = %this.client; - if (%data.className $= Pack && %data.getName() $= Lootbag) - { - if (%obj.cash > 0) - { - messageClient(%client,'msgClient',"\c3That bag had "@%obj.cash@" coins in it."); - %client.cash = %client.cash + %obj.cash; - } - } - // Don't pick up a pack if we already have one mounted - if (%data.className $= Pack && - %this.getMountedImage($BackpackSlot) != 0) - return 0; - // don't pick up a weapon (other than targeting laser) if player's at maxWeapons - else if(%data.className $= Weapon - && %data.getName() !$= "TargetingLaser" // Special case - && %this.weaponCount >= %this.getDatablock().maxWeapons) - return 0; - // don't allow players to throw large packs at pilots (thanks Wizard) - else if(%data.className $= Pack && %data.image.isLarge && %this.isPilot()) - return 0; - return ShapeBase::pickup(%this,%obj,%amount); -} - -function Player::use( %this,%data ) -{ - // If player is in a station then he can't use any items - if(%this.station !$= "") - return false; - - // Convert the word "Backpack" to whatever is in the backpack slot. - if ( %data $= "Backpack" ) - { - if ( %this.inStation ) - return false; - - if ( %this.isPilot() ) - { - messageClient( %this.client, 'MsgCantUsePack', '\c2You can\'t use your pack while piloting.~wfx/misc/misc.error.wav' ); - return( false ); - } - else if ( %this.isWeaponOperator() ) - { - messageClient( %this.client, 'MsgCantUsePack', '\c2You can\'t use your pack while in a weaponry position.~wfx/misc/misc.error.wav' ); - return( false ); - } - - %image = %this.getMountedImage( $BackpackSlot ); - if ( %image ) - %data = %image.item; - } - - // Can't use some items when piloting or your a weapon operator - if ( %this.isPilot() || %this.isWeaponOperator() ) - if ( %data.getName() !$= "RepairKit" ) - return false; - - return ShapeBase::use( %this, %data ); -} - -function Player::maxInventory(%this,%data) -{ - %max = ShapeBase::maxInventory(%this,%data); - if (%this.getInventory(AmmoPack)) - %max += AmmoPack.max[%data.getName()]; - return %max; -} - -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::isWeaponOperator(%this) -{ - %vehicle = %this.getObjectMount(); - if ( %vehicle ) - { - %weaponNode = %vehicle.getDatablock().weaponNode; - if ( %weaponNode > 0 && %vehicle.getMountNodeObject( %weaponNode ) == %this ) - return( true ); - } - - return( false ); -} - -function Player::liquidDamage(%obj, %data, %damageAmount, %damageType) -{ - if(%obj.getState() !$= "Dead") - { - %data.damageObject(%obj, 0, "0 0 0", %damageAmount, %damageType); - %obj.lDamageSchedule = %obj.schedule(50, "liquidDamage", %data, %damageAmount, %damageType); - } - else - %obj.lDamageSchedule = ""; -} - -function Armor::onEnterLiquid(%data, %obj, %coverage, %type) -{ - switch(%type) - { - case 0: - //Water - %obj.shouldBurn = false; - case 1: - //Ocean Water - %obj.shouldBurn = false; - case 2: - //River Water - %obj.shouldBurn = false; - case 3: - //Stagnant Water - %obj.shouldBurn = false; - case 4: - //Lava - %obj.liquidDamage(%data, $DamageLava, $DamageType::Lava); - case 5: - //Hot Lava - %obj.liquidDamage(%data, $DamageHotLava, $DamageType::Lava); - case 6: - //Crusty Lava - %obj.liquidDamage(%data, $DamageCrustyLava, $DamageType::Lava); - case 7: - //Quick Sand - } -} - -function Armor::onLeaveLiquid(%data, %obj, %type) -{ - switch(%type) - { - case 0: - //Water - %obj.shouldBurn = true; - case 1: - //Ocean Water - %obj.shouldBurn = true; - case 2: - //River Water - %obj.shouldBurn = true; - case 3: - //Stagnant Water - %obj.shouldBurn = true; - case 4: - //Lava - case 5: - //Hot Lava - case 6: - //Crusty Lava - case 7: - //Quick Sand - } - - if(%obj.lDamageSchedule !$= "") - { - cancel(%obj.lDamageSchedule); - %obj.lDamageSchedule = ""; - } -} - -function Armor::onTrigger(%data, %player, %triggerNum, %val) -{ - if (%triggerNum == 4) - { - // Throw grenade - if (%val == 1) - { - %player.grenTimer = 1; - } - else - { - if (%player.grenTimer == 0) - { - // Bad throw for some reason - } - else - { - %player.use(Grenade); - %player.grenTimer = 0; - } - } - } - else if (%triggerNum == 5) - { - // Throw mine - if (%val == 1) - { - %player.mineTimer = 1; - } - else - { - if (%player.mineTimer == 0) - { - // Bad throw for some reason - } - else - { - %player.use(Mine); - %player.mineTimer = 0; - } - } - } - else if (%triggerNum == 3) - { - // val = 1 when jet key (LMB) first pressed down - // val = 0 when jet key released - // MES - do we need this at all any more? - if(%val == 1) - %player.isJetting = true; - else - %player.isJetting = false; - } -} - -function Player::setMoveState(%obj, %move) -{ - %obj.disableMove(%move); -} - -function Armor::onLeaveMissionArea(%data, %obj) -{ - Game.leaveMissionArea(%data, %obj); -} - -function Armor::onEnterMissionArea(%data, %obj) -{ - Game.enterMissionArea(%data, %obj); -} - -function Armor::animationDone(%data, %obj) -{ - if(%obj.animResetWeapon !$= "") - { - if(%obj.getMountedImage($WeaponSlot) == 0) - if(%obj.inv[%obj.lastWeapon]) - %obj.use(%obj.lastWeapon); - %obj.animSetWeapon = ""; - } -} - -function playDeathAnimation(%player, %damageLocation, %type) -{ - %vertPos = firstWord(%damageLocation); - %quadrant = getWord(%damageLocation, 1); - - //echo("vert Pos: " @ %vertPos); - //echo("quad: " @ %quadrant); - - if( %type == $DamageType::Explosion || %type == $DamageType::Mortar || %type == $DamageType::Grenade) - { - if(%quadrant $= "front_left" || %quadrant $= "front_right") - %curDie = $PlayerDeathAnim::ExplosionBlowBack; - else - %curDie = $PlayerDeathAnim::TorsoBackFallForward; - } - else if(%vertPos $= "head") - { - if(%quadrant $= "front_left" || %quadrant $= "front_right" ) - %curDie = $PlayerDeathAnim::HeadFrontDirect; - else - %curDie = $PlayerDeathAnim::HeadBackFallForward; - } - else if(%vertPos $= "torso") - { - if(%quadrant $= "front_left" ) - %curDie = $PlayerDeathAnim::TorsoLeftSpinDeath; - else if(%quadrant $= "front_right") - %curDie = $PlayerDeathAnim::TorsoRightSpinDeath; - else if(%quadrant $= "back_left" ) - %curDie = $PlayerDeathAnim::TorsoBackFallForward; - else if(%quadrant $= "back_right") - %curDie = $PlayerDeathAnim::TorsoBackFallForward; - } - else if (%vertPos $= "legs") - { - if(%quadrant $= "front_left" || %quadrant $= "back_left") - %curDie = $PlayerDeathAnim::LegsLeftGimp; - if(%quadrant $= "front_right" || %quadrant $= "back_right") - %curDie = $PlayerDeathAnim::LegsRightGimp; - } - - if(%curDie $= "" || %curDie < 1 || %curDie > 11) - %curDie = 1; - - %player.setActionThread("Death" @ %curDie); -} - -function Armor::onDamage(%data, %obj) -{ - if(%obj.station !$= "" && %obj.getDamageLevel() == 0) - %obj.station.getDataBlock().endRepairing(%obj.station); -} +$InvincibleTime = 6; +// Load dts shapes and merge animations +exec("scripts/light_male.cs"); +exec("scripts/medium_male.cs"); +exec("scripts/heavy_male.cs"); +exec("scripts/light_female.cs"); +exec("scripts/medium_female.cs"); +exec("scripts/bioderm_light.cs"); +exec("scripts/bioderm_medium.cs"); +exec("scripts/bioderm_heavy.cs"); + +$CorpseTimeoutValue = 22 * 1000; + +//Damage Rate for entering Liquid +$DamageLava = 0.0325; +$DamageHotLava = 0.0325; +$DamageCrustyLava = 0.0325; + +$PlayerDeathAnim::TorsoFrontFallForward = 1; +$PlayerDeathAnim::TorsoFrontFallBack = 2; +$PlayerDeathAnim::TorsoBackFallForward = 3; +$PlayerDeathAnim::TorsoLeftSpinDeath = 4; +$PlayerDeathAnim::TorsoRightSpinDeath = 5; +$PlayerDeathAnim::LegsLeftGimp = 6; +$PlayerDeathAnim::LegsRightGimp = 7; +$PlayerDeathAnim::TorsoBackFallForward = 8; +$PlayerDeathAnim::HeadFrontDirect = 9; +$PlayerDeathAnim::HeadBackFallForward = 10; +$PlayerDeathAnim::ExplosionBlowBack = 11; + +datablock SensorData(PlayerSensor) +{ + detects = true; + detectsUsingLOS = true; + detectsPassiveJammed = true; + detectRadius = 2000; + detectionPings = false; + detectsFOVOnly = true; + detectFOVPercent = 1.3; + useObjectFOV = true; +}; + +//---------------------------------------------------------------------------- + +datablock EffectProfile(ArmorJetEffect) +{ + effectname = "armor/thrust"; + minDistance = 5.0; + maxDistance = 10.0; +}; + +datablock EffectProfile(ImpactSoftEffect) +{ + effectname = "armor/light_land_soft"; + minDistance = 5.0; + maxDistance = 10.0; +}; + +datablock EffectProfile(ImpactHardEffect) +{ + effectname = "armor/light_land_hard"; + minDistance = 5.0; + maxDistance = 10.0; +}; + +datablock EffectProfile(ImpactMetalEffect) +{ + effectname = "armor/light_land_metal"; + minDistance = 5.0; + maxDistance = 10.0; +}; + +datablock EffectProfile(ImpactSnowEffect) +{ + effectname = "armor/light_land_snow"; + minDistance = 5.0; + maxDistance = 10.0; +}; + +datablock EffectProfile(CorpseLootingEffect) +{ + effectname = "weapons/generic_switch"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock EffectProfile(MountVehicleEffect) +{ + effectname = "vehicles/mount_dis"; + minDistance = 5; + maxDistance = 20; +}; + +datablock EffectProfile(UnmountVehicleEffect) +{ + effectname = "weapons/generic_switch"; + minDistance = 5; + maxDistance = 20; +}; + +datablock EffectProfile(GenericPainEffect) +{ + effectname = "misc/generic_pain"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock EffectProfile(GenericDeathEffect) +{ + effectname = "misc/generic_death"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock EffectProfile(ImpactHeavyWaterEasyEffect) +{ + effectname = "armor/general_water_smallsplash"; + minDistance = 5; + maxDistance = 15; +}; + +datablock EffectProfile(ImpactHeavyMediumWaterEffect) +{ + effectname = "armor/general_water_medsplash"; + minDistance = 5; + maxDistance = 15; +}; + +datablock EffectProfile(ImpactHeavyWaterHardEffect) +{ + effectname = "armor/general_water_bigsplash"; + minDistance = 5; + maxDistance = 15; +}; + +//---------------------------------------------------------------------------- +//datablock AudioProfile( DeathCrySound ) +//{ +// fileName = ""; +// description = AudioClose3d; +// preload = true; +//}; +// +//datablock AudioProfile( PainCrySound ) +//{ +// fileName = ""; +// description = AudioClose3d; +// preload = true; +//}; + +datablock AudioProfile(ArmorJetSound) +{ + filename = "fx/armor/thrust.wav"; + description = CloseLooping3d; + preload = true; + effect = ArmorJetEffect; +}; + +datablock AudioProfile(ArmorWetJetSound) +{ + filename = "fx/armor/thrust_uw.wav"; + description = CloseLooping3d; + preload = true; + effect = ArmorJetEffect; +}; + +datablock AudioProfile(MountVehicleSound) +{ + filename = "fx/vehicles/mount_dis.wav"; + description = AudioClose3d; + preload = true; + effect = MountVehicleEffect; +}; + +datablock AudioProfile(UnmountVehicleSound) +{ + filename = "fx/vehicles/mount.wav"; + description = AudioClose3d; + preload = true; + effect = UnmountVehicleEffect; +}; + +datablock AudioProfile(CorpseLootingSound) +{ + fileName = "fx/weapons/generic_switch.wav"; + description = AudioClosest3d; + preload = true; + effect = CorpseLootingEffect; +}; + +datablock AudioProfile(ArmorMoveBubblesSound) +{ + filename = "fx/armor/bubbletrail2.wav"; + description = CloseLooping3d; + preload = true; +}; + +datablock AudioProfile(WaterBreathMaleSound) +{ + filename = "fx/armor/breath_uw.wav"; + description = ClosestLooping3d; + preload = true; +}; + +datablock AudioProfile(WaterBreathFemaleSound) +{ + filename = "fx/armor/breath_fem_uw.wav"; + description = ClosestLooping3d; + preload = true; +}; + +datablock AudioProfile(waterBreathBiodermSound) +{ + filename = "fx/armor/breath_bio_uw.wav"; + description = ClosestLooping3d; + preload = true; +}; + +datablock AudioProfile(SkiAllSoftSound) +{ + filename = "fx/armor/ski_soft.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(SkiAllHardSound) +{ + filename = "fx/armor/ski_soft.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(SkiAllMetalSound) +{ + filename = "fx/armor/ski_soft.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(SkiAllSnowSound) +{ + filename = "fx/armor/ski_soft.wav"; + description = AudioClosest3d; + preload = true; +}; + +//SOUNDS ----- LIGHT ARMOR-------- +datablock AudioProfile(LFootLightSoftSound) +{ + filename = "fx/armor/light_LF_soft.wav"; + description = AudioClosest3d; + preload = true; +}; + +datablock AudioProfile(RFootLightSoftSound) +{ + filename = "fx/armor/light_RF_soft.wav"; + description = AudioClosest3d; + preload = true; +}; + +datablock AudioProfile(LFootLightHardSound) +{ + filename = "fx/armor/light_LF_hard.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(RFootLightHardSound) +{ + filename = "fx/armor/light_RF_hard.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(LFootLightMetalSound) +{ + filename = "fx/armor/light_LF_metal.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(RFootLightMetalSound) +{ + filename = "fx/armor/light_RF_metal.wav"; + description = AudioClose3d; + preload = true; +}; +datablock AudioProfile(LFootLightSnowSound) +{ + filename = "fx/armor/light_LF_snow.wav"; + description = AudioClosest3d; + preload = true; +}; + +datablock AudioProfile(RFootLightSnowSound) +{ + filename = "fx/armor/light_RF_snow.wav"; + description = AudioClosest3d; + preload = true; +}; + +datablock AudioProfile(LFootLightShallowSplashSound) +{ + filename = "fx/armor/light_LF_water.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(RFootLightShallowSplashSound) +{ + filename = "fx/armor/light_RF_water.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(LFootLightWadingSound) +{ + filename = "fx/armor/light_LF_wade.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(RFootLightWadingSound) +{ + filename = "fx/armor/light_RF_wade.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(LFootLightUnderwaterSound) +{ + filename = "fx/armor/light_LF_uw.wav"; + description = AudioClosest3d; + preload = true; +}; + +datablock AudioProfile(RFootLightUnderwaterSound) +{ + filename = "fx/armor/light_RF_uw.wav"; + description = AudioClosest3d; + preload = true; +}; + +datablock AudioProfile(LFootLightBubblesSound) +{ + filename = "fx/armor/light_LF_bubbles.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(RFootLightBubblesSound) +{ + filename = "fx/armor/light_RF_bubbles.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(ImpactLightSoftSound) +{ + filename = "fx/armor/light_land_soft.wav"; + description = AudioClose3d; + preload = true; + effect = ImpactSoftEffect; +}; + +datablock AudioProfile(ImpactLightHardSound) +{ + filename = "fx/armor/light_land_hard.wav"; + description = AudioClose3d; + preload = true; + effect = ImpactHardEffect; +}; + +datablock AudioProfile(ImpactLightMetalSound) +{ + filename = "fx/armor/light_land_metal.wav"; + description = AudioClose3d; + preload = true; + effect = ImpactMetalEffect; +}; + +datablock AudioProfile(ImpactLightSnowSound) +{ + filename = "fx/armor/light_land_snow.wav"; + description = AudioClosest3d; + preload = true; + effect = ImpactSnowEffect; +}; + +datablock AudioProfile(ImpactLightWaterEasySound) +{ + filename = "fx/armor/general_water_smallsplash2.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(ImpactLightWaterMediumSound) +{ + filename = "fx/armor/general_water_medsplash.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(ImpactLightWaterHardSound) +{ + filename = "fx/armor/general_water_bigsplash.wav"; + description = AudioDefault3d; + preload = true; +}; + +datablock AudioProfile(ExitingWaterLightSound) +{ + filename = "fx/armor/general_water_exit2.wav"; + description = AudioClose3d; + preload = true; +}; + +//SOUNDS ----- Medium ARMOR-------- +datablock AudioProfile(LFootMediumSoftSound) +{ + filename = "fx/armor/med_LF_soft.wav"; + description = AudioClosest3d; + preload = true; +}; + +datablock AudioProfile(RFootMediumSoftSound) +{ + filename = "fx/armor/med_RF_soft.wav"; + description = AudioClosest3d; + preload = true; +}; + +datablock AudioProfile(LFootMediumHardSound) +{ + filename = "fx/armor/med_LF_hard.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(RFootMediumHardSound) +{ + filename = "fx/armor/med_RF_hard.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(LFootMediumMetalSound) +{ + filename = "fx/armor/med_LF_metal.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(RFootMediumMetalSound) +{ + filename = "fx/armor/med_RF_metal.wav"; + description = AudioClose3d; + preload = true; +}; +datablock AudioProfile(LFootMediumSnowSound) +{ + filename = "fx/armor/med_LF_snow.wav"; + description = AudioClosest3d; + preload = true; +}; + +datablock AudioProfile(RFootMediumSnowSound) +{ + filename = "fx/armor/med_RF_snow.wav"; + description = AudioClosest3d; + preload = true; +}; + +datablock AudioProfile(LFootMediumShallowSplashSound) +{ + filename = "fx/armor/med_LF_water.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(RFootMediumShallowSplashSound) +{ + filename = "fx/armor/med_RF_water.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(LFootMediumWadingSound) +{ + filename = "fx/armor/med_LF_uw.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(RFootMediumWadingSound) +{ + filename = "fx/armor/med_RF_uw.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(LFootMediumUnderwaterSound) +{ + filename = "fx/armor/med_LF_uw.wav"; + description = AudioClosest3d; + preload = true; +}; + +datablock AudioProfile(RFootMediumUnderwaterSound) +{ + filename = "fx/armor/med_RF_uw.wav"; + description = AudioClosest3d; + preload = true; +}; + +datablock AudioProfile(LFootMediumBubblesSound) +{ + filename = "fx/armor/light_LF_bubbles.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(RFootMediumBubblesSound) +{ + filename = "fx/armor/light_RF_bubbles.wav"; + description = AudioClose3d; + preload = true; +}; +datablock AudioProfile(ImpactMediumSoftSound) +{ + filename = "fx/armor/med_land_soft.wav"; + description = AudioClosest3d; + preload = true; + effect = ImpactSoftEffect; +}; + +datablock AudioProfile(ImpactMediumHardSound) +{ + filename = "fx/armor/med_land_hard.wav"; + description = AudioClose3d; + preload = true; + effect = ImpactHardEffect; +}; + +datablock AudioProfile(ImpactMediumMetalSound) +{ + filename = "fx/armor/med_land_metal.wav"; + description = AudioClose3d; + preload = true; + effect = ImpactMetalEffect; +}; + +datablock AudioProfile(ImpactMediumSnowSound) +{ + filename = "fx/armor/med_land_snow.wav"; + description = AudioClosest3d; + preload = true; + effect = ImpactSnowEffect; +}; + +datablock AudioProfile(ImpactMediumWaterEasySound) +{ + filename = "fx/armor/general_water_smallsplash.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(ImpactMediumWaterMediumSound) +{ + filename = "fx/armor/general_water_medsplash.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(ImpactMediumWaterHardSound) +{ + filename = "fx/armor/general_water_bigsplash.wav"; + description = AudioDefault3d; + preload = true; +}; + +datablock AudioProfile(ExitingWaterMediumSound) +{ + filename = "fx/armor/general_water_exit.wav"; + description = AudioClose3d; + preload = true; +}; + +//SOUNDS ----- HEAVY ARMOR-------- +datablock AudioProfile(LFootHeavySoftSound) +{ + filename = "fx/armor/heavy_LF_soft.wav"; + description = AudioClosest3d; + preload = true; +}; + +datablock AudioProfile(RFootHeavySoftSound) +{ + filename = "fx/armor/heavy_RF_soft.wav"; + description = AudioClosest3d; + preload = true; +}; + +datablock AudioProfile(LFootHeavyHardSound) +{ + filename = "fx/armor/heavy_LF_hard.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(RFootHeavyHardSound) +{ + filename = "fx/armor/heavy_RF_hard.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(LFootHeavyMetalSound) +{ + filename = "fx/armor/heavy_LF_metal.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(RFootHeavyMetalSound) +{ + filename = "fx/armor/heavy_RF_metal.wav"; + description = AudioClose3d; + preload = true; +}; +datablock AudioProfile(LFootHeavySnowSound) +{ + filename = "fx/armor/heavy_LF_snow.wav"; + description = AudioClosest3d; + preload = true; +}; + +datablock AudioProfile(RFootHeavySnowSound) +{ + filename = "fx/armor/heavy_RF_snow.wav"; + description = AudioClosest3d; + preload = true; +}; + +datablock AudioProfile(LFootHeavyShallowSplashSound) +{ + filename = "fx/armor/heavy_LF_water.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(RFootHeavyShallowSplashSound) +{ + filename = "fx/armor/heavy_RF_water.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(LFootHeavyWadingSound) +{ + filename = "fx/armor/heavy_LF_uw.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(RFootHeavyWadingSound) +{ + filename = "fx/armor/heavy_RF_uw.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(LFootHeavyUnderwaterSound) +{ + filename = "fx/armor/heavy_LF_uw.wav"; + description = AudioClosest3d; + preload = true; +}; + +datablock AudioProfile(RFootHeavyUnderwaterSound) +{ + filename = "fx/armor/heavy_RF_uw.wav"; + description = AudioClosest3d; + preload = true; +}; + +datablock AudioProfile(LFootHeavyBubblesSound) +{ + filename = "fx/armor/light_LF_bubbles.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(RFootHeavyBubblesSound) +{ + filename = "fx/armor/light_RF_bubbles.wav"; + description = AudioClose3d; + preload = true; +}; +datablock AudioProfile(ImpactHeavySoftSound) +{ + filename = "fx/armor/heavy_land_soft.wav"; + description = AudioClose3d; + preload = true; + effect = ImpactSoftEffect; +}; + +datablock AudioProfile(ImpactHeavyHardSound) +{ + filename = "fx/armor/heavy_land_hard.wav"; + description = AudioClose3d; + preload = true; + effect = ImpactHardEffect; +}; + +datablock AudioProfile(ImpactHeavyMetalSound) +{ + filename = "fx/armor/heavy_land_metal.wav"; + description = AudioClose3d; + preload = true; + effect = ImpactMetalEffect; +}; + +datablock AudioProfile(ImpactHeavySnowSound) +{ + filename = "fx/armor/heavy_land_snow.wav"; + description = AudioClosest3d; + preload = true; + effect = ImpactSnowEffect; +}; + +datablock AudioProfile(ImpactHeavyWaterEasySound) +{ + filename = "fx/armor/general_water_smallsplash.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(ImpactHeavyWaterMediumSound) +{ + filename = "fx/armor/general_water_medsplash.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(ImpactHeavyWaterHardSound) +{ + filename = "fx/armor/general_water_bigsplash.wav"; + description = AudioDefault3d; + preload = true; +}; + +datablock AudioProfile(ExitingWaterHeavySound) +{ + filename = "fx/armor/general_water_exit2.wav"; + description = AudioClose3d; + 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 = "particleTest"; + colors[0] = "0.7 0.8 1.0 1.0"; + colors[1] = "0.7 0.8 1.0 0.5"; + colors[2] = "0.7 0.8 1.0 0.0"; + sizes[0] = 0.5; + sizes[1] = 0.5; + sizes[2] = 0.8; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; +}; + +datablock ParticleEmitterData(PlayerSplashMistEmitter) +{ + ejectionPeriodMS = 5; + periodVarianceMS = 0; + ejectionVelocity = 3.0; + velocityVariance = 2.0; + ejectionOffset = 0.0; + thetaMin = 85; + thetaMax = 85; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + lifetimeMS = 250; + particles = "PlayerSplashMist"; +}; + + +datablock ParticleData(PlayerBubbleParticle) +{ + dragCoefficient = 0.0; + gravityCoefficient = -0.50; + inheritedVelFactor = 0.0; + constantAcceleration = 0.0; + lifetimeMS = 400; + lifetimeVarianceMS = 100; + useInvAlpha = false; + textureName = "special/bubbles"; + 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; + overrideAdvances = false; + particles = "PlayerBubbleParticle"; +}; + +datablock ParticleData(PlayerFoamParticle) +{ + dragCoefficient = 2.0; + gravityCoefficient = -0.05; + inheritedVelFactor = 0.0; + constantAcceleration = 0.0; + lifetimeMS = 400; + lifetimeVarianceMS = 100; + useInvAlpha = false; + spinRandomMin = -90.0; + spinRandomMax = 500.0; + textureName = "particleTest"; + colors[0] = "0.7 0.8 1.0 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; + overrideAdvances = false; + particles = "PlayerFoamParticle"; +}; + + +datablock ParticleData( PlayerFoamDropletsParticle ) +{ + dragCoefficient = 1; + gravityCoefficient = 0.2; + inheritedVelFactor = 0.2; + constantAcceleration = -0.0; + lifetimeMS = 600; + lifetimeVarianceMS = 0; + textureName = "special/droplet"; + colors[0] = "0.7 0.8 1.0 1.0"; + colors[1] = "0.7 0.8 1.0 0.5"; + colors[2] = "0.7 0.8 1.0 0.0"; + sizes[0] = 0.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; + overrideAdvances = false; + orientParticles = true; + particles = "PlayerFoamDropletsParticle"; +}; + + + +datablock ParticleData( PlayerSplashParticle ) +{ + dragCoefficient = 1; + gravityCoefficient = 0.2; + inheritedVelFactor = 0.2; + constantAcceleration = -0.0; + lifetimeMS = 600; + lifetimeVarianceMS = 0; + textureName = "special/droplet"; + colors[0] = "0.7 0.8 1.0 1.0"; + colors[1] = "0.7 0.8 1.0 0.5"; + colors[2] = "0.7 0.8 1.0 0.0"; + sizes[0] = 0.5; + sizes[1] = 0.5; + sizes[2] = 0.5; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; +}; + +datablock ParticleEmitterData( PlayerSplashEmitter ) +{ + ejectionPeriodMS = 1; + periodVarianceMS = 0; + ejectionVelocity = 3; + velocityVariance = 1.0; + ejectionOffset = 0.0; + thetaMin = 60; + thetaMax = 80; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + orientParticles = true; + lifetimeMS = 100; + particles = "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 = "special/water2"; + + 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; +}; + +//---------------------------------------------------------------------------- +// Jet data +//---------------------------------------------------------------------------- +datablock ParticleData(HumanArmorJetParticle) +{ + dragCoefficient = 0.0; + gravityCoefficient = 0; + inheritedVelFactor = 0.2; + constantAcceleration = 0.0; + lifetimeMS = 100; + lifetimeVarianceMS = 0; + textureName = "particleTest"; + colors[0] = "0.32 0.47 0.47 1.0"; + colors[1] = "0.32 0.47 0.47 0"; + sizes[0] = 0.40; + sizes[1] = 0.15; +}; + +datablock ParticleEmitterData(HumanArmorJetEmitter) +{ + ejectionPeriodMS = 3; + periodVarianceMS = 0; + ejectionVelocity = 3; + velocityVariance = 2.9; + ejectionOffset = 0.0; + thetaMin = 0; + thetaMax = 5; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + particles = "HumanArmorJetParticle"; +}; + +datablock JetEffectData(HumanArmorJetEffect) +{ + texture = "special/jetExhaust02"; + coolColor = "0.0 0.0 1.0 1.0"; + hotColor = "0.2 0.4 0.7 1.0"; + activateTime = 0.2; + deactivateTime = 0.05; + length = 0.75; + width = 0.2; + speed = -15; + stretch = 2.0; + yOffset = 0.2; +}; + +datablock JetEffectData(HumanMediumArmorJetEffect) +{ + texture = "special/jetExhaust02"; + coolColor = "0.0 0.0 1.0 1.0"; + hotColor = "0.2 0.4 0.7 1.0"; + activateTime = 0.2; + deactivateTime = 0.05; + length = 0.75; + width = 0.2; + speed = -15; + stretch = 2.0; + yOffset = 0.4; +}; + +datablock JetEffectData(HumanLightFemaleArmorJetEffect) +{ + texture = "special/jetExhaust02"; + coolColor = "0.0 0.0 1.0 1.0"; + hotColor = "0.2 0.4 0.7 1.0"; + activateTime = 0.2; + deactivateTime = 0.05; + length = 0.75; + width = 0.2; + speed = -15; + stretch = 2.0; + yOffset = 0.2; +}; + +datablock JetEffectData(BiodermArmorJetEffect) +{ + texture = "special/jetExhaust02"; + coolColor = "0.0 0.0 1.0 1.0"; + hotColor = "0.8 0.6 0.2 1.0"; + activateTime = 0.2; + deactivateTime = 0.05; + length = 0.75; + width = 0.2; + speed = -15; + stretch = 2.0; + yOffset = 0.0; +}; + +//---------------------------------------------------------------------------- +// Foot puffs +//---------------------------------------------------------------------------- +datablock ParticleData(LightPuff) +{ + dragCoefficient = 2.0; + gravityCoefficient = -0.01; + inheritedVelFactor = 0.0; + constantAcceleration = 0.0; + lifetimeMS = 500; + lifetimeVarianceMS = 100; + useInvAlpha = true; + spinRandomMin = -35.0; + spinRandomMax = 35.0; + textureName = "particleTest"; + colors[0] = "0.46 0.36 0.26 0.4"; + colors[1] = "0.46 0.46 0.36 0.0"; + sizes[0] = 0.4; + sizes[1] = 1.0; +}; + +datablock ParticleEmitterData(LightPuffEmitter) +{ + ejectionPeriodMS = 35; + periodVarianceMS = 10; + ejectionVelocity = 0.1; + velocityVariance = 0.05; + ejectionOffset = 0.0; + thetaMin = 5; + thetaMax = 20; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = 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; + textureName = "particleTest"; + colors[0] = "0.46 0.36 0.26 0.0"; + colors[1] = "0.46 0.46 0.36 0.4"; + colors[2] = "0.46 0.46 0.36 0.0"; + sizes[0] = 0.2; + sizes[1] = 0.6; + sizes[2] = 1.0; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; +}; + +datablock ParticleEmitterData(LiftoffDustEmitter) +{ + ejectionPeriodMS = 5; + periodVarianceMS = 0; + ejectionVelocity = 2.0; + velocityVariance = 0.0; + ejectionOffset = 0.0; + thetaMin = 90; + thetaMax = 90; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + useEmitterColors = true; + particles = "LiftoffDust"; +}; + +//---------------------------------------------------------------------------- + +datablock ParticleData(BiodermArmorJetParticle) : HumanArmorJetParticle +{ + colors[0] = "0.50 0.48 0.36 1.0"; + colors[1] = "0.50 0.48 0.36 0"; +}; + +datablock ParticleEmitterData(BiodermArmorJetEmitter) : HumanArmorJetEmitter +{ + particles = "BiodermArmorJetParticle"; +}; + + +//---------------------------------------------------------------------------- +datablock DecalData(LightMaleFootprint) +{ + sizeX = 0.125; + sizeY = 0.25; + textureName = "special/footprints/L_male"; +}; + +datablock DebrisData( PlayerDebris ) +{ + explodeOnMaxBounce = false; + + elasticity = 0.35; + friction = 0.5; + + lifetime = 4.0; + lifetimeVariance = 0.0; + + minSpinSpeed = 60; + maxSpinSpeed = 600; + + numBounces = 5; + bounceVariance = 0; + + staticOnMaxBounce = true; + gravModifier = 1.0; + + useRadiusMass = true; + baseRadius = 1; + + velocity = 18.0; + velocityVariance = 12.0; +}; + +datablock DebrisData( HumanRedPlayerDebris ) //Omfg, blood. +{ + explodeOnMaxBounce = false; + + elasticity = 0.35; + friction = 0.5; + + lifetime = 4.0; + lifetimeVariance = 0.0; + + emitters[0] = HumanRedBloodEmitter; + emitters[1] = HumanRedPlayerSplashMistEmitter; + emitters[2] = HumanRedDropletsEmitter; + + minSpinSpeed = 60; + maxSpinSpeed = 900; + + numBounces = 15; + bounceVariance = 0; + + staticOnMaxBounce = true; + gravModifier = 1.0; + + useRadiusMass = true; + baseRadius = 1; + + velocity = 18.0; + velocityVariance = 12.0; + +}; + +datablock DebrisData( BiodermPlayerDebris ) //Green Blood! +{ + explodeOnMaxBounce = false; + + elasticity = 0.35; + friction = 0.5; + + lifetime = 4.0; + lifetimeVariance = 0.0; + + emitters[0] = BiodermBloodEmitter; + emitters[1] = BiodermPlayerSplashMistEmitter; + emitters[2] = PurpleBiodermDropletsEmitter; + + minSpinSpeed = 60; + maxSpinSpeed = 900; + + numBounces = 15; + bounceVariance = 0; + + staticOnMaxBounce = true; + gravModifier = 1.0; + + useRadiusMass = true; + baseRadius = 1; + + velocity = 18.0; + velocityVariance = 12.0; + +}; + +// z0dd - ZOD, 4/21/02. Altered most of these properties +datablock PlayerData(LightMaleHumanArmor) : LightPlayerDamageProfile +{ + emap = true; + + className = Armor; + shapeFile = "light_male.dts"; + cameraMaxDist = 3; + computeCRC = true; + + canObserve = true; + cmdCategory = "Clients"; + cmdIcon = CMDPlayerIcon; + cmdMiniIconName = "commander/MiniIcons/com_player_grey"; + + hudImageNameFriendly[0] = "gui/hud_playertriangle"; + hudImageNameEnemy[0] = "gui/hud_playertriangle_enemy"; + hudRenderModulated[0] = true; + + hudImageNameFriendly[1] = "commander/MiniIcons/com_flag_grey"; + hudImageNameEnemy[1] = "commander/MiniIcons/com_flag_grey"; + hudRenderModulated[1] = true; + hudRenderAlways[1] = true; + hudRenderCenter[1] = true; + hudRenderDistance[1] = true; + + hudImageNameFriendly[2] = "commander/MiniIcons/com_flag_grey"; + hudImageNameEnemy[2] = "commander/MiniIcons/com_flag_grey"; + hudRenderModulated[2] = true; + hudRenderAlways[2] = true; + hudRenderCenter[2] = true; + hudRenderDistance[2] = true; + + cameraDefaultFov = 90.0; + cameraMinFov = 5.0; + cameraMaxFov = 120.0; + + debrisShapeName = "debris_player.dts"; + debris = HumanRedPlayerDebris; + + aiAvoidThis = true; + + minLookAngle = -1.5; + maxLookAngle = 1.5; + maxFreelookAngle = 3.0; + + mass = 90; + drag = 0.134; + maxdrag = 0.3; + density = 19; + maxDamage = 0.66; + maxEnergy = 60; + repairRate = 0.0033; + energyPerDamagePoint = 75.0; // shield energy required to block one point of damage + + rechargeRate = 0.256; + jetForce = 37.28 * 90; + underwaterJetForce = 28.00 * 90 * 1.5; + underwaterVertJetFactor = 1.5; + jetEnergyDrain = 0.90; + underwaterJetEnergyDrain = 0.7; + minJetEnergy = 3; + maxJetHorizontalPercentage = 0.6; + + runForce = 55.20 * 90; + runEnergyDrain = 0; + minRunEnergy = 0; + maxForwardSpeed = 15; + maxBackwardSpeed = 13; + maxSideSpeed = 13; + + maxUnderwaterForwardSpeed = 13; + maxUnderwaterBackwardSpeed = 11; + maxUnderwaterSideSpeed = 11; + + jumpForce = 8.34 * 90; + jumpEnergyDrain = 0; + minJumpEnergy = 0; + jumpDelay = 0; + + recoverDelay = 8; + recoverRunForceScale = 1.4; + + minImpactSpeed = 45; + speedDamageScale = 0.0022; + + jetSound = ArmorJetSound; + wetJetSound = ArmorJetSound; + jetEmitter = HumanArmorJetEmitter; + jetEffect = HumanArmorJetEffect; + + boundingBox = "1.2 1.2 2.3"; + pickupRadius = 0.75; + + // damage location details + boxNormalHeadPercentage = 0.83; + boxNormalTorsoPercentage = 0.49; + boxHeadLeftPercentage = 0; + boxHeadRightPercentage = 1; + boxHeadBackPercentage = 0; + boxHeadFrontPercentage = 1; + + //Foot Prints + decalData = LightMaleFootprint; + decalOffset = 0.25; + + footPuffEmitter = LightPuffEmitter; + footPuffNumParts = 15; + footPuffRadius = 0.25; + + dustEmitter = LiftoffDustEmitter; + + splash = PlayerSplash; + splashVelocity = 4.0; + splashAngle = 67.0; + splashFreqMod = 300.0; + splashVelEpsilon = 0.60; + bubbleEmitTime = 0.4; + splashEmitter[0] = PlayerFoamDropletsEmitter; + splashEmitter[1] = PlayerFoamEmitter; + splashEmitter[2] = PlayerBubbleEmitter; + mediumSplashSoundVelocity = 10.0; + hardSplashSoundVelocity = 20.0; + exitSplashSoundVelocity = 5.0; + + // Controls over slope of runnable/jumpable surfaces + runSurfaceAngle = 70; + jumpSurfaceAngle = 80; + + minJumpSpeed = 20; + maxJumpSpeed = 30; + + noFrictionOnSki = true; + horizMaxSpeed = 500; + horizResistSpeed = 48.74; + horizResistFactor = 0; + maxJetForwardSpeed = 30; + + upMaxSpeed = 52; + upResistSpeed = 20.89; + upResistFactor = 0.35; + + // heat inc'ers and dec'ers + heatDecayPerSec = 1.0 / 4.0; // takes 4 seconds to clear heat sig. + heatIncreasePerSec = 1.0 / 3.0; // takes 3.0 seconds of constant jet to get full heat sig. + + footstepSplashHeight = 0.35; + //Footstep Sounds + LFootSoftSound = LFootLightSoftSound; + RFootSoftSound = RFootLightSoftSound; + LFootHardSound = LFootLightHardSound; + RFootHardSound = RFootLightHardSound; + LFootMetalSound = LFootLightMetalSound; + RFootMetalSound = RFootLightMetalSound; + LFootSnowSound = LFootLightSnowSound; + RFootSnowSound = RFootLightSnowSound; + LFootShallowSound = LFootLightShallowSplashSound; + RFootShallowSound = RFootLightShallowSplashSound; + LFootWadingSound = LFootLightWadingSound; + RFootWadingSound = RFootLightWadingSound; + LFootUnderwaterSound = LFootLightUnderwaterSound; + RFootUnderwaterSound = RFootLightUnderwaterSound; + LFootBubblesSound = LFootLightBubblesSound; + RFootBubblesSound = RFootLightBubblesSound; + movingBubblesSound = ArmorMoveBubblesSound; + waterBreathSound = WaterBreathMaleSound; + + impactSoftSound = ImpactLightSoftSound; + impactHardSound = ImpactLightHardSound; + impactMetalSound = ImpactLightMetalSound; + impactSnowSound = ImpactLightSnowSound; + + skiSoftSound = SkiAllSoftSound; + skiHardSound = SkiAllHardSound; + skiMetalSound = SkiAllMetalSound; + skiSnowSound = SkiAllSnowSound; + + impactWaterEasy = ImpactLightWaterEasySound; + impactWaterMedium = ImpactLightWaterMediumSound; + impactWaterHard = ImpactLightWaterHardSound; + + groundImpactMinSpeed = 14.0; + groundImpactShakeFreq = "3.0 3.0 3.0"; + groundImpactShakeAmp = "1.0 1.0 1.0"; + groundImpactShakeDuration = 0.6; + groundImpactShakeFalloff = 10.0; + + exitingWater = ExitingWaterLightSound; + + maxWeapons = 3; // Max number of different weapons the player can have + maxGrenades = 1; // Max number of different grenades the player can have + maxMines = 1; // Max number of different mines the player can have + + // Inventory restrictions + max[RepairKit] = 1; + max[Mine] = 3; + max[Grenade] = 5; + max[Blaster] = 1; + max[Plasma] = 1; + max[PlasmaAmmo] = 20; + max[Disc] = 1; + max[DiscAmmo] = 15; + max[SniperRifle] = 1; + max[GrenadeLauncher] = 1; + max[GrenadeLauncherAmmo]= 10; + max[Mortar] = 0; + max[MortarAmmo] = 0; + max[MissileLauncher] = 0; + max[MissileLauncherAmmo]= 0; + max[Chaingun] = 1; + max[ChaingunAmmo] = 100; + max[RepairGun] = 1; + max[CloakingPack] = 1; + max[SensorJammerPack] = 1; + max[EnergyPack] = 1; + max[RepairPack] = 1; + max[ShieldPack] = 1; + max[AmmoPack] = 1; + max[SatchelCharge] = 1; + max[MortarBarrelPack] = 0; + max[MissileBarrelPack] = 0; + max[AABarrelPack] = 0; + max[PlasmaBarrelPack] = 0; + max[ELFBarrelPack] = 0; + max[InventoryDeployable]= 0; + max[MotionSensorDeployable] = 1; + max[PulseSensorDeployable] = 1; + max[TurretOutdoorDeployable] = 0; + max[TurretIndoorDeployable] = 0; + max[FlashGrenade] = 5; + max[ConcussionGrenade] = 5; + max[FlareGrenade] = 5; + max[TargetingLaser] = 1; + max[ELFGun] = 1; + max[R700] = 1; + max[ShockLance] = 1; + max[CameraGrenade] = 2; + max[Beacon] = 3; + max[Lootbag] = 1; + max[MiningTool] = 1; + max[C4Charge] = 1; + max[Flamer] = 0; //Just in case + + observeParameters = "0.5 4.5 4.5"; + shieldEffectScale = "0.7 0.7 1.0"; +}; + +//---------------------------------------------------------------------------- + +datablock DecalData(MediumMaleFootprint) +{ + sizeX = 0.125; + sizeY = 0.25; + textureName = "special/footprints/M_male"; +}; + +// z0dd - ZOD, 4/21/02. Altered most of these properties +datablock PlayerData(MediumMaleHumanArmor) : MediumPlayerDamageProfile +{ + emap = true; + + className = Armor; + shapeFile = "medium_male.dts"; + cameraMaxDist = 3; + computeCRC = true; + + canObserve = true; + cmdCategory = "Clients"; + cmdIcon = CMDPlayerIcon; + cmdMiniIconName = "commander/MiniIcons/com_player_grey"; + + hudImageNameFriendly[0] = "gui/hud_playertriangle"; + hudImageNameEnemy[0] = "gui/hud_playertriangle_enemy"; + hudRenderModulated[0] = true; + + hudImageNameFriendly[1] = "commander/MiniIcons/com_flag_grey"; + hudImageNameEnemy[1] = "commander/MiniIcons/com_flag_grey"; + hudRenderModulated[1] = true; + hudRenderAlways[1] = true; + hudRenderCenter[1] = true; + hudRenderDistance[1] = true; + + hudImageNameFriendly[2] = "commander/MiniIcons/com_flag_grey"; + hudImageNameEnemy[2] = "commander/MiniIcons/com_flag_grey"; + hudRenderModulated[2] = true; + hudRenderAlways[2] = true; + hudRenderCenter[2] = true; + hudRenderDistance[2] = true; + + cameraDefaultFov = 90.0; + cameraMinFov = 5.0; + cameraMaxFov = 120.0; + + debrisShapeName = "debris_player.dts"; + debris = HumanRedPlayerDebris; + + aiAvoidThis = true; + + minLookAngle = -1.5; + maxLookAngle = 1.5; + maxFreelookAngle = 3.0; + + mass = 130; + drag = 0.2; + maxdrag = 0.4; + density = 20; + maxDamage = 1.1; + maxEnergy = 80; + repairRate = 0.0033; + energyPerDamagePoint = 75.0; // shield energy required to block one point of damage + + rechargeRate = 0.256; + jetForce = 33.79 * 130; + underwaterJetForce = 27.00 * 130 * 1.5; + underwaterVertJetFactor = 1.5; + jetEnergyDrain = 1.1; + underwaterJetEnergyDrain = 0.65; + minJetEnergy = 3; + maxJetHorizontalPercentage = 0.5; + + runForce = 46 * 130; + runEnergyDrain = 0; + minRunEnergy = 0; + maxForwardSpeed = 12; + maxBackwardSpeed = 10; + maxSideSpeed = 10; + + maxUnderwaterForwardSpeed = 10; + maxUnderwaterBackwardSpeed = 8; + maxUnderwaterSideSpeed = 8; + + recoverDelay = 8; + recoverRunForceScale = 0.8; + + // heat inc'ers and dec'ers + heatDecayPerSec = 1.0 / 4.0; // takes 4 seconds to clear heat sig. + heatIncreasePerSec = 1.0 / 3.0; // takes 3.0 seconds of constant jet to get full heat sig. + + jumpForce = 8.5 * 130; + jumpEnergyDrain = 0; + minJumpEnergy = 0; + jumpDelay = 0; + + // Controls over slope of runnable/jumpable surfaces + runSurfaceAngle = 70; + jumpSurfaceAngle = 80; + + minJumpSpeed = 15; + maxJumpSpeed = 25; + + noFrictionOnSki = true; + horizMaxSpeed = 500; + horizResistSpeed = 41.78; + horizResistFactor = 0; + maxJetForwardSpeed = 25; + + upMaxSpeed = 52; + upResistSpeed = 20.89; + upResistFactor = 0.23; + + minImpactSpeed = 45; + speedDamageScale = 0.0023; + + jetSound = ArmorJetSound; + wetJetSound = ArmorWetJetSound; + + jetEmitter = HumanArmorJetEmitter; + jetEffect = HumanMediumArmorJetEffect; + + boundingBox = "1.45 1.45 2.4"; + pickupRadius = 0.75; + + // damage location details + boxNormalHeadPercentage = 0.83; + boxNormalTorsoPercentage = 0.49; + boxHeadLeftPercentage = 0; + boxHeadRightPercentage = 1; + boxHeadBackPercentage = 0; + boxHeadFrontPercentage = 1; + + //Foot Prints + decalData = MediumMaleFootprint; + decalOffset = 0.35; + + footPuffEmitter = LightPuffEmitter; + footPuffNumParts = 15; + footPuffRadius = 0.25; + + dustEmitter = LiftoffDustEmitter; + + splash = PlayerSplash; + splashVelocity = 4.0; + splashAngle = 67.0; + splashFreqMod = 300.0; + splashVelEpsilon = 0.60; + bubbleEmitTime = 0.4; + splashEmitter[0] = PlayerFoamDropletsEmitter; + splashEmitter[1] = PlayerFoamEmitter; + splashEmitter[2] = PlayerBubbleEmitter; + mediumSplashSoundVelocity = 10.0; + hardSplashSoundVelocity = 20.0; + exitSplashSoundVelocity = 5.0; + + footstepSplashHeight = 0.35; + //Footstep Sounds + LFootSoftSound = LFootMediumSoftSound; + RFootSoftSound = RFootMediumSoftSound; + LFootHardSound = LFootMediumHardSound; + RFootHardSound = RFootMediumHardSound; + LFootMetalSound = LFootMediumMetalSound; + RFootMetalSound = RFootMediumMetalSound; + LFootSnowSound = LFootMediumSnowSound; + RFootSnowSound = RFootMediumSnowSound; + LFootShallowSound = LFootMediumShallowSplashSound; + RFootShallowSound = RFootMediumShallowSplashSound; + LFootWadingSound = LFootMediumWadingSound; + RFootWadingSound = RFootMediumWadingSound; + LFootUnderwaterSound = LFootMediumUnderwaterSound; + RFootUnderwaterSound = RFootMediumUnderwaterSound; + LFootBubblesSound = LFootMediumBubblesSound; + RFootBubblesSound = RFootMediumBubblesSound; + movingBubblesSound = ArmorMoveBubblesSound; + waterBreathSound = WaterBreathMaleSound; + + impactSoftSound = ImpactMediumSoftSound; + impactHardSound = ImpactMediumHardSound; + impactMetalSound = ImpactMediumMetalSound; + impactSnowSound = ImpactMediumSnowSound; + + skiSoftSound = SkiAllSoftSound; + skiHardSound = SkiAllHardSound; + skiMetalSound = SkiAllMetalSound; + skiSnowSound = SkiAllSnowSound; + + impactWaterEasy = ImpactMediumWaterEasySound; + impactWaterMedium = ImpactMediumWaterMediumSound; + impactWaterHard = ImpactMediumWaterHardSound; + + groundImpactMinSpeed = 13.0; + groundImpactShakeFreq = "3.5 3.5 3.5"; + groundImpactShakeAmp = "1.0 1.0 1.0"; + groundImpactShakeDuration = 0.7; + groundImpactShakeFalloff = 10.0; + + exitingWater = ExitingWaterMediumSound; + + maxWeapons = 4; // Max number of different weapons the player can have + maxGrenades = 1; // Max number of different grenades the player can have + maxMines = 1; // Max number of different mines the player can have + + // Inventory restrictions + max[RepairKit] = 1; + max[Mine] = 3; + max[Grenade] = 6; + max[Blaster] = 1; + max[Plasma] = 1; + max[PlasmaAmmo] = 40; + max[Disc] = 1; + max[DiscAmmo] = 15; + max[SniperRifle] = 0; + max[GrenadeLauncher] = 1; + max[GrenadeLauncherAmmo]= 15; // z0dd - ZOD, 9/28/02. Was 12 + max[Mortar] = 0; + max[MortarAmmo] = 0; + max[MissileLauncher] = 1; + max[MissileLauncherAmmo]= 4; + max[Chaingun] = 1; + max[ChaingunAmmo] = 150; + max[RepairGun] = 1; + max[CloakingPack] = 0; + max[SensorJammerPack] = 1; + max[EnergyPack] = 1; + max[RepairPack] = 1; + max[ShieldPack] = 1; + max[AmmoPack] = 1; + max[SatchelCharge] = 1; + max[MortarBarrelPack] = 1; + max[MissileBarrelPack] = 1; + max[AABarrelPack] = 1; + max[PlasmaBarrelPack] = 1; + max[ELFBarrelPack] = 1; + max[InventoryDeployable]= 1; + max[MotionSensorDeployable] = 1; + max[PulseSensorDeployable] = 1; + max[TurretOutdoorDeployable] = 1; + max[TurretIndoorDeployable] = 1; + max[FlashGrenade] = 6; + max[ConcussionGrenade] = 6; + max[FlareGrenade] = 6; + max[TargetingLaser] = 1; + max[ELFGun] = 1; + max[ShockLance] = 1; + max[CameraGrenade] = 3; + max[Beacon] = 3; + max[Lootbag] = 1; + max[MiningTool] = 1; + max[C4Charge] = 1; + max[Flamer] = 0; + + observeParameters = "0.5 4.5 4.5"; + + shieldEffectScale = "0.7 0.7 1.0"; +}; + +//---------------------------------------------------------------------------- +datablock DecalData(HeavyMaleFootprint) +{ + sizeX = 0.25; + sizeY = 0.5; + textureName = "special/footprints/H_male"; +}; + +// z0dd - ZOD, 4/21/02. Altered most of these properties +datablock PlayerData(HeavyMaleHumanArmor) : HeavyPlayerDamageProfile +{ + emap = true; + + className = Armor; + shapeFile = "heavy_male.dts"; + cameraMaxDist = 3; + computeCRC = true; + + canObserve = true; + cmdCategory = "Clients"; + cmdIcon = CMDPlayerIcon; + cmdMiniIconName = "commander/MiniIcons/com_player_grey"; + + hudImageNameFriendly[0] = "gui/hud_playertriangle"; + hudImageNameEnemy[0] = "gui/hud_playertriangle_enemy"; + hudRenderModulated[0] = true; + + hudImageNameFriendly[1] = "commander/MiniIcons/com_flag_grey"; + hudImageNameEnemy[1] = "commander/MiniIcons/com_flag_grey"; + hudRenderModulated[1] = true; + hudRenderAlways[1] = true; + hudRenderCenter[1] = true; + hudRenderDistance[1] = true; + + hudImageNameFriendly[2] = "commander/MiniIcons/com_flag_grey"; + hudImageNameEnemy[2] = "commander/MiniIcons/com_flag_grey"; + hudRenderModulated[2] = true; + hudRenderAlways[2] = true; + hudRenderCenter[2] = true; + hudRenderDistance[2] = true; + + cameraDefaultFov = 90.0; + cameraMinFov = 5.0; + cameraMaxFov = 120.0; + + debrisShapeName = "debris_player.dts"; + debris = HumanRedPlayerDebris; + + aiAvoidThis = true; + + minLookAngle = -1.5; + maxLookAngle = 1.5; + maxFreelookAngle = 3.0; + + mass = 180; + drag = 0.23; + maxdrag = 0.5; + density = 27; + maxDamage = 1.32; + maxEnergy = 110; + repairRate = 0.0033; + energyPerDamagePoint = 54.0; // shield energy required to block one point of damage + + rechargeRate = 0.256; + jetForce = 29.58 * 180; + underwaterJetForce = 25.25 * 180 * 1.5; + underwaterVertJetFactor = 1.5; + jetEnergyDrain = 1.25; + underwaterJetEnergyDrain = 0.65; + minJetEnergy = 3; + maxJetHorizontalPercentage = 0.3; + + runForce = 40.25 * 180; + runEnergyDrain = 0; + minRunEnergy = 0; + maxForwardSpeed = 7.5; + maxBackwardSpeed = 5; + maxSideSpeed = 5; + + maxUnderwaterForwardSpeed = 5; + maxUnderwaterBackwardSpeed = 3; + maxUnderwaterSideSpeed = 3; + + recoverDelay = 8; + recoverRunForceScale = 0.2; + + jumpForce = 8.35 * 180; + jumpEnergyDrain = 0; + minJumpEnergy = 0; + jumpDelay = 0; + + // heat inc'ers and dec'ers + heatDecayPerSec = 1.0 / 4.0; // takes 4 seconds to clear heat sig. + heatIncreasePerSec = 1.0 / 3.0; // takes 3.0 seconds of constant jet to get full heat sig. + + // Controls over slope of runnable/jumpable surfaces + runSurfaceAngle = 70; + jumpSurfaceAngle = 75; + + minJumpSpeed = 20; + maxJumpSpeed = 30; + + noFrictionOnSki = true; + horizMaxSpeed = 500; + horizResistSpeed = 34.81; + horizResistFactor = 0; + maxJetForwardSpeed = 20; + + upMaxSpeed = 52; + upResistSpeed = 20.89; + upResistFactor = 0.18; + + minImpactSpeed = 45; + speedDamageScale = 0.0030; + + jetSound = ArmorJetSound; + wetJetSound = ArmorJetSound; + jetEmitter = HumanArmorJetEmitter; + + boundingBox = "1.63 1.63 2.6"; + pickupRadius = 0.75; + + // damage location details + boxNormalHeadPercentage = 0.83; + boxNormalTorsoPercentage = 0.49; + boxHeadLeftPercentage = 0; + boxHeadRightPercentage = 1; + boxHeadBackPercentage = 0; + boxHeadFrontPercentage = 1; + + //Foot Prints + decalData = HeavyMaleFootprint; + decalOffset = 0.4; + + footPuffEmitter = LightPuffEmitter; + footPuffNumParts = 15; + footPuffRadius = 0.25; + + dustEmitter = LiftoffDustEmitter; + + splash = PlayerSplash; + splashVelocity = 4.0; + splashAngle = 67.0; + splashFreqMod = 300.0; + splashVelEpsilon = 0.60; + bubbleEmitTime = 0.4; + splashEmitter[0] = PlayerFoamDropletsEmitter; + splashEmitter[1] = PlayerFoamEmitter; + splashEmitter[2] = PlayerBubbleEmitter; + mediumSplashSoundVelocity = 10.0; + hardSplashSoundVelocity = 20.0; + exitSplashSoundVelocity = 5.0; + + footstepSplashHeight = 0.35; + //Footstep Sounds + LFootSoftSound = LFootHeavySoftSound; + RFootSoftSound = RFootHeavySoftSound; + LFootHardSound = LFootHeavyHardSound; + RFootHardSound = RFootHeavyHardSound; + LFootMetalSound = LFootHeavyMetalSound; + RFootMetalSound = RFootHeavyMetalSound; + LFootSnowSound = LFootHeavySnowSound; + RFootSnowSound = RFootHeavySnowSound; + LFootShallowSound = LFootHeavyShallowSplashSound; + RFootShallowSound = RFootHeavyShallowSplashSound; + LFootWadingSound = LFootHeavyWadingSound; + RFootWadingSound = RFootHeavyWadingSound; + LFootUnderwaterSound = LFootHeavyUnderwaterSound; + RFootUnderwaterSound = RFootHeavyUnderwaterSound; + LFootBubblesSound = LFootHeavyBubblesSound; + RFootBubblesSound = RFootHeavyBubblesSound; + movingBubblesSound = ArmorMoveBubblesSound; + waterBreathSound = WaterBreathMaleSound; + + impactSoftSound = ImpactHeavySoftSound; + impactHardSound = ImpactHeavyHardSound; + impactMetalSound = ImpactHeavyMetalSound; + impactSnowSound = ImpactHeavySnowSound; + + skiSoftSound = SkiAllSoftSound; + skiHardSound = SkiAllHardSound; + skiMetalSound = SkiAllMetalSound; + skiSnowSound = SkiAllSnowSound; + + impactWaterEasy = ImpactHeavyWaterEasySound; + impactWaterMedium = ImpactHeavyWaterMediumSound; + impactWaterHard = ImpactHeavyWaterHardSound; + + groundImpactMinSpeed = 11.0; + groundImpactShakeFreq = "4.0 4.0 4.0"; + groundImpactShakeAmp = "1.0 1.0 1.0"; + groundImpactShakeDuration = 0.8; + groundImpactShakeFalloff = 10.0; + + exitingWater = ExitingWaterHeavySound; + + maxWeapons = 5; // Max number of different weapons the player can have + maxGrenades = 1; // Max number of different grenades the player can have + maxMines = 1; // Max number of different mines the player can have + + // Inventory restrictions + max[RepairKit] = 1; + max[Mine] = 3; + max[Grenade] = 8; + max[Blaster] = 1; + max[Plasma] = 1; + max[PlasmaAmmo] = 50; + max[Disc] = 1; + max[DiscAmmo] = 15; + max[SniperRifle] = 0; + max[GrenadeLauncher] = 1; + max[GrenadeLauncherAmmo]= 15; + max[Mortar] = 1; + max[MortarAmmo] = 10; + max[MissileLauncher] = 1; + max[MissileLauncherAmmo]= 8; + max[Chaingun] = 1; + max[ChaingunAmmo] = 200; + max[RepairGun] = 1; + max[CloakingPack] = 0; + max[SensorJammerPack] = 1; + max[EnergyPack] = 1; + max[RepairPack] = 1; + max[ShieldPack] = 1; + max[AmmoPack] = 1; + max[SatchelCharge] = 1; + max[MortarBarrelPack] = 1; + max[MissileBarrelPack] = 1; + max[AABarrelPack] = 1; + max[PlasmaBarrelPack] = 1; + max[ELFBarrelPack] = 1; + max[InventoryDeployable]= 1; + max[MotionSensorDeployable] = 1; + max[PulseSensorDeployable] = 1; + max[TurretOutdoorDeployable] = 1; + max[TurretIndoorDeployable] = 1; + max[FlashGrenade] = 8; + max[ConcussionGrenade] = 8; + max[FlareGrenade] = 8; + max[TargetingLaser] = 1; + max[ELFGun] = 1; + max[ShockLance] = 1; + max[CameraGrenade] = 3; + max[Beacon] = 3; + max[Lootbag] = 1; + max[MiningTool] = 1; + max[C4Charge] = 1; + max[Flamer] = 0; + + observeParameters = "0.5 4.5 4.5"; + + shieldEffectScale = "0.7 0.7 1.0"; +}; + +//---------------------------------------------------------------------------- +datablock PlayerData(LightFemaleHumanArmor) : LightMaleHumanArmor +{ + shapeFile = "light_female.dts"; + waterBreathSound = WaterBreathFemaleSound; + jetEffect = HumanMediumArmorJetEffect; +}; + +//---------------------------------------------------------------------------- +datablock PlayerData(MediumFemaleHumanArmor) : MediumMaleHumanArmor +{ + shapeFile = "medium_female.dts"; + waterBreathSound = WaterBreathFemaleSound; + jetEffect = HumanArmorJetEffect; +}; + +//---------------------------------------------------------------------------- +datablock PlayerData(HeavyFemaleHumanArmor) : HeavyMaleHumanArmor +{ + shapeFile = "heavy_male.dts"; + waterBreathSound = WaterBreathFemaleSound; +}; + +//---------------------------------------------------------------------------- +datablock DecalData(LightBiodermFootprint) +{ + sizeX = 0.25; + sizeY = 0.25; + textureName = "special/footprints/L_bioderm"; +}; + +datablock PlayerData(LightMaleBiodermArmor) : LightMaleHumanArmor +{ + shapeFile = "bioderm_light.dts"; + jetEmitter = BiodermArmorJetEmitter; + jetEffect = BiodermArmorJetEffect; + + + debrisShapeName = "bio_player_debris.dts"; + debris = BiodermPlayerDebris; + + //Foot Prints + decalData = LightBiodermFootprint; + decalOffset = 0.3; + + waterBreathSound = WaterBreathBiodermSound; +}; + +//TODO: Balance out the Draakan armors +datablock PlayerData(LightMaleDraakanArmor) : LightMaleHumanArmor +{ + shapeFile = "bioderm_light.dts"; + jetEmitter = BiodermArmorJetEmitter; + jetEffect = BiodermArmorJetEffect; + + + debrisShapeName = "bio_player_debris.dts"; + debris = BiodermPlayerDebris; + + max[Flamer] = 1; + + //All the values from here and down (all Draakan armors) was severely unbalanced + + damageScale[$DamageType::Flame] = 0.2; + damageScale[$DamageType::Ground] = 0.37; //Was 0.07 + damageScale[$DamageType::Lava] = 0.1; //Was 0.01 + + + //Foot Prints + decalData = LightBiodermFootprint; + decalOffset = 0.3; + //Movement + runForce = 40.25 * 120; //Was 150 + runEnergyDrain = 0; + minRunEnergy = 0; + maxForwardSpeed = 20; + maxBackwardSpeed = 15.8; + maxSideSpeed = 9.9; + + maxUnderwaterForwardSpeed = 5; + maxUnderwaterBackwardSpeed = 3; + maxUnderwaterSideSpeed = 3; + + recoverDelay = 8; + recoverRunForceScale = 0.2; + + jumpForce = 8.35 * 135; //Was 160 + jumpEnergyDrain = 0; + minJumpEnergy = 0; + jumpDelay = 0; + + waterBreathSound = WaterBreathBiodermSound; +}; + +datablock PlayerData(LightMaleCriollosArmor) : LightMaleHumanArmor +{ + shapeFile = "bioderm_light.dts"; + jetEmitter = BiodermArmorJetEmitter; + jetEffect = BiodermArmorJetEffect; + + + debrisShapeName = "bio_player_debris.dts"; + debris = BiodermPlayerDebris; + + + //Foot Prints + decalData = LightBiodermFootprint; + decalOffset = 0.3; + + waterBreathSound = WaterBreathBiodermSound; +}; + + +//---------------------------------------------------------------------------- +datablock DecalData(MediumBiodermFootprint) +{ + sizeX = 0.25; + sizeY = 0.25; + textureName = "special/footprints/M_bioderm"; +}; + +datablock PlayerData(MediumMaleBiodermArmor) : MediumMaleHumanArmor +{ + shapeFile = "bioderm_medium.dts"; + jetEmitter = BiodermArmorJetEmitter; + jetEffect = BiodermArmorJetEffect; + + debrisShapeName = "bio_player_debris.dts"; + debris = BiodermPlayerDebris; + + //Foot Prints + decalData = MediumBiodermFootprint; + decalOffset = 0.35; + + waterBreathSound = WaterBreathBiodermSound; +}; + +datablock PlayerData(MediumMaleDraakanArmor) : MediumMaleHumanArmor +{ + emap = false; + + shapeFile = "bioderm_medium.dts"; + jetEmitter = BiodermArmorJetEmitter; + + damageScale[$DamageType::Flame] = 0; + damageScale[$DamageType::Ground] = 0.06; + damageScale[$DamageType::Lava] = 0.009; + + runForce = 40.25 * 180; + runEnergyDrain = 0; + minRunEnergy = 0; + maxForwardSpeed = 18.7; + maxBackwardSpeed = 13.2; + maxSideSpeed = 7.7; + + maxUnderwaterForwardSpeed = 5; + maxUnderwaterBackwardSpeed = 3; + maxUnderwaterSideSpeed = 3; + + recoverDelay = 8; + recoverRunForceScale = 0.2; + + jumpForce = 8.35 * 200; + jumpEnergyDrain = 0; + minJumpEnergy = 0; + jumpDelay = 0; + + debrisShapeName = "bio_player_debris.dts"; + debris = BiodermPlayerDebris; + + //Foot Prints + decalData = HeavyBiodermFootprint; + decalOffset = 0.4; + + waterBreathSound = WaterBreathBiodermSound; +}; + +datablock PlayerData(MediumMaleCriollosArmor) : MediumMaleHumanArmor +{ + emap = false; + + shapeFile = "bioderm_medium.dts"; + jetEmitter = BiodermArmorJetEmitter; + + debrisShapeName = "bio_player_debris.dts"; + debris = BiodermPlayerDebris; + + //Foot Prints + decalData = HeavyBiodermFootprint; + decalOffset = 0.4; + + waterBreathSound = WaterBreathBiodermSound; +}; + +//---------------------------------------------------------------------------- +datablock DecalData(HeavyBiodermFootprint) +{ + sizeX = 0.25; + sizeY = 0.5; + textureName = "special/footprints/H_bioderm"; +}; + +datablock PlayerData(HeavyMaleBiodermArmor) : HeavyMaleHumanArmor +{ + emap = false; + + shapeFile = "bioderm_heavy.dts"; + jetEmitter = BiodermArmorJetEmitter; + + debrisShapeName = "bio_player_debris.dts"; + debris = BiodermPlayerDebris; + + //Foot Prints + decalData = HeavyBiodermFootprint; + decalOffset = 0.4; + + waterBreathSound = WaterBreathBiodermSound; +}; + +datablock PlayerData(HeavyMaleDraakanArmor) : HeavyMaleHumanArmor +{ + shapeFile = "bioderm_heavy.dts"; + debrisShapeName = "bio_player_debris.dts"; + debris = BiodermPlayerDebris; + + damageScale[$DamageType::Flame] = 0; + damageScale[$DamageType::Ground] = 0.06; + damageScale[$DamageType::Lava] = 0.009; + + runForce = 40.25 * 180; + runEnergyDrain = 0; + minRunEnergy = 0; + maxForwardSpeed = 18.7; + maxBackwardSpeed = 13.2; + maxSideSpeed = 7.7; + + maxUnderwaterForwardSpeed = 5; + maxUnderwaterBackwardSpeed = 3; + maxUnderwaterSideSpeed = 3; + + recoverDelay = 8; + recoverRunForceScale = 0.2; + + jumpForce = 8.35 * 200; + jumpEnergyDrain = 0; + minJumpEnergy = 0; + jumpDelay = 0; + +}; + +datablock PlayerData(HeavyMaleCriollosArmor) : HeavyMaleHumanArmor +{ +shapeFile = "bioderm_heavy.dts"; +debrisShapeName = "bio_player_debris.dts"; +debris = BiodermPlayerDebris; +}; + +//---------------------------------------------------------------------------- + +function Armor::onAdd(%data,%obj) +{ + Parent::onAdd(%data, %obj); + // Vehicle timeout + %obj.mountVehicle = true; + + // Default dynamic armor stats + %obj.setRechargeRate(%data.rechargeRate); + %obj.setRepairRate(0); + + %obj.setSelfPowered(); +} + +function Armor::onRemove(%this, %obj) +{ + //Frohny asked me to remove this - all players are deleted now on mission cycle... + //if(%obj.getState() !$= "Dead") + //{ + // error("ERROR PLAYER REMOVED WITHOUT DEATH - TRACE:"); + // trace(1); + // schedule(0,0,trace,0); + //} + + if (%obj.client.player == %obj) + %obj.client.player = 0; +} + +function Armor::onNewDataBlock(%this,%obj) +{ +} + +//------------------------------------------------------------------------------------- +// z0dd - ZOD, 4-15-02. Allow respawn switching during tourney wait. Function rewrite. +function Armor::onDisabled(%this,%obj,%state) +{ + if($MatchStarted) + { + %obj.startFade( 1000, $CorpseTimeoutValue - 1000, true ); + %obj.schedule( $CorpseTimeoutValue, "delete" ); + } + else + { + %obj.schedule( 150, "delete" ); + } +} +//------------------------------------------------------------------------------------- + +function Armor::shouldApplyImpulse(%data, %obj) +{ + return true; +} + +$wasFirstPerson = true; + +function Armor::onMount(%this,%obj,%vehicle,%node) +{ + if (%node == 0) + { + // Node 0 is the pilot's pos. + %obj.setTransform("0 0 0 0 0 1 0"); + %obj.setActionThread(%vehicle.getDatablock().mountPose[%node],true,true); + + if(!%obj.inStation) + %obj.lastWeapon = (%obj.getMountedImage($WeaponSlot) == 0 ) ? "" : %obj.getMountedImage($WeaponSlot).getName().item; + + %obj.unmountImage($WeaponSlot); + + if(!%obj.client.isAIControlled()) + { + %obj.setControlObject(%vehicle); + %obj.client.setObjectActiveImage(%vehicle, 2); + } + + //E3 respawn... + + if(%obj == %obj.lastVehicle.lastPilot && %obj.lastVehicle != %vehicle) + { + schedule(15000, %obj.lastVehicle,"vehicleAbandonTimeOut", %obj.lastVehicle); + %obj.lastVehicle.lastPilot = ""; + } + if(%vehicle.lastPilot !$= "" && %vehicle == %vehicle.lastPilot.lastVehicle) + %vehicle.lastPilot.lastVehicle = ""; + + %vehicle.abandon = false; + %vehicle.lastPilot = %obj; + %obj.lastVehicle = %vehicle; + + // update the vehicle's team + if((%vehicle.getTarget() != -1) && %vehicle.getDatablock().cantTeamSwitch $= "") + { + setTargetSensorGroup(%vehicle.getTarget(), %obj.client.getSensorGroup()); + if( %vehicle.turretObject > 0 ) + setTargetSensorGroup(%vehicle.turretObject.getTarget(), %obj.client.getSensorGroup()); + } + + // Send a message to the client so they can decide if they want to change view or not: + commandToClient( %obj.client, 'VehicleMount' ); + + } + else + { + // tailgunner/passenger positions + if(%vehicle.getDataBlock().mountPose[%node] !$= "") + %obj.setActionThread(%vehicle.getDatablock().mountPose[%node]); + else + %obj.setActionThread("root", true); + } + // z0dd - ZOD, 6/27/02. announce to any other passengers that you've boarded + if(%vehicle.getDatablock().numMountPoints > 1) + { + %nodeName = findNodeName(%vehicle, %node); // function in vehicle.cs + for(%i = 0; %i < %vehicle.getDatablock().numMountPoints; %i++) + { + if (%vehicle.getMountNodeObject(%i) > 0) + { + if(%vehicle.getMountNodeObject(%i).client != %obj.client) + { + %team = (%obj.team == %vehicle.getMountNodeObject(%i).client.team ? 'Teammate' : 'Enemy'); + messageClient( %vehicle.getMountNodeObject(%i).client, 'MsgShowPassenger', '\c2%3: \c3%1\c2 has boarded in the \c3%2\c2 position.', %obj.client.name, %nodeName, %team ); + } + commandToClient( %vehicle.getMountNodeObject(%i).client, 'showPassenger', %node, true); + } + } + } + //make sure they don't have any packs active +// if ( %obj.getImageState( $BackpackSlot ) $= "activate") +// %obj.use("Backpack"); + if ( %obj.getImageTrigger( $BackpackSlot ) ) + %obj.setImageTrigger( $BackpackSlot, false ); + + //AI hooks + %obj.client.vehicleMounted = %vehicle; + AIVehicleMounted(%vehicle); + if(%obj.client.isAIControlled()) + %this.AIonMount(%obj, %vehicle, %node); +} + + +function Armor::onUnmount( %this, %obj, %vehicle, %node ) +{ + if ( %node == 0 ) + { + commandToClient( %obj.client, 'VehicleDismount' ); + commandToClient(%obj.client, 'removeReticle'); + + if(%obj.inv[%obj.lastWeapon]) + %obj.use(%obj.lastWeapon); + + if(%obj.getMountedImage($WeaponSlot) == 0) + %obj.selectWeaponSlot( 0 ); + + //Inform gunner position when pilot leaves... + //if(%vehicle.getDataBlock().showPilotInfo !$= "") + // if((%gunner = %vehicle.getMountNodeObject(1)) != 0) + // commandToClient(%gunner.client, 'PilotInfo', "PILOT EJECTED", 6, 1); + } + // z0dd - ZOD, 6/27/02. announce to any other passengers that you've left + if(%vehicle.getDatablock().numMountPoints > 1) + { + %nodeName = findNodeName(%vehicle, %node); // function in vehicle.cs + for(%i = 0; %i < %vehicle.getDatablock().numMountPoints; %i++) + { + if (%vehicle.getMountNodeObject(%i) > 0) + { + if(%vehicle.getMountNodeObject(%i).client != %obj.client) + { + %team = (%obj.team == %vehicle.getMountNodeObject(%i).client.team ? 'Teammate' : 'Enemy'); + messageClient( %vehicle.getMountNodeObject(%i).client, 'MsgShowPassenger', '\c2%3: \c3%1\c2 has ejected from the \c3%2\c2 position.', %obj.client.name, %nodeName, %team ); + } + commandToClient( %vehicle.getMountNodeObject(%i).client, 'showPassenger', %node, false); + } + } + } + //AI hooks + %obj.client.vehicleMounted = ""; + if(%obj.client.isAIControlled()) + %this.AIonUnMount(%obj, %vehicle, %node); +} + +$ammoType[0] = "PlasmaAmmo"; +$ammoType[1] = "DiscAmmo"; +$ammoType[2] = "GrenadeLauncherAmmo"; +$ammoType[3] = "MortarAmmo"; +$ammoType[4] = "MissileLauncherAmmo"; +$ammoType[5] = "ChaingunAmmo"; +// ------------------------------------- +// z0dd - ZOD, 9/13/02. For TR2 weapons +$ammoType[6] = "TR2DiscAmmo"; +$ammoType[7] = "TR2GrenadeLauncherAmmo"; +$ammoType[8] = "TR2ChaingunAmmo"; +$ammoType[9] = "TR2MortarAmmo"; +// ------------------------------------- + +function Armor::onCollision(%this,%obj,%col,%forceVehicleNode) +{ + if (%obj.getState() $= "Dead") + return; + + %dataBlock = %col.getDataBlock(); + %className = %dataBlock.className; + %client = %obj.client; + // player collided with a vehicle + %node = -1; + if (%forceVehicleNode !$= "" || (%className $= WheeledVehicleData || %className $= FlyingVehicleData || %className $= HoverVehicleData) && + %obj.mountVehicle && %obj.getState() $= "Move" && %col.mountable && !%obj.inStation && %col.getDamageState() !$= "Destroyed") { + + //if the player is an AI, he should snap to the mount points in node order, + //to ensure they mount the turret before the passenger seat, regardless of where they collide... + if (%obj.client.isAIControlled()) + { + %transform = %col.getTransform(); + + //either the AI is *required* to pilot, or they'll pick the first available passenger seat + if (%client.pilotVehicle) + { + //make sure the bot is in light armor + if (%client.player.getArmorSize() $= "Light") + { + //make sure the pilot seat is empty + if (!%col.getMountNodeObject(0)) + %node = 0; + } + } + else + %node = findAIEmptySeat(%col, %obj); + } + else + %node = findEmptySeat(%col, %obj, %forceVehicleNode); + + //now mount the player in the vehicle + if(%node >= 0) + { + // players can't be pilots, bombardiers or turreteers if they have + // "large" packs -- stations, turrets, turret barrels + if(hasLargePack(%obj)) { + // check to see if attempting to enter a "sitting" node + if(nodeIsSitting(%datablock, %node)) { + // send the player a message -- can't sit here with large pack + if(!%obj.noSitMessage) + { + %obj.noSitMessage = true; + %obj.schedule(2000, "resetSitMessage"); + messageClient(%obj.client, 'MsgCantSitHere', '\c2Pack too large, can\'t occupy this seat.~wfx/misc/misc.error.wav'); + } + return; + } + } + if(%col.noEnemyControl && %obj.team != %col.team) + return; + + commandToClient(%obj.client,'SetDefaultVehicleKeys', true); + //If pilot or passenger then bind a few extra keys + if(%node == 0) + commandToClient(%obj.client,'SetPilotVehicleKeys', true); + else + commandToClient(%obj.client,'SetPassengerVehicleKeys', true); + + if(!%obj.inStation) + %col.lastWeapon = ( %col.getMountedImage($WeaponSlot) == 0 ) ? "" : %col.getMountedImage($WeaponSlot).getName().item; + else + %col.lastWeapon = %obj.lastWeapon; + + %col.mountObject(%obj,%node); + %col.playAudio(0, MountVehicleSound); + %obj.mVehicle = %col; + + // if player is repairing something, stop it + if(%obj.repairing) + stopRepairing(%obj); + + //this will setup the huds as well... + %dataBlock.playerMounted(%col,%obj, %node); + } + } + else if (%className $= "Armor") { + // player has collided with another player + if(%col.getState() $= "Dead") { + %gotSomething = false; + // it's corpse-looting time! + // weapons -- don't pick up more than you are allowed to carry! + for(%i = 0; ( %obj.weaponCount < %obj.getDatablock().maxWeapons ) && $InvWeapon[%i] !$= ""; %i++) + { + %weap = $NameToInv[$InvWeapon[%i]]; + if ( %col.hasInventory( %weap ) ) + { + if ( %obj.incInventory(%weap, 1) > 0 ) + { + %col.decInventory(%weap, 1); + %gotSomething = true; + messageClient(%obj.client, 'MsgItemPickup', '\c0You picked up %1.', %weap.pickUpName); + } + } + } + // targeting laser: + if ( %col.hasInventory( "TargetingLaser" ) ) + { + if ( %obj.incInventory( "TargetingLaser", 1 ) > 0 ) + { + %col.decInventory( "TargetingLaser", 1 ); + %gotSomething = true; + messageClient( %obj.client, 'MsgItemPickup', '\c0You picked up a targeting laser.' ); + } + } + // ammo + for(%j = 0; $ammoType[%j] !$= ""; %j++) + { + %ammoAmt = %col.inv[$ammoType[%j]]; + if(%ammoAmt) + { + // incInventory returns the amount of stuff successfully grabbed + %grabAmt = %obj.incInventory($ammoType[%j], %ammoAmt); + if(%grabAmt > 0) + { + %col.decInventory($ammoType[%j], %grabAmt); + %gotSomething = true; + messageClient(%obj.client, 'MsgItemPickup', '\c0You picked up %1.', $ammoType[%j].pickUpName); + %obj.client.setWeaponsHudAmmo($ammoType[%j], %obj.getInventory($ammoType[%j])); + } + } + } + // figure out what type, if any, grenades the (live) player has + %playerGrenType = "None"; + for(%x = 0; $InvGrenade[%x] !$= ""; %x++) { + %gren = $NameToInv[$InvGrenade[%x]]; + %playerGrenAmt = %obj.inv[%gren]; + if(%playerGrenAmt > 0) + { + %playerGrenType = %gren; + break; + } + } + // grenades + for(%k = 0; $InvGrenade[%k] !$= ""; %k++) + { + %gren = $NameToInv[$InvGrenade[%k]]; + %corpseGrenAmt = %col.inv[%gren]; + // does the corpse hold any of this grenade type? + if(%corpseGrenAmt) + { + // can the player pick up this grenade type? + if((%playerGrenType $= "None") || (%playerGrenType $= %gren)) + { + %taken = %obj.incInventory(%gren, %corpseGrenAmt); + if(%taken > 0) + { + %col.decInventory(%gren, %taken); + %gotSomething = true; + messageClient(%obj.client, 'MsgItemPickup', '\c0You picked up %1.', %gren.pickUpName); + %obj.client.setInventoryHudAmount(%gren, %obj.getInventory(%gren)); + } + } + break; + } + } + // figure out what type, if any, mines the (live) player has + %playerMineType = "None"; + for(%y = 0; $InvMine[%y] !$= ""; %y++) + { + %mType = $NameToInv[$InvMine[%y]]; + %playerMineAmt = %obj.inv[%mType]; + if(%playerMineAmt > 0) + { + %playerMineType = %mType; + break; + } + } + // mines + for(%l = 0; $InvMine[%l] !$= ""; %l++) + { + %mine = $NameToInv[$InvMine[%l]]; + %mineAmt = %col.inv[%mine]; + if(%mineAmt) { + if((%playerMineType $= "None") || (%playerMineType $= %mine)) + { + %grabbed = %obj.incInventory(%mine, %mineAmt); + if(%grabbed > 0) + { + %col.decInventory(%mine, %grabbed); + %gotSomething = true; + messageClient(%obj.client, 'MsgItemPickup', '\c0You picked up %1.', %mine.pickUpName); + %obj.client.setInventoryHudAmount(%mine, %obj.getInventory(%mine)); + } + } + break; + } + } + // beacons + %beacAmt = %col.inv[Beacon]; + if(%beacAmt) + { + %bTaken = %obj.incInventory(Beacon, %beacAmt); + if(%bTaken > 0) + { + %col.decInventory(Beacon, %bTaken); + %gotSomething = true; + messageClient(%obj.client, 'MsgItemPickup', '\c0You picked up %1.', Beacon.pickUpName); + %obj.client.setInventoryHudAmount(Beacon, %obj.getInventory(Beacon)); + } + } + // repair kit + %rkAmt = %col.inv[RepairKit]; + if(%rkAmt) + { + %rkTaken = %obj.incInventory(RepairKit, %rkAmt); + if(%rkTaken > 0) + { + %col.decInventory(RepairKit, %rkTaken); + %gotSomething = true; + messageClient(%obj.client, 'MsgItemPickup', '\c0You picked up %1.', RepairKit.pickUpName); + %obj.client.setInventoryHudAmount(RepairKit, %obj.getInventory(RepairKit)); + } + } + } + if(%gotSomething) + %col.playAudio(0, CorpseLootingSound); + } +} + +// ------------------------------------------------------------ +// z0dd - ZOD, 9/27/02. Delay on grabbing flag after tossing it +function Player::resetFlagTossWait(%this) +{ + %this.flagTossWait = false; +} +// ------------------------------------------------------------ + +function Player::resetSitMessage(%obj) +{ + %obj.noSitMessage = false; +} + +function Player::setInvincible(%this, %val) +{ + %this.invincible = %val; +} + +function Player::causedRecentDamage(%this, %val) +{ + %this.causedRecentDamage = %val; +} + +function hasLargePack(%player) +{ + %pack = %player.getMountedImage($BackpackSlot); + if(%pack.isLarge) + return true; + else + return false; +} + +function nodeIsSitting(%vehDBlock, %node) +{ + // pilot == always a "sitting" node + if(%node == 0) + return true; + else { + switch$ (%vehDBlock.getName()) + { + // note: for assault tank -- both nodes are sitting + // for any single-user vehicle -- pilot node is sitting + case "BomberFlyer": + // bombardier == sitting; tailgunner == not sitting + if(%node == 1) + return true; + else + return false; + case "HAPCFlyer": + // only the pilot node is sitting + return false; + default: + return true; + } + } +} + +//---------------------------------------------------------------------------- +function Player::setMountVehicle(%this, %val) +{ + %this.mountVehicle = %val; +} + +function Armor::doDismount(%this, %obj, %forced) +{ + // This function is called by player.cc when the jump trigger + // is true while mounted + if (!%obj.isMounted()) + return; + + if(isObject(%obj.getObjectMount().shield)) + %obj.getObjectMount().shield.delete(); + + commandToClient(%obj.client,'SetDefaultVehicleKeys', false); + + // Position above dismount point + + %pos = getWords(%obj.getTransform(), 0, 2); + %oldPos = %pos; + %vec[0] = " 0 0 1"; + %vec[1] = " 0 0 1"; + %vec[2] = " 0 0 -1"; + %vec[3] = " 1 0 0"; + %vec[4] = "-1 0 0"; + %numAttempts = 5; + %success = -1; + %impulseVec = "0 0 0"; + if (%obj.getObjectMount().getDatablock().hasDismountOverrides() == true) + { + %vec[0] = %obj.getObjectMount().getDatablock().getDismountOverride(%obj.getObjectMount(), %obj); + %vec[0] = MatrixMulVector(%obj.getObjectMount().getTransform(), %vec[0]); + } + else + { + %vec[0] = MatrixMulVector( %obj.getTransform(), %vec[0]); + } + + %pos = "0 0 0"; + for (%i = 0; %i < %numAttempts; %i++) + { + %pos = VectorAdd(%oldPos, VectorScale(%vec[%i], 5)); // z0dd - ZOD, 4/24/02. More ejection clearance. 5 was 3 + if (%obj.checkDismountPoint(%oldPos, %pos)) + { + %success = %i; + %impulseVec = %vec[%i]; + break; + } + } + if (%forced && %success == -1) + { + %pos = %oldPos; + } + + // hide the dashboard HUD and delete elements based on node + commandToClient(%obj.client, 'setHudMode', 'Standard', "", 0); + // Unmount and control body + if(%obj.vehicleTurret) + %obj.vehicleTurret.getDataBlock().playerDismount(%obj.vehicleTurret); + %obj.unmount(); + if(%obj.mVehicle) + %obj.mVehicle.getDataBlock().playerDismounted(%obj.mVehicle, %obj); + + // bots don't change their control objects when in vehicles + if(!%obj.client.isAIControlled()) + { + %vehicle = %obj.getControlObject(); + %obj.setControlObject(0); + } + + %obj.mountVehicle = false; + %obj.schedule(1500, "setMountVehicle", true); // z0dd - ZOD, 3/29/02. Reduce time between being able to mount vehicles . Was 4000 + + // Position above dismount point + %obj.setTransform(%pos); + %obj.playAudio(0, UnmountVehicleSound); + %obj.applyImpulse(%pos, VectorScale(%impulseVec, %obj.getDataBlock().mass * 3)); + %obj.setPilot(false); + %obj.vehicleTurret = ""; + + // ----------------------------------------------------- + // z0dd - ZOD, 4/8/02. Set player velocity when ejecting + %vel = %obj.getVelocity(); + %vec = vectorDot(%vel, vectorNormalize(%vel)); + if(%vec > 50) + { + %scale = 50 / %vec; + %obj.setVelocity(VectorScale(%vel, %scale)); + } + // ----------------------------------------------------- +} + +function resetObserveFollow( %client, %dismount ) +{ + if( %dismount ) + { + if( !isObject( %client.player ) ) + return; + + for( %i = 0; %i < %client.observeCount; %i++ ) + { + %client.observers[%i].camera.setOrbitMode( %client.player, %client.player.getTransform(), 0.5, 4.5, 4.5); + } + } + else + { + if( !%client.player.isMounted() ) + return; + + // grab the vehicle... + %mount = %client.player.getObjectMount(); + if( %mount.getDataBlock().observeParameters $= "" ) + %params = %client.player.getTransform(); + else + %params = %mount.getDataBlock().observeParameters; + + for( %i = 0; %i < %client.observeCount; %i++ ) + { + %client.observers[%i].camera.setOrbitMode(%mount, %mount.getTransform(), getWord( %params, 0 ), getWord( %params, 1 ), getWord( %params, 2 )); + } + } +} + + +//---------------------------------------------------------------------------- + +function Player::scriptKill(%player, %damageType) +{ + %player.scriptKilled = 1; + %player.setInvincible(false); + %player.damage(0, %player.getPosition(), 10000, %damageType); +} + +function Armor::damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType, %momVec, %mineSC) +{ +//error("Armor::damageObject( "@%data@", "@%targetObject@", "@%sourceObject@", "@%position@", "@%amount@", "@%damageType@", "@%momVec@" )"); + if(%targetObject.invincible || %targetObject.getState() $= "Dead") + return; + + //---------------------------------------------------------------- + // z0dd - ZOD, 6/09/02. Check to see if this vehicle is destroyed, + // if it is do no damage. Fixes vehicle ghosting bug. We do not + // check for isObject here, destroyed objects fail it even though + // they exist as objects, go figure. + if(%damageType == $DamageType::Impact) + if(%sourceObject.getDamageState() $= "Destroyed") + return; + + if (%targetObject.isMounted() && %targetObject.scriptKilled $= "") + { + %mount = %targetObject.getObjectMount(); + if(%mount.team == %targetObject.team) + { + %found = -1; + for (%i = 0; %i < %mount.getDataBlock().numMountPoints; %i++) + { + if (%mount.getMountNodeObject(%i) == %targetObject) + { + %found = %i; + break; + } + } + + if (%found != -1) + { + if (%mount.getDataBlock().isProtectedMountPoint[%found]) + { + %mount.getDataBlock().damageObject(%mount, %sourceObject, %position, %amount, %damageType); + return; + } + } + } + } + + %targetClient = %targetObject.getOwnerClient(); + if(isObject(%mineSC)) + %sourceClient = %mineSC; + else + %sourceClient = isObject(%sourceObject) ? %sourceObject.getOwnerClient() : 0; + + %targetTeam = %targetClient.team; + + //if the source object is a player object, player's don't have sensor groups + // if it's a turret, get the sensor group of the target + // if its a vehicle (of any type) use the sensor group + if (%sourceClient) + %sourceTeam = %sourceClient.getSensorGroup(); + else if(%damageType == $DamageType::Suicide) + %sourceTeam = 0; + //-------------------------------------------------------------------------------------------------------------------- + // z0dd - ZOD, 4/8/02. Check to see if this turret has a valid owner, if not clear the variable. + else if(isObject(%sourceObject) && %sourceObject.getClassName() $= "Turret") + { + %sourceTeam = getTargetSensorGroup(%sourceObject.getTarget()); + if(%sourceObject.owner !$="" && (%sourceObject.owner.team != %sourceObject.team || !isObject(%sourceObject.owner))) + { + %sourceObject.owner = ""; + } + } + //-------------------------------------------------------------------------------------------------------------------- + else if( isObject(%sourceObject) && + ( %sourceObject.getClassName() $= "FlyingVehicle" || %sourceObject.getClassName() $= "WheeledVehicle" || %sourceObject.getClassName() $= "HoverVehicle")) + %sourceTeam = getTargetSensorGroup(%sourceObject.getTarget()); + else + { + if (isObject(%sourceObject) && %sourceObject.getTarget() >= 0 ) + { + %sourceTeam = getTargetSensorGroup(%sourceObject.getTarget()); + } + else + { + %sourceTeam = -1; + } + } + + // if teamdamage is off, and both parties are on the same team + // (but are not the same person), apply no damage + if(!$teamDamage && (%targetClient != %sourceClient) && (%targetTeam == %sourceTeam)) + return; + + if(%targetObject.isShielded && %damageType != $DamageType::Blaster) + %amount = %data.checkShields(%targetObject, %position, %amount, %damageType); + + if(%amount == 0) + return; + + // Set the damage flash + %damageScale = %data.damageScale[%damageType]; + if(%damageScale !$= "") + %amount *= %damageScale; + + %flash = %targetObject.getDamageFlash() + (%amount * 2); + if (%flash > 0.75) + %flash = 0.75; + + %previousDamage = %targetObject.getDamagePercent(); + %targetObject.setDamageFlash(%flash); + %targetObject.applyDamage(%amount); + Game.onClientDamaged(%targetClient, %sourceClient, %damageType, %sourceObject); + + %targetClient.lastDamagedBy = %damagingClient; + %targetClient.lastDamaged = getSimTime(); + + //now call the "onKilled" function if the client was... you know... + if(%targetObject.getState() $= "Dead") + { + // where did this guy get it? + %damLoc = %targetObject.getDamageLocation(%position); + + // should this guy be blown apart? + if( %damageType == $DamageType::Explosion || + %damageType == $DamageType::TankMortar || + %damageType == $DamageType::Mortar || + %damageType == $DamageType::MortarTurret || + %damageType == $DamageType::BomberBombs || + %damageType == $DamageType::SatchelCharge || + %damageType == $DamageType::Missile ) + { + if( %previousDamage >= 0.35 ) // only if <= 35 percent damage remaining + { + %targetObject.setMomentumVector(%momVec); + %targetObject.blowup(); + } + } + + // this should be funny... + if( %damageType == $DamageType::VehicleSpawn ) + { + %targetObject.setMomentumVector("0 0 1"); + %targetObject.blowup(); + } + + // If we were killed, max out the flash + %targetObject.setDamageFlash(0.75); + + %damLoc = %targetObject.getDamageLocation(%position); + Game.onClientKilled(%targetClient, %sourceClient, %damageType, %sourceObject, %damLoc); + + if ( %amount > 0.1 ) + { + if( %targetObject.station $= "" && %targetObject.isCloaked() ) + { + %targetObject.setCloaked( false ); + %targetObject.reCloak = %targetObject.schedule( 500, "setCloaked", true ); + } + + playPain( %targetObject ); + } + } +} + +function Armor::onImpact(%data, %playerObject, %collidedObject, %vec, %vecLen) +{ + %data.damageObject(%playerObject, 0, VectorAdd(%playerObject.getPosition(),%vec), + %vecLen * %data.speedDamageScale, $DamageType::Ground); +} + +function Armor::applyConcussion( %this, %dist, %radius, %sourceObject, %targetObject ) +{ + %percentage = 1 - ( %dist / %radius ); + %random = getRandom(); + + if( %sourceObject == %targetObject ) + { + %flagChance = 1.0; + %itemChance = 1.0; + } + else + { + %flagChance = 0.7; + %itemChance = 0.7; + } + + %probabilityFlag = %flagChance * %percentage; + %probabilityItem = %itemChance * %percentage; + + if( %random <= %probabilityFlag ) + { + Game.applyConcussion( %targetObject ); + } + + if( %random <= %probabilityItem ) + { + %player = %targetObject; + %numWeapons = 0; + + // blaster 0 + // plasma 1 + // chain 2 + // disc 3 + // grenade 4 + // snipe 5 + // elf 6 + // mortar 7 + + //get our inventory + if( %weaps[0] = %player.getInventory("Blaster") > 0 ) %numWeapons++; + if( %weaps[1] = %player.getInventory("Plasma") > 0 ) %numWeapons++; + if( %weaps[2] = %player.getInventory("Chaingun") > 0 ) %numWeapons++; + if( %weaps[3] = %player.getInventory("Disc") > 0 ) %numWeapons++; + if( %weaps[4] = %player.getInventory("GrenadeLauncher") > 0 ) %numWeapons++; + if( %weaps[5] = %player.getInventory("SniperRifle") > 0 ) %numWeapons++; + if( %weaps[6] = %player.getInventory("ELFGun") > 0 ) %numWeapons++; + if( %weaps[7] = %player.getInventory("Mortar") > 0 ) %numWeapons++; + + %foundWeapon = false; + %attempts = 0; + + if( %numWeapons > 0 ) + { + while( !%foundWeapon ) + { + %rand = mFloor( getRandom() * 8 ); + if( %weaps[ %rand ] ) + { + %foundWeapon = true; + + switch ( %rand ) + { + case 0: + %player.use("Blaster"); + case 1: + %player.use("Plasma"); + case 2: + %player.use("Chaingun"); + case 3: + %player.use("Disc"); + case 4: + %player.use("GrenadeLauncher"); + case 5: + %player.use("SniperRifle"); + case 6: + %player.use("ElfGun"); + case 7: + %player.use("Mortar"); + } + + %image = %player.getMountedImage( $WeaponSlot ); + %player.throw( %image.item ); + %player.client.setWeaponsHudItem( %image.item, 0, 0 ); + %player.throwPack(); + } + else + { + %attempts++; + if( %attempts > 10 ) + %foundWeapon = true; + } + } + } + else + { + %targetObject.throwPack(); + %targetObject.throwWeapon(); + } + } +} + +//---------------------------------------------------------------------------- + +$DeathCry[1] = 'avo.deathCry_01'; +$DeathCry[2] = 'avo.deathCry_02'; +$PainCry[1] = 'avo.grunt'; +$PainCry[2] = 'avo.pain'; + +function playDeathCry( %obj ) +{ + %client = %obj.client; + %random = getRandom(1) + 1; + %desc = AudioClosest3d; + + playTargetAudio( %client.target, $DeathCry[%random], %desc, false ); +} + +function playPain( %obj ) +{ + %client = %obj.client; + %random = getRandom(1) + 1; + %desc = AudioClosest3d; + + playTargetAudio( %client.target, $PainCry[%random], %desc, false); +} + +//---------------------------------------------------------------------------- + +//$DefaultPlayerArmor = LightMaleHumanArmor; +$DefaultPlayerArmor = Light; + +function Player::setArmor(%this,%size) +{ + // Takes size as "Light","Medium", "Heavy" + %client = %this.client; + if (%client.race $= "Bioderm") + // Only have male bioderms. + %armor = %size @ "Male" @ %client.race @ Armor; + else + %armor = %size @ %client.sex @ %client.race @ Armor; + //echo("Player::armor: " @ %armor); + %this.setDataBlock(%armor); + %client.armor = %size; +} + +function getDamagePercent(%maxDmg, %dmgLvl) +{ + return (%dmgLvl / %maxDmg); +} + +function Player::getArmorSize(%this) +{ + // return size as "Light","Medium", "Heavy" + %dataBlock = %this.getDataBlock().getName(); + if (getSubStr(%dataBlock, 0, 5) $= "Light") + return "Light"; + else if (getSubStr(%dataBlock, 0, 6) $= "Medium") + return "Medium"; + else if (getSubStr(%dataBlock, 0, 5) $= "Heavy") + return "Heavy"; + else + return "Unknown"; +} + +function Player::pickup(%this,%obj,%amount) +{ + %data = %obj.getDataBlock(); + %client = %this.client; + if (%data.className $= Pack && %data.getName() $= Lootbag) + { + if (%obj.cash > 0) + { + messageClient(%client,'msgClient',"\c3That bag had "@%obj.cash@" coins in it."); + %client.cash = %client.cash + %obj.cash; + } + } + // Don't pick up a pack if we already have one mounted + if (%data.className $= Pack && + %this.getMountedImage($BackpackSlot) != 0) + return 0; + // don't pick up a weapon (other than targeting laser) if player's at maxWeapons + else if(%data.className $= Weapon + && %data.getName() !$= "TargetingLaser" // Special case + && %this.weaponCount >= %this.getDatablock().maxWeapons) + return 0; + // don't allow players to throw large packs at pilots (thanks Wizard) + else if(%data.className $= Pack && %data.image.isLarge && %this.isPilot()) + return 0; + return ShapeBase::pickup(%this,%obj,%amount); +} + +function Player::use( %this,%data ) +{ + // If player is in a station then he can't use any items + if(%this.station !$= "") + return false; + + // Convert the word "Backpack" to whatever is in the backpack slot. + if ( %data $= "Backpack" ) + { + if ( %this.inStation ) + return false; + + if ( %this.isPilot() ) + { + messageClient( %this.client, 'MsgCantUsePack', '\c2You can\'t use your pack while piloting.~wfx/misc/misc.error.wav' ); + return( false ); + } + else if ( %this.isWeaponOperator() ) + { + messageClient( %this.client, 'MsgCantUsePack', '\c2You can\'t use your pack while in a weaponry position.~wfx/misc/misc.error.wav' ); + return( false ); + } + + %image = %this.getMountedImage( $BackpackSlot ); + if ( %image ) + %data = %image.item; + } + + // Can't use some items when piloting or your a weapon operator + if ( %this.isPilot() || %this.isWeaponOperator() ) + if ( %data.getName() !$= "RepairKit" ) + return false; + + return ShapeBase::use( %this, %data ); +} + +function Player::maxInventory(%this,%data) +{ + %max = ShapeBase::maxInventory(%this,%data); + if (%this.getInventory(AmmoPack)) + %max += AmmoPack.max[%data.getName()]; + return %max; +} + +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::isWeaponOperator(%this) +{ + %vehicle = %this.getObjectMount(); + if ( %vehicle ) + { + %weaponNode = %vehicle.getDatablock().weaponNode; + if ( %weaponNode > 0 && %vehicle.getMountNodeObject( %weaponNode ) == %this ) + return( true ); + } + + return( false ); +} + +function Player::liquidDamage(%obj, %data, %damageAmount, %damageType) +{ + if(%obj.getState() !$= "Dead") + { + %data.damageObject(%obj, 0, "0 0 0", %damageAmount, %damageType); + %obj.lDamageSchedule = %obj.schedule(50, "liquidDamage", %data, %damageAmount, %damageType); + } + else + %obj.lDamageSchedule = ""; +} + +function Armor::onEnterLiquid(%data, %obj, %coverage, %type) +{ + switch(%type) + { + case 0: + //Water + %obj.shouldBurn = false; + case 1: + //Ocean Water + %obj.shouldBurn = false; + case 2: + //River Water + %obj.shouldBurn = false; + case 3: + //Stagnant Water + %obj.shouldBurn = false; + case 4: + //Lava + %obj.liquidDamage(%data, $DamageLava, $DamageType::Lava); + case 5: + //Hot Lava + %obj.liquidDamage(%data, $DamageHotLava, $DamageType::Lava); + case 6: + //Crusty Lava + %obj.liquidDamage(%data, $DamageCrustyLava, $DamageType::Lava); + case 7: + //Quick Sand + } +} + +function Armor::onLeaveLiquid(%data, %obj, %type) +{ + switch(%type) + { + case 0: + //Water + %obj.shouldBurn = true; + case 1: + //Ocean Water + %obj.shouldBurn = true; + case 2: + //River Water + %obj.shouldBurn = true; + case 3: + //Stagnant Water + %obj.shouldBurn = true; + case 4: + //Lava + case 5: + //Hot Lava + case 6: + //Crusty Lava + case 7: + //Quick Sand + } + + if(%obj.lDamageSchedule !$= "") + { + cancel(%obj.lDamageSchedule); + %obj.lDamageSchedule = ""; + } +} + +function Armor::onTrigger(%data, %player, %triggerNum, %val) +{ + if (%triggerNum == 4) + { + // Throw grenade + if (%val == 1) + { + %player.grenTimer = 1; + } + else + { + if (%player.grenTimer == 0) + { + // Bad throw for some reason + } + else + { + %player.use(Grenade); + %player.grenTimer = 0; + } + } + } + else if (%triggerNum == 5) + { + // Throw mine + if (%val == 1) + { + %player.mineTimer = 1; + } + else + { + if (%player.mineTimer == 0) + { + // Bad throw for some reason + } + else + { + %player.use(Mine); + %player.mineTimer = 0; + } + } + } + else if (%triggerNum == 3) + { + // val = 1 when jet key (LMB) first pressed down + // val = 0 when jet key released + // MES - do we need this at all any more? + if(%val == 1) + %player.isJetting = true; + else + %player.isJetting = false; + } +} + +function Player::setMoveState(%obj, %move) +{ + %obj.disableMove(%move); +} + +function Armor::onLeaveMissionArea(%data, %obj) +{ + Game.leaveMissionArea(%data, %obj); +} + +function Armor::onEnterMissionArea(%data, %obj) +{ + Game.enterMissionArea(%data, %obj); +} + +function Armor::animationDone(%data, %obj) +{ + if(%obj.animResetWeapon !$= "") + { + if(%obj.getMountedImage($WeaponSlot) == 0) + if(%obj.inv[%obj.lastWeapon]) + %obj.use(%obj.lastWeapon); + %obj.animSetWeapon = ""; + } +} + +function playDeathAnimation(%player, %damageLocation, %type) +{ + %vertPos = firstWord(%damageLocation); + %quadrant = getWord(%damageLocation, 1); + + //echo("vert Pos: " @ %vertPos); + //echo("quad: " @ %quadrant); + + if( %type == $DamageType::Explosion || %type == $DamageType::Mortar || %type == $DamageType::Grenade) + { + if(%quadrant $= "front_left" || %quadrant $= "front_right") + %curDie = $PlayerDeathAnim::ExplosionBlowBack; + else + %curDie = $PlayerDeathAnim::TorsoBackFallForward; + } + else if(%vertPos $= "head") + { + if(%quadrant $= "front_left" || %quadrant $= "front_right" ) + %curDie = $PlayerDeathAnim::HeadFrontDirect; + else + %curDie = $PlayerDeathAnim::HeadBackFallForward; + } + else if(%vertPos $= "torso") + { + if(%quadrant $= "front_left" ) + %curDie = $PlayerDeathAnim::TorsoLeftSpinDeath; + else if(%quadrant $= "front_right") + %curDie = $PlayerDeathAnim::TorsoRightSpinDeath; + else if(%quadrant $= "back_left" ) + %curDie = $PlayerDeathAnim::TorsoBackFallForward; + else if(%quadrant $= "back_right") + %curDie = $PlayerDeathAnim::TorsoBackFallForward; + } + else if (%vertPos $= "legs") + { + if(%quadrant $= "front_left" || %quadrant $= "back_left") + %curDie = $PlayerDeathAnim::LegsLeftGimp; + if(%quadrant $= "front_right" || %quadrant $= "back_right") + %curDie = $PlayerDeathAnim::LegsRightGimp; + } + + if(%curDie $= "" || %curDie < 1 || %curDie > 11) + %curDie = 1; + + %player.setActionThread("Death" @ %curDie); +} + +function Armor::onDamage(%data, %obj) +{ + if(%obj.station !$= "" && %obj.getDamageLevel() == 0) + %obj.station.getDataBlock().endRepairing(%obj.station); +} diff --git a/scripts/practice.cs b/scripts/practice.cs index 4aed00d..5f4c037 100644 --- a/scripts/practice.cs +++ b/scripts/practice.cs @@ -1,411 +1,411 @@ -//////////////////////////////////////////////////////////////////////////////////////// -// z0dd - ZOD: PRACTICE HUD SERVER CALLS /////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// - -function serverCMDpracticeHudInitialize(%client, %val) -{ - Game.initPracticeHud(%client, %val); -} - -function serverCmdpracticeBtnCall(%client, %btn, %val) -{ - Game.practiceBtnCmd(%client, %btn, %val); -} - -function serverCmdpracticeUpdateSettings(%client, %opt, %val) -{ - // USAGE: commandToServer(%opt, %val); - // %opt is the index # of the hud option - // %val is the index # of the option setting - - Game.updatePracticeHudSet(%client, %opt, %val); -} - -function serverCmdneedPracHudUpdate(%client) -{ - Game.sendPracHudUpdate(%client, ""); -} - -function sendAllPracHudUpdate(%game, %msg) -{ - %count = ClientGroup.getCount(); - for(%i = 0; %i < %count; %i++) - { - %cl = ClientGroup.getObject(%i); - %game.sendPracHudUpdate(%cl, %msg); - } -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Practice Mode projectile and effects datablocks ////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////// - -//Mortar -datablock ExplosionData(UnderwaterObsMortarExp) : UnderwaterMortarExplosion -{ - shakeCamera = false; -}; - -datablock ExplosionData(ObsMortarExp) : MortarExplosion -{ - shakeCamera = false; -}; - -datablock GrenadeProjectileData(ObsMortarShot) : MortarShot -{ - explosion = "ObsMortarExp"; - underwaterExplosion = "UnderwaterObsMortarExp"; -}; - -//Tank Mortar -datablock GrenadeProjectileData(ObsAssaultMortar) : AssaultMortar -{ - explosion = "ObsMortarExp"; -}; - -//Missile -datablock ExplosionData(ObsMissileExp) : MissileExplosion -{ - shakeCamera = false; -}; - -datablock SeekerProjectileData(ObsShoulderMissile) : ShoulderMissile -{ - explosion = "ObsMissileExp"; -}; - -//GrandeLauncher -datablock ExplosionData(UnderwaterObsGrenadeExp) : UnderwaterGrenadeExplosion -{ - shakeCamera = false; -}; - -datablock ExplosionData(ObsGrenadeExp) : GrenadeExplosion -{ - shakeCamera = false; -}; - -datablock GrenadeProjectileData(ObsGrenade) : BasicGrenade -{ - explosion = "ObsGrenadeExp"; - underwaterExplosion = "UnderwaterObsGrenadeExp"; -}; - -//Disc -datablock ExplosionData(UnderwaterObsDiscExp) : UnderwaterDiscExplosion -{ - shakeCamera = false; -}; - -datablock ExplosionData(ObsDiscExp) : DiscExplosion -{ - shakeCamera = false; -}; - -datablock LinearProjectileData(ObsDiscProjectile) : DiscProjectile -{ - explosion = "ObsDiscExp"; - underwaterExplosion = "UnderwaterObsDiscExp"; -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// z0dd - ZOD: Practice Mode transfer pad functions and datablocks ////////////////////// -///////////////////////////////////////////////////////////////////////////////////////// - -datablock ItemData(TransferPad) -{ - className = HandInventory; - catagory = "Misc"; - shapeFile = "Nexuscap.dts"; - mass = 1; - elasticity = 0.2; - friction = 0.8; - pickupRadius = 1; - pickUpName = "a deployable transfer pad"; - computeCRC = false; -}; - -datablock StaticShapeData(DeployedTransferPad) : StaticShapeDamageProfile -{ - shapeFile = "Nexuscap.dts"; - explosion = DeployablesExplosion; - maxDamage = 100; - disabledLevel = 100; - destroyedLevel = 100; - dynamicType = $TypeMasks::SensorObjectType; - deployedObject = true; - - cmdCategory = "DSupport"; - cmdIcon = "CMDSwitchIcon"; - cmdMiniIconName = "commander/MiniIcons/com_switch_grey"; - targetNameTag = 'Deployed'; - targetTypeTag = 'transfer pad'; - - debrisShapeName = "debris_generic_small.dts"; - debris = SmallShapeDebris; -}; - -// Are max telepads deployed? -function maxSpawnPads(%obj) -{ - for( %i = 0; %i < $Host::ClassicMaxTelepads; %i++ ) - { - if(%obj.client.spawnPad[%i] $="") - return 0; - } - return 1; -} - -// Deploy a transfer telepad -function deployTransferPad(%data, %obj) -{ - if(%obj.inv[%data.getName()] <= 0) - { - return 0; - } - %eyePos = posFromTransform(%obj.getEyeTransform()); - %scEyeVec = VectorScale(VectorNormalize(%obj.getEyeVector()), 4.25); - %eyeEnd = VectorAdd(%eyePos, %scEyeVec); - %mask = $TypeMasks::TerrainObjectType | $TypeMasks::InteriorObjectType; - %searchResult = containerRayCast(%eyePos, %eyeEnd, %mask, 0); - if(!%searchResult) - { - if(%obj.inv[%data.getName()] > 0) - messageClient(%obj.client, 'MsgBeaconNoSurface', '\c2Cannot place pad. Too far from surface.'); - - return 0; - } - %test = ($TypeMasks::VehicleObjectType | $TypeMasks::MoveableObjectType | - $TypeMasks::StaticShapeObjectType | $TypeMasks::ForceFieldObjectType | - $TypeMasks::ItemObjectType | $TypeMasks::PlayerObjectType | - $TypeMasks::TurretObjectType | $TypeMasks::StaticTSObjectType); - - InitContainerRadiusSearch( %eyeEnd, 2.5, %test ); - %res = containerSearchNext(); - if(%res) - { - messageClient(%obj.client, 'MsgBeaconNoSurface', '\c2You cannot place this item so close to another object.'); - return 0; - } - else if(maxSpawnPads(%obj)) - { - messageClient(%obj.client, 'MsgDeployFailed', '\c2You do not have a vacant telepad slot.~wfx/misc/misc.error.wav'); - return 0; - } - else - { - %terrPt = posFromRaycast(%searchResult); - %terrNrm = normalFromRaycast(%searchResult); - - // getTerrainAngle() function found in staticShape.cs - %intAngle = getTerrainAngle(%terrNrm); - if(%intAngle > 30) - { - messageClient(%obj.client, 'MsgDeployFailed', '\c2Surface is too steep for this item.~wfx/misc/misc.error.wav'); - return; - } - %rotAxis = vectorNormalize(vectorCross(%terrNrm, "0 0 1")); - if (getWord(%terrNrm, 2) == 1 || getWord(%terrNrm, 2) == -1) - %rotAxis = vectorNormalize(vectorCross(%terrNrm, "0 1 0")); - - %rotation = %rotAxis @ " " @ %intAngle; - %obj.decInventory(%data, 1); - %deplObj = new StaticShape() { - dataBlock = "DeployedTransferPad"; - position = %terrPt; // VectorAdd(%terrPt, VectorScale(%terrNrm, 0.05)); - rotation = %rotation; - }; - //%deplObj.playThread($AmbientThread, "ambient"); - %deplObj.team = %obj.client.team; - %deplObj.sourceObject = %obj; - %deplObj.owner = %obj.client; - if(%deplObj.getTarget() != -1) - setTargetSensorGroup(%deplObj.getTarget(), %obj.client.team); - - MissionCleanup.add(%deplObj); - - // Stuff this transfer pad into an array so we can have multi pads. - // Help with this code provided by Founder (founder@mechina.com) - for( %i = 0; %i < $Host::ClassicMaxTelepads; %i++ ) { - if(%obj.client.spawnPad[%i] $= "") - { - %obj.client.spawnPad[%i] = %deplObj; - messageClient(%obj.client, 'MsgPracMode', '\c2Deployed Telepad: %1', %i+1); - break; - } - } - %deplObj.deploy(); - return %deplObj; - } -} - -function DeployedTransferPad::onDestroyed(%data, %obj, %prevState) -{ - for( %i = 0; %i < $Host::ClassicMaxTelepads; %i++ ) - { - if(%obj.owner.spawnPad[%i] $= %obj) - { - %obj.owner.spawnPad[%i] = ""; - break; - } - } - - %obj.schedule(800, delete); -} - -// Select telepad -function selectPad(%client) -{ - if(%client.transPad $="") - %client.transPad = 1; - else - %client.transPad = (%client.transPad % $Host::ClassicMaxTelepads) + 1; - - messageClient( %client, 'MsgPracMode', '\c2Transfer Pad selected: \c3%1', %client.transPad ); -} - -// Destroy a telepad -function destroyPad(%client) -{ - if(isObject(%client.spawnPad[%client.transPad-1])) - %client.spawnPad[%client.transPad-1].setDamageState(Destroyed); - else - messageClient(%client, 'MsgError', '\c2Transfer Pad %1 does not exist!~wfx/misc/misc.error.wav', %client.transPad); -} - -// Teleport to pad -function teleportToPad(%client) -{ - %player = %client.player; - if(!isObject(%player)) - return; - - %pad = %client.spawnPad[%client.transPad-1]; - if(isObject(%pad)) - { - if(%player.holdingFlag) - { - messageClient(%client, 'MsgError', '\c2You cannot teleport with the flag!~wfx/misc/misc.error.wav'); - %player.throwObject( %player.holdingFlag ); - } - %pos = getWord(%pad.position, 0) @ " " @ getWord(%pad.position, 1) @ " " @ (getWord(%pad.position, 2)+0.5); - %player.setTransform(%pos @ " " @ rotFromTransform(%pad.getTransform())); - %player.teleporting = 0; - - %player.setVelocity("0 0 0"); - if($PracticeCtf::SpawnFavs) - { - buyFavorites(%client); - } - %player.setDamageLevel(0); - %player.setEnergyLevel(%player.getDataBlock().maxEnergy); - %player.selectWeaponSlot( 0 ); - } - else - { - messageClient(%client, 'MsgError', '\c2Transfer Pad %1 does not exist!~wfx/misc/misc.error.wav', %client.transPad); - } -} - -// Spawn Vehicle at telepad -function spawnVehAtPad(%client, %blockname) -{ - %pad = %client.spawnPad[%client.transPad-1]; - %team = %client.getSensorGroup(); - if(isObject(%pad)) - { - // Check for obstructions above the pad - %pos = getBoxCenter(%pad.getWorldBox()); - %height = firstWord(%pos) SPC getWord(%pos, 1) SPC (getWord(%pos, 2)+30); - %mask = $TypeMasks::ShapeBaseObjectType | $TypeMasks::InteriorObjectType; - %obstruction = ContainerRayCast(%pos, %height, %mask); - if(%obstruction) - { - messageClient(%client, 'MsgError', '\c2Cannot spawn vehicle. Area above pad is blocked.'); - return; - } - if(%blockName !$="") - { - if(vehicleCheck(%blockName, %team)) - { - %pos = posFromTransform(%pad.getTransform()); - %rotation = rotFromTransform(%pad.getTransform()); - %position = vectorAdd(%pos, %blockName.spawnOffset); - - // Check for obstructions - %mask = $TypeMasks::TerrainObjectType | $TypeMasks::InteriorObjectType; - InitContainerRadiusSearch(%position, %blockName.checkRadius, %mask); - while(%found = containerSearchNext() != 0) - { - %position = vectorAdd(%position, %blockName.spawnOffset); - } - %veh = %blockName.create(%team); - if(%veh) - { - %veh.team = %team; - %veh.useCreateHeight(true); - %veh.schedule(4000, "useCreateHeight", false); - %veh.getDataBlock().isMountable(%obj, false); - %veh.getDataBlock().schedule(1000, "isMountable", %obj, true); - vehicleListAdd(%blockName, %veh); - MissionCleanup.add(%veh); - %veh.setTransform(%position @ " " @ %rotation); - - if(%client.player.lastVehicle) - { - %client.player.lastVehicle.lastPilot = ""; - vehicleAbandonTimeOut(%client.player.lastVehicle); - %client.player.lastVehicle = ""; - } - %client.player.lastVehicle = %veh; - %veh.lastPilot = %obj.player; - - if(%client.isVehicleTeleportEnabled()) - { - if(%client.player.holdingFlag) - { - messageClient(%client, 'MsgError', '\c2You cannot teleport into your vehicle with the flag!~wfx/misc/misc.error.wav'); - %client.player.throwObject( %client.player.holdingFlag ); - } - %veh.getDataBlock().schedule(3000, "mountDriver", %veh, %client.player); - } - if(%veh.getTarget() != -1) - setTargetSensorGroup(%veh.getTarget(), %client.getSensorGroup()); - } - } - else - messageClient(%client, 'MsgError', '\c2Your team\'s control network has reached its capacity for this vehicle.~wfx/misc/misc.error.wav'); - } - else - messageClient(%client, 'MsgError', '\c2Unknown vehicle type.~wfx/misc/misc.error.wav'); - } - else - messageClient(%client, 'MsgError', '\c2Transfer Pad %1 does not exist!~wfx/misc/misc.error.wav', %client.transPad); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// z0dd - ZOD: Practice Mission types Console Spam fixes //////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////// - -function DefaultGame::initPracticeHud(%game, %client, %val) -{ - commandToClient(%client, 'initializePracHud', "Default"); - commandToClient(%client, 'practiceHudHead', "CTF Practice Config", "Server Settings", "Player Settings", "Projectile Observation", "Telepad Options", "Spawn Vehicle at Pad"); - commandToClient(%client, 'practiceHudPopulate', "Disabled", "Empty"); - commandToClient(%client, 'practiceHudDone'); -} - -function DefaultGame::practiceBtnCmd(%game, %client, %btn, %val) -{ - // Do nothing -} - -function DefaultGame::updatePracticeHudSet(%game, %client, %opt, %val) -{ - // Do nothing -} - -function DefaultGame::sendPracHudUpdate(%game, %client) -{ - // Do nothing -} +//////////////////////////////////////////////////////////////////////////////////////// +// z0dd - ZOD: PRACTICE HUD SERVER CALLS /////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////// + +function serverCMDpracticeHudInitialize(%client, %val) +{ + Game.initPracticeHud(%client, %val); +} + +function serverCmdpracticeBtnCall(%client, %btn, %val) +{ + Game.practiceBtnCmd(%client, %btn, %val); +} + +function serverCmdpracticeUpdateSettings(%client, %opt, %val) +{ + // USAGE: commandToServer(%opt, %val); + // %opt is the index # of the hud option + // %val is the index # of the option setting + + Game.updatePracticeHudSet(%client, %opt, %val); +} + +function serverCmdneedPracHudUpdate(%client) +{ + Game.sendPracHudUpdate(%client, ""); +} + +function sendAllPracHudUpdate(%game, %msg) +{ + %count = ClientGroup.getCount(); + for(%i = 0; %i < %count; %i++) + { + %cl = ClientGroup.getObject(%i); + %game.sendPracHudUpdate(%cl, %msg); + } +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Practice Mode projectile and effects datablocks ////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// + +//Mortar +datablock ExplosionData(UnderwaterObsMortarExp) : UnderwaterMortarExplosion +{ + shakeCamera = false; +}; + +datablock ExplosionData(ObsMortarExp) : MortarExplosion +{ + shakeCamera = false; +}; + +datablock GrenadeProjectileData(ObsMortarShot) : MortarShot +{ + explosion = "ObsMortarExp"; + underwaterExplosion = "UnderwaterObsMortarExp"; +}; + +//Tank Mortar +datablock GrenadeProjectileData(ObsAssaultMortar) : AssaultMortar +{ + explosion = "ObsMortarExp"; +}; + +//Missile +datablock ExplosionData(ObsMissileExp) : MissileExplosion +{ + shakeCamera = false; +}; + +datablock SeekerProjectileData(ObsShoulderMissile) : ShoulderMissile +{ + explosion = "ObsMissileExp"; +}; + +//GrandeLauncher +datablock ExplosionData(UnderwaterObsGrenadeExp) : UnderwaterGrenadeExplosion +{ + shakeCamera = false; +}; + +datablock ExplosionData(ObsGrenadeExp) : GrenadeExplosion +{ + shakeCamera = false; +}; + +datablock GrenadeProjectileData(ObsGrenade) : BasicGrenade +{ + explosion = "ObsGrenadeExp"; + underwaterExplosion = "UnderwaterObsGrenadeExp"; +}; + +//Disc +datablock ExplosionData(UnderwaterObsDiscExp) : UnderwaterDiscExplosion +{ + shakeCamera = false; +}; + +datablock ExplosionData(ObsDiscExp) : DiscExplosion +{ + shakeCamera = false; +}; + +datablock LinearProjectileData(ObsDiscProjectile) : DiscProjectile +{ + explosion = "ObsDiscExp"; + underwaterExplosion = "UnderwaterObsDiscExp"; +}; + +///////////////////////////////////////////////////////////////////////////////////////// +// z0dd - ZOD: Practice Mode transfer pad functions and datablocks ////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// + +datablock ItemData(TransferPad) +{ + className = HandInventory; + catagory = "Misc"; + shapeFile = "Nexuscap.dts"; + mass = 1; + elasticity = 0.2; + friction = 0.8; + pickupRadius = 1; + pickUpName = "a deployable transfer pad"; + computeCRC = false; +}; + +datablock StaticShapeData(DeployedTransferPad) : StaticShapeDamageProfile +{ + shapeFile = "Nexuscap.dts"; + explosion = DeployablesExplosion; + maxDamage = 100; + disabledLevel = 100; + destroyedLevel = 100; + dynamicType = $TypeMasks::SensorObjectType; + deployedObject = true; + + cmdCategory = "DSupport"; + cmdIcon = "CMDSwitchIcon"; + cmdMiniIconName = "commander/MiniIcons/com_switch_grey"; + targetNameTag = 'Deployed'; + targetTypeTag = 'transfer pad'; + + debrisShapeName = "debris_generic_small.dts"; + debris = SmallShapeDebris; +}; + +// Are max telepads deployed? +function maxSpawnPads(%obj) +{ + for( %i = 0; %i < $Host::ClassicMaxTelepads; %i++ ) + { + if(%obj.client.spawnPad[%i] $="") + return 0; + } + return 1; +} + +// Deploy a transfer telepad +function deployTransferPad(%data, %obj) +{ + if(%obj.inv[%data.getName()] <= 0) + { + return 0; + } + %eyePos = posFromTransform(%obj.getEyeTransform()); + %scEyeVec = VectorScale(VectorNormalize(%obj.getEyeVector()), 4.25); + %eyeEnd = VectorAdd(%eyePos, %scEyeVec); + %mask = $TypeMasks::TerrainObjectType | $TypeMasks::InteriorObjectType; + %searchResult = containerRayCast(%eyePos, %eyeEnd, %mask, 0); + if(!%searchResult) + { + if(%obj.inv[%data.getName()] > 0) + messageClient(%obj.client, 'MsgBeaconNoSurface', '\c2Cannot place pad. Too far from surface.'); + + return 0; + } + %test = ($TypeMasks::VehicleObjectType | $TypeMasks::MoveableObjectType | + $TypeMasks::StaticShapeObjectType | $TypeMasks::ForceFieldObjectType | + $TypeMasks::ItemObjectType | $TypeMasks::PlayerObjectType | + $TypeMasks::TurretObjectType | $TypeMasks::StaticTSObjectType); + + InitContainerRadiusSearch( %eyeEnd, 2.5, %test ); + %res = containerSearchNext(); + if(%res) + { + messageClient(%obj.client, 'MsgBeaconNoSurface', '\c2You cannot place this item so close to another object.'); + return 0; + } + else if(maxSpawnPads(%obj)) + { + messageClient(%obj.client, 'MsgDeployFailed', '\c2You do not have a vacant telepad slot.~wfx/misc/misc.error.wav'); + return 0; + } + else + { + %terrPt = posFromRaycast(%searchResult); + %terrNrm = normalFromRaycast(%searchResult); + + // getTerrainAngle() function found in staticShape.cs + %intAngle = getTerrainAngle(%terrNrm); + if(%intAngle > 30) + { + messageClient(%obj.client, 'MsgDeployFailed', '\c2Surface is too steep for this item.~wfx/misc/misc.error.wav'); + return; + } + %rotAxis = vectorNormalize(vectorCross(%terrNrm, "0 0 1")); + if (getWord(%terrNrm, 2) == 1 || getWord(%terrNrm, 2) == -1) + %rotAxis = vectorNormalize(vectorCross(%terrNrm, "0 1 0")); + + %rotation = %rotAxis @ " " @ %intAngle; + %obj.decInventory(%data, 1); + %deplObj = new StaticShape() { + dataBlock = "DeployedTransferPad"; + position = %terrPt; // VectorAdd(%terrPt, VectorScale(%terrNrm, 0.05)); + rotation = %rotation; + }; + //%deplObj.playThread($AmbientThread, "ambient"); + %deplObj.team = %obj.client.team; + %deplObj.sourceObject = %obj; + %deplObj.owner = %obj.client; + if(%deplObj.getTarget() != -1) + setTargetSensorGroup(%deplObj.getTarget(), %obj.client.team); + + MissionCleanup.add(%deplObj); + + // Stuff this transfer pad into an array so we can have multi pads. + // Help with this code provided by Founder (founder@mechina.com) + for( %i = 0; %i < $Host::ClassicMaxTelepads; %i++ ) { + if(%obj.client.spawnPad[%i] $= "") + { + %obj.client.spawnPad[%i] = %deplObj; + messageClient(%obj.client, 'MsgPracMode', '\c2Deployed Telepad: %1', %i+1); + break; + } + } + %deplObj.deploy(); + return %deplObj; + } +} + +function DeployedTransferPad::onDestroyed(%data, %obj, %prevState) +{ + for( %i = 0; %i < $Host::ClassicMaxTelepads; %i++ ) + { + if(%obj.owner.spawnPad[%i] $= %obj) + { + %obj.owner.spawnPad[%i] = ""; + break; + } + } + + %obj.schedule(800, delete); +} + +// Select telepad +function selectPad(%client) +{ + if(%client.transPad $="") + %client.transPad = 1; + else + %client.transPad = (%client.transPad % $Host::ClassicMaxTelepads) + 1; + + messageClient( %client, 'MsgPracMode', '\c2Transfer Pad selected: \c3%1', %client.transPad ); +} + +// Destroy a telepad +function destroyPad(%client) +{ + if(isObject(%client.spawnPad[%client.transPad-1])) + %client.spawnPad[%client.transPad-1].setDamageState(Destroyed); + else + messageClient(%client, 'MsgError', '\c2Transfer Pad %1 does not exist!~wfx/misc/misc.error.wav', %client.transPad); +} + +// Teleport to pad +function teleportToPad(%client) +{ + %player = %client.player; + if(!isObject(%player)) + return; + + %pad = %client.spawnPad[%client.transPad-1]; + if(isObject(%pad)) + { + if(%player.holdingFlag) + { + messageClient(%client, 'MsgError', '\c2You cannot teleport with the flag!~wfx/misc/misc.error.wav'); + %player.throwObject( %player.holdingFlag ); + } + %pos = getWord(%pad.position, 0) @ " " @ getWord(%pad.position, 1) @ " " @ (getWord(%pad.position, 2)+0.5); + %player.setTransform(%pos @ " " @ rotFromTransform(%pad.getTransform())); + %player.teleporting = 0; + + %player.setVelocity("0 0 0"); + if($PracticeCtf::SpawnFavs) + { + buyFavorites(%client); + } + %player.setDamageLevel(0); + %player.setEnergyLevel(%player.getDataBlock().maxEnergy); + %player.selectWeaponSlot( 0 ); + } + else + { + messageClient(%client, 'MsgError', '\c2Transfer Pad %1 does not exist!~wfx/misc/misc.error.wav', %client.transPad); + } +} + +// Spawn Vehicle at telepad +function spawnVehAtPad(%client, %blockname) +{ + %pad = %client.spawnPad[%client.transPad-1]; + %team = %client.getSensorGroup(); + if(isObject(%pad)) + { + // Check for obstructions above the pad + %pos = getBoxCenter(%pad.getWorldBox()); + %height = firstWord(%pos) SPC getWord(%pos, 1) SPC (getWord(%pos, 2)+30); + %mask = $TypeMasks::ShapeBaseObjectType | $TypeMasks::InteriorObjectType; + %obstruction = ContainerRayCast(%pos, %height, %mask); + if(%obstruction) + { + messageClient(%client, 'MsgError', '\c2Cannot spawn vehicle. Area above pad is blocked.'); + return; + } + if(%blockName !$="") + { + if(vehicleCheck(%blockName, %team)) + { + %pos = posFromTransform(%pad.getTransform()); + %rotation = rotFromTransform(%pad.getTransform()); + %position = vectorAdd(%pos, %blockName.spawnOffset); + + // Check for obstructions + %mask = $TypeMasks::TerrainObjectType | $TypeMasks::InteriorObjectType; + InitContainerRadiusSearch(%position, %blockName.checkRadius, %mask); + while(%found = containerSearchNext() != 0) + { + %position = vectorAdd(%position, %blockName.spawnOffset); + } + %veh = %blockName.create(%team); + if(%veh) + { + %veh.team = %team; + %veh.useCreateHeight(true); + %veh.schedule(4000, "useCreateHeight", false); + %veh.getDataBlock().isMountable(%obj, false); + %veh.getDataBlock().schedule(1000, "isMountable", %obj, true); + vehicleListAdd(%blockName, %veh); + MissionCleanup.add(%veh); + %veh.setTransform(%position @ " " @ %rotation); + + if(%client.player.lastVehicle) + { + %client.player.lastVehicle.lastPilot = ""; + vehicleAbandonTimeOut(%client.player.lastVehicle); + %client.player.lastVehicle = ""; + } + %client.player.lastVehicle = %veh; + %veh.lastPilot = %obj.player; + + if(%client.isVehicleTeleportEnabled()) + { + if(%client.player.holdingFlag) + { + messageClient(%client, 'MsgError', '\c2You cannot teleport into your vehicle with the flag!~wfx/misc/misc.error.wav'); + %client.player.throwObject( %client.player.holdingFlag ); + } + %veh.getDataBlock().schedule(3000, "mountDriver", %veh, %client.player); + } + if(%veh.getTarget() != -1) + setTargetSensorGroup(%veh.getTarget(), %client.getSensorGroup()); + } + } + else + messageClient(%client, 'MsgError', '\c2Your team\'s control network has reached its capacity for this vehicle.~wfx/misc/misc.error.wav'); + } + else + messageClient(%client, 'MsgError', '\c2Unknown vehicle type.~wfx/misc/misc.error.wav'); + } + else + messageClient(%client, 'MsgError', '\c2Transfer Pad %1 does not exist!~wfx/misc/misc.error.wav', %client.transPad); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// z0dd - ZOD: Practice Mission types Console Spam fixes //////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// + +function DefaultGame::initPracticeHud(%game, %client, %val) +{ + commandToClient(%client, 'initializePracHud', "Default"); + commandToClient(%client, 'practiceHudHead', "CTF Practice Config", "Server Settings", "Player Settings", "Projectile Observation", "Telepad Options", "Spawn Vehicle at Pad"); + commandToClient(%client, 'practiceHudPopulate', "Disabled", "Empty"); + commandToClient(%client, 'practiceHudDone'); +} + +function DefaultGame::practiceBtnCmd(%game, %client, %btn, %val) +{ + // Do nothing +} + +function DefaultGame::updatePracticeHudSet(%game, %client, %opt, %val) +{ + // Do nothing +} + +function DefaultGame::sendPracHudUpdate(%game, %client) +{ + // Do nothing +} diff --git a/scripts/projectiles.cs b/scripts/projectiles.cs index 35bb491..1014ae1 100644 --- a/scripts/projectiles.cs +++ b/scripts/projectiles.cs @@ -1,759 +1,759 @@ -//-------------------------------------------------------------------------- -// Projectiles.cs: Note that the actual projectile blocks are stored with -// with weapon that uses them in base/scripts/weapons/*.cs, -// the blocks below are only to illustrate the default values -// for each block type. Also, ProjectileData cannot be used -// as a concrete datablock type. -// Inheritance: -// ProjectileData : GameBaseData -// LinearProjectileData : ProjectileData -// LinearFlareProjectileData : LinearProjectileData -// GrenadeProjectileData : ProjectileData -// SeekerProjectileData : ProjectileData -// SniperProjectileData : ProjectileData -// -//-------------------------------------------------------------------------- -//-------------------------------------- Default functions -// -function ProjectileData::onCollision(%data, %projectile, %targetObject, %modifier, %position, %normal) -{ - if(isObject(%targetObject)) // z0dd - ZOD, 4/24/02. Console spam fix. - { - if (%data.getname() $="FlameboltMain") - { - burnloop(%targetobject,%projectile.sourceObject, %data.directDamage * %modifier, %data.directDamageType); - - //Look for anything within range to light. - InitContainerRadiusSearch(%projectile.getposition(),3,$TypeMasks::PlayerObjectType); - - while ((%potentialTarget = ContainerSearchNext()) != 0) - { - if (%potentialTarget.getclassname() $="player" && %potentialTarget.getstate() !$="dead" && %potentialTarget.client != %projectile.sourceclient) - { - burnloop(%potentialTarget,%projectile.sourceObject, %data.directDamage * %modifier, %data.directDamageType); - - } - } - } -} - -//We hit something directly or indirectly, either way, it's a hit. -if ($CurrentMissionType !$= "RPG" && %targetObject.team != %projectile.sourceObject.client.team && isObject(%projectile.sourceObject.client)) -$Data::Hits[%projectile.sourceObject.client.guid]++; -%targetObject.damage(%projectile.sourceObject, %position, %data.directDamage * %modifier, %data.directDamageType); -} - -function SniperProjectileData::onCollision(%data, %projectile, %targetObject, %modifier, %position, %normal) -{ - %damageAmount = %data.directDamage * %projectile.damageFactor; - - if(isObject(%targetObject)) // z0dd - ZOD, 4/24/02. Console spam fix. - { - if(%targetObject.getDataBlock().getClassName() $= "PlayerData") - { - %damLoc = firstWord(%targetObject.getDamageLocation(%position)); - if(%damLoc $= "head") - { - %targetObject.getOwnerClient().headShot = 1; - %modifier = %data.rifleHeadMultiplier; - } - else - { - %modifier = 1; - %targetObject.getOwnerClient().headShot = 0; - } - } - %targetObject.damage(%projectile.sourceObject, %position, %modifier * %damageAmount, %data.directDamageType); - } -} - -// ------------------------------------------------------- -// z0dd - ZOD, 9/3/02. Anti rapid fire mortar/missile fix. -function resetFire(%obj,%bool) -{ - cancel(%obj.reloadSchedule); - %obj.cantFire = ""; -} -// ------------------------------------------------------- - -function ShapeBaseImageData::onFire(%data, %obj, %slot) -{ - // --------------------------------------------------------------------------- - // z0dd - ZOD, 9/3/02. Anti rapid fire mortar/missile fix. - if (%obj.cantFire !$= "") - { - return 0; - } - - - %wpnName = %data.getName(); - if((%wpnName $= "MortarImage") || (%wpnName $= "MissileLauncherImage")) - { - %obj.cantFire = 1; - %preventTime = %data.stateTimeoutValue[4]; - %obj.reloadSchedule = schedule(%preventTime * 1000, %obj, resetFire, %obj); - } - // --------------------------------------------------------------------------- - - %data.lightStart = getSimTime(); - - if( %obj.station $= "" && %obj.isCloaked() ) - { - if( %obj.respawnCloakThread !$= "" ) - { - Cancel(%obj.respawnCloakThread); - %obj.setCloaked( false ); - %obj.respawnCloakThread = ""; - } - else - { - if( %obj.getEnergyLevel() > 20 ) - { - %obj.setCloaked( false ); - %obj.reCloak = %obj.schedule( 500, "setCloaked", true ); - } - } - } - - if( %obj.client > 0 ) - { - %obj.setInvincibleMode(0 ,0.00); - %obj.setInvincible( false ); // fire your weapon and your invincibility goes away. - } - - %vehicle = 0; - if(%data.usesEnergy) - { - if(%data.useMountEnergy) - { - %useEnergyObj = %obj.getObjectMount(); - if(!%useEnergyObj) - %useEnergyObj = %obj; - %energy = %useEnergyObj.getEnergyLevel(); - %vehicle = %useEnergyObj; - } - else - %energy = %obj.getEnergyLevel(); - - if(%data.useCapacitor && %data.usesEnergy) - { - if( %useEnergyObj.turretObject.getCapacitorLevel() < %data.minEnergy ) - { - return; - } - } - else if(%energy < %data.minEnergy) - return; - } - // --------------------------------------------------------------------- - // z0dd - ZOD, 4/24/02. Code optimization - if(%data.projectileSpread) - { - %vec = %obj.getMuzzleVector(%slot); - %x = (getRandom() - 0.5) * 2 * 3.1415926 * %data.projectileSpread; - %y = (getRandom() - 0.5) * 2 * 3.1415926 * %data.projectileSpread; - %z = (getRandom() - 0.5) * 2 * 3.1415926 * %data.projectileSpread; - %mat = MatrixCreateFromEuler(%x @ " " @ %y @ " " @ %z); - %vector = MatrixMulVector(%mat, %vec); - } - else - { - %vector = %obj.getMuzzleVector(%slot); - } - - %p = new (%data.projectileType)() { - dataBlock = %data.projectile; - initialDirection = %vector; - initialPosition = %obj.getMuzzlePoint(%slot); - sourceObject = %obj; - sourceSlot = %slot; - vehicleObject = %vehicle; - }; - // End streamlining - // --------------------------------------------------------------------- - if (isObject(%obj.lastProjectile) && %obj.deleteLastProjectile) - %obj.lastProjectile.delete(); - - %obj.lastProjectile = %p; - %obj.deleteLastProjectile = %data.deleteLastProjectile; - MissionCleanup.add(%p); - - // AI hook - if(%obj.client) - %obj.client.projectile = %p; - - if(%data.usesEnergy) - { - if(%data.useMountEnergy) - { - if( %data.useCapacitor ) - { - %vehicle.turretObject.setCapacitorLevel( %vehicle.turretObject.getCapacitorLevel() - %data.fireEnergy ); - } - else - %useEnergyObj.setEnergyLevel(%energy - %data.fireEnergy); - } - else - %obj.setEnergyLevel(%energy - %data.fireEnergy); - } - else - %obj.decInventory(%data.ammo,1); - - //Ok, we fired. Increase my total number of weapon fires if this not an RPG gamemode - if ($CurrentMissionType !$= "RPG") - $Data::Shots[%obj.client.guid]++; - - return %p; -} - -function ShapeBaseImageData::onUnmount(%data, %obj, %slot) -{ - if (%data.deleteLastProjectile && isObject(%obj.lastProjectile)) - { - %obj.lastProjectile.delete(); - %obj.lastProjectile = ""; - } -} - -function TurretImageData::deconstruct(%data, %obj, %slot) -{ - if (%data.deleteLastProjectile && isObject(%obj.lastProjectile)) - { - %obj.lastProjectile.delete(); - %obj.lastProjectile = ""; - } -} - -function ShapeBaseImageData::deconstruct(%data, %obj, %slot) -{ - if (%data.deleteLastProjectile && isObject(%obj.lastProjectile)) - { - %obj.lastProjectile.delete(); - %obj.lastProjectile = ""; - } -} - -function MissileLauncherImage::onFire(%data,%obj,%slot) -{ - %p = Parent::onFire(%data, %obj, %slot); - - //-------------------------------------------------------- - // z0dd - ZOD, 9/3/02. Anti rapid fire mortar/missile fix. - if(!%p) - { - return; - } - //-------------------------------------------------------- - - MissileSet.add(%p); - - %target = %obj.getLockedTarget(); - if(%target) - %p.setObjectTarget(%target); - else if(%obj.isLocked()) - %p.setPositionTarget(%obj.getLockedPosition()); - else - %p.setNoTarget(); -} - -function MissileLauncherImage::onWetFire(%data, %obj, %slot) -{ - %p = Parent::onFire(%data, %obj, %slot); - - //-------------------------------------------------------- - // z0dd - ZOD, 9/3/02. Anti rapid fire mortar/missile fix. - if(!%p) - { - return; - } - //-------------------------------------------------------- - - MissileSet.add(%p); - - %p.setObjectTarget(0); -} - -//-------------------------------------------------------------------------- - -function MissileBarrelLarge::onFire(%data,%obj,%slot) -{ - %p = Parent::onFire(%data,%obj,%slot); - - //-------------------------------------------------------- - // z0dd - ZOD, 9/3/02. Anti rapid fire mortar/missile fix. - if(!%p) - { - return; - } - //-------------------------------------------------------- - - if (%obj.getControllingClient()) - { - // a player is controlling the turret - %target = %obj.getLockedTarget(); - } - else - { - // The ai is controlling the turret - %target = %obj.getTargetObject(); - } - - if(%target) - %p.setObjectTarget(%target); - else if(%obj.isLocked()) - %p.setPositionTarget(%obj.getLockedPosition()); - else - %p.setNoTarget(); // set as unguided. Only happens when itchy trigger can't wait for lock tone. -} - -//add mortars to the "grenade set" so the AI's can avoid them better... -function MortarImage::onFire(%data,%obj,%slot) -{ - %p = Parent::onFire(%data, %obj, %slot); - - //-------------------------------------------------------- - // z0dd - ZOD, 9/3/02. Anti rapid fire mortar/missile fix. - if(!%p) - { - return; - } - //-------------------------------------------------------- - - AIGrenadeThrown(%p); -} - -function SniperRifleImage::onFire(%data,%obj,%slot) -{ - if(!%obj.hasEnergyPack) - { - // siddown Junior, you can't use it - serverPlay3D(SniperRifleDryFireSound, %obj.getTransform()); - return; - } - %pct = %obj.getEnergyLevel() / %obj.getDataBlock().maxEnergy; - %p = new (%data.projectileType)() { - dataBlock = %data.projectile; - initialDirection = %obj.getMuzzleVector(%slot); - initialPosition = %obj.getMuzzlePoint(%slot); - sourceObject = %obj; - damageFactor = %pct * %pct; - sourceSlot = %slot; - }; - %p.setEnergyPercentage(%pct); - - %obj.lastProjectile = %p; - MissionCleanup.add(%p); - serverPlay3D(SniperRifleFireSound, %obj.getTransform()); - - // AI hook - if(%obj.client) - %obj.client.projectile = %p; - - %obj.setEnergyLevel(0); -} - -function ElfGunImage::onFire(%data, %obj, %slot) -{ - %p = Parent::onFire(%data, %obj, %slot); - - //-------------------------------------------------------- - // z0dd - ZOD, 9/3/02. Anti rapid fire mortar/missile fix. - if(!%p) - { - return; - } - //-------------------------------------------------------- - - if(!%p.hasTarget()) - %obj.playAudio(0, ELFFireWetSound); -} - -function TargetingLaserImage::onFire(%data,%obj,%slot) -{ - %p = Parent::onFire(%data, %obj, %slot); - - //-------------------------------------------------------- - // z0dd - ZOD, 9/3/02. Anti rapid fire mortar/missile fix. - if(!%p) - { - return; - } - //-------------------------------------------------------- - - %p.setTarget(%obj.team); -} - -function ShockLanceImage::onFire(%this, %obj, %slot) -{ - if( %obj.isCloaked() ) - { - if( %obj.respawnCloakThread !$= "" ) - { - Cancel(%obj.respawnCloakThread); - %obj.setCloaked( false ); - } - else - { - if( %obj.getEnergyLevel() > 20 ) - { - %obj.setCloaked( false ); - %obj.reCloak = %obj.schedule( 500, "setCloaked", true ); - } - } - } - - %muzzlePos = %obj.getMuzzlePoint(%slot); - %muzzleVec = %obj.getMuzzleVector(%slot); - - %endPos = VectorAdd(%muzzlePos, VectorScale(%muzzleVec, %this.projectile.extension)); - - %damageMasks = $TypeMasks::PlayerObjectType | $TypeMasks::VehicleObjectType | - $TypeMasks::StationObjectType | $TypeMasks::GeneratorObjectType | - $TypeMasks::SensorObjectType | $TypeMasks::TurretObjectType; - - %everythingElseMask = $TypeMasks::TerrainObjectType | - $TypeMasks::InteriorObjectType | - $TypeMasks::ForceFieldObjectType | - $TypeMasks::StaticObjectType | - $TypeMasks::MoveableObjectType | - $TypeMasks::DamagableItemObjectType; - - // did I miss anything? players, vehicles, stations, gens, sensors, turrets - %hit = ContainerRayCast(%muzzlePos, %endPos, %damageMasks | %everythingElseMask, %obj); - - %noDisplay = true; - - if (%hit !$= "0") - { - %obj.setEnergyLevel(%obj.getEnergyLevel() - %this.hitEnergy); - - %hitobj = getWord(%hit, 0); - %hitpos = getWord(%hit, 1) @ " " @ getWord(%hit, 2) @ " " @ getWord(%hit, 3); - - if ( %hitObj.getType() & %damageMasks ) - { - %hitobj.applyImpulse(%hitpos, VectorScale(%muzzleVec, %this.projectile.impulse)); - %obj.playAudio(0, ShockLanceHitSound); - - // This is truly lame, but we need the sourceobject property present... - %p = new ShockLanceProjectile() { - dataBlock = %this.projectile; - initialDirection = %obj.getMuzzleVector(%slot); - initialPosition = %obj.getMuzzlePoint(%slot); - sourceObject = %obj; - sourceSlot = %slot; - targetId = %hit; - }; - MissionCleanup.add(%p); - - %damageMultiplier = 1.0; - - if(%hitObj.getDataBlock().getClassName() $= "PlayerData") - { - // Now we see if we hit from behind... - %forwardVec = %hitobj.getForwardVector(); - %objDir2D = getWord(%forwardVec, 0) @ " " @ getWord(%forwardVec,1) @ " " @ "0.0"; - %objPos = %hitObj.getPosition(); - %dif = VectorSub(%objPos, %muzzlePos); - %dif = getWord(%dif, 0) @ " " @ getWord(%dif, 1) @ " 0"; - %dif = VectorNormalize(%dif); - %dot = VectorDot(%dif, %objDir2D); - - // 120 Deg angle test... - // 1.05 == 60 degrees in radians - if (%dot >= mCos(1.05)) - { - // Rear hit - %damageMultiplier = 3.0; - %hitObj.getOwnerClient().rearshot = 1; // z0dd - ZOD, 8/25/02. Added Lance rear shot messages - } - // -------------------------------------------------------------- - // z0dd - ZOD, 8/25/02. Added Lance rear shot messages - else - { - %hitObj.getOwnerClient().rearshot = 0; - } - // -------------------------------------------------------------- - } - - %totalDamage = %this.Projectile.DirectDamage * %damageMultiplier; - %hitObj.getDataBlock().damageObject(%hitobj, %p.sourceObject, %hitpos, %totalDamage, $DamageType::ShockLance); - - %noDisplay = false; - } - } - - if( %noDisplay ) - { - // Miss - %obj.setEnergyLevel(%obj.getEnergyLevel() - %this.missEnergy); - %obj.playAudio(0, ShockLanceMissSound); - - %p = new ShockLanceProjectile() { - dataBlock = %this.projectile; - initialDirection = %obj.getMuzzleVector(%slot); - initialPosition = %obj.getMuzzlePoint(%slot); - sourceObject = %obj; - sourceSlot = %slot; - }; - MissionCleanup.add(%p); - - } -} - -$ELFZapSound = 2; -$ELFFireSound = 3; - -function ELFProjectileData::zapTarget(%data, %projectile, %target, %targeter) -{ - %oldERate = %target.getRechargeRate(); - %target.teamDamageStateOnZap = $teamDamage; - %teammates = %target.client.team == %targeter.client.team; - - if( %target.teamDamageStateOnZap || !%teammates ) - %target.setRechargeRate(%oldERate - %data.drainEnergy); - else - %target.setRechargeRate(%oldERate); - - %projectile.checkELFStatus(%data, %target, %targeter); -} - -function ELFProjectileData::unzapTarget(%data, %projectile, %target, %targeter) -{ - cancel(%projectile.ELFrecur); - %target.stopAudio($ELFZapSound); - %targeter.stopAudio($ELFFireSound); - %target.zapSound = false; - %targeter.zappingSound = false; - %teammates = %target.client.team == %targeter.client.team; - - if(!%target.isDestroyed()) - { - %oldERate = %target.getRechargeRate(); - if( %target.teamDamageStateOnZap || !%teammates ) - %target.setRechargeRate(%oldERate + %data.drainEnergy); - else - %target.setRechargeRate(%oldERate); - } -} - -function ELFProjectileData::targetDestroyedCancel(%data, %projectile, %target, %targeter) -{ - cancel(%projectile.ELFrecur); - %target.stopAudio($ELFZapSound); - %targeter.stopAudio($ELFFireSound); - %target.zapSound = false; - %targeter.zappingSound = false; - %projectile.delete(); -} - -function ELFProjectile::checkELFStatus(%this, %data, %target, %targeter) -{ - if(isObject(%target)) - { - if(%target.getDamageState() $= "Destroyed") - { - %data.targetDestroyedCancel(%this, %target, %targeter); - return; - } - - %enLevel = %target.getEnergyLevel(); - if(%enLevel < 1.0) - { - %dataBlock = %target.getDataBlock(); - %dataBlock.damageObject(%target, %this.sourceObject, %target.getPosition(), %data.drainHealth, %data.directDamageType); - - } - else - { - %normal = "0.0 0.0 1.0"; - %target.playShieldEffect( %normal ); - } - %this.ELFrecur = %this.schedule(32, checkELFStatus, %data, %target, %targeter); - - %targeter.playAudio($ELFFireSound, ELFGunFireSound); - if(!%target.zapSound) - { - %target.playAudio($ELFZapSound, ELFHitTargetSound); - %target.zapSound = true; - %targeter.zappingSound = true; - } - } - // ------------------------------------------------------- - // z0dd - ZOD, 5/27/02. Stop firing if there is no target, - // fixes continuous fire bug. - //else if(%targeter.zappingSound) - //{ - // %targeter.stopAudio($ELFFireSound); - // %targeter.zappingSound = false; - //} - else - { - if(%targeter.zappingSound) - { - %targeter.stopAudio($ELFFireSound); - %targeter.zappingSound = false; - } - %data.targetDestroyedCancel(%this, %target, %targeter); - return; - } - // End z0dd - ZOD - // ------------------------------------------------------- -} - -function RadiusExplosion(%explosionSource, %position, %radius, %damage, %impulse, %sourceObject, %damageType) -{ - InitContainerRadiusSearch(%position, %radius, $TypeMasks::PlayerObjectType | - $TypeMasks::VehicleObjectType | - $TypeMasks::StaticShapeObjectType | - $TypeMasks::TurretObjectType | - $TypeMasks::ItemObjectType); - - %numTargets = 0; - while ((%targetObject = containerSearchNext()) != 0) - { - %dist = containerSearchCurrRadDamageDist(); - - if (%dist > %radius) - continue; - - if (%targetObject.isMounted()) - { - %mount = %targetObject.getObjectMount(); - %found = -1; - for (%i = 0; %i < %mount.getDataBlock().numMountPoints; %i++) - { - if (%mount.getMountNodeObject(%i) == %targetObject) - { - %found = %i; - break; - } - } - - if (%found != -1) - { - if (%mount.getDataBlock().isProtectedMountPoint[%found]) - { - continue; - } - } - } - - %targets[%numTargets] = %targetObject; - %targetDists[%numTargets] = %dist; - %numTargets++; - } - - for (%i = 0; %i < %numTargets; %i++) - { - %targetObject = %targets[%i]; - %dist = %targetDists[%i]; - - %coverage = calcExplosionCoverage(%position, %targetObject, - ($TypeMasks::InteriorObjectType | - $TypeMasks::TerrainObjectType | - $TypeMasks::ForceFieldObjectType | - $TypeMasks::VehicleObjectType)); - if (%coverage == 0) - continue; - - //if ( $splashTest ) - %amount = (1.0 - ((%dist / %radius) * 0.88)) * %coverage * %damage; - //else - //%amount = (1.0 - (%dist / %radius)) * %coverage * %damage; - - //error( "damage: " @ %amount @ " at distance: " @ %dist @ " radius: " @ %radius @ " maxDamage: " @ %damage ); - - %data = %targetObject.getDataBlock(); - %className = %data.className; - - if (%impulse && %data.shouldApplyImpulse(%targetObject)) - { - %p = %targetObject.getWorldBoxCenter(); - %momVec = VectorSub(%p, %position); - %momVec = VectorNormalize(%momVec); - - //------------------------------------------------------------------------------ - // z0dd - ZOD, 7/08/02. More kick when player damages self with disc or mortar. - // Stronger DJs and mortar jumps without impacting others (mainly HoFs) - if(%sourceObject == %targetObject) - { - if (%damageType == $DamageType::Disc) - { - %impulse = 4475; - } - else if (%damageType == $DamageType::Mortar) - { - %impulse = 5750; - } - } - //------------------------------------------------------------------------------ - - %impulseVec = VectorScale(%momVec, %impulse * (1.0 - (%dist / %radius))); - %doImpulse = true; - } - else if( %className $= FlyingVehicleData || %className $= HoverVehicleData ) // Removed WheeledVehicleData. z0dd - ZOD, 4/24/02. Do not allow impulse applied to MPB, conc MPB bug fix. - { - %p = %targetObject.getWorldBoxCenter(); - %momVec = VectorSub(%p, %position); - %momVec = VectorNormalize(%momVec); - - %impulseVec = VectorScale(%momVec, %impulse * (1.0 - (%dist / %radius))); - - if( getWord( %momVec, 2 ) < -0.5 ) - %momVec = "0 0 1"; - - // Add obj's velocity into the momentum vector - %velocity = %targetObject.getVelocity(); - //%momVec = VectorNormalize( vectorAdd( %momVec, %velocity) ); - %doImpulse = true; - } - else - { - %momVec = "0 0 1"; - %doImpulse = false; - } - - if(%amount > 0) - %data.damageObject(%targetObject, %sourceObject, %position, %amount, %damageType, %momVec, %explosionSource.theClient, %explosionSource); - else if( %explosionSource.getDataBlock().getName() $= "ConcussionGrenadeThrown" && %data.getClassName() $= "PlayerData" ) - { - %data.applyConcussion( %dist, %radius, %sourceObject, %targetObject ); - - if(!$teamDamage && %sourceObject != %targetObject && %sourceObject.client.team == %targetObject.client.team) - { - messageClient(%targetObject.client, 'msgTeamConcussionGrenade', '\c1You were hit by %1\'s concussion grenade.', getTaggedString(%sourceObject.client.name)); - } - } - - //------------------------------------------------------------------------------- - // z0dd - ZOD, 4/16/02. Tone done the how much bomber & HPC flip out when damaged - if( %doImpulse ) - { - %vehName = %targetObject.getDataBlock().getName(); - if ((%vehName $= "BomberFlyer") || (%vehName $= "HAPCFlyer")) - { - %bomberimp = VectorScale(%impulseVec, 0.6); - %impulseVec = %bomberimp; - } - %targetObject.applyImpulse(%position, %impulseVec); - } - //if( %doImpulse ) - // %targetObject.applyImpulse(%position, %impulseVec); - //------------------------------------------------------------------------------- - } -} - -function ProjectileData::onExplode(%data, %proj, %pos, %mod) -{ - if (%data.hasDamageRadius) - RadiusExplosion(%proj, %pos, %data.damageRadius, %data.indirectDamage, %data.kickBackStrength, %proj.sourceObject, %data.radiusDamageType); -} - -function Flag::shouldApplyImpulse(%data, %obj) -{ - if(%obj.isHome) - return false; - else - return true; -} +//-------------------------------------------------------------------------- +// Projectiles.cs: Note that the actual projectile blocks are stored with +// with weapon that uses them in base/scripts/weapons/*.cs, +// the blocks below are only to illustrate the default values +// for each block type. Also, ProjectileData cannot be used +// as a concrete datablock type. +// Inheritance: +// ProjectileData : GameBaseData +// LinearProjectileData : ProjectileData +// LinearFlareProjectileData : LinearProjectileData +// GrenadeProjectileData : ProjectileData +// SeekerProjectileData : ProjectileData +// SniperProjectileData : ProjectileData +// +//-------------------------------------------------------------------------- +//-------------------------------------- Default functions +// +function ProjectileData::onCollision(%data, %projectile, %targetObject, %modifier, %position, %normal) +{ + if(isObject(%targetObject)) // z0dd - ZOD, 4/24/02. Console spam fix. + { + if (%data.getname() $="FlameboltMain") + { + burnloop(%targetobject,%projectile.sourceObject, %data.directDamage * %modifier, %data.directDamageType); + + //Look for anything within range to light. + InitContainerRadiusSearch(%projectile.getposition(),3,$TypeMasks::PlayerObjectType); + + while ((%potentialTarget = ContainerSearchNext()) != 0) + { + if (%potentialTarget.getclassname() $="player" && %potentialTarget.getstate() !$="dead" && %potentialTarget.client != %projectile.sourceclient) + { + burnloop(%potentialTarget,%projectile.sourceObject, %data.directDamage * %modifier, %data.directDamageType); + + } + } + } +} + +//We hit something directly or indirectly, either way, it's a hit. +if ($CurrentMissionType !$= "RPG" && %targetObject.team != %projectile.sourceObject.client.team && isObject(%projectile.sourceObject.client)) +$Data::Hits[%projectile.sourceObject.client.guid]++; +%targetObject.damage(%projectile.sourceObject, %position, %data.directDamage * %modifier, %data.directDamageType); +} + +function SniperProjectileData::onCollision(%data, %projectile, %targetObject, %modifier, %position, %normal) +{ + %damageAmount = %data.directDamage * %projectile.damageFactor; + + if(isObject(%targetObject)) // z0dd - ZOD, 4/24/02. Console spam fix. + { + if(%targetObject.getDataBlock().getClassName() $= "PlayerData") + { + %damLoc = firstWord(%targetObject.getDamageLocation(%position)); + if(%damLoc $= "head") + { + %targetObject.getOwnerClient().headShot = 1; + %modifier = %data.rifleHeadMultiplier; + } + else + { + %modifier = 1; + %targetObject.getOwnerClient().headShot = 0; + } + } + %targetObject.damage(%projectile.sourceObject, %position, %modifier * %damageAmount, %data.directDamageType); + } +} + +// ------------------------------------------------------- +// z0dd - ZOD, 9/3/02. Anti rapid fire mortar/missile fix. +function resetFire(%obj,%bool) +{ + cancel(%obj.reloadSchedule); + %obj.cantFire = ""; +} +// ------------------------------------------------------- + +function ShapeBaseImageData::onFire(%data, %obj, %slot) +{ + // --------------------------------------------------------------------------- + // z0dd - ZOD, 9/3/02. Anti rapid fire mortar/missile fix. + if (%obj.cantFire !$= "") + { + return 0; + } + + + %wpnName = %data.getName(); + if((%wpnName $= "MortarImage") || (%wpnName $= "MissileLauncherImage")) + { + %obj.cantFire = 1; + %preventTime = %data.stateTimeoutValue[4]; + %obj.reloadSchedule = schedule(%preventTime * 1000, %obj, resetFire, %obj); + } + // --------------------------------------------------------------------------- + + %data.lightStart = getSimTime(); + + if( %obj.station $= "" && %obj.isCloaked() ) + { + if( %obj.respawnCloakThread !$= "" ) + { + Cancel(%obj.respawnCloakThread); + %obj.setCloaked( false ); + %obj.respawnCloakThread = ""; + } + else + { + if( %obj.getEnergyLevel() > 20 ) + { + %obj.setCloaked( false ); + %obj.reCloak = %obj.schedule( 500, "setCloaked", true ); + } + } + } + + if( %obj.client > 0 ) + { + %obj.setInvincibleMode(0 ,0.00); + %obj.setInvincible( false ); // fire your weapon and your invincibility goes away. + } + + %vehicle = 0; + if(%data.usesEnergy) + { + if(%data.useMountEnergy) + { + %useEnergyObj = %obj.getObjectMount(); + if(!%useEnergyObj) + %useEnergyObj = %obj; + %energy = %useEnergyObj.getEnergyLevel(); + %vehicle = %useEnergyObj; + } + else + %energy = %obj.getEnergyLevel(); + + if(%data.useCapacitor && %data.usesEnergy) + { + if( %useEnergyObj.turretObject.getCapacitorLevel() < %data.minEnergy ) + { + return; + } + } + else if(%energy < %data.minEnergy) + return; + } + // --------------------------------------------------------------------- + // z0dd - ZOD, 4/24/02. Code optimization + if(%data.projectileSpread) + { + %vec = %obj.getMuzzleVector(%slot); + %x = (getRandom() - 0.5) * 2 * 3.1415926 * %data.projectileSpread; + %y = (getRandom() - 0.5) * 2 * 3.1415926 * %data.projectileSpread; + %z = (getRandom() - 0.5) * 2 * 3.1415926 * %data.projectileSpread; + %mat = MatrixCreateFromEuler(%x @ " " @ %y @ " " @ %z); + %vector = MatrixMulVector(%mat, %vec); + } + else + { + %vector = %obj.getMuzzleVector(%slot); + } + + %p = new (%data.projectileType)() { + dataBlock = %data.projectile; + initialDirection = %vector; + initialPosition = %obj.getMuzzlePoint(%slot); + sourceObject = %obj; + sourceSlot = %slot; + vehicleObject = %vehicle; + }; + // End streamlining + // --------------------------------------------------------------------- + if (isObject(%obj.lastProjectile) && %obj.deleteLastProjectile) + %obj.lastProjectile.delete(); + + %obj.lastProjectile = %p; + %obj.deleteLastProjectile = %data.deleteLastProjectile; + MissionCleanup.add(%p); + + // AI hook + if(%obj.client) + %obj.client.projectile = %p; + + if(%data.usesEnergy) + { + if(%data.useMountEnergy) + { + if( %data.useCapacitor ) + { + %vehicle.turretObject.setCapacitorLevel( %vehicle.turretObject.getCapacitorLevel() - %data.fireEnergy ); + } + else + %useEnergyObj.setEnergyLevel(%energy - %data.fireEnergy); + } + else + %obj.setEnergyLevel(%energy - %data.fireEnergy); + } + else + %obj.decInventory(%data.ammo,1); + + //Ok, we fired. Increase my total number of weapon fires if this not an RPG gamemode + if ($CurrentMissionType !$= "RPG") + $Data::Shots[%obj.client.guid]++; + + return %p; +} + +function ShapeBaseImageData::onUnmount(%data, %obj, %slot) +{ + if (%data.deleteLastProjectile && isObject(%obj.lastProjectile)) + { + %obj.lastProjectile.delete(); + %obj.lastProjectile = ""; + } +} + +function TurretImageData::deconstruct(%data, %obj, %slot) +{ + if (%data.deleteLastProjectile && isObject(%obj.lastProjectile)) + { + %obj.lastProjectile.delete(); + %obj.lastProjectile = ""; + } +} + +function ShapeBaseImageData::deconstruct(%data, %obj, %slot) +{ + if (%data.deleteLastProjectile && isObject(%obj.lastProjectile)) + { + %obj.lastProjectile.delete(); + %obj.lastProjectile = ""; + } +} + +function MissileLauncherImage::onFire(%data,%obj,%slot) +{ + %p = Parent::onFire(%data, %obj, %slot); + + //-------------------------------------------------------- + // z0dd - ZOD, 9/3/02. Anti rapid fire mortar/missile fix. + if(!%p) + { + return; + } + //-------------------------------------------------------- + + MissileSet.add(%p); + + %target = %obj.getLockedTarget(); + if(%target) + %p.setObjectTarget(%target); + else if(%obj.isLocked()) + %p.setPositionTarget(%obj.getLockedPosition()); + else + %p.setNoTarget(); +} + +function MissileLauncherImage::onWetFire(%data, %obj, %slot) +{ + %p = Parent::onFire(%data, %obj, %slot); + + //-------------------------------------------------------- + // z0dd - ZOD, 9/3/02. Anti rapid fire mortar/missile fix. + if(!%p) + { + return; + } + //-------------------------------------------------------- + + MissileSet.add(%p); + + %p.setObjectTarget(0); +} + +//-------------------------------------------------------------------------- + +function MissileBarrelLarge::onFire(%data,%obj,%slot) +{ + %p = Parent::onFire(%data,%obj,%slot); + + //-------------------------------------------------------- + // z0dd - ZOD, 9/3/02. Anti rapid fire mortar/missile fix. + if(!%p) + { + return; + } + //-------------------------------------------------------- + + if (%obj.getControllingClient()) + { + // a player is controlling the turret + %target = %obj.getLockedTarget(); + } + else + { + // The ai is controlling the turret + %target = %obj.getTargetObject(); + } + + if(%target) + %p.setObjectTarget(%target); + else if(%obj.isLocked()) + %p.setPositionTarget(%obj.getLockedPosition()); + else + %p.setNoTarget(); // set as unguided. Only happens when itchy trigger can't wait for lock tone. +} + +//add mortars to the "grenade set" so the AI's can avoid them better... +function MortarImage::onFire(%data,%obj,%slot) +{ + %p = Parent::onFire(%data, %obj, %slot); + + //-------------------------------------------------------- + // z0dd - ZOD, 9/3/02. Anti rapid fire mortar/missile fix. + if(!%p) + { + return; + } + //-------------------------------------------------------- + + AIGrenadeThrown(%p); +} + +function SniperRifleImage::onFire(%data,%obj,%slot) +{ + if(!%obj.hasEnergyPack) + { + // siddown Junior, you can't use it + serverPlay3D(SniperRifleDryFireSound, %obj.getTransform()); + return; + } + %pct = %obj.getEnergyLevel() / %obj.getDataBlock().maxEnergy; + %p = new (%data.projectileType)() { + dataBlock = %data.projectile; + initialDirection = %obj.getMuzzleVector(%slot); + initialPosition = %obj.getMuzzlePoint(%slot); + sourceObject = %obj; + damageFactor = %pct * %pct; + sourceSlot = %slot; + }; + %p.setEnergyPercentage(%pct); + + %obj.lastProjectile = %p; + MissionCleanup.add(%p); + serverPlay3D(SniperRifleFireSound, %obj.getTransform()); + + // AI hook + if(%obj.client) + %obj.client.projectile = %p; + + %obj.setEnergyLevel(0); +} + +function ElfGunImage::onFire(%data, %obj, %slot) +{ + %p = Parent::onFire(%data, %obj, %slot); + + //-------------------------------------------------------- + // z0dd - ZOD, 9/3/02. Anti rapid fire mortar/missile fix. + if(!%p) + { + return; + } + //-------------------------------------------------------- + + if(!%p.hasTarget()) + %obj.playAudio(0, ELFFireWetSound); +} + +function TargetingLaserImage::onFire(%data,%obj,%slot) +{ + %p = Parent::onFire(%data, %obj, %slot); + + //-------------------------------------------------------- + // z0dd - ZOD, 9/3/02. Anti rapid fire mortar/missile fix. + if(!%p) + { + return; + } + //-------------------------------------------------------- + + %p.setTarget(%obj.team); +} + +function ShockLanceImage::onFire(%this, %obj, %slot) +{ + if( %obj.isCloaked() ) + { + if( %obj.respawnCloakThread !$= "" ) + { + Cancel(%obj.respawnCloakThread); + %obj.setCloaked( false ); + } + else + { + if( %obj.getEnergyLevel() > 20 ) + { + %obj.setCloaked( false ); + %obj.reCloak = %obj.schedule( 500, "setCloaked", true ); + } + } + } + + %muzzlePos = %obj.getMuzzlePoint(%slot); + %muzzleVec = %obj.getMuzzleVector(%slot); + + %endPos = VectorAdd(%muzzlePos, VectorScale(%muzzleVec, %this.projectile.extension)); + + %damageMasks = $TypeMasks::PlayerObjectType | $TypeMasks::VehicleObjectType | + $TypeMasks::StationObjectType | $TypeMasks::GeneratorObjectType | + $TypeMasks::SensorObjectType | $TypeMasks::TurretObjectType; + + %everythingElseMask = $TypeMasks::TerrainObjectType | + $TypeMasks::InteriorObjectType | + $TypeMasks::ForceFieldObjectType | + $TypeMasks::StaticObjectType | + $TypeMasks::MoveableObjectType | + $TypeMasks::DamagableItemObjectType; + + // did I miss anything? players, vehicles, stations, gens, sensors, turrets + %hit = ContainerRayCast(%muzzlePos, %endPos, %damageMasks | %everythingElseMask, %obj); + + %noDisplay = true; + + if (%hit !$= "0") + { + %obj.setEnergyLevel(%obj.getEnergyLevel() - %this.hitEnergy); + + %hitobj = getWord(%hit, 0); + %hitpos = getWord(%hit, 1) @ " " @ getWord(%hit, 2) @ " " @ getWord(%hit, 3); + + if ( %hitObj.getType() & %damageMasks ) + { + %hitobj.applyImpulse(%hitpos, VectorScale(%muzzleVec, %this.projectile.impulse)); + %obj.playAudio(0, ShockLanceHitSound); + + // This is truly lame, but we need the sourceobject property present... + %p = new ShockLanceProjectile() { + dataBlock = %this.projectile; + initialDirection = %obj.getMuzzleVector(%slot); + initialPosition = %obj.getMuzzlePoint(%slot); + sourceObject = %obj; + sourceSlot = %slot; + targetId = %hit; + }; + MissionCleanup.add(%p); + + %damageMultiplier = 1.0; + + if(%hitObj.getDataBlock().getClassName() $= "PlayerData") + { + // Now we see if we hit from behind... + %forwardVec = %hitobj.getForwardVector(); + %objDir2D = getWord(%forwardVec, 0) @ " " @ getWord(%forwardVec,1) @ " " @ "0.0"; + %objPos = %hitObj.getPosition(); + %dif = VectorSub(%objPos, %muzzlePos); + %dif = getWord(%dif, 0) @ " " @ getWord(%dif, 1) @ " 0"; + %dif = VectorNormalize(%dif); + %dot = VectorDot(%dif, %objDir2D); + + // 120 Deg angle test... + // 1.05 == 60 degrees in radians + if (%dot >= mCos(1.05)) + { + // Rear hit + %damageMultiplier = 3.0; + %hitObj.getOwnerClient().rearshot = 1; // z0dd - ZOD, 8/25/02. Added Lance rear shot messages + } + // -------------------------------------------------------------- + // z0dd - ZOD, 8/25/02. Added Lance rear shot messages + else + { + %hitObj.getOwnerClient().rearshot = 0; + } + // -------------------------------------------------------------- + } + + %totalDamage = %this.Projectile.DirectDamage * %damageMultiplier; + %hitObj.getDataBlock().damageObject(%hitobj, %p.sourceObject, %hitpos, %totalDamage, $DamageType::ShockLance); + + %noDisplay = false; + } + } + + if( %noDisplay ) + { + // Miss + %obj.setEnergyLevel(%obj.getEnergyLevel() - %this.missEnergy); + %obj.playAudio(0, ShockLanceMissSound); + + %p = new ShockLanceProjectile() { + dataBlock = %this.projectile; + initialDirection = %obj.getMuzzleVector(%slot); + initialPosition = %obj.getMuzzlePoint(%slot); + sourceObject = %obj; + sourceSlot = %slot; + }; + MissionCleanup.add(%p); + + } +} + +$ELFZapSound = 2; +$ELFFireSound = 3; + +function ELFProjectileData::zapTarget(%data, %projectile, %target, %targeter) +{ + %oldERate = %target.getRechargeRate(); + %target.teamDamageStateOnZap = $teamDamage; + %teammates = %target.client.team == %targeter.client.team; + + if( %target.teamDamageStateOnZap || !%teammates ) + %target.setRechargeRate(%oldERate - %data.drainEnergy); + else + %target.setRechargeRate(%oldERate); + + %projectile.checkELFStatus(%data, %target, %targeter); +} + +function ELFProjectileData::unzapTarget(%data, %projectile, %target, %targeter) +{ + cancel(%projectile.ELFrecur); + %target.stopAudio($ELFZapSound); + %targeter.stopAudio($ELFFireSound); + %target.zapSound = false; + %targeter.zappingSound = false; + %teammates = %target.client.team == %targeter.client.team; + + if(!%target.isDestroyed()) + { + %oldERate = %target.getRechargeRate(); + if( %target.teamDamageStateOnZap || !%teammates ) + %target.setRechargeRate(%oldERate + %data.drainEnergy); + else + %target.setRechargeRate(%oldERate); + } +} + +function ELFProjectileData::targetDestroyedCancel(%data, %projectile, %target, %targeter) +{ + cancel(%projectile.ELFrecur); + %target.stopAudio($ELFZapSound); + %targeter.stopAudio($ELFFireSound); + %target.zapSound = false; + %targeter.zappingSound = false; + %projectile.delete(); +} + +function ELFProjectile::checkELFStatus(%this, %data, %target, %targeter) +{ + if(isObject(%target)) + { + if(%target.getDamageState() $= "Destroyed") + { + %data.targetDestroyedCancel(%this, %target, %targeter); + return; + } + + %enLevel = %target.getEnergyLevel(); + if(%enLevel < 1.0) + { + %dataBlock = %target.getDataBlock(); + %dataBlock.damageObject(%target, %this.sourceObject, %target.getPosition(), %data.drainHealth, %data.directDamageType); + + } + else + { + %normal = "0.0 0.0 1.0"; + %target.playShieldEffect( %normal ); + } + %this.ELFrecur = %this.schedule(32, checkELFStatus, %data, %target, %targeter); + + %targeter.playAudio($ELFFireSound, ELFGunFireSound); + if(!%target.zapSound) + { + %target.playAudio($ELFZapSound, ELFHitTargetSound); + %target.zapSound = true; + %targeter.zappingSound = true; + } + } + // ------------------------------------------------------- + // z0dd - ZOD, 5/27/02. Stop firing if there is no target, + // fixes continuous fire bug. + //else if(%targeter.zappingSound) + //{ + // %targeter.stopAudio($ELFFireSound); + // %targeter.zappingSound = false; + //} + else + { + if(%targeter.zappingSound) + { + %targeter.stopAudio($ELFFireSound); + %targeter.zappingSound = false; + } + %data.targetDestroyedCancel(%this, %target, %targeter); + return; + } + // End z0dd - ZOD + // ------------------------------------------------------- +} + +function RadiusExplosion(%explosionSource, %position, %radius, %damage, %impulse, %sourceObject, %damageType) +{ + InitContainerRadiusSearch(%position, %radius, $TypeMasks::PlayerObjectType | + $TypeMasks::VehicleObjectType | + $TypeMasks::StaticShapeObjectType | + $TypeMasks::TurretObjectType | + $TypeMasks::ItemObjectType); + + %numTargets = 0; + while ((%targetObject = containerSearchNext()) != 0) + { + %dist = containerSearchCurrRadDamageDist(); + + if (%dist > %radius) + continue; + + if (%targetObject.isMounted()) + { + %mount = %targetObject.getObjectMount(); + %found = -1; + for (%i = 0; %i < %mount.getDataBlock().numMountPoints; %i++) + { + if (%mount.getMountNodeObject(%i) == %targetObject) + { + %found = %i; + break; + } + } + + if (%found != -1) + { + if (%mount.getDataBlock().isProtectedMountPoint[%found]) + { + continue; + } + } + } + + %targets[%numTargets] = %targetObject; + %targetDists[%numTargets] = %dist; + %numTargets++; + } + + for (%i = 0; %i < %numTargets; %i++) + { + %targetObject = %targets[%i]; + %dist = %targetDists[%i]; + + %coverage = calcExplosionCoverage(%position, %targetObject, + ($TypeMasks::InteriorObjectType | + $TypeMasks::TerrainObjectType | + $TypeMasks::ForceFieldObjectType | + $TypeMasks::VehicleObjectType)); + if (%coverage == 0) + continue; + + //if ( $splashTest ) + %amount = (1.0 - ((%dist / %radius) * 0.88)) * %coverage * %damage; + //else + //%amount = (1.0 - (%dist / %radius)) * %coverage * %damage; + + //error( "damage: " @ %amount @ " at distance: " @ %dist @ " radius: " @ %radius @ " maxDamage: " @ %damage ); + + %data = %targetObject.getDataBlock(); + %className = %data.className; + + if (%impulse && %data.shouldApplyImpulse(%targetObject)) + { + %p = %targetObject.getWorldBoxCenter(); + %momVec = VectorSub(%p, %position); + %momVec = VectorNormalize(%momVec); + + //------------------------------------------------------------------------------ + // z0dd - ZOD, 7/08/02. More kick when player damages self with disc or mortar. + // Stronger DJs and mortar jumps without impacting others (mainly HoFs) + if(%sourceObject == %targetObject) + { + if (%damageType == $DamageType::Disc) + { + %impulse = 4475; + } + else if (%damageType == $DamageType::Mortar) + { + %impulse = 5750; + } + } + //------------------------------------------------------------------------------ + + %impulseVec = VectorScale(%momVec, %impulse * (1.0 - (%dist / %radius))); + %doImpulse = true; + } + else if( %className $= FlyingVehicleData || %className $= HoverVehicleData ) // Removed WheeledVehicleData. z0dd - ZOD, 4/24/02. Do not allow impulse applied to MPB, conc MPB bug fix. + { + %p = %targetObject.getWorldBoxCenter(); + %momVec = VectorSub(%p, %position); + %momVec = VectorNormalize(%momVec); + + %impulseVec = VectorScale(%momVec, %impulse * (1.0 - (%dist / %radius))); + + if( getWord( %momVec, 2 ) < -0.5 ) + %momVec = "0 0 1"; + + // Add obj's velocity into the momentum vector + %velocity = %targetObject.getVelocity(); + //%momVec = VectorNormalize( vectorAdd( %momVec, %velocity) ); + %doImpulse = true; + } + else + { + %momVec = "0 0 1"; + %doImpulse = false; + } + + if(%amount > 0) + %data.damageObject(%targetObject, %sourceObject, %position, %amount, %damageType, %momVec, %explosionSource.theClient, %explosionSource); + else if( %explosionSource.getDataBlock().getName() $= "ConcussionGrenadeThrown" && %data.getClassName() $= "PlayerData" ) + { + %data.applyConcussion( %dist, %radius, %sourceObject, %targetObject ); + + if(!$teamDamage && %sourceObject != %targetObject && %sourceObject.client.team == %targetObject.client.team) + { + messageClient(%targetObject.client, 'msgTeamConcussionGrenade', '\c1You were hit by %1\'s concussion grenade.', getTaggedString(%sourceObject.client.name)); + } + } + + //------------------------------------------------------------------------------- + // z0dd - ZOD, 4/16/02. Tone done the how much bomber & HPC flip out when damaged + if( %doImpulse ) + { + %vehName = %targetObject.getDataBlock().getName(); + if ((%vehName $= "BomberFlyer") || (%vehName $= "HAPCFlyer")) + { + %bomberimp = VectorScale(%impulseVec, 0.6); + %impulseVec = %bomberimp; + } + %targetObject.applyImpulse(%position, %impulseVec); + } + //if( %doImpulse ) + // %targetObject.applyImpulse(%position, %impulseVec); + //------------------------------------------------------------------------------- + } +} + +function ProjectileData::onExplode(%data, %proj, %pos, %mod) +{ + if (%data.hasDamageRadius) + RadiusExplosion(%proj, %pos, %data.damageRadius, %data.indirectDamage, %data.kickBackStrength, %proj.sourceObject, %data.radiusDamageType); +} + +function Flag::shouldApplyImpulse(%data, %obj) +{ + if(%obj.isHome) + return false; + else + return true; +} diff --git a/scripts/scoreList.cs b/scripts/scoreList.cs index 27a7f8b..9658b98 100644 --- a/scripts/scoreList.cs +++ b/scripts/scoreList.cs @@ -1,131 +1,131 @@ -//------------------------------------------------------------------------------ -// -// scoreList.cs -// -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -// Server side functions: -//------------------------------------------------------------------------------ -$lastScoreUpdate = 0; - -function updateScores() -{ - if ( !isObject( Game ) ) - return; - - %numTeams = Game.numTeams; - - // Initialize the team counts: - for ( %teamIndex = 0; %teamIndex <= %numTeams; %teamIndex++ ) - Game.teamCount[%teamIndex] = 0; - - %count = ClientGroup.getCount(); - for ( %clientIndex = 0; %clientIndex < %count; %clientIndex++ ) - { - %cl = ClientGroup.getObject( %clientIndex ); - %team = %cl.getSensorGroup(); - if ( %numTeams == 1 && %team != 0 ) - %team = 1; - Game.teamScores[%team, Game.teamCount[%team], 0] = %cl.name; - if ( %cl.score $= "" ) - Game.teamScores[%team, Game.teamCount[%team], 1] = 0; - else - Game.teamScores[%team, Game.teamCount[%team], 1] = %cl.score; - Game.teamCount[%team]++; - } -} - - -//------------------------------------------------------------------------------ -function serverCmdGetScores( %client ) -{ - // Client has requested the score list, so give it to 'em... - if (isObject(Game)) - { - updateScores(); - %teamCount = Game.numTeams; - - if (%teamCount > 1) - { - // Send team messages: - for (%team = 1; %team <= %teamCount; %team++) - messageClient(%client, 'MsgTeamScore', "", %team, $teamScore[%team]); - - //send the player scores in order of their team rank... - for (%team = 1; %team <= %teamCount; %team++) - { - for (%i = 0; %i < $TeamRank[%team, count]; %i++) - { - %cl = $TeamRank[%team, %i]; - if (IsObject(%cl)) - messageClient( %client, 'MsgPlayerScore', "", %cl, %cl.score, %cl.getPing(), %cl.getPacketLoss()); - } - } - } - else - { - //send the player scores in order of their rank... - for (%i = 0; %i < $TeamRank[0, count]; %i++) - { - %cl = $TeamRank[0, %i]; - if (isObject(%cl)) - messageClient( %client, 'MsgPlayerScore', "", %cl, %cl.score, %cl.getPing(), %cl.getPacketLoss()); - } - } - - //now send the observers over - %count = ClientGroup.getCount(); - for (%i = 0; %i < %count; %i++) - { - %cl = ClientGroup.getObject(%i); - if (%cl.team <= 0) - messageClient( %client, 'MsgPlayerScore', "", %cl, %cl.score, %cl.getPing(), %cl.getPacketLoss()); - } - } -} - - -//------------------------------------------------------------------------------ -// Client side functions: -//------------------------------------------------------------------------------ -addMessageCallback( 'MsgTeamScore', handleTeamScore ); -addMessageCallback( 'MsgPlayerScore', handlePlayerScore ); - -//------------------------------------------------------------------------------ -// client team score list is called $clTeamScore -// number of teams is $clTeamCount -$clTeamCount = 0; - -function handleTeamScore( %msgType, %msgString, %team, %teamScore ) -{ - if ( %teamScore $= "" ) - %score = "0"; - else - %score = %teamScore; - - // Add the new entry: - $clTeamScore[%team, 1] = %score; - - if ( %team > $clTeamCount ) - $clTeamCount = %team; -} - - -//------------------------------------------------------------------------------ -// Store the player score on the client-side player object: -function handlePlayerScore( %msgType, %msgString, %clientId, %score, %ping, %packetLoss ) -{ - %player = $PlayerList[%clientId]; - if ( %player ) - { - %player.score = %score; - %player.ping = %ping; - %player.packetLoss = %packetLoss; - lobbyUpdatePlayer( %clientId ); - } - else - warn( "Received score for client that hasn't joined!" ); -} - - +//------------------------------------------------------------------------------ +// +// scoreList.cs +// +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// Server side functions: +//------------------------------------------------------------------------------ +$lastScoreUpdate = 0; + +function updateScores() +{ + if ( !isObject( Game ) ) + return; + + %numTeams = Game.numTeams; + + // Initialize the team counts: + for ( %teamIndex = 0; %teamIndex <= %numTeams; %teamIndex++ ) + Game.teamCount[%teamIndex] = 0; + + %count = ClientGroup.getCount(); + for ( %clientIndex = 0; %clientIndex < %count; %clientIndex++ ) + { + %cl = ClientGroup.getObject( %clientIndex ); + %team = %cl.getSensorGroup(); + if ( %numTeams == 1 && %team != 0 ) + %team = 1; + Game.teamScores[%team, Game.teamCount[%team], 0] = %cl.name; + if ( %cl.score $= "" ) + Game.teamScores[%team, Game.teamCount[%team], 1] = 0; + else + Game.teamScores[%team, Game.teamCount[%team], 1] = %cl.score; + Game.teamCount[%team]++; + } +} + + +//------------------------------------------------------------------------------ +function serverCmdGetScores( %client ) +{ + // Client has requested the score list, so give it to 'em... + if (isObject(Game)) + { + updateScores(); + %teamCount = Game.numTeams; + + if (%teamCount > 1) + { + // Send team messages: + for (%team = 1; %team <= %teamCount; %team++) + messageClient(%client, 'MsgTeamScore', "", %team, $teamScore[%team]); + + //send the player scores in order of their team rank... + for (%team = 1; %team <= %teamCount; %team++) + { + for (%i = 0; %i < $TeamRank[%team, count]; %i++) + { + %cl = $TeamRank[%team, %i]; + if (IsObject(%cl)) + messageClient( %client, 'MsgPlayerScore', "", %cl, %cl.score, %cl.getPing(), %cl.getPacketLoss()); + } + } + } + else + { + //send the player scores in order of their rank... + for (%i = 0; %i < $TeamRank[0, count]; %i++) + { + %cl = $TeamRank[0, %i]; + if (isObject(%cl)) + messageClient( %client, 'MsgPlayerScore', "", %cl, %cl.score, %cl.getPing(), %cl.getPacketLoss()); + } + } + + //now send the observers over + %count = ClientGroup.getCount(); + for (%i = 0; %i < %count; %i++) + { + %cl = ClientGroup.getObject(%i); + if (%cl.team <= 0) + messageClient( %client, 'MsgPlayerScore', "", %cl, %cl.score, %cl.getPing(), %cl.getPacketLoss()); + } + } +} + + +//------------------------------------------------------------------------------ +// Client side functions: +//------------------------------------------------------------------------------ +addMessageCallback( 'MsgTeamScore', handleTeamScore ); +addMessageCallback( 'MsgPlayerScore', handlePlayerScore ); + +//------------------------------------------------------------------------------ +// client team score list is called $clTeamScore +// number of teams is $clTeamCount +$clTeamCount = 0; + +function handleTeamScore( %msgType, %msgString, %team, %teamScore ) +{ + if ( %teamScore $= "" ) + %score = "0"; + else + %score = %teamScore; + + // Add the new entry: + $clTeamScore[%team, 1] = %score; + + if ( %team > $clTeamCount ) + $clTeamCount = %team; +} + + +//------------------------------------------------------------------------------ +// Store the player score on the client-side player object: +function handlePlayerScore( %msgType, %msgString, %clientId, %score, %ping, %packetLoss ) +{ + %player = $PlayerList[%clientId]; + if ( %player ) + { + %player.score = %score; + %player.ping = %ping; + %player.packetLoss = %packetLoss; + lobbyUpdatePlayer( %clientId ); + } + else + warn( "Received score for client that hasn't joined!" ); +} + + diff --git a/scripts/scoreScreen.cs b/scripts/scoreScreen.cs index 1661600..91902e2 100644 --- a/scripts/scoreScreen.cs +++ b/scripts/scoreScreen.cs @@ -1,97 +1,97 @@ -//------------------------------------------------------------------------------ -function ScoreScreen::setupHud(%obj, %tag) -{ -} - -//------------------------------------------------------------------------------ -function ScoreScreen::loadHud(%obj, %tag) -{ - $Hud[%tag] = ScoreScreen; - $Hud[%tag].childGui = ScoreContent; - $Hud[%tag].parent = ScoreParent; -} - -//------------------------------------------------------------------------------ -function ScoreScreen::onWake(%this) -{ - if ( isObject( hudMap ) ) - { - hudMap.pop(); - hudMap.delete(); - } - new ActionMap( hudMap ); - hudMap.blockBind( moveMap, toggleInventoryHud ); - hudMap.blockBind( moveMap, toggleCommanderMap ); - hudMap.bindCmd( keyboard, escape, "", "toggleCursorHuds('scoreScreen');" ); - hudMap.push(); -} - -//------------------------------------------------------------------------------ -function ScoreScreen::onSleep(%this) -{ - hudMap.pop(); - hudMap.delete(); - - //make sure the action maps are still pushed in the correct order... - updateActionMaps(); -} - -//------------------------------------------------------------------------------ -function ScoreScreen::addLine(%obj, %tag, %lineNum, %name) -{ - %yOffset = (%lineNum * 20) + 5; - - $Hud[%tag].count++; - $Hud[%tag].childGui.resize( 3, 3, 586, %yOffset + 25 ); - $Hud[%tag].data[%lineNum,0] = new GuiMLTextCtrl() - { - profile = "ScoreTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "0 " @ %yOffset; - extent = "566 22"; - minExtent = "8 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - helpTag = "0"; - text = ""; -// command = "ScoreScreenOnMouseDown(" @ %lineNum @ ");"; - }; - return 1; -} - -//------------------------------------------------------------------------------ -addMessageCallback( 'SetScoreHudHeader', setScoreHudHeader ); -addMessageCallback( 'SetScoreHudSubheader', setScoreHudSubheader ); - -function setScoreHudHeader( %msgType, %msgString, %a0 ) -{ - %text = detag( %a0 ); - ScoreHeaderText.setValue( %text ); - if ( %text $= "" ) - { - ScoreHeaderField.setVisible( false ); - ScoreField.resize( 23, 32, 594, 426 ); - } - else - { - ScoreHeaderField.setVisible( true ); - ScoreField.resize( 23, 72, 594, 386 ); - } -} - -function setScoreHudSubheader( %msgType, %msgString, %a0 ) -{ - ScoreSubheaderText.setValue( detag( %a0 ) ); -} - -///////////////////////////////////////////////////////////////////////////////// -// Hunters Tracking requires this - if we put it back in, uncomment this section -// function ScoreScreenOnMouseDown(%line) -// { -// if ($CurrentMissionType $= "Hunters") -// commandToServer('huntersTrackPlayer', %line, firstWord($MLTextMousePoint)); -// } -///////////////////////////////////////////////////////////////////////////////// - +//------------------------------------------------------------------------------ +function ScoreScreen::setupHud(%obj, %tag) +{ +} + +//------------------------------------------------------------------------------ +function ScoreScreen::loadHud(%obj, %tag) +{ + $Hud[%tag] = ScoreScreen; + $Hud[%tag].childGui = ScoreContent; + $Hud[%tag].parent = ScoreParent; +} + +//------------------------------------------------------------------------------ +function ScoreScreen::onWake(%this) +{ + if ( isObject( hudMap ) ) + { + hudMap.pop(); + hudMap.delete(); + } + new ActionMap( hudMap ); + hudMap.blockBind( moveMap, toggleInventoryHud ); + hudMap.blockBind( moveMap, toggleCommanderMap ); + hudMap.bindCmd( keyboard, escape, "", "toggleCursorHuds('scoreScreen');" ); + hudMap.push(); +} + +//------------------------------------------------------------------------------ +function ScoreScreen::onSleep(%this) +{ + hudMap.pop(); + hudMap.delete(); + + //make sure the action maps are still pushed in the correct order... + updateActionMaps(); +} + +//------------------------------------------------------------------------------ +function ScoreScreen::addLine(%obj, %tag, %lineNum, %name) +{ + %yOffset = (%lineNum * 20) + 5; + + $Hud[%tag].count++; + $Hud[%tag].childGui.resize( 3, 3, 586, %yOffset + 25 ); + $Hud[%tag].data[%lineNum,0] = new GuiMLTextCtrl() + { + profile = "ScoreTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 " @ %yOffset; + extent = "566 22"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + helpTag = "0"; + text = ""; +// command = "ScoreScreenOnMouseDown(" @ %lineNum @ ");"; + }; + return 1; +} + +//------------------------------------------------------------------------------ +addMessageCallback( 'SetScoreHudHeader', setScoreHudHeader ); +addMessageCallback( 'SetScoreHudSubheader', setScoreHudSubheader ); + +function setScoreHudHeader( %msgType, %msgString, %a0 ) +{ + %text = detag( %a0 ); + ScoreHeaderText.setValue( %text ); + if ( %text $= "" ) + { + ScoreHeaderField.setVisible( false ); + ScoreField.resize( 23, 32, 594, 426 ); + } + else + { + ScoreHeaderField.setVisible( true ); + ScoreField.resize( 23, 72, 594, 386 ); + } +} + +function setScoreHudSubheader( %msgType, %msgString, %a0 ) +{ + ScoreSubheaderText.setValue( detag( %a0 ) ); +} + +///////////////////////////////////////////////////////////////////////////////// +// Hunters Tracking requires this - if we put it back in, uncomment this section +// function ScoreScreenOnMouseDown(%line) +// { +// if ($CurrentMissionType $= "Hunters") +// commandToServer('huntersTrackPlayer', %line, firstWord($MLTextMousePoint)); +// } +///////////////////////////////////////////////////////////////////////////////// + diff --git a/scripts/server.cs b/scripts/server.cs index d7d845b..ba1832d 100644 --- a/scripts/server.cs +++ b/scripts/server.cs @@ -1,3186 +1,3156 @@ -if($Host::TimeLimit $= "") - $Host::TimeLimit = 20; - -$SB::WODec = 0.004; // whiteout -$SB::DFDec = 0.02; // damageFlash - -$Classic::gravSetting = -26.9; // z0dd - ZOD, 9/13/02. Classic Gravity setting -$Classic::cameraSpeed = 50; -$Camera::movementSpeed = $Classic::cameraSpeed; // z0dd - ZOD, 9/13/02. Classic camera speed. - -// ----------------------------------------------------- -// z0dd - ZOD, 6/22/02. Addition. -// Alert players on server that a remote connection has -// been established to the server. -$TelnetSpam = 0; -function onTelnetConnect(%ip, %access) -{ - %level = %access == 1 ? "full" : "read"; - %snd = '~wfx/misc/diagnostic_on.wav'; - %msg = '\c1Remote telnet connection established.%1'; - if($Host::TournamentMode && $TelnetSpam == 0) - { - messageAll('MsgTelnetConnect', %msg, %snd); - logEcho("Incomming telnet connection from: " @ %ip @ " with " @ %level @ " access privledges"); - $TelnetSpam = 1; - schedule(2000, 0, "clearTelnetSpam"); - } -} - -function clearTelnetSpam() -{ - $TelnetSpam = 0; -} -// ----------------------------------------------------- - -// ----------------------------------------------------- -// Reload by JackTL -- I think -function reload(%script) -{ - compile(%script); // Added by JackTL - Duh!! - exec(%script); - %count = ClientGroup.getCount(); - - for(%i = 0; %i < %count; %i++) - { - %cl = ClientGroup.getObject(%i); - - if(!%cl.isAIControlled()) // no sending bots datablocks.. LOL - %cl.transmitDataBlocks(0); // all clients on server - } -} -// ----------------------------------------------------- - -function VerifyCDCheck(%func) -{ - if (!cdFileCheck()) - messageBoxOkCancel("TRIBES 2 CD CHECK", "You must have the Tribes 2 CD in the CD-ROM drive while playing Tribes 2. Please insert the CD.", "schedule(0, 0, VerifyCDCheck, " @ %func @ ");", "quit();"); - else - call(%func); -} - -function logEcho(%msg) -{ - // z0dd - ZOD, 4/10/02. Changed from $ClassicLogEchoEnabled, allow server owners to modify - if($Host::ClassicLogEchoEnabled) - echo("LOG: " @ %msg); -} - -//-------------------------------------------------------------------------- -// z0dd - ZOD, 3/27/02. Auto restart server after specified time - -function AutoRestart() -{ - if(!$Host::TournamentMode) - { - $AutoRestart = 1; - centerPrintAll("SERVER WILL BE AUTO REBOOTING NEXT MISSION.", 5, 1); - messageAll( 'MsgServerRestart', '\c2SERVER WILL BE AUTO REBOOTING NEXT MISSION.~wfx/misc/red_alert.wav'); - logEcho("Automatic server restart on mission end begining."); - } - else - schedule(300000, 0, "AutoRestart"); // Check back in 5 minutes -} -//-------------------------------------------------------------------------- - -function CreateServer(%mission, %missionType) -{ - DestroyServer(); - - // z0dd - ZOD, 3/27/02. Automatically reboot the server after a specified time. - $AutoRestart = 0; // Paranoia - if($Host::ClassicAutoRestartServer == 1) - schedule($Host::ClassicRestartTime * 3600000, 0, "AutoRestart"); - - if($Host::ClassicTelnet) - telnetsetparameters($Host::ClassicTelnetPort, $Host::ClassicTelnetPassword, $Host::ClassicTelnetListenPass); - - // Load server data blocks - exec("scripts/commanderMapIcons.cs"); - exec("scripts/markers.cs"); - exec("scripts/serverAudio.cs"); - exec("scripts/damageTypes.cs"); - exec("scripts/deathMessages.cs"); - exec("scripts/inventory.cs"); - exec("scripts/camera.cs"); - exec("scripts/particleEmitter.cs"); // Must exist before item.cs and explosion.cs - exec("scripts/particleDummies.cs"); - exec("scripts/projectiles.cs"); // Must exits before item.cs - exec("scripts/modScripts/server/initialize.cs"); - exec("scripts/player.cs"); - exec("scripts/gameBase.cs"); - exec("scripts/staticShape.cs"); - exec("scripts/weapons.cs"); - exec("scripts/turret.cs"); - exec("scripts/weapTurretCode.cs"); - exec("scripts/pack.cs"); - exec("scripts/vehicles/vehicle_spec_fx.cs"); // Must exist before other vehicle files or CRASH BOOM - exec("scripts/vehicles/serverVehicleHud.cs"); - exec("scripts/vehicles/vehicle_shrike.cs"); - exec("scripts/vehicles/vehicle_bomber.cs"); - exec("scripts/vehicles/vehicle_havoc.cs"); - exec("scripts/vehicles/vehicle_wildcat.cs"); - exec("scripts/vehicles/vehicle_tank.cs"); - exec("scripts/vehicles/vehicle_mpb.cs"); - exec("scripts/vehicles/vehicle.cs"); // Must be added after all other vehicle files or EVIL BAD THINGS - exec("scripts/ai.cs"); - exec("scripts/item.cs"); - exec("scripts/station.cs"); - exec("scripts/simGroup.cs"); - exec("scripts/trigger.cs"); - exec("scripts/forceField.cs"); - exec("scripts/lightning.cs"); - exec("scripts/weather.cs"); - exec("scripts/deployables.cs"); - exec("scripts/stationSetInv.cs"); - exec("scripts/navGraph.cs"); - exec("scripts/targetManager.cs"); - exec("scripts/serverCommanderMap.cs"); - exec("scripts/environmentals.cs"); - exec("scripts/power.cs"); - exec("scripts/supportClassic.cs"); // z0dd - ZOD, 5/13/02. Execute the support functions. - exec("scripts/practice.cs"); // z0dd - ZOD, 3/13/02. Execute practice mode server functions. - exec("scripts/serverTasks.cs"); - exec("scripts/admin.cs"); - exec("prefs/banlist.cs"); - - exec("scripts/modScripts/shared/initialise.cs"); - exec("scripts/modScripts/server/initialise.cs"); - - //Execute saved data, if possible - if (IsFile("Data/SavedData.cs")) - exec("Data/SavedData.cs"); - - // --------------------------------------------------- - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - %search = "scripts/*Game.cs"; - for(%file = findFirstFile(%search); %file !$= ""; %file = findNextFile(%search)) - { - %type = fileBase(%file); // get the name of the script - exec("scripts/" @ %type @ ".cs"); - } - // --------------------------------------------------- - - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - - $missionSequence = 0; - $CurrentMissionType = %missionType; - $HostGameBotCount = 0; - $HostGamePlayerCount = 0; - if ( $HostGameType !$= "SinglePlayer" ) - allowConnections(true); - $ServerGroup = new SimGroup (ServerGroup); - if(%mission $= "") - { - %mission = $HostMissionFile[$HostMission[0,0]]; - %missionType = $HostTypeName[0]; - } - - if ( ( $HostGameType $= "Online" && $pref::Net::DisplayOnMaster !$= "Never" ) ) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - schedule(0,0,startHeartbeat); - - // setup the bots for this server - if( $Host::BotsEnabled ) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - initGameBots( %mission, %missionType ); - - // z0dd - ZOD, 9/13/02. For TR2 compatability - // This is a failsafe way of ensuring that default gravity is always restored - // if a game type (such as TR2) changes it. It is placed here so that listen - // servers will work after opening and closing different gametypes. - $DefaultGravity = getGravity(); - - // load the mission... - loadMission(%mission, %missionType, true); -} - -function SimObject::setRotation(%obj, %rot) -{ - setRotation(%obj, %rot); -} - -function setRotation(%obj, %rot) -{ - %pos = getWords(%obj.getTransform(), 0, 2); - %trans = %pos@" "@%rot; - %obj.setTransform(%trans); -} - -function dropAI(%client) -{ -//if (!%client.isAIControlled()) -//return false; - -//clear any flags -AIUnassignClient(%client); -%client.stop(); -%client.clearStep(); -%client.lastDamageClient = -1; -%client.lastDamageTurret = -1; -%client.shouldEngage = -1; -%client.setEngageTarget(-1); -%client.setTargetObject(-1); -%client.clearTasks(); -%client.clearStep(); -%client.pilotVehicle = false; - cancel(%client.objectiveThread); -return true; -} - -function serverCmdDoRefill(%client) //Shitty hack I used to make the RPG gamemode force clients to pay for refills -{ -if (!%client.isatInv) -return; - -%obj = %client.player.obj; -%data = %client.player.data; -%colObj = %client.player; - -if ($CurrentMissionType $= "RPG") -{ - %client.money = %client.money - 100; - messageClient(%client,'MsgSPCurrentObjective2',"\c3$100 has been subtracted from your account.",'Money: $%1.',%client.money); -} - // z0dd - ZOD, 7/13/02 Part of hack to keep people from mounting - // vehicles in disallowed armors. - if(%obj.station.getDataBlock().getName() !$= "StationVehicle") - %colObj.client.inInv = true; - - %colObj.inStation = true; - commandToClient(%colObj.client,'setStationKeys', true); - if(Game.stationOnEnterTrigger(%data, %obj, %colObj)) { - //verify station.team is team associated and isn't on player's team - if((%obj.mainObj.team != %colObj.client.team) && (%obj.mainObj.team != 0)) - { - //%obj.station.playAudio(2, StationAccessDeniedSound); - messageClient(%colObj.client, 'msgStationDenied', '\c2Access Denied -- Wrong team.~wfx/powered/station_denied.wav'); - } - else if(%obj.disableObj.isDisabled()) - { - messageClient(%colObj.client, 'msgStationDisabled', '\c2Station is disabled.'); - } - else if(!%obj.mainObj.isPowered()) - { - messageClient(%colObj.client, 'msgStationNoPower', '\c2Station is not powered.'); - } - else if(%obj.station.notDeployed) - { - messageClient(%colObj.client, 'msgStationNotDeployed', '\c2Station is not deployed.'); - } - else if(%obj.station.triggeredBy $= "") - { - if(%obj.station.getDataBlock().setPlayersPosition(%obj.station, %obj, %colObj)) - { - messageClient(%colObj.client, 'CloseHud', "", 'inventoryScreen'); - commandToClient(%colObj.client, 'TogglePlayHuds', true); - %obj.station.triggeredBy = %colObj; - %obj.station.getDataBlock().stationTriggered(%obj.station, 1); - %colObj.station = %obj.station; - %colObj.lastWeapon = ( %colObj.getMountedImage($WeaponSlot) == 0 ) ? "" : %colObj.getMountedImage($WeaponSlot).getName().item; - %colObj.unmountImage($WeaponSlot); - } - } - } - - if (%colObj.client.race $= "Draakan") - %colObj.schedule(100,"setInventory","Flamer",1,true); //Make sure our player gets to keep the flame Breath -} - -function saveGame() -{ -if (!IsObject(ClientGroup)) -return; - -%count = ClientGroup.getCount(); - -if ($CurrentMissionType $= "RPG") //If it's not an RPG gamemode, don't do anything except save the variables that are already initialized.. -{ - for (%i = 0; %i < %count; %i++) - { - %cl = ClientGroup.getObject(%i); - if (!%cl.isAIControlled() && isObject(%cl.player)) - { - %trans = %cl.player.getTransform(); - %health = %cl.player.getDamageLevel(); - %whiteout = %cl.player.getWhiteout(); - %damageFlash = %cl.player.getDamageFlash(); - %velocity = %cl.player.getVelocity(); - %energy = %cl.player.getEnergyLevel(); - - $Data::Transform[%cl.GUID,$CurrentMission] = %trans; - $Data::Health[%cl.GUID,$CurrentMission] = %health; - $Data::Whiteout[%cl.GUID,$CurrentMission] = %whiteout; - $Data::DamageFlash[%cl.GUID,$CurrentMission] = %damageFlash; - $Data::Velocity[%cl.GUID,$CurrentMission] = %velocity; - $Data::ShouldApply[%cl.GUID,$CurrentMission] = true; - $Data::Energy[%cl.GUID,$CurrentMission] = %energy; - $Data::Money[%cl.GUID,$CurrentMission] = %cl.money; - - //A little more complicated, what weapons does our client have? - %armor = %cl.armor; - $Data::Armor[%cl.guid, $CurrentMission] = %armor; - - for (%i = 0; %i < 5; %i++) - { - %weap = %cl.player.weaponSlot[%i]; - if (%weap !$= "Flamer") //Skip the Flamer, if we try to save it, the player isn't given one on spawn - { - $Data::Weapon[%cl.guid, %i, $CurrentMission] = %weap; - $Data::Ammo[%cl.guid, %i, $CurrentMission] = %cl.player.inv[%cl.player.weaponSlot[%i] @ "ammo"]; - } - } - - //See WTF else the client may have - %pack = %cl.player.getMountedImage(2).item; - $Data::Pack[%cl.GUID,$CurrentMission] = %pack; - $Data::RepairKits[%cl.GUID,$CurrentMission] = %cl.player.invRepairKit; - - //Does the client have a vehicle? - if (IsObject(%cl.vehicleMounted)) - { - %veh = %cl.vehicleMounted; - - %type = %veh.getClassName(); - %transform = %veh.getTransform(); - %velocity = %veh.getVelocity(); - %damage = %veh.getDamageLevel(); - %energy = %veh.getEnergyLevel(); - %db = %veh.getDatablock().getName(); - - $Data::VehicleType[%cl.GUID, $CurrentMission] = %type; - $Data::VehicleTransform[%cl.GUID, $CurrentMission] = %transform; - $Data::VehicleDamage[%cl.GUID, $CurrentMission] = %damage; - $Data::VehicleEnergy[%cl.GUID, $CurrentMission] = %energy; - $Data::VehicleDB[%cl.GUID, $CurrentMission] = %db; - $Data::VehicleVelocity[%cl.GUID, $CurrentMission] = %velocity; - $Data::WasInVehicle[%cl.GUID, $CurrentMission] = true; - } - else - $Data::WasInVehicle[%cl.GUID, $CurrentMission] = false; - - //Minerals.. - $Data::Steel[%cl.GUID,$CurrentMission] = %cl.units["Steel"]; - } - } -} -logEcho("Saved all clients in server."); -export( "$Data::*", "Data/SavedData.cs", false ); -} - -function applyPlayerSave(%client) //This script is much worse than an eyesore.. -{ -if ($Data::ShouldApply[%client.GUID, $CurrentMission]) -{ - %client.sex = $Data::Sex[%client.guid]; - %client.race = $Data::Race[%client.guid]; - - %client.units["Steel"] = $Data::Steel[%client.GUID, $CurrentMission]; - %client.money = $Data::Money[%client.GUID, $CurrentMission]; - - //Clear the defaultGame inventory - %client.player.clearInventory(); - for(%i =0; %i<$InventoryHudCount; %i++) - %client.setInventoryHudItem($InventoryHudData[%i, itemDataName], 0, 1); - %client.clearBackpackIcon(); - - //Armor is set first before anything - %client.player.setArmor($Data::Armor[%client.guid, $CurrentMission]); - - //armor and weapons - for (%i = 0; %i < 5; %i++) - { - %client.player.setInventory($Data::Weapon[%client.guid, %i, $CurrentMission],1); - %client.player.setInventory($Data::Weapon[%client.guid, %i, $CurrentMission] @ "ammo",$Data::Ammo[%client.GUID, %i, $CurrentMission]); - %client.player.use(%client.player.weaponSlot0); - } - - if (%client.race $= "Draakan") - %client.player.setInventory(Flamer, 1, 1); //Apply player save fucks this up - - //Pack and rep kits.. - %client.player.setInventory("RepairKit",$Data::RepairKits[%client.guid, $CurrentMission]); - %client.player.setInventory($Data::Pack[%client.guid, $CurrentMission],1); - - //Now apply other stuff - %client.player.setDamageLevel($Data::Health[%client.GUID, $CurrentMission]); - %client.player.setEnergyLevel($Data::Energy[%client.GUID, $CurrentMission]); - %client.player.setWhiteout($Data::Whiteout[%client.GUID, $CurrentMission]); - %client.player.setDamageFlash($Data::DamageFlash[%client.GUID, $CurrentMission]); - %client.player.setTransform($Data::Transform[%client.GUID, $CurrentMission]); - %client.player.setVelocity($Data::Velocity[%client.GUID, $CurrentMission]); - - //Since the player is setup, was the player in a vehicle when saved? - if ($Data::wasInVehicle[%client.GUID, $CurrentMission]) //Yes, we need to setup the vehicle then mount the player to it - { - %veh = new ($Data::VehicleType[%client.GUID, $CurrentMission])() - { - Datablock = $Data::VehicleDB[%client.GUID, $CurrentMission]; - Team = %client.team; - }; - %veh.mountObject(%client.player,0); - %veh.setTransform($Data::VehicleTransform[%client.GUID, $CurrentMission]); - %veh.setEnergyLevel($Data::VehicleEnergy[%client.GUID, $CurrentMission]); - %veh.setDamageLevel($Data::VehicleDamage[%client.GUID, $CurrentMission]); - %veh.setVelocity($Data::VehicleVelocity[%client.GUID, $CurrentMission]); - } -} -else -%client.player.setTransform(Game.pickPlayerSpawn(%client,false)); - -//Clan Data - Fixed to prevent the tag being appended multiple times -if (%client.oldName $= "") -%client.oldName = %client.namebase; -if ($Data::IsInClan[%client.GUID]) -{ - %client.namebase = %client.oldName; - %client.name = addTaggedString(%client.oldName); - setName(%client,"\cp\c7" @ $Data::ClanTag[$Data::ClanID[%client.GUID]] @ "\c6" @ %client.namebase @ "\co"); -} -} - -function clientDisconnect(%client,%reason) -{ -messageClient(%client, 'onClientKicked', ""); -messageAllExcept( %client, -1, 'MsgClientDrop', "", Game.kickClientName, %client ); - -if( isObject( %client.player ) ) -%client.player.scriptKill(0); - -%client.setDisconnectReason( %reason ); -%client.schedule(700, "delete"); -return %client SPC %reason; -} - -function forceClientSpawn(%client,%setupBool) -{ -%client.race = $Data::Race[%client.GUID]; -%client.sex = $Data::Sex[%client.GUID]; -%client.team = getRaceTeam(%client.race); -Game.spawnPlayer( %client, false ); -%client.setControlObject(%client.player); -CloseScoreScreen(%client); -commandToClient(%client,'HandleScriptedCommand',7); -commandToClient(%client,'HandleScriptedCommand',3,3000); -commandToClient(%client,'bottomPrint',"Try not to die.",3); - -if (%setupBool) -applyPlayerSave(%client); - -setClientTeam(%client,0); //Has to be after everything else, or the player spawns in the middle of fucking nowhere.. -} - -function setClientTeam(%client,%team) -{ -if (%client.oldTeam $= "") -%client.oldTeam = %client.team; - -%client.team = %team; -%client.setSensorGroup(%team); -setTargetSensorGroup(%client.target,%team); -} - -function initGameBots( %mission, %mType ) -{ - echo( "adding bots..." ); - - AISystemEnabled( false ); - if ( $Host::BotCount > 0 && %mType !$= "SinglePlayer" ) - { - // Make sure this mission is bot enabled: - for ( %idx = 0; %idx < $HostMissionCount; %idx++ ) - { - if ( $HostMissionFile[%idx] $= %mission ) - break; - } - - if ( $BotEnabled[%idx] ) - { - if ( $Host::BotCount > 16 ) - $HostGameBotCount = 16; - else - $HostGameBotCount = $Host::BotCount; - - if ( $Host::BotCount > $Host::MaxPlayers - 1 ) - $HostGameBotCount = $Host::MaxPlayers - 1; - - //set the objective reassessment timeslice var - $AITimeSliceReassess = 0; - aiConnectMultiple( $HostGameBotCount, $Host::MinBotDifficulty, $Host::MaxBotDifficulty, -1 ); - } - else - { - $HostGameBotCount = 0; - } - } -} - -function findNextCycleMission() -{ - %numPlayers = ClientGroup.getCount(); - %tempMission = $CurrentMission; - %failsafe = 0; - while (1) - { - %nextMissionIndex = getNextMission(%tempMission, $CurrentMissionType); - %nextPotentialMission = $HostMissionFile[%nextMissionIndex]; - - //just cycle to the next if we've gone all the way around... - if (%nextPotentialMission $= $CurrentMission || %failsafe >= 1000) - { - %nextMissionIndex = getNextMission($CurrentMission, $CurrentMissionType); - //return $HostMissionName[%nextMissionIndex]; // z0dd - ZOD - Founder, 10/06/02. Was trying to load a mission name instead of file. - return $HostMissionFile[%nextMissionIndex]; - } - - //get the player count limits for this mission - %limits = $Host::MapPlayerLimits[%nextPotentialMission, $CurrentMissionType]; - if (%limits $= "") - return %nextPotentialMission; - else - { - %minPlayers = getWord(%limits, 0); - %maxPlayers = getWord(%limits, 1); - - if ((%minPlayers < 0 || %numPlayers >= %minPlayers) && (%maxPlayers < 0 || %numPlayers <= %maxPlayers)) - return %nextPotentialMission; - } - - //since we didn't return the mission, we must not have an acceptable number of players - check the next - %tempMission = %nextPotentialMission; - %failsafe++; - } -} - -function CycleMissions() -{ - echo( "cycling mission. " @ ClientGroup.getCount() @ " clients in game." ); - %nextMission = findNextCycleMission(); - messageAll( 'MsgClient', 'Loading %1 (%2)...', %nextMission, $MissionTypeDisplayName ); - loadMission( %nextMission, $CurrentMissionType ); -} - -function DestroyServer() -{ - $missionRunning = false; - allowConnections(false); - stopHeartbeat(); - if ( isObject( MissionGroup ) ) - MissionGroup.delete(); - if ( isObject( MissionCleanup ) ) - MissionCleanup.delete(); - if(isObject(game)) - { - game.deactivatePackages(); - game.delete(); - } - if(isObject($ServerGroup)) - $ServerGroup.delete(); - - // delete all the connections: - while(ClientGroup.getCount()) - { - %client = ClientGroup.getObject(0); - if (%client.isAIControlled()) - %client.drop(); - else - %client.delete(); - } - - // delete all the data blocks... - // this will cause problems if there are any connections - deleteDataBlocks(); - - // reset the target manager - resetTargetManager(); - - echo( "exporting server prefs..." ); - export( "$Host::*", "prefs/ServerPrefs.cs", false ); - purgeResources(); - - // z0dd - ZOD, 9/13/02. For TR2 compatability. - // This is a failsafe way of ensuring that default gravity is always restored - // if a game type (such as TR2) changes it. It is placed here so that listen - // servers will work after opening and closing different gametypes. - if ($DefaultGravity !$= "") - setGravity($DefaultGravity); -} - -function Disconnect() -{ - if ( isObject( ServerConnection ) ) - ServerConnection.delete(); - DisconnectedCleanup(); - DestroyServer(); -} - -function DisconnectedCleanup() -{ - $CurrentMissionType = ""; - $CurrentMission = ""; - - // Make sure we're not still waiting for the loading info: - cancelLoadInfoCheck(); - - // clear the chat hud message vector - HudMessageVector.clear(); - if ( isObject( PlayerListGroup ) ) - PlayerListGroup.delete(); - - // terminate all playing sounds - alxStopAll(); - - // clean up voting - voteHud.voting = false; - mainVoteHud.setvisible(0); - - // clear all print messages - clientCmdclearBottomPrint(); - clientCmdClearCenterPrint(); - - // clear the inventory and weapons hud - weaponsHud.clearAll(); - inventoryHud.clearAll(); - - // back to the launch screen - Canvas.setContent(LaunchGui); - if ( isObject( MusicPlayer ) ) - MusicPlayer.stop(); - clearTextureHolds(); - purgeResources(); - - if ( $PlayingOnline ) - { - // Restart the email check: - if ( !EmailGui.checkingEmail && EmailGui.checkSchedule $= "" ) - CheckEmail( true ); - - IRCClient::onLeaveGame(); - } -} - -// we pass the guid as well, in case this guy leaves the server. -function kick( %client, %admin, %guid ) -{ - if(%admin) - messageAll( 'MsgAdminForce', '\c2The Admin has kicked %1.', Game.kickClientName ); - else - messageAll( 'MsgVotePassed', '\c2%1 was kicked by vote.', Game.kickClientName ); - - messageClient(%client, 'onClientKicked', ""); - messageAllExcept( %client, -1, 'MsgClientDrop', "", Game.kickClientName, %client ); - - if( %client.isAIControlled() ) - { - $HostGameBotCount--; - %client.drop(); - } - else - { - if( $playingOnline ) // won games - { - %count = ClientGroup.getCount(); - %found = false; - for( %i = 0; %i < %count; %i++ ) // see if this guy is still here... - { - %cl = ClientGroup.getObject( %i ); - if( %cl.guid == %guid ) - { - %found = true; - - // kill and delete this client, their done in this server. - if( isObject( %cl.player ) ) - %cl.player.scriptKill(0); - - if ( isObject( %cl ) ) - { - %cl.setDisconnectReason( "You have been kicked out of the game." ); - %cl.schedule(700, "delete"); - } - - BanList::add( %guid, "0", $Host::KickBanTime ); - } - } - if( !%found ) - BanList::add( %guid, "0", $Host::KickBanTime ); // keep this guy out for a while since he left. - } - else // lan games - { - // kill and delete this client - if( isObject( %client.player ) ) - %client.player.scriptKill(0); - - if ( isObject( %client ) ) - { - %client.setDisconnectReason( "You have been kicked out of the game." ); - %client.schedule(700, "delete"); - } - - BanList::add( 0, %client.getAddress(), $Host::KickBanTime ); - } - } -} - -function ban( %client, %admin ) -{ - if ( %admin ) - messageAll('MsgAdminForce', '\c2%1 has banned %2.', %admin.name, %client.name); // z0dd - ZOD, 10/03/2. Tell who banned - else - messageAll( 'MsgVotePassed', '\c2%1 was banned by vote.', %client.name ); - - messageClient(%client, 'onClientBanned', ""); - messageAllExcept( %client, -1, 'MsgClientDrop', "", %client.name, %client ); - - // kill and delete this client - if( isObject(%client.player) ) - %client.player.scriptKill(0); - - if ( isObject( %client ) ) - { - %client.setDisconnectReason( %admin.nameBase @ " has banned you from this server." ); // z0dd - ZOD, 10/03/2. Tell who banned - %client.schedule(700, "delete"); - } - - BanList::add(%client.guid, %client.getAddress(), $Host::BanTime); -} - -function getValidVoicePitch(%voice, %voicePitch) -{ - if (%voicePitch < -1.0) - %voicePitch = -1.0; - else if (%voicePitch > 1.0) - %voicePitch = 1.0; - - //Voice pitch range is from 0.5 to 2.0, however, we should tighten the range to - //avoid players sounding like mickey mouse, etc... - //see if we're pitching down - clamp the min pitch at 0.875 - if (%voicePitch < 0) - return (1.0 + (0.125 * %voicePitch)); - - //max voice pitch is 1.125 - else if (%voicePitch > 0) - return 1.0 + (0.125 * %voicePitch); - - else - return 1.0; -} - -// z0dd - ZOD, 9/29/02. Removed T2 demo code from here - -function GameConnection::onConnect( %client, %name, %raceGender, %skin, %voice, %voicePitch ) -{ - %client.setMissionCRC($missionCRC); - sendLoadInfoToClient( %client ); - - //%client.setSimulatedNetParams(0.1, 30); - - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - - // --------------------------------------------------- - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - - // if hosting this server, set this client to superAdmin - if(%client.getAddress() $= "Local") - { - %client.isAdmin = true; - %client.isSuperAdmin = true; - } - // Get the client's unique id: - %authInfo = %client.getAuthInfo(); - %client.guid = getField( %authInfo, 3 ); - - // check admin and super admin list, and set status accordingly - if ( !%client.isSuperAdmin ) - { - if ( isOnSuperAdminList( %client ) ) - { - %client.isAdmin = true; - %client.isSuperAdmin = true; - } - else if( isOnAdminList( %client ) ) - { - %client.isAdmin = true; - } - } - - // Sex/Race defaults - switch$ ( %raceGender ) - { - case "Human Male": - %client.sex = "Male"; - %client.race = "Human"; - case "Human Female": - %client.sex = "Female"; - %client.race = "Human"; - case "Bioderm": - %client.sex = "Male"; - %client.race = "Bioderm"; - case "Draakan A": - %client.sex = "A"; - %client.race = "Draakan"; - case "Draakan B": - %client.sex = "B"; - %client.race = "Draakan"; - case "Draakan C": - %client.sex = "C"; - %client.race = "Draakan"; - case "Criollos": - %client.sex = "Male"; - %client.race = "Criollos"; - default: - error("Invalid race/gender combo passed: " @ %raceGender); - %client.sex = "Male"; - %client.race = "Human"; - } - %client.armor = "Light"; - - // Override the connect name if this server does not allow smurfs: - %realName = getField( %authInfo, 0 ); - if ( $PlayingOnline && $Host::NoSmurfs ) - %name = %realName; - - if ( strcmp( %name, %realName ) == 0 ) - { - %client.isSmurf = false; - - //make sure the name is unique - that a smurf isn't using this name... - %dup = -1; - %count = ClientGroup.getCount(); - for (%i = 0; %i < %count; %i++) - { - %test = ClientGroup.getObject( %i ); - if (%test != %client) - { - %rawName = stripChars( detag( getTaggedString( %test.name ) ), "\cp\co\c6\c7\c8\c9" ); - if (%realName $= %rawName) - { - %dup = %test; - %dupName = %rawName; - break; - } - } - } - - //see if we found a duplicate name - if (isObject(%dup)) - { - //change the name of the dup - %isUnique = false; - %suffixCount = 1; - while (!%isUnique) - { - %found = false; - %testName = %dupName @ "." @ %suffixCount; - for (%i = 0; %i < %count; %i++) - { - %cl = ClientGroup.getObject(%i); - %rawName = stripChars( detag( getTaggedString( %cl.name ) ), "\cp\co\c6\c7\c8\c9" ); - if (%rawName $= %testName) - { - %found = true; - break; - } - } - - if (%found) - %suffixCount++; - else - %isUnique = true; - } - - //%testName will now have the new unique name... - %oldName = %dupName; - %newName = %testName; - - MessageAll( 'MsgSmurfDupName', '\c2The real \"%1\" has joined the server.', %dupName ); - MessageAll( 'MsgClientNameChanged', '\c2The smurf \"%1\" is now called \"%2\".', %oldName, %newName, %dup ); - - %dup.name = addTaggedString(%newName); - setTargetName(%dup.target, %dup.name); - } - - // Add the tribal tag: - %tag = getField( %authInfo, 1 ); - %append = getField( %authInfo, 2 ); - if ( %append ) - %name = "\cp\c6" @ %name @ "\c7" @ %tag @ "\co"; - else - %name = "\cp\c7" @ %tag @ "\c6" @ %name @ "\co"; - - %client.sendGuid = %client.guid; - } - else - { - %client.isSmurf = true; - %client.sendGuid = 0; - %name = stripTrailingSpaces( strToPlayerName( %name ) ); - if ( strlen( %name ) < 3 ) - %name = "Poser"; - - // Make sure the alias is unique: - %isUnique = true; - %count = ClientGroup.getCount(); - for ( %i = 0; %i < %count; %i++ ) - { - %test = ClientGroup.getObject( %i ); - %rawName = stripChars( detag( getTaggedString( %test.name ) ), "\cp\co\c6\c7\c8\c9" ); - if ( strcmp( %name, %rawName ) == 0 ) - { - %isUnique = false; - break; - } - } - - // Append a number to make the alias unique: - if ( !%isUnique ) - { - %suffix = 1; - while ( !%isUnique ) - { - %nameTry = %name @ "." @ %suffix; - %isUnique = true; - - %count = ClientGroup.getCount(); - for ( %i = 0; %i < %count; %i++ ) - { - %test = ClientGroup.getObject( %i ); - %rawName = stripChars( detag( getTaggedString( %test.name ) ), "\cp\co\c6\c7\c8\c9" ); - if ( strcmp( %nameTry, %rawName ) == 0 ) - { - %isUnique = false; - break; - } - } - - %suffix++; - } - - // Success! - %name = %nameTry; - } - - %smurfName = %name; - // Tag the name with the "smurf" color: - %name = "\cp\c8" @ %name @ "\co"; - } - - %client.name = addTaggedString(%name); - if(%client.isSmurf) - %client.nameBase = %smurfName; - else - %client.nameBase = %realName; - - // Make sure that the connecting client is not trying to use a bot skin: - %temp = detag( %skin ); - if ( %temp $= "basebot" || %temp $= "basebbot" ) - %client.skin = addTaggedString( "base" ); - else - %client.skin = addTaggedString( %skin ); - - %client.voice = %voice; - %client.voiceTag = addtaggedString(%voice); - - //set the voice pitch based on a lookup table from their chosen voice - %client.voicePitch = getValidVoicePitch(%voice, %voicePitch); - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - // --------------------------------------------------- - - %client.justConnected = true; - %client.isReady = false; - - // full reset of client target manager - clientResetTargets(%client, false); - - %client.target = allocClientTarget(%client, %client.name, %client.skin, %client.voiceTag, '_ClientConnection', 0, 0, %client.voicePitch); - %client.score = 0; - %client.team = 0; - - $instantGroup = ServerGroup; - $instantGroup = MissionCleanup; - - echo("CADD: " @ %client @ " " @ %client.getAddress()); - - %count = ClientGroup.getCount(); - for(%cl = 0; %cl < %count; %cl++) - { - %recipient = ClientGroup.getObject(%cl); - if((%recipient != %client)) - { - // These should be "silent" versions of these messages... - messageClient(%client, 'MsgClientJoin', "", - %recipient.name, - %recipient, - %recipient.target, - %recipient.isAIControlled(), - %recipient.isAdmin, - %recipient.isSuperAdmin, - %recipient.isSmurf, - %recipient.sendGuid); - - messageClient(%client, 'MsgClientJoinTeam', "", %recipient.name, $teamName[%recipient.team], %recipient, %recipient.team ); - } - } - -// commandToClient(%client, 'getManagerID', %client); - - commandToClient(%client, 'setBeaconNames', "Target Beacon", "Marker Beacon", "Bomb Target"); - - if ( $CurrentMissionType !$= "SinglePlayer" ) - { - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - messageClient(%client, 'MsgClientJoin', '\c2Welcome to Tribes 2: Birth of Legend %1.', - %client.name, - %client, - %client.target, - false, // isBot - %client.isAdmin, - %client.isSuperAdmin, - %client.isSmurf, - %client.sendGuid ); - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - - messageAllExcept(%client, -1, 'MsgClientJoin', '\c1%1 joined the game.', - %client.name, - %client, - %client.target, - false, // isBot - %client.isAdmin, - %client.isSuperAdmin, - %client.isSmurf, - %client.sendGuid ); - } - else - messageClient(%client, 'MsgClientJoin', "\c0Mission Insertion complete...", - %client.name, - %client, - %client.target, - false, // isBot - false, // isAdmin - false, // isSuperAdmin - false, // isSmurf - %client.sendGuid ); - - //Game.missionStart(%client); - setDefaultInventory(%client); - - if($missionRunning) - %client.startMission(); - $HostGamePlayerCount++; - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - - // z0dd - ZOD 4/29/02. Activate the clients Classic Huds - // and start off with 0 SAD access attempts. - %client.SadAttempts = 0; - messageClient(%client, 'MsgBomberPilotHud', ""); // Activate the bomber pilot hud - - // z0dd - ZOD, 8/10/02. Get player hit sounds etc. - commandToClient(%client, 'GetClassicModSettings', 1); - - //--------------------------------------------------------- - // z0dd - ZOD, 7/12/02. New AutoPW server function. Sets - // server join password when server reaches x player count. - if($Host::ClassicAutoPWEnabled) - { - if(($Host::ClassicAutoPWPlayerCount != 0 && $Host::ClassicAutoPWPlayerCount !$= "") && ($HostGamePlayerCount >= $Host::ClassicAutoPWPlayerCount)) - AutoPWServer(1); - } -} - -function GameConnection::onDrop(%client, %reason) -{ - - if (!%client.isAIControlled()) //Bots disconnect left and right in this mod, ignore the client if it's a bot - saveGame(); - - if(isObject(Game)) - Game.onClientLeaveGame(%client); - - // make sure that tagged string of player name is not used - if (!%client.isAIControlled()) - { - if ( $CurrentMissionType $= "SinglePlayer" || $CurrentMissionType $= "SV") - messageAllExcept(%client, -1, 'MsgClientDrop', "", getTaggedString(%client.name), %client); - else - messageAllExcept(%client, -1, 'MsgClientDrop', '\c1%1 has left the game.', getTaggedString(%client.name), %client); - } - - if ( isObject( %client.camera ) ) - %client.camera.delete(); - - // z0dd - ZOD, 6/19/02. Strip the hit sound tags - removeTaggedString(%client.playerHitWav); - removeTaggedString(%client.vehicleHitWav); - - removeTaggedString(%client.name); - removeTaggedString(%client.voiceTag); - removeTaggedString(%client.skin); - freeClientTarget(%client); - - echo("CDROP: " @ %client @ " " @ %client.getAddress()); - $HostGamePlayerCount--; - - //--------------------------------------------------------- - // z0dd - ZOD, 7/12/02. New AutoPW server function. Sets - // server join password when server reaches x player count. - if($Host::ClassicAutoPWEnabled) - { - if($HostGamePlayerCount < $Host::ClassicAutoPWPlayerCount) - AutoPWServer(0); - } - // reset the server if everyone has left the game - //if( $HostGamePlayerCount - $HostGameBotCount == 0 && $Host::Dedicated && !$resettingServer && !$LoadingMission ) - // schedule(0, 0, "resetServerDefaults"); - - // ------------------------------------------------------------------------------------------------------------ - // z0dd - ZOD, 5/12/02. Reset the server if everyone has left the game and set this mission as startup mission. - // This helps with $Host::ClassicRandomMissions to keep the random more random. - if( $HostGamePlayerCount - $HostGameBotCount == 0 && $Host::Dedicated && !$resettingServer && !$LoadingMission && $CurrentMissionType !$= "RPG" ) //The server should never reset itself.. - { - $Host::Map = $CurrentMission; - export("$Host::*", "prefs/ServerPrefs.cs", false); - $Host::MissionType = $CurrentMissionType; - export("$Host::*", "prefs/ServerPrefs.cs", false); - schedule(10, 0, "resetServerDefaults"); - } - // ------------------------------------------------------------------------------------------------------------ -} - -function dismountPlayers() -{ - // make sure all palyers are dismounted from vehicles and have normal huds - %count = ClientGroup.getCount(); - for(%cl = 0; %cl < %count; %cl++) - { - %client = ClientGroup.getObject(%cl); - %player = %client.player; - if(%player.isMounted()) { - %player.unmount(); - commandToClient(%client, 'setHudMode', 'Standard', "", 0); - } - } -} - -function loadMission( %missionName, %missionType, %firstMission ) -{ - if ($AutoRestart) // z0dd - ZOD, 3/26/02. Auto restart server after a specified time. - { - $AutoRestart = 0; - messageAll( 'MsgServerRestart', '\c2SERVER IS AUTO REBOOTING! COME BACK IN 5 MINUTES.~wfx/misc/red_alert.wav'); - logEcho("Auto server restart commencing."); - //schedule(10000, 0, "CreateServer", %missionName, %missionType); // this wasn't working as a cure for servers with NULLs - schedule(10000, 0, quit ); - } - - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - - // z0dd - ZOD, 9/13/02. TR2 needs this. - if( %missionType $= "TR2" ) - { - $_Camera::movementSpeed = $Camera::movementSpeed; - $Camera::movementSpeed = 80; - } - else - { - %val = ($_Camera::movementSpeed $= "") ? $Classic::cameraSpeed : $_Camera::movementSpeed; // z0dd - ZOD, 9/13/02. Classic camera speed. - $Camera::movementSpeed = %val; - } - - $LoadingMission = true; - disableCyclingConnections(true); - if (!$pref::NoClearConsole) - cls(); - if ( isObject( LoadingGui ) ) - LoadingGui.gotLoadInfo = ""; - buildLoadInfo( %missionName, %missionType ); - - // reset all of these - ClearCenterPrintAll(); - ClearBottomPrintAll(); - - if( $Host::TournamentMode ) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - resetTournamentPlayers(); - - // Send load info to all the connected clients: - %count = ClientGroup.getCount(); - for ( %cl = 0; %cl < %count; %cl++ ) - { - %client = ClientGroup.getObject( %cl ); - if ( !%client.isAIControlled() ) - sendLoadInfoToClient( %client ); - } - - // allow load condition to exit out - schedule(0,ServerGroup,loadMissionStage1,%missionName,%missionType,%firstMission); -} - -function loadMissionStage1(%missionName, %missionType, %firstMission) -{ - // if a mission group was there, delete prior mission stuff - if(isObject(MissionGroup)) - { - // clear out the previous mission paths - for(%clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++) - { - // clear ghosts and paths from all clients - %cl = ClientGroup.getObject(%clientIndex); - %cl.resetGhosting(); - %cl.clearPaths(); - %cl.isReady = ""; - %cl.matchStartReady = false; - } - Game.endMission(); - $lastMissionTeamCount = Game.numTeams; - - MissionGroup.delete(); - MissionCleanup.delete(); - Game.deactivatePackages(); - Game.delete(); - $ServerGroup.delete(); - $ServerGroup = new SimGroup(ServerGroup); - } - - %oldMissionType = $CurrentMissionType; - //Ok, make sure we deactivate the mission package before loading a new one - deactivatePackage($CurrentMission); - $CurrentMission = %missionName; - $CurrentMissionType = %missionType; - - createInvBanCount(); - echo("LOADING MISSION: " @ %missionName); - - // increment the mission sequence (used for ghost sequencing) - $missionSequence++; - - // if this isn't the first mission, allow some time for the server - // to transmit information to the clients: - -// jff: $currentMission already being used for this purpose, used in 'finishLoadMission' - $MissionName = %missionName; - $missionRunning = false; - - if(!%firstMission) - schedule(15000, ServerGroup, loadMissionStage2); - else - loadMissionStage2(); -} - - -function loadMissionStage2() -{ - // create the mission group off the ServerGroup - echo("Stage 2 load"); - $instantGroup = ServerGroup; - - new SimGroup (MissionCleanup); - - if($CurrentMissionType $= "") - { - new ScriptObject(Game) { - class = DefaultGame; - }; - } - else - { - new ScriptObject(Game) { - class = $CurrentMissionType @ "Game"; - superClass = DefaultGame; - }; - } - // allow the game to activate any packages. - Game.activatePackages(); - - // reset the target manager - resetTargetManager(); - - %file = "missions/" @ $missionName @ ".mis"; - %script = "missions/" @ $missionName @ ".cs"; - - if(!isFile(%file)) - return; - - // send the mission file crc to the clients (used for mission lighting) - $missionCRC = getFileCRC(%file); - %count = ClientGroup.getCount(); - for(%i = 0; %i < %count; %i++) - { - %client = ClientGroup.getObject(%i); - if(!%client.isAIControlled()) - %client.setMissionCRC($missionCRC); - } - - $countDownStarted = false; - if (IsFile(%script)) //If the mission has a script.. - exec(%script); //execute - exec(%file); //Load our mission while we're at it - $instantGroup = MissionCleanup; - - // pre-game mission stuff - if(!isObject(MissionGroup)) - { - error("No 'MissionGroup' found in mission \"" @ $missionName @ "\"."); - schedule(3000, ServerGroup, CycleMissions); - return; - } - - MissionGroup.cleanNonType($CurrentMissionType); - - // construct paths - pathOnMissionLoadDone(); - - $ReadyCount = 0; - $MatchStarted = false; - $CountdownStarted = false; - AISystemEnabled( false ); - - // Set the team damage here so that the game type can override it: - - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - if ( $Host::TournamentMode ) - $TeamDamage = 1; - else - $TeamDamage = $Host::TeamDamageOn; - // ---------------------------------------- - - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - - // z0dd - ZOD, 8/4/02. Gravity change - if(getGravity() !$= $Classic::gravSetting) - setGravity($Classic::gravSetting); - // --------------------------------------------- - - Game.missionLoadDone(); - - // start all the clients in the mission - $missionRunning = true; - for(%clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++) - ClientGroup.getObject(%clientIndex).startMission(); - - if(!$MatchStarted && $LaunchMode !$= "NavBuild" && $LaunchMode !$= "SpnBuild" ) - { - if( $Host::TournamentMode ) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - checkTourneyMatchStart(); - else if( $currentMissionType !$= "SinglePlayer" ) - checkMissionStart(); - } - - // offline graph builder... - if( $LaunchMode $= "NavBuild" ) - buildNavigationGraph( "Nav" ); - - if( $LaunchMode $= "SpnBuild" ) - buildNavigationGraph( "Spn" ); - purgeResources(); - disableCyclingConnections(false); - $LoadingMission = false; - - //Ok, if the script exists, activate the package and load AI's for this map - if (IsFile(%script) && $CurrentMissionType $= "RPG") - { - activatePackage($missionName); - DefineGeneralAI(); //Load the AI's - - //Now, the game is pretty much done. We got to spawn our AI's - for (%i = 0; %i < $BotCount; %i++) - { - spawnGeneralBot(%i); - } - } - - serverThink(); //Start server think loop - - if (%oldMissionType !$= "RPG" && %missionType $= "RPG") //Going from some gamemode to RPG - disconnectAllBots(); - else if (%oldMissionType $= "RPG" && %missionType !$= "RPG") //Going from RPG to some gamemode - discconectAllBots(); - -} - -function ShapeBase::cleanNonType(%this, %type) -{ - if(%this.missionTypesList $= "") - return; - - for(%i = 0; (%typei = getWord(%this.missionTypesList, %i)) !$= ""; %i++) - if(%typei $= %type) - return; - - // first 32 targets are team targets (never allocated/freed) - // - must reallocate the target if unhiding - if(%this.getTarget() >= 32) - { - freeTarget(%this.getTarget()); - %this.setTarget(-1); - } - if(isObject(%this.trigger)) // z0dd - ZOD, 8/10/02. Clean them triggers too! - %this.trigger.delete(); - - %this.hide(true); -} - -function SimObject::cleanNonType(%this, %type) -{ -} - -function SimGroup::cleanNonType(%this, %type) -{ - for (%i = 0; %i < %this.getCount(); %i++) - %this.getObject(%i).cleanNonType(%type); -} - -function GameConnection::endMission(%this) -{ - commandToClient(%this, 'MissionEnd', $missionSequence); -} - -//-------------------------------------------------------------------------- -// client start phases: -// 0: start mission -// 1: got phase1 done -// 2: got datablocks done -// 3: got phase2 done -// 4: got phase3 done -function GameConnection::startMission(%this) -{ - // send over the information that will display the server info - // when we learn it got there, we'll send the data blocks - %this.currentPhase = 0; - - //Make sure the client is an RPG client.. - if ($CurrentMissionType $= "RPG") - commandToClient(%this, 'HandleScriptedCommand',5,true); //Send us the current time in military format - else - commandToClient(%this, 'HandleScriptedCommand',5,false); //Not running the RPG gamemode, so don't setup the clock & scoreScreen text change - - %this.team = getRaceTeam(%this.race); - - commandToClient(%this, 'MissionStartPhase1', $missionSequence, $MissionName, MissionGroup.musicTrack); -} - -function serverCmdInputDone(%client, %type, %value) //Used when creating/editing clans -{ - switch$(%type) - { - case "ClanN": - %client.clanN = %value; - case "ClanT": - %client.clanT = %value; - case "Desc": - %client.description = %value; - case "emailTitle": - %client.emailTitle = %value; - case "emailCont": - //Every 39 chars add a \t tag.. - %cont = %value; - %len = strLen(%value); - - if (%len > 39) - %value = subStrInsert(%value,"\t",39); - - %client.emailCont = %value; - } - if (%type $= "ClanN" || %type $= "ClanT" || %type $= "Desc") - forceScoreScreenOpen(%client,"CLNSTP"); - else - forceScoreScreenOpen(%client,"EMAILSEND"); -} - -function serverCmdMissionStartPhase1Done(%client, %seq) -{ - if(%seq != $missionSequence || !$MissionRunning) - return; - - if(%client.currentPhase != 0) - return; - %client.currentPhase = 1; - - // if (!%client.isValid && $RequiresClient[$CurrentMissionType]) //Did this person say he's a client and the gamemode requires //clientside stuff? -/// return clientDisconnect(%client,"You do not have a Tribes 2: Birth of Legend mod client running."); - - schedule(1000, 0, "debriefLoad", %client); - - // when the datablocks are transmitted, we'll send the ghost always objects - %client.transmitDataBlocks($missionSequence); -} - -function GameConnection::dataBlocksDone( %client, %missionSequence ) -{ - echo("GOT DATA BLOCKS DONE FOR: " @ %client); - if(%missionSequence != $missionSequence) - return; - - if(%client.currentPhase != 1) - return; - %client.currentPhase = 2; - - // only want to set this once... (targets will not be updated/sent until a - // client has this flag set) - if(!%client.getReceivedDataBlocks()) - { - %client.setReceivedDataBlocks(true); - sendTargetsToClient(%client); - } - - commandToClient(%client, 'MissionStartPhase2', $missionSequence); -} - -function serverCmdMissionStartPhase2Done(%client, %seq) -{ - if(%seq != $missionSequence || !$MissionRunning) - return; - - if(%client.currentPhase != 2) - return; - %client.currentPhase = 3; - - // when all this good love is over, we'll know that the mission lighting is done - %client.transmitPaths(); - - // setup the client team state - if ( $CurrentMissionType !$= "SinglePlayer" ) - serverSetClientTeamState( %client ); - - // start ghosting - %client.activateGhosting(); - %client.camera.scopeToClient(%client); - - // to the next phase... - commandToClient(%client, 'MissionStartPhase3', $missionSequence, $CurrentMission); -} - -function serverCmdMissionStartPhase3Done(%client, %seq) -{ - if(%seq != $missionSequence || !$MissionRunning) - return; - - if(%client.currentPhase != 3) - return; - %client.currentPhase = 4; - - %client.isReady = true; - Game.clientMissionDropReady(%client); -} - -function serverSetClientTeamState( %client ) -{ - // set all player states prior to mission drop ready - - // create a new camera for this client - %client.camera = new Camera() - { - dataBlock = Observer; - }; - - if( isObject( %client.rescheduleVote ) ) - Cancel( %client.rescheduleVote ); - %client.canVote = true; - %client.rescheduleVote = ""; - - MissionCleanup.add( %client.camera ); // we get automatic cleanup this way. - - %observer = false; - if( !$Host::TournamentMode ) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - { - if( %client.justConnected ) - { - %client.justConnected = false; - %client.camera.getDataBlock().setMode( %client.camera, "justJoined" ); - } - else - { - // server just changed maps - this guy was here before - if( %client.lastTeam !$= "" ) - { - // see if this guy was an observer from last game - if(%client.lastTeam == 0) - { - %observer = true; - - %client.camera.getDataBlock().setMode( %client.camera, "ObserverFly" ); - } - else // let this player join the team he was on last game - { - if(Game.numTeams > 1 && %client.lastTeam <= Game.numTeams ) - { - Game.clientJoinTeam( %client, %client.lastTeam, false ); - } - else - { - Game.assignClientTeam( %client ); - - // spawn the player - Game.spawnPlayer( %client, false ); - } - } - } - else - { - Game.assignClientTeam( %client ); - - // spawn the player - Game.spawnPlayer( %client, false ); - } - - if( !%observer ) - { - if(!$MatchStarted && !$CountdownStarted) - %client.camera.getDataBlock().setMode( %client.camera, "pre-game", %client.player ); - else if(!$MatchStarted && $CountdownStarted) - %client.camera.getDataBlock().setMode( %client.camera, "pre-game", %client.player ); - } - } - } - else - { - // don't need to do anything. MissionDrop will handle things from here. - } -} - -//function serverCmdPreviewDropReady( %client ) -//{ -// $MatchStarted = true; -// commandToClient( %client, 'SetMoveKeys', true); -// %markerObj = "0 0 0"; -// %client.camera.mode = "PreviewMode"; -// %client.camera.setTransform( %markerObj ); -// %client.camera.setFlyMode(); -// -// %client.setControlObject( %client.camera ); -//} - -function HideHudHACK(%visible) -{ - //compassHud.setVisible(%visible); - //enerDamgHud.setVisible(%visible); - retCenterHud.setVisible(%visible); - reticleFrameHud.setVisible(%visible); - //invPackHud.setVisible(%visible); - weaponsHud.setVisible(%visible); - outerChatHud.setVisible(%visible); - objectiveHud.setVisible(%visible); - chatHud.setVisible(%visible); - navHud.setVisible(%visible); - //watermarkHud.setVisible(%visible); - hudClusterBack.setVisible(%visible); - inventoryHud.setVisible(%visible); - clockHUD.setVisible(%visible); -} - -function ServerPlay2D(%profile) -{ - for(%idx = 0; %idx < ClientGroup.getCount(); %idx++) - ClientGroup.getObject(%idx).play2D(%profile); -} - -function ServerPlay3D(%profile,%transform) -{ - for(%idx = 0; %idx < ClientGroup.getCount(); %idx++) - ClientGroup.getObject(%idx).play3D(%profile,%transform); -} - -function clientCmdSetFirstPerson(%value) -{ - $firstPerson = %value; - if(%value) - ammoHud.setVisible(true); - else - ammoHud.setVisible(false); -} - -function clientCmdGetFirstPerson() -{ - commandToServer('FirstPersonValue', $firstPerson); -} - -function serverCmdFirstPersonValue(%client, %firstPerson) -{ - %client.player.firstPerson = %firstPerson; -} - -function clientCmdVehicleMount() -{ - if ( $pref::toggleVehicleView ) - { - $wasFirstPerson = $firstPerson; - $firstPerson = false; - } -} - -function clientCmdVehicleDismount() -{ - if ( $pref::toggleVehicleView ) - $firstPerson = $wasFirstPerson; -} - -//---------------------------------------------------- -// z0dd - ZOD, 3/09/02. Re-write. It's more flexible. -function serverCmdSAD(%client, %password) -{ - if(%password $= "") - { - messageClient(%client, 'MsgPasswordFailed', '\c2You did not supply a PW.'); - return; - } - %name = %client.name; - - switch$ (%password) - { - case $Host::ClassicSuperAdminPassword: - if(!%client.isSuperAdmin) - { - if(%password $= "changeme") - { - messageClient(%client, 'MsgPasswordFailed', '\c2Illegal SAD PW. You need to change the default \"$Host::ClassicSuperAdminPassword\" value in \"ServerPrefs.cs\"!'); - return; - } - %client.isAdmin = true; - %client.isSuperAdmin = true; - MessageAll( 'MsgSuperAdminPlayer', '\c2%2 has become a Super Admin by force.', %client, %name); - logEcho(%client.nameBase @ " has become a Super Admin by force."); - } - - case $Host::AdminPassword: - if(!%client.isAdmin) - { - if(%password $= "changethis") - { - messageClient(%client, 'MsgPasswordFailed', '\c2Illegal Admin PW. You need to change the default \"$Host::AdminPassword\" value in \"ServerPrefs.cs\"!'); - return; - } - %client.isAdmin = true; - %client.isSuperAdmin = false; - MessageAll( 'MsgAdminForce', '\c2%2 has become a Admin by force.', %client, %name); - logEcho(%client.nameBase @ " has become an Admin by force."); - } - default: - messageClient(%client, 'MsgPasswordFailed', '\c2Illegal SAD PW.'); - %client.SadAttempts++; - if(%client.SadAttempts >= 6 && !%client.isSuperAdmin) - { - %client.getAddress(); - %client.getAuthInfo(); - messageClient(%client, 'onClientBanned', 'For attempting to exploit SAD to gain unauthorized Admin by entering\ntoo many passwords, you are being Banned'); - if( isObject(%client.player) ) - { - %client.player.scriptKill(0); - %client.schedule(700, "delete"); - } - schedule(10, %client @ "ResetSadAttp", %client); - %client.setDisconnectReason( 'For attempting to exploit SAD to gain unauthorized Admin by entering\ntoo many passwords, you are being Banned.' ); - %client.schedule(700, "delete"); - BanList::add(%client.guid, %client.getAddress(), $Host::BanTime); - logEcho(%client.nameBase @ " " @ %client.guid @ " has been banned for excessive use of SAD"); - } - } -} - -function ResetSadAttp(%client) -{ - %client.SadAttempts = 0; -} - -//--------------------------------------------------------------- -// z0dd - ZOD, 8/13/02. Added this function. Writen by Writer -// -// Returns true if %text consists of nothing but digits and/or -// decimals. -// Note: rejects strings with more than one decimal, or with a + -// or - as anything but the first character (+ or - are only -// allowed as the first character in the string) -function isNumber(%text) -{ - for(%i = 0; (%char = getSubStr(%text, %i, 1)) !$= ""; %i++) - { - switch$(%char) - { - case "0": - continue; - case "1": - continue; - case "2": - continue; - case "3": - continue; - case "4": - continue; - case "5": - continue; - case "6": - continue; - case "7": - continue; - case "8": - continue; - case "9": - continue; - case ".": - if(%dot_count > 1) - return false; - - %dot_count++; - continue; - case "-": - if(%i) // only valid as first character - return false; - - continue; - case "+": - if(%i) // only valid as first character - return false; - - continue; - default: - return false; - } - } - // %text passed the test - return true; -} -//--------------------------------------------------------------- - -//--------------------------------------------------------- -// z0dd - ZOD, 3/10/02. New remote admin control function -function serverCmdSet(%client, %type, %val) -{ - // USAGE: commandToServer('Set', type, value); - %type = deTag(%type); - %val = deTag(%val); - - if(!%client.isSuperAdmin) - { - messageClient(%client, 'MsgNotSuperAdmin', '\c2Only Super Admins can use that command.'); - return; - } - if(%type $= "") - { - messageClient(%client, 'MsgTypeFailed', '\c2No Changes. You did not supply a type.'); - return; - } - //if( (%val $= "") && (%type !$= "joinpw") ) - if(%val $= "") - { - if(%type $= "joinpw") - messageClient(%client, 'MsgValueFailed', '\c2No Changes. You did not supply a value. Use \"remove\" to remove join pw.'); - else - messageClient(%client, 'MsgValueFailed', '\c2No Changes. You did not supply a value.'); - return; - } - %name = %client.name; - switch$ (%type) - { - case "superpw": - $Host::ClassicSuperAdminPassword = %val; - export( "$Host::*", "prefs/ServerPrefs.cs", false ); - messageClient(%client, 'MsgSuperPassword', '\c2\"Super Admin\" PW changed to: \c3%1\c2.', addTaggedString(%val)); - logEcho(%client.nameBase @ " changed the Super Admin password."); - - case "adminpw": - $Host::AdminPassword = %val; - export( "$Host::*", "prefs/ServerPrefs.cs", false ); - messageClient(%client, 'MsgAdminPassword', '\c2\"Admin\" PW changed to: \c3%1\c2.', addTaggedString(%val)); - logEcho(%client.nameBase @ " changed the Admin password."); - - case "joinpw": - if(%val $= "remove") - $Host::Password = ""; - else - $Host::Password = %val; - - export( "$Host::*", "prefs/ServerPrefs.cs", false ); - messageAll( 'MsgServerPassword', '\c3%1\c2: JOIN PASSWORD CHANGED.~wfx/misc/diagnostic_on.wav', %name); - if(%val $= "remove") - messageClient(%client, 'MsgServerPassword', '\c2Join PW removed.'); - else - messageClient(%client, 'MsgServerPassword', '\c2Join PW changed to: \c3%1\c2.', addTaggedString(%val)); - logEcho(%client.nameBase @ " changed the join password."); - - case "maxplayers": - - if(isNumber(%val) && (%val > 0)) - { - $Host::MaxPlayers = %val; - export( "$Host::*", "prefs/ServerPrefs.cs", false ); - messageAll( 'MsgMaxPlayersSet', '\c3%1\c2: PLAYER LIMIT CHANGED TO: \c3%2\c2.~wfx/misc/diagnostic_on.wav', %name, %val); - logEcho(%client.nameBase @ " changed the Player Limit."); - } - else - { - messageClient( %client, 'MsgAdmin', '\c2Value must be a positive number.' ); - } - - case "restart": - if (%val $= "0") - { - $AutoRestart = 0; - messageClient( %client, 'MsgAdmin', '\c2Server restart at mission end aborted.' ); - messageAll( 'MsgServerRestart', '\c3%1\c2: SERVER RESTART HAS BEEN CANCELED.~wfx/misc/diagnostic_on.wav', %name); - } - else if (%val $= "1") - { - messageAll( 'MsgServerRestart', '\c3%1\c2: SERVER WILL BE REBOOTING IN 30 SECONDS!.~wfx/misc/red_alert.wav', %name); - schedule(20000, 0, "messageAll", 'MsgServerRestart', '\c2SERVER WILL REBOOT IN 10 SECONDS!.~wfx/misc/hunters_10.wav'); - schedule(30000, 0, quit); - logEcho(%client.nameBase @ " forced a server restrart."); - } - else - { - messageClient( %client, 'MsgAdmin', '\c2Unknown restart value. 0 cancels restart, 1 forces restart.' ); - } - - case "random": - if(%val $= "0" || %val $= "1") - { - if($CurrentMissionType $= TR2) // z0dd - ZOD, 9/17/02. Check for Team Rabbit 2 - { - messageClient( %client, 'MsgAdmin', '\c2This feature is unavailable in Team Rabbit 2.' ); - return; - } - $Host::ClassicRandomizeTeams = %val; - export( "$Host::*", "prefs/ServerPrefs.cs", false ); - %detail = ($Host::ClassicRandomizeTeams ? "ENABLED" : "DISABLED"); - messageAll( 'MsgRandomTeams', '\c3%1\c2: RANDOM TEAMS %2. Changes will take place next mission.~wfx/misc/diagnostic_on.wav', %name, %detail); - logEcho(%client.nameBase @ " " @ %detail @ " random teams."); - } - else - { - messageClient( %client, 'MsgAdmin', '\c2Unknown input value. 0 disables Random Teams, 1 enables Random Teams.' ); - } - - case "fairteams": - if(%val $= "0" || %val $= "1") - { - if($CurrentMissionType $= TR2) // z0dd - ZOD, 9/17/02. Check for Team Rabbit 2 - { - messageClient( %client, 'MsgAdmin', '\c2This feature is unavailable in Team Rabbit 2.' ); - return; - } - $Host::ClassicFairTeams = %val; - export( "$Host::*", "prefs/ServerPrefs.cs", false ); - %detail = ($Host::ClassicFairTeams ? "ENABLED" : "DISABLED"); - messageAll( 'MsgRandomTeams', '\c3%1\c2: FAIR TEAMS %2.~wfx/misc/diagnostic_on.wav', %name, %detail ); - logEcho(%client.nameBase @ " " @ %detail @ " fair teams."); - } - else - { - messageClient( %client, 'MsgAdmin', '\c2Unknown input value. 0 disables Fair Teams, 1 enables Fair Teams.' ); - } - - default: - messageClient(%client, 'MsgValueFailed', '\c2No Changes. You did not specify a valid type.'); - } -} -//---------------------------------------------------------- -// z0dd - ZOD, 7/12/02. New AutoPW server functions. Sets -// server join password when server reaches x player count. -function AutoPWServer(%val) -{ - if(%val && ($Host::ClassicAutoPWPassword !$= "changeit")) - $Host::Password = $Host::ClassicAutoPWPassword; - else - $Host::Password = ""; - -// z0dd - ZOD, 9/27/02, Chat was being spammed every time someone joined if limit was hit or above -// %detail = (($Host::Password $= "") ? "removed" : "set"); -// messageAll( 'MsgAdmin', '\c2Join password %1 by Auto-password feature.', %detail ); -} - -function serverCmdAutoPWSetup(%client, %type, %val) -{ - // USAGE: commandToServer('AutoPWSetup', type, value); - %type = deTag(%type); - %val = deTag(%val); - if(!%client.isSuperAdmin) - { - messageClient(%client, 'MsgNotSuperAdmin', '\c2Only Super Admins can use this command.'); - return; - } - if(%type $= "") - { - messageClient(%client, 'MsgTypeFailed', '\c2No Changes. You did not supply a type.'); - return; - } - switch$ (%type) - { - case "autopw": - if (%val $= "0") - { - $Host::ClassicAutoPWEnabled = 0; - AutoPWServer(0); - messageClient( %client, 'MsgAdmin', '\c2Auto-password disabled.' ); - } - else if (%val $= "1") - { - $Host::ClassicAutoPWEnabled = 1; - messageClient( %client, 'MsgAdmin', '\c2Auto-password enabled.' ); - logEcho(%client.nameBase @ " enabled Auto-password."); - } - else - { - messageClient( %client, 'MsgAdmin', '\c2Unknown value. 0 disables Auto-password, 1 enables Auto-password.' ); - } - - case "autopwpass": - if(%val !$= "") - { - $Host::ClassicAutoPWPassword = %val; - } - else - { - messageClient( %client, 'MsgAdmin', '\c2You must specify a password.' ); - return; - } - export( "$Host::*", "prefs/ServerPrefs.cs", false ); - messageClient(%client, 'MsgServerPassword', '\c2Server Auto-password PW changed to: \c3%1\c2.', addTaggedString(%val)); - logEcho(%client.nameBase @ " changed the Auto-password PW."); - - case "autopwcount": - if(%val !$= "" && %val !$= "0") - { - $Host::ClassicAutoPWPlayerCount = %val; - } - else - { - messageClient( %client, 'MsgAdmin', '\c2You must specify a numerical value.' ); - return; - } - export( "$Host::*", "prefs/ServerPrefs.cs", false ); - messageClient(%client, 'MsgServerPassword', '\c2Server Auto-password player count changed to: \c3%1\c2.', addTaggedString(%val)); - logEcho(%client.nameBase @ " changed the Auto-password player count."); - } -} - -//--------------------------------------------------------------------------------------------------- -// z0dd - ZOD, 4-15-02. Pick spawn spot by killing self during tourney wait. Also addresses -// team switching to crash server exploit. New function -$WAIT_PERIOD = 20000; -$WAIT_MESSAGE = '\c3WAIT MESSAGE:\cr You must wait another %1 seconds'; - -function GameConnection::waitTimeout(%this) -{ - %this.isWaiting = false; -} - -function SpawnPosChange( %client ) -{ - if( isObject( Game ) && %client != Game.kickClient && $Host::TournamentMode && !$CountdownStarted) - { - if (!%client.isWaiting) - { - %client.isWaiting = true; - %client.waitStart = getSimTime(); - %client.schedule($WAIT_PERIOD, waitTimeout); - - clearBottomPrint(%client); - Game.clientChangeTeam( %client, %client.team, 0, true ); - - if(!$MatchStarted) - { - %client.observerMode = "pregame"; - %client.notReady = true; - %client.camera.getDataBlock().setMode( %client.camera, "pre-game", %client.player ); - %client.setControlObject( %client.camera ); - - if( !$CountdownStarted) - { - %client.notReady = true; - centerprint( %client, "\nPress FIRE when ready.", 0, 3 ); - } - } - else - { - commandToClient(%client, 'setHudMode', 'Standard', "", 0); - } - } - else - { - %wait = mFloor(($WAIT_PERIOD - (getSimTime() - %client.waitStart)) / 1000); - messageClient(%client, "", $WAIT_MESSAGE, %wait); - } - } -} -//--------------------------------------------------------------------------------------------------- - -function serverCmdSuicide(%client) -{ -if ($CurrentMissionType $= "RPG") //If it's RPG, stop here! -return; - - if(!isObject(%client.player)) // z0dd - ZOD, 4-15-02. Console spam fix. - return; - - // z0dd - ZOD, 4-15-02: Pick spawn spot by killing self during tourney wait - if( $MatchStarted ) - { - %client.player.scriptKill($DamageType::Suicide); - } - else - { - if($CurrentMissionType !$= TR2) // z0dd - ZOD, 9/17/02. Check for Team Rabbit 2 - SpawnPosChange( %client ); - } -} - -function serverCmdToggleCamera(%client) -{ - if ($testcheats || $CurrentMissionType $= "SinglePlayer") - { - %control = %client.getControlObject(); - if (%control == %client.player) - { - %control = %client.camera; - %control.mode = toggleCameraFly; - %control.setFlyMode(); - } - else - { - %control = %client.player; - %control.mode = observerFly; - %control.setFlyMode(); - } - %client.setControlObject(%control); - } -} - -function serverCmdDropPlayerAtCamera(%client) -{ - if ($testcheats) - { - %client.player.setTransform(%client.camera.getTransform()); - %client.player.setVelocity("0 0 0"); - %client.setControlObject(%client.player); - } -} - -function serverCmdDropCameraAtPlayer(%client) -{ - if ($testcheats) - { - %client.camera.setTransform(%client.player.getTransform()); - %client.camera.setVelocity("0 0 0"); - %client.setControlObject(%client.camera); - } -} - -function serverCmdToggleRace(%client) -{ - if ($testcheats) - { - if (%client.race $= "Human") - %client.race = "Bioderm"; - else - %client.race = "Human"; - %client.player.setArmor(%client.armor); - } -} - -function serverCmdToggleGender(%client) -{ - if ($testcheats) - { - if (%client.sex $= "Male") - %client.sex = "Female"; - else - %client.sex = "Male"; - %client.player.setArmor(%client.armor); - } -} - -function serverCmdToggleArmor(%client) -{ - if ($testcheats) - { - if (%client.armor $= "Light") - %client.armor = "Medium"; - else - if (%client.armor $= "Medium") - %client.armor = "Heavy"; - else - %client.armor = "Light"; - %client.player.setArmor(%client.armor); - } -} - -function serverCmdPlayCel(%client,%anim) -{ - if ($testcheats) - { - %anim = %client.player.celIdx; - if (%anim++ > 8) - %anim = 1; - %client.player.setActionThread("cel"@%anim); - %client.player.celIdx = %anim; - } -} - -// NOTENOTENOTE: Review -function PlayAnim(%client, %anim) // z0dd - ZOD, 8/15/02. Remove client direct requests to start animations. Was: serverCmdPlayAnim -{ - if( %anim $= "Death1" || %anim $= "Death2" || %anim $= "Death3" || %anim $= "Death4" || %anim $= "Death5" || - %anim $= "Death6" || %anim $= "Death7" || %anim $= "Death8" || %anim $= "Death9" || %anim $= "Death10" || %anim $= "Death11" ) - return; - - %player = %client.player; - - // don't play animations if player is in a vehicle - // z0dd - ZOD, 4-15-02. Console spam fix, check for player object. - if(%player.isMounted() || !isObject(%player)) - return; - - %weapon = ( %player.getMountedImage($WeaponSlot) == 0 ) ? "" : %player.getMountedImage($WeaponSlot).getName().item; - if(%weapon $= "MissileLauncher" || %weapon $= "SniperRifle") - { - %player.animResetWeapon = true; - %player.lastWeapon = %weapon; - %player.unmountImage($WeaponSlot); - %player.setArmThread(look); // z0dd - ZOD, 4-15-02. Dynamix used %obj. - } - %player.setActionThread(%anim); -} - -function serverCmdPlayDeath(%client,%anim) -{ - if ($testcheats) - { - %anim = %client.player.deathIdx; - if (%anim++ > 11) - %anim = 1; - %client.player.setActionThread("death"@%anim,true); - %client.player.deathIdx = %anim; - } -} - -// NOTENOTENOTE: Review these! -//------------------------------------------------------------ -// TODO - make this function specify a team to switch to... -function serverCmdClientTeamChange( %client ) -{ - // pass this to the game object to handle: - if ( isObject( Game ) && Game.kickClient != %client) - { - %fromObs = %client.team == 0; - - if(%fromObs) - clearBottomPrint(%client); - - Game.clientChangeTeam( %client, "", %fromObs ); - } -} - -function serverCanAddBot() -{ - //find out how many bots are already playing - %botCount = 0; - %numClients = ClientGroup.getCount(); - for (%i = 0; %i < %numClients; %i++) - { - %cl = ClientGroup.getObject(%i); - if (%cl.isAIcontrolled()) - %botCount++; - } - - //add only if we have less bots than the bot count, and if there would still be room for a - if ($HostGameBotCount > 0 && %botCount < $Host::botCount && %numClients < $Host::maxPlayers - 1) - return true; - else - return false; -} - -function serverCmdAddBot( %client ) -{ - //only admins can add bots... - if (%client.isAdmin) - { - if (serverCanAddBot()) - aiConnectMultiple( 1, $Host::MinBotDifficulty, $Host::MaxBotDifficulty, -1 ); - } -} - -// --------------------------------------------------------------------------------- -// z0dd - ZOD, 6/22/02. Changed function to use a waiting period when changing teams -// to prevent team change exploit to crash servers. Added admin varible so admins -// can teamchange whoever they want. -function serverCmdClientJoinTeam( %client, %team, %admin ) -{ - if( %team == -1 ) - { - if( %client.team == 1 ) - %team = 2; - else - %team = 1; - } - if ( isObject( Game ) && Game.kickClient != %client) - { - if(%client.team != %team) - { - // z0dd - ZOD, 9/17/02. Fair teams, check for Team Rabbit 2 as well. - if(($Host::ClassicFairTeams && !%client.isAdmin) && ($CurrentMissionType !$= TR2)) - { - %otherTeam = %team == 1 ? 2 : 1; - if(!%admin.isAdmin && %team != 0 && ($TeamRank[%team, count]+1) > $TeamRank[%otherTeam, count]) - { - messageClient(%client, 'MsgFairTeams', '\c2Teams will be uneven, please choose another team.'); - return; - } - } - - if(!%client.isWaiting || %admin.isAdmin) - { - %client.isWaiting = true; - %client.waitStart = getSimTime(); - %client.schedule($WAIT_PERIOD, waitTimeout); - - %fromObs = %client.team == 0; - - if(%fromObs) - clearBottomPrint(%client); - - if( %client.isAIControlled() ) - Game.AIChangeTeam( %client, %team ); - else - Game.clientChangeTeam( %client, %team, %fromObs ); - } - else - { - %wait = mFloor(($WAIT_PERIOD - (getSimTime() - %client.waitStart)) / 1000); - messageClient(%client, "", $WAIT_MESSAGE, %wait); - } - } - } -} -// --------------------------------------------------------------------------------- - -// this should only happen in single team games -function serverCmdClientAddToGame( %client, %targetClient ) -{ - if ( isObject( Game ) ) - Game.clientJoinTeam( %targetClient, 0, $matchstarted ); - - clearBottomPrint(%targetClient); - - if($matchstarted) - { - %targetClient.setControlObject( %targetClient.player ); - commandToClient(%targetClient, 'setHudMode', 'Standard'); - } - else - { - %targetClient.notReady = true; - %targetClient.camera.getDataBlock().setMode( %targetClient.camera, "pre-game", %targetClient.player ); - %targetClient.setControlObject( %targetClient.camera ); - } - - if( $Host::TournamentMode && !$CountdownStarted) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - { - %targetClient.notReady = true; - centerprint( %targetClient, "\nPress FIRE when ready.", 0, 3 ); - } -} - -function serverCmdClientJoinGame( %client ) -{ - if ( isObject( Game ) ) - Game.clientJoinTeam( %client, 0, 1 ); - - %client.setControlObject( %client.player ); - clearBottomPrint(%client); - commandToClient(%client, 'setHudMode', 'Standard'); -} - -function serverCmdClientMakeObserver( %client ) -{ - if ( isObject( Game ) && Game.kickClient != %client ) - Game.forceObserver( %client, "playerChoose" ); -} - -function serverCmdChangePlayersTeam( %clientRequesting, %client, %team) -{ - if( isObject( Game ) && %client != Game.kickClient && %clientRequesting.isAdmin) - { - // z0dd - ZOD, 6/22/02. Added admin varible to enable admins to teamchange - // even players under the Wait timer. - //serverCmdClientJoinTeam(%client, %team); - serverCmdClientJoinTeam(%client, %team, %clientRequesting); - - if(!$MatchStarted) - { - %client.observerMode = "pregame"; - %client.notReady = true; - %client.camera.getDataBlock().setMode( %client.camera, "pre-game", %client.player ); - %client.setControlObject( %client.camera ); - - if( $Host::TournamentMode && !$CountdownStarted) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - { - %client.notReady = true; - centerprint( %client, "\nPress FIRE when ready.", 0, 3 ); - } - } - else - commandToClient(%client, 'setHudMode', 'Standard', "", 0); - - %multiTeam = (Game.numTeams > 1); - - %aname = %clientRequesting.name; // z0dd - ZOD, 4-15-02. who did what - %name = %client.name; // z0dd - ZOD, 4-15-02. who did what - - if(%multiTeam) - { - messageClient( %client, 'MsgClient', '\c2%1 has changed your team.', %aname); // z0dd - ZOD, 4-15-02. who did what - messageAllExcept( %client, -1, 'MsgClient', '\c2%1 forced %2 to join the %3 team.', %aname, %name, game.getTeamName(%client.team) ); // z0dd - ZOD, 4-15-02. who did what - } - else - { - messageClient( %client, 'MsgClient', '\c2%1 has added you to the game.', %aname); // z0dd - ZOD, 4-15-02. who did what - messageAllExcept( %client, -1, 'MsgClient', '\c2%1 added %2 to the game.', %aname, %name); // z0dd - ZOD, 4-15-02. who did what - } - } -} - -//--------------------------------------------------------------------------------------------------------- -// z0dd - ZOD 4/18/02. Allow SuperAdmins to De-Admin normal Admins -function serverCmdStripAdmin(%client, %admin) -{ - if(!%admin.isAdmin) - return; - - if(%client.isSuperAdmin) - { - messageAll( 'MsgStripAdminPlayer', '\c2%1 removed %2\'s admin privledges.', %client.name, %admin.name, %admin ); - messageClient(%admin, 'MsgStripAdminPlayer', 'You are being stripped of your admin privledges by %1.', %client.name); - %admin.isAdmin = 0; - logEcho(%client.nameBase @ " stripped admin from " @ %admin.nameBase); - } - else - messageClient(%client, 'MsgError', '\c2Only Super Admins can use this command.'); -} - -// z0dd - ZOD 4/18/02. Allow Admins to warn players -function serverCmdWarnPlayer(%client, %target) -{ - if(%client.isAdmin) - { - messageAllExcept(%target, -1, 'MsgAdminForce', '%1 has been warned for inappropriate conduct by %2.', %target.name, %client.name); - messageClient(%target, 'MsgAdminForce', 'You are recieving this warning for inappropriate conduct by %1. Behave or you will be kicked..~wfx/misc/lightning_impact.wav', %client.name); - centerprint(%target, "You are recieving this warning for inappropriate conduct.\nBehave or you will be kicked.", 10, 2); - logEcho(%client.nameBase @ " sent warning to " @ %target.nameBase); - } - else - messageClient(%client, 'MsgError', '\c2Only Admins can use this command.'); -} - -//--------------------------------------------------------------------------------------------------------- - -function serverCmdForcePlayerToObserver( %clientRequesting, %client ) -{ - if( isObject( Game ) && %clientRequesting.isAdmin) - Game.forceObserver( %client, "adminForce" ); -} - -//-------------------------------------------------------------------------- - -function serverCmdTogglePlayerMute(%client, %who) -{ - if (%client.muted[%who]) - { - %client.muted[%who] = false; - messageClient(%client, 'MsgPlayerMuted', '%1 has been unmuted.', %who.name, %who, false); - } - else - { - %client.muted[%who] = true; - messageClient(%client, 'MsgPlayerMuted', '%1 has been muted.', %who.name, %who, true); - } -} - -//-------------------------------------------------------------------------- -// VOTE MENU FUNCTIONS: -function serverCmdGetVoteMenu( %client, %key ) -{ - if ( isObject( Game ) ) - Game.sendGameVoteMenu( %client, %key ); -} - -function serverCmdGetPlayerPopupMenu( %client, %targetClient, %key ) -{ - if ( isObject( Game ) ) - Game.sendGamePlayerPopupMenu( %client, %targetClient, %key ); -} - -function serverCmdGetTeamList( %client, %key ) -{ - if ( isObject( Game ) ) - Game.sendGameTeamList( %client, %key ); -} - -function serverCmdGetMissionTypes( %client, %key ) -{ - for ( %type = 0; %type < $HostTypeCount; %type++ ) - messageClient( %client, 'MsgVoteItem', "", %key, %type, "", $HostTypeDisplayName[%type], true ); -} - -function serverCmdGetMissionList( %client, %key, %type ) -{ - if ( %type < 0 || %type >= $HostTypeCount ) - return; - - for ( %i = $HostMissionCount[%type] - 1; %i >= 0; %i-- ) - { - %idx = $HostMission[%type, %i]; - - // If we have bots, don't change to a mission that doesn't support bots: - if ( $HostGameBotCount > 0 ) - { - if( !$BotEnabled[%idx] ) - continue; - } - - messageClient( %client, 'MsgVoteItem', "", %key, - %idx, // mission index, will be stored in $clVoteCmd - "", - $HostMissionName[%idx], - true ); - } -} - -function serverCmdGetTimeLimitList( %client, %key, %type ) -{ - if ( isObject( Game ) ) - Game.sendTimeLimitList( %client, %key ); -} - -function serverCmdClientPickedTeam( %client, %option ) -{ - // ------------------------------------------------------------------------------------- - // z0dd - ZOD 4/18/02. Tourney mode bug fix. Fix provided by FSB-AO - // Bug description: In tournament mode, If a player is teamchanged by an admin before - // they select a team, the server just changes their team and re-skins the player. They - // are not moved from their initial spawn point, meaning they could spawn very close to - // the other teams flag. This script kills the player if they are already teamed when - // they select an option and spawns them on the correct side of the map. - switch(%option) - { - case 1: - if ( isObject(%client.player) ) - { - %client.player.scriptKill(0); - Game.clientChangeTeam(%client, %option, 0); - } - else - Game.clientJoinTeam( %client, %option, false ); - case 2: - if ( isObject(%client.player) ) - { - %client.player.scriptKill(0); - Game.clientChangeTeam(%client, %option, 0); - } - else - Game.clientJoinTeam( %client, %option, false ); - case 3: - if( !isObject(%client.player) ) - { - Game.assignClientTeam( %client, $MatchStarted ); - Game.spawnPlayer( %client, false ); - } - default: - if( isObject(%client.player) ) - { - %client.player.scriptKill(0); - ClearBottomPrint(%client); - } - Game.forceObserver( %client, "playerChoose" ); - %client.observerMode = "observer"; - %client.notReady = false; - return; - } - // ------------------------------------------------------------------------------------- - - ClearBottomPrint(%client); - %client.observerMode = "pregame"; - %client.notReady = true; - %client.camera.getDataBlock().setMode( %client.camera, "pre-game", %client.player ); - commandToClient(%client, 'setHudMode', 'Observer'); - %client.setControlObject( %client.camera ); - centerprint( %client, "\nPress FIRE when ready.", 0, 3 ); -} - -function playerPickTeam( %client ) -{ - %numTeams = Game.numTeams; - - if(%numTeams > 1) - { - %client.camera.mode = "PickingTeam"; - schedule( 0, 0, "commandToClient", %client, 'pickTeamMenu', Game.getTeamName(1), Game.getTeamName(2)); - } - else - { - Game.clientJoinTeam(%client, 0, 0); - %client.observerMode = "pregame"; - %client.notReady = true; - %client.camera.getDataBlock().setMode( %client.camera, "pre-game", %client.player ); - centerprint( %client, "\nPress FIRE when ready.", 0, 3 ); - %client.setControlObject( %client.camera ); - } -} - -function serverCmdPlayContentSet( %client ) -{ - if( $Host::TournamentMode && !$CountdownStarted && !$MatchStarted ) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - playerPickTeam( %client ); -} - -//-------------------------------------------------------------------------- -// This will probably move elsewhere... -function getServerStatusString() -{ - return isObject(Game) ? Game.getServerStatusString() : "NoGame"; -} - - -function dumpGameString() -{ - error( getServerStatusString() ); -} - -function isOnAdminList(%client) -{ - if( !%totalRecords = getFieldCount( $Host::AdminList ) ) - { - return false; - } - - for(%i = 0; %i < %totalRecords; %i++) - { - %record = getField( getRecord( $Host::AdminList, 0 ), %i); - if(%record == %client.guid) - return true; - } - - return false; -} - -function isOnSuperAdminList(%client) -{ - if( !%totalRecords = getFieldCount( $Host::superAdminList ) ) - { - return false; - } - - for(%i = 0; %i < %totalRecords; %i++) - { - %record = getField( getRecord( $Host::superAdminList, 0 ), %i); - if(%record == %client.guid) - return true; - } - - return false; -} - -function ServerCmdAddToAdminList( %admin, %client ) -{ - if( !%admin.isSuperAdmin ) - return; - - %count = getFieldCount( $Host::AdminList ); - - for ( %i = 0; %i < %count; %i++ ) - { - %id = getField( $Host::AdminList, %i ); - if ( %id == %client.guid ) - { - return; // They're already there! - } - } - - if( %count == 0 ) - $Host::AdminList = %client.guid; - else - $Host::AdminList = $Host::AdminList TAB %client.guid; - - // z0dd - ZOD, 4/29/02. Was not exporting to serverPrefs and did not message admin - export( "$Host::*", "prefs/ServerPrefs.cs", false ); - messageClient(%admin, 'MsgAdmin', '\c3\"%1\"\c2 added to Admin list: \c3%2\c2.', %client.name, %client.guid); - logEcho(%admin.nameBase @ " added " @ %client.nameBase @ " " @ %client.guid @ " to Admin list."); -} - -function ServerCmdAddToSuperAdminList( %admin, %client ) -{ - if( !%admin.isSuperAdmin ) - return; - - %count = getFieldCount( $Host::SuperAdminList ); - - for ( %i = 0; %i < %count; %i++ ) - { - %id = getField( $Host::SuperAdminList, %i ); - if ( %id == %client.guid ) - return; // They're already there! - } - - if( %count == 0 ) - $Host::SuperAdminList = %client.guid; - else - $Host::SuperAdminList = $Host::SuperAdminList TAB %client.guid; - - // z0dd - ZOD, 4/29/02. Was not exporting to serverPrefs and did not message admin - export( "$Host::*", "prefs/ServerPrefs.cs", false ); - messageClient(%admin, 'MsgAdmin', '\c3\"%1\"\c2 added to Super Admin list: \c3%2\c2.', %client.name, %client.guid); - logEcho(%admin.nameBase @ " added " @ %client.nameBase @ " " @ %client.guid @ " to Super Admin list."); -} - -function resetTournamentPlayers() -{ - %count = ClientGroup.getCount(); - for( %i = 0; %i < %count; %i++ ) - { - %cl = ClientGroup.getObject(%i); - %cl.notready = 1; - %cl.notReadyCount = ""; - } -} - -function forceTourneyMatchStart() -{ - %playerCount = 0; - %count = ClientGroup.getCount(); - for( %i = 0; %i < %count; %i++ ) - { - %cl = ClientGroup.getObject(%i); - if(%cl.camera.Mode $= "pre-game") - %playerCount++; - } - - // don't start the mission until we have players - if(%playerCount == 0) - { - return false; - } - - %count = ClientGroup.getCount(); - for( %i = 0; %i < %count; %i++ ) - { - %cl = ClientGroup.getObject(%i); - if(%cl.camera.Mode $= "pickingTeam") - { - // throw these guys into observer mode - if(Game.numTeams > 1) - commandToClient( %cl, 'processPickTeam'); // clear the pickteam menu - Game.forceObserver( %cl, "adminForce" ); - } - } - return true; -} - -function startTourneyCountdown() -{ - %count = ClientGroup.getCount(); - for( %i = 0; %i < %count; %i++ ) - { - %cl = ClientGroup.getObject(%i); - ClearCenterPrint(%cl); - ClearBottomPrint(%cl); - } - - // lets get it on! - Countdown( 30 * 1000 ); -} - -function checkTourneyMatchStart() -{ - if( $CountdownStarted || $matchStarted ) - return; - - // loop through all the clients and see if any are still notready - %playerCount = 0; - %notReadyCount = 0; - - %count = ClientGroup.getCount(); - for( %i = 0; %i < %count; %i++ ) - { - %cl = ClientGroup.getObject(%i); - if(%cl.camera.mode $= "pickingTeam") - { - %notReady[%notReadyCount] = %cl; - %notReadyCount++; - } - else if(%cl.camera.Mode $= "pre-game") - { - if(%cl.notready) - { - %notReady[%notReadyCount] = %cl; - %notReadyCount++; - } - else - { - %playerCount++; - } - } - else if(%cl.camera.Mode $= "observer") - { - // this guy is watching - } - } - - if(%notReadyCount) - { - if(%notReadyCount == 1) - MessageAll( 'msgHoldingUp', '\c1%1 is holding things up!', %notReady[0].name); - else if(%notReadyCount < 4) - { - for(%i = 0; %i < %notReadyCount - 2; %i++) - %str = getTaggedString(%notReady[%i].name) @ ", " @ %str; - - %str = "\c2" @ %str @ getTaggedString(%notReady[%i].name) @ " and " @ getTaggedString(%notReady[%i+1].name) - @ " are holding things up!"; - MessageAll( 'msgHoldingUp', %str ); - } - return; - } - - if(%playerCount != 0) - { - %count = ClientGroup.getCount(); - for( %i = 0; %i < %count; %i++ ) - { - %cl = ClientGroup.getObject(%i); - %cl.notready = ""; - %cl.notReadyCount = ""; - ClearCenterPrint(%cl); - ClearBottomPrint(%cl); - } - - if ( Game.scheduleVote !$= "" && Game.voteType $= "VoteMatchStart") - { - messageAll('closeVoteHud', ""); - cancel(Game.scheduleVote); - Game.scheduleVote = ""; - } - - Countdown(30 * 1000); - } -} - -function checkMissionStart() -{ - %readyToStart = false; - for(%clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++) - { - %client = ClientGroup.getObject(%clientIndex); - if(%client.isReady) - { - %readyToStart = true; - break; - } - } - - if(%readyToStart || ClientGroup.getCount() < 1) - { - if($Host::warmupTime > 0 && $CurrentMissionType !$= "SinglePlayer") - countDown($Host::warmupTime * 1000); - else - Game.startMatch(); - - for(%x = 0; %x < $NumVehiclesDeploy; %x++) - $VehiclesDeploy[%x].getDataBlock().schedule(%timeMS / 2, "vehicleDeploy", $VehiclesDeploy[%x], 0, 1); - $NumVehiclesDeploy = 0; - } - else - { - schedule(2000, ServerGroup, "checkMissionStart"); - } -} - -function Countdown(%timeMS) -{ - if($countdownStarted) - return; - - echo("starting mission countdown..."); - - if(isObject(Game)) - %game = Game.getId(); - else - return; - - $countdownStarted = true; - Game.matchStart = Game.schedule( %timeMS, "StartMatch" ); - - if (%timeMS > 30000) - notifyMatchStart(%timeMS); - - if(%timeMS >= 30000) - Game.thirtyCount = schedule(%timeMS - 30000, Game, "notifyMatchStart", 30000); - if(%timeMS >= 15000) - Game.fifteenCount = schedule(%timeMS - 15000, Game, "notifyMatchStart", 15000); - if(%timeMS >= 10000) - Game.tenCount = schedule(%timeMS - 10000, Game, "notifyMatchStart", 10000); - if(%timeMS >= 5000) - Game.fiveCount = schedule(%timeMS - 5000, Game, "notifyMatchStart", 5000); - if(%timeMS >= 4000) - Game.fourCount = schedule(%timeMS - 4000, Game, "notifyMatchStart", 4000); - if(%timeMS >= 3000) - Game.threeCount = schedule(%timeMS - 3000, Game, "notifyMatchStart", 3000); - if(%timeMS >= 2000) - Game.twoCount = schedule(%timeMS - 2000, Game, "notifyMatchStart", 2000); - if(%timeMS >= 1000) - Game.oneCount = schedule(%timeMS - 1000, Game, "notifyMatchStart", 1000); -} - -function EndCountdown(%timeMS) -{ - echo("mission end countdown..."); - - if(isObject(Game)) - %game = Game.getId(); - else - return; - - if(%timeMS >= 60000) - Game.endsixtyCount = schedule(%timeMS - 60000, Game, "notifyMatchEnd", 60000); - if(%timeMS >= 30000) - Game.endthirtyCount = schedule(%timeMS - 30000, Game, "notifyMatchEnd", 30000); - if(%timeMS >= 10000) - Game.endtenCount = schedule(%timeMS - 10000, Game, "notifyMatchEnd", 10000); - if(%timeMS >= 5000) - Game.endfiveCount = schedule(%timeMS - 5000, Game, "notifyMatchEnd", 5000); - if(%timeMS >= 4000) - Game.endfourCount = schedule(%timeMS - 4000, Game, "notifyMatchEnd", 4000); - if(%timeMS >= 3000) - Game.endthreeCount = schedule(%timeMS - 3000, Game, "notifyMatchEnd", 3000); - if(%timeMS >= 2000) - Game.endtwoCount = schedule(%timeMS - 2000, Game, "notifyMatchEnd", 2000); - if(%timeMS >= 1000) - Game.endoneCount = schedule(%timeMS - 1000, Game, "notifyMatchEnd", 1000); -} - -function CancelCountdown() -{ - if(Game.sixtyCount !$= "") - cancel(Game.sixtyCount); - if(Game.thirtyCount !$= "") - cancel(Game.thirtyCount); - if(Game.fifteenCount !$= "") - cancel(Game.fifteenCount); - if(Game.tenCount !$= "") - cancel(Game.tenCount); - if(Game.fiveCount !$= "") - cancel(Game.fiveCount); - if(Game.fourCount !$= "") - cancel(Game.fourCount); - if(Game.threeCount !$= "") - cancel(Game.threeCount); - if(Game.twoCount !$= "") - cancel(Game.twoCount); - if(Game.oneCount !$= "") - cancel(Game.oneCount); - if(isObject(Game)) - cancel(Game.matchStart); - - Game.matchStart = ""; - Game.thirtyCount = ""; - Game.fifteenCount = ""; - Game.tenCount = ""; - Game.fiveCount = ""; - Game.fourCount = ""; - Game.threeCount = ""; - Game.twoCount = ""; - Game.oneCount = ""; - - $countdownStarted = false; -} - -function CancelEndCountdown() -{ - //cancel the mission end countdown... - if(Game.endsixtyCount !$= "") - cancel(Game.endsixtyCount); - if(Game.endthirtyCount !$= "") - cancel(Game.endthirtyCount); - if(Game.endtenCount !$= "") - cancel(Game.endtenCount); - if(Game.endfiveCount !$= "") - cancel(Game.endfiveCount); - if(Game.endfourCount !$= "") - cancel(Game.endfourCount); - if(Game.endthreeCount !$= "") - cancel(Game.endthreeCount); - if(Game.endtwoCount !$= "") - cancel(Game.endtwoCount); - if(Game.endoneCount !$= "") - cancel(Game.endoneCount); - - Game.endmatchStart = ""; - Game.endthirtyCount = ""; - Game.endtenCount = ""; - Game.endfiveCount = ""; - Game.endfourCount = ""; - Game.endthreeCount = ""; - Game.endtwoCount = ""; - Game.endoneCount = ""; -} - -function resetServerDefaults() -{ - $resettingServer = true; - echo( "Resetting server defaults..." ); - - if( isObject( Game ) ) - Game.gameOver(); - - // Override server defaults with prefs: - exec( "scripts/ServerDefaults.cs" ); - exec( $serverprefs ); - - // --------------------------------------------------- - // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - //convert the team skin and name vars to tags... - %index = 0; - while ($Host::TeamSkin[%index] !$= "") - { - $TeamSkin[%index] = addTaggedString($Host::TeamSkin[%index]); - %index++; - } - - %index = 0; - while ($Host::TeamName[%index] !$= "") - { - $TeamName[%index] = addTaggedString($Host::TeamName[%index]); - %index++; - } - - // Get the hologram names from the prefs... - %index = 1; - while ( $Host::holoName[%index] !$= "" ) - { - $holoName[%index] = $Host::holoName[%index]; - %index++; - } - // --------------------------------------------------- - - // kick all bots... - removeAllBots(); - - // add bots back if they were there before.. - if( $Host::botsEnabled ) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here - initGameBots( $Host::Map, $Host::MissionType ); - - // load the missions - loadMission( $Host::Map, $Host::MissionType ); - $resettingServer = false; - echo( "Server reset complete." ); -} - -function removeAllBots() //Wtf -- it crashes. -{ - while( ClientGroup.getCount() ) - { - %client = ClientGroup.getObject(0); - if(%client.isAIControlled()) - { - %client.drop(); - } - else - %client.delete(); - } -} -//------------------------------------------------------------------------------ -function getServerGUIDList() -{ - %count = ClientGroup.getCount(); - for ( %i = 0; %i < %count; %i++ ) - { - %cl = ClientGroup.getObject( %i ); - if ( isObject( %cl ) && !%cl.isSmurf && !%cl.isAIControlled() ) - { - %guid = getField( %cl.getAuthInfo(), 3 ); - if ( %guid != 0 ) - { - if ( %list $= "" ) - %list = %guid; - else - %list = %list TAB %guid; - } - } - } - - return( %list ); -} - -//------------------------------------------------------------------------------ -// will return the first admin found on the server -function getAdmin() -{ - %admin = 0; - for ( %clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++ ) - { - %cl = ClientGroup.getObject( %clientIndex ); - if(%cl.isAdmin || %cl.isSuperAdmin) - { - %admin = %cl; - break; - } - } - return %admin; -} - -function serverCmdSetPDAPose(%client, %val) -{ - if(!isObject(%client.player)) - return; - - // if client is in a vehicle, return - if(%client.player.isMounted()) - return; - - if(%val) - { - // play "PDA" animation thread on player - if (%client.race $="Bioderm" || %client.race $="Draakan" || %client.race $= "Criollos") //PDA pose hackery to allow the Bioderm PDA anim - %client.player.setActionThread("IdlePDA", true); - else - %client.player.setActionThread("PDA", true); - } - else - { - // cancel PDA animation thread with another one. - %client.player.setActionThread("light_recoil", false); - } -} - -function serverCmdProcessGameLink(%client, %arg1, %arg2, %arg3, %arg4, %arg5) -{ - Game.processGameLink(%client, %arg1, %arg2, %arg3, %arg4, %arg5); -} - -//----------------------------------------------------------------------------------- -// z0dd - ZOD, 6/03/02. New function. Impact hit sounds settings from clientprefs.cs. -function serverCmdSetHitSounds( %client, %playerHitsOn, %playerHitWav, %vehicleHitsOn, %vehicleHitWav ) -{ - %client.playerHitSound = %playerHitsOn; - %client.playerHitWav = addtaggedString(%playerHitWav); - - %client.vehicleHitSound = %vehicleHitsOn; - %client.vehicleHitWav = addtaggedString(%vehicleHitWav); -} -//----------------------------------------------------------------------------------- - -//----------------------------------------------------------------------------------- -// z0dd - ZOD, 6/03/02. New function. Get mod name from server. -function serverCMDgetMod(%client) -{ - %paths = getModPaths(); - commandToClient(%client, 'serverMod', %paths); -} -//----------------------------------------------------------------------------------- - -//----------------------------------------------------------------------------------- -// z0dd - ZOD, 10/03/02. New function. Admin HUD print feature -function serverCMDaprint(%client, %msg, %bottom) -{ - if(%client.isAdmin) - { - %name = getTaggedString(%client.name); - %message = %name @ ": " @ %msg; - if(%bottom) - bottomprintAll(%message, 8, 3); - else - centerprintAll(%message, 8, 3); - } -} +if($Host::TimeLimit $= "") + $Host::TimeLimit = 20; + +$SB::WODec = 0.004; // whiteout +$SB::DFDec = 0.02; // damageFlash + +$Classic::gravSetting = -26.9; // z0dd - ZOD, 9/13/02. Classic Gravity setting +$Classic::cameraSpeed = 50; +$Camera::movementSpeed = $Classic::cameraSpeed; // z0dd - ZOD, 9/13/02. Classic camera speed. + +// ----------------------------------------------------- +// z0dd - ZOD, 6/22/02. Addition. +// Alert players on server that a remote connection has +// been established to the server. +$TelnetSpam = 0; +function onTelnetConnect(%ip, %access) +{ + %level = %access == 1 ? "full" : "read"; + %snd = '~wfx/misc/diagnostic_on.wav'; + %msg = '\c1Remote telnet connection established.%1'; + if($Host::TournamentMode && $TelnetSpam == 0) + { + messageAll('MsgTelnetConnect', %msg, %snd); + logEcho("Incomming telnet connection from: " @ %ip @ " with " @ %level @ " access privledges"); + $TelnetSpam = 1; + schedule(2000, 0, "clearTelnetSpam"); + } +} + +function clearTelnetSpam() +{ + $TelnetSpam = 0; +} +// ----------------------------------------------------- + +// ----------------------------------------------------- +// Reload by JackTL -- I think +function reload(%script) +{ + compile(%script); // Added by JackTL - Duh!! + exec(%script); + %count = ClientGroup.getCount(); + + for(%i = 0; %i < %count; %i++) + { + %cl = ClientGroup.getObject(%i); + + if(!%cl.isAIControlled()) // no sending bots datablocks.. LOL + %cl.transmitDataBlocks(0); // all clients on server + } +} +// ----------------------------------------------------- + +function VerifyCDCheck(%func) +{ + if (!cdFileCheck()) + messageBoxOkCancel("TRIBES 2 CD CHECK", "You must have the Tribes 2 CD in the CD-ROM drive while playing Tribes 2. Please insert the CD.", "schedule(0, 0, VerifyCDCheck, " @ %func @ ");", "quit();"); + else + call(%func); +} + +function logEcho(%msg) +{ + // z0dd - ZOD, 4/10/02. Changed from $ClassicLogEchoEnabled, allow server owners to modify + if($Host::ClassicLogEchoEnabled) + echo("LOG: " @ %msg); +} + +//-------------------------------------------------------------------------- +// z0dd - ZOD, 3/27/02. Auto restart server after specified time + +function AutoRestart() +{ + if(!$Host::TournamentMode) + { + $AutoRestart = 1; + centerPrintAll("SERVER WILL BE AUTO REBOOTING NEXT MISSION.", 5, 1); + messageAll( 'MsgServerRestart', '\c2SERVER WILL BE AUTO REBOOTING NEXT MISSION.~wfx/misc/red_alert.wav'); + logEcho("Automatic server restart on mission end begining."); + } + else + schedule(300000, 0, "AutoRestart"); // Check back in 5 minutes +} +//-------------------------------------------------------------------------- + +function CreateServer(%mission, %missionType) +{ + DestroyServer(); + + // z0dd - ZOD, 3/27/02. Automatically reboot the server after a specified time. + $AutoRestart = 0; // Paranoia + if($Host::ClassicAutoRestartServer == 1) + schedule($Host::ClassicRestartTime * 3600000, 0, "AutoRestart"); + + if($Host::ClassicTelnet) + telnetsetparameters($Host::ClassicTelnetPort, $Host::ClassicTelnetPassword, $Host::ClassicTelnetListenPass); + + // Load server data blocks + exec("scripts/commanderMapIcons.cs"); + exec("scripts/markers.cs"); + exec("scripts/serverAudio.cs"); + exec("scripts/damageTypes.cs"); + exec("scripts/deathMessages.cs"); + exec("scripts/inventory.cs"); + exec("scripts/camera.cs"); + exec("scripts/particleEmitter.cs"); // Must exist before item.cs and explosion.cs + exec("scripts/particleDummies.cs"); + exec("scripts/projectiles.cs"); // Must exits before item.cs + exec("scripts/modScripts/server/initialize.cs"); + exec("scripts/player.cs"); + exec("scripts/gameBase.cs"); + exec("scripts/staticShape.cs"); + exec("scripts/weapons.cs"); + exec("scripts/turret.cs"); + exec("scripts/weapTurretCode.cs"); + exec("scripts/pack.cs"); + exec("scripts/vehicles/vehicle_spec_fx.cs"); // Must exist before other vehicle files or CRASH BOOM + exec("scripts/vehicles/serverVehicleHud.cs"); + exec("scripts/vehicles/vehicle_shrike.cs"); + exec("scripts/vehicles/vehicle_bomber.cs"); + exec("scripts/vehicles/vehicle_havoc.cs"); + exec("scripts/vehicles/vehicle_wildcat.cs"); + exec("scripts/vehicles/vehicle_tank.cs"); + exec("scripts/vehicles/vehicle_mpb.cs"); + exec("scripts/vehicles/vehicle.cs"); // Must be added after all other vehicle files or EVIL BAD THINGS + exec("scripts/ai.cs"); + exec("scripts/item.cs"); + exec("scripts/station.cs"); + exec("scripts/simGroup.cs"); + exec("scripts/trigger.cs"); + exec("scripts/forceField.cs"); + exec("scripts/lightning.cs"); + exec("scripts/weather.cs"); + exec("scripts/deployables.cs"); + exec("scripts/stationSetInv.cs"); + exec("scripts/navGraph.cs"); + exec("scripts/targetManager.cs"); + exec("scripts/serverCommanderMap.cs"); + exec("scripts/environmentals.cs"); + exec("scripts/power.cs"); + exec("scripts/supportClassic.cs"); // z0dd - ZOD, 5/13/02. Execute the support functions. + exec("scripts/practice.cs"); // z0dd - ZOD, 3/13/02. Execute practice mode server functions. + exec("scripts/serverTasks.cs"); + exec("scripts/admin.cs"); + exec("prefs/banlist.cs"); + + exec("scripts/modScripts/shared/initialise.cs"); + exec("scripts/modScripts/server/initialise.cs"); + + //Execute saved data, if possible + if (IsFile("Data/SavedData.cs")) + exec("Data/SavedData.cs"); + + // --------------------------------------------------- + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + %search = "scripts/*Game.cs"; + for(%file = findFirstFile(%search); %file !$= ""; %file = findNextFile(%search)) + { + %type = fileBase(%file); // get the name of the script + exec("scripts/" @ %type @ ".cs"); + } + // --------------------------------------------------- + + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + + $missionSequence = 0; + $CurrentMissionType = %missionType; + $HostGameBotCount = 0; + $HostGamePlayerCount = 0; + if ( $HostGameType !$= "SinglePlayer" ) + allowConnections(true); + $ServerGroup = new SimGroup (ServerGroup); + if(%mission $= "") + { + %mission = $HostMissionFile[$HostMission[0,0]]; + %missionType = $HostTypeName[0]; + } + + if ( ( $HostGameType $= "Online" && $pref::Net::DisplayOnMaster !$= "Never" ) ) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + schedule(0,0,startHeartbeat); + + // setup the bots for this server + if( $Host::BotsEnabled ) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + initGameBots( %mission, %missionType ); + + // z0dd - ZOD, 9/13/02. For TR2 compatability + // This is a failsafe way of ensuring that default gravity is always restored + // if a game type (such as TR2) changes it. It is placed here so that listen + // servers will work after opening and closing different gametypes. + $DefaultGravity = getGravity(); + + // load the mission... + loadMission(%mission, %missionType, true); +} + +function SimObject::setRotation(%obj, %rot) +{ + setRotation(%obj, %rot); +} + +function setRotation(%obj, %rot) +{ + %pos = getWords(%obj.getTransform(), 0, 2); + %trans = %pos@" "@%rot; + %obj.setTransform(%trans); +} + +function dropAI(%client) +{ +//if (!%client.isAIControlled()) +//return false; + +//clear any flags +AIUnassignClient(%client); +%client.stop(); +%client.clearStep(); +%client.lastDamageClient = -1; +%client.lastDamageTurret = -1; +%client.shouldEngage = -1; +%client.setEngageTarget(-1); +%client.setTargetObject(-1); +%client.clearTasks(); +%client.clearStep(); +%client.pilotVehicle = false; + cancel(%client.objectiveThread); +return true; +} + +function serverCmdDoRefill(%client) //Shitty hack I used to make the RPG gamemode force clients to pay for refills +{ +if (!%client.isatInv) +return; + +%obj = %client.player.obj; +%data = %client.player.data; +%colObj = %client.player; + +if ($CurrentMissionType $= "RPG") +{ + %client.money = %client.money - 100; + messageClient(%client,'MsgSPCurrentObjective2',"\c3$100 has been subtracted from your account.",'Money: $%1.',%client.money); +} + // z0dd - ZOD, 7/13/02 Part of hack to keep people from mounting + // vehicles in disallowed armors. + if(%obj.station.getDataBlock().getName() !$= "StationVehicle") + %colObj.client.inInv = true; + + %colObj.inStation = true; + commandToClient(%colObj.client,'setStationKeys', true); + if(Game.stationOnEnterTrigger(%data, %obj, %colObj)) { + //verify station.team is team associated and isn't on player's team + if((%obj.mainObj.team != %colObj.client.team) && (%obj.mainObj.team != 0)) + { + //%obj.station.playAudio(2, StationAccessDeniedSound); + messageClient(%colObj.client, 'msgStationDenied', '\c2Access Denied -- Wrong team.~wfx/powered/station_denied.wav'); + } + else if(%obj.disableObj.isDisabled()) + { + messageClient(%colObj.client, 'msgStationDisabled', '\c2Station is disabled.'); + } + else if(!%obj.mainObj.isPowered()) + { + messageClient(%colObj.client, 'msgStationNoPower', '\c2Station is not powered.'); + } + else if(%obj.station.notDeployed) + { + messageClient(%colObj.client, 'msgStationNotDeployed', '\c2Station is not deployed.'); + } + else if(%obj.station.triggeredBy $= "") + { + if(%obj.station.getDataBlock().setPlayersPosition(%obj.station, %obj, %colObj)) + { + messageClient(%colObj.client, 'CloseHud', "", 'inventoryScreen'); + commandToClient(%colObj.client, 'TogglePlayHuds', true); + %obj.station.triggeredBy = %colObj; + %obj.station.getDataBlock().stationTriggered(%obj.station, 1); + %colObj.station = %obj.station; + %colObj.lastWeapon = ( %colObj.getMountedImage($WeaponSlot) == 0 ) ? "" : %colObj.getMountedImage($WeaponSlot).getName().item; + %colObj.unmountImage($WeaponSlot); + } + } + } + + if (%colObj.client.race $= "Draakan") + %colObj.schedule(100,"setInventory","Flamer",1,true); //Make sure our player gets to keep the flame Breath +} + +function saveGame() +{ +if (!IsObject(ClientGroup)) +return; + +%count = ClientGroup.getCount(); + +if ($CurrentMissionType $= "RPG") //If it's not an RPG gamemode, don't do anything except save the variables that are already initialized.. +{ + for (%i = 0; %i < %count; %i++) + { + %cl = ClientGroup.getObject(%i); + if (!%cl.isAIControlled() && isObject(%cl.player)) + { + %trans = %cl.player.getTransform(); + %health = %cl.player.getDamageLevel(); + %whiteout = %cl.player.getWhiteout(); + %damageFlash = %cl.player.getDamageFlash(); + %velocity = %cl.player.getVelocity(); + %energy = %cl.player.getEnergyLevel(); + + $Data::Transform[%cl.GUID,$CurrentMission] = %trans; + $Data::Health[%cl.GUID,$CurrentMission] = %health; + $Data::Whiteout[%cl.GUID,$CurrentMission] = %whiteout; + $Data::DamageFlash[%cl.GUID,$CurrentMission] = %damageFlash; + $Data::Velocity[%cl.GUID,$CurrentMission] = %velocity; + $Data::ShouldApply[%cl.GUID,$CurrentMission] = true; + $Data::Energy[%cl.GUID,$CurrentMission] = %energy; + $Data::Money[%cl.GUID,$CurrentMission] = %cl.money; + + //A little more complicated, what weapons does our client have? + %armor = %cl.armor; + $Data::Armor[%cl.guid, $CurrentMission] = %armor; + + for (%i = 0; %i < 5; %i++) + { + %weap = %cl.player.weaponSlot[%i]; + if (%weap !$= "Flamer") //Skip the Flamer, if we try to save it, the player isn't given one on spawn + { + $Data::Weapon[%cl.guid, %i, $CurrentMission] = %weap; + $Data::Ammo[%cl.guid, %i, $CurrentMission] = %cl.player.inv[%cl.player.weaponSlot[%i] @ "ammo"]; + } + } + + //See WTF else the client may have + %pack = %cl.player.getMountedImage(2).item; + $Data::Pack[%cl.GUID,$CurrentMission] = %pack; + $Data::RepairKits[%cl.GUID,$CurrentMission] = %cl.player.invRepairKit; + + //Does the client have a vehicle? + if (IsObject(%cl.vehicleMounted)) + { + %veh = %cl.vehicleMounted; + + %type = %veh.getClassName(); + %transform = %veh.getTransform(); + %velocity = %veh.getVelocity(); + %damage = %veh.getDamageLevel(); + %energy = %veh.getEnergyLevel(); + %db = %veh.getDatablock().getName(); + + $Data::VehicleType[%cl.GUID, $CurrentMission] = %type; + $Data::VehicleTransform[%cl.GUID, $CurrentMission] = %transform; + $Data::VehicleDamage[%cl.GUID, $CurrentMission] = %damage; + $Data::VehicleEnergy[%cl.GUID, $CurrentMission] = %energy; + $Data::VehicleDB[%cl.GUID, $CurrentMission] = %db; + $Data::VehicleVelocity[%cl.GUID, $CurrentMission] = %velocity; + $Data::WasInVehicle[%cl.GUID, $CurrentMission] = true; + } + else + $Data::WasInVehicle[%cl.GUID, $CurrentMission] = false; + + //Minerals.. + $Data::Steel[%cl.GUID,$CurrentMission] = %cl.units["Steel"]; + } + } +} +logEcho("Saved all clients in server."); +export( "$Data::*", "Data/SavedData.cs", false ); +} + +function applyPlayerSave(%client) //This script is much worse than an eyesore.. +{ +if ($Data::ShouldApply[%client.GUID, $CurrentMission]) +{ + %client.sex = $Data::Sex[%client.guid]; + %client.race = $Data::Race[%client.guid]; + + %client.units["Steel"] = $Data::Steel[%client.GUID, $CurrentMission]; + %client.money = $Data::Money[%client.GUID, $CurrentMission]; + + //Clear the defaultGame inventory + %client.player.clearInventory(); + for(%i =0; %i<$InventoryHudCount; %i++) + %client.setInventoryHudItem($InventoryHudData[%i, itemDataName], 0, 1); + %client.clearBackpackIcon(); + + //Armor is set first before anything + %client.player.setArmor($Data::Armor[%client.guid, $CurrentMission]); + + //armor and weapons + for (%i = 0; %i < 5; %i++) + { + %client.player.setInventory($Data::Weapon[%client.guid, %i, $CurrentMission],1); + %client.player.setInventory($Data::Weapon[%client.guid, %i, $CurrentMission] @ "ammo",$Data::Ammo[%client.GUID, %i, $CurrentMission]); + %client.player.use(%client.player.weaponSlot0); + } + + if (%client.race $= "Draakan") + %client.player.setInventory(Flamer, 1, 1); //Apply player save fucks this up + + //Pack and rep kits.. + %client.player.setInventory("RepairKit",$Data::RepairKits[%client.guid, $CurrentMission]); + %client.player.setInventory($Data::Pack[%client.guid, $CurrentMission],1); + + //Now apply other stuff + %client.player.setDamageLevel($Data::Health[%client.GUID, $CurrentMission]); + %client.player.setEnergyLevel($Data::Energy[%client.GUID, $CurrentMission]); + %client.player.setWhiteout($Data::Whiteout[%client.GUID, $CurrentMission]); + %client.player.setDamageFlash($Data::DamageFlash[%client.GUID, $CurrentMission]); + %client.player.setTransform($Data::Transform[%client.GUID, $CurrentMission]); + %client.player.setVelocity($Data::Velocity[%client.GUID, $CurrentMission]); + + //Since the player is setup, was the player in a vehicle when saved? + if ($Data::wasInVehicle[%client.GUID, $CurrentMission]) //Yes, we need to setup the vehicle then mount the player to it + { + %veh = new ($Data::VehicleType[%client.GUID, $CurrentMission])() + { + Datablock = $Data::VehicleDB[%client.GUID, $CurrentMission]; + Team = %client.team; + }; + %veh.mountObject(%client.player,0); + %veh.setTransform($Data::VehicleTransform[%client.GUID, $CurrentMission]); + %veh.setEnergyLevel($Data::VehicleEnergy[%client.GUID, $CurrentMission]); + %veh.setDamageLevel($Data::VehicleDamage[%client.GUID, $CurrentMission]); + %veh.setVelocity($Data::VehicleVelocity[%client.GUID, $CurrentMission]); + } +} +else +%client.player.setTransform(Game.pickPlayerSpawn(%client,false)); + +//Clan Data - Fixed to prevent the tag being appended multiple times +if (%client.oldName $= "") +%client.oldName = %client.namebase; +if ($Data::IsInClan[%client.GUID]) +{ + %client.namebase = %client.oldName; + %client.name = addTaggedString(%client.oldName); + setName(%client,"\cp\c7" @ $Data::ClanTag[$Data::ClanID[%client.GUID]] @ "\c6" @ %client.namebase @ "\co"); +} +} + +function clientDisconnect(%client,%reason) +{ +messageClient(%client, 'onClientKicked', ""); +messageAllExcept( %client, -1, 'MsgClientDrop', "", Game.kickClientName, %client ); + +if( isObject( %client.player ) ) +%client.player.scriptKill(0); + +%client.setDisconnectReason( %reason ); +%client.schedule(700, "delete"); +return %client SPC %reason; +} + +function initGameBots( %mission, %mType ) +{ + echo( "adding bots..." ); + + AISystemEnabled( false ); + if ( $Host::BotCount > 0 && %mType !$= "SinglePlayer" ) + { + // Make sure this mission is bot enabled: + for ( %idx = 0; %idx < $HostMissionCount; %idx++ ) + { + if ( $HostMissionFile[%idx] $= %mission ) + break; + } + + if ( $BotEnabled[%idx] ) + { + if ( $Host::BotCount > 16 ) + $HostGameBotCount = 16; + else + $HostGameBotCount = $Host::BotCount; + + if ( $Host::BotCount > $Host::MaxPlayers - 1 ) + $HostGameBotCount = $Host::MaxPlayers - 1; + + //set the objective reassessment timeslice var + $AITimeSliceReassess = 0; + aiConnectMultiple( $HostGameBotCount, $Host::MinBotDifficulty, $Host::MaxBotDifficulty, -1 ); + } + else + { + $HostGameBotCount = 0; + } + } +} + +function findNextCycleMission() +{ + %numPlayers = ClientGroup.getCount(); + %tempMission = $CurrentMission; + %failsafe = 0; + while (1) + { + %nextMissionIndex = getNextMission(%tempMission, $CurrentMissionType); + %nextPotentialMission = $HostMissionFile[%nextMissionIndex]; + + //just cycle to the next if we've gone all the way around... + if (%nextPotentialMission $= $CurrentMission || %failsafe >= 1000) + { + %nextMissionIndex = getNextMission($CurrentMission, $CurrentMissionType); + //return $HostMissionName[%nextMissionIndex]; // z0dd - ZOD - Founder, 10/06/02. Was trying to load a mission name instead of file. + return $HostMissionFile[%nextMissionIndex]; + } + + //get the player count limits for this mission + %limits = $Host::MapPlayerLimits[%nextPotentialMission, $CurrentMissionType]; + if (%limits $= "") + return %nextPotentialMission; + else + { + %minPlayers = getWord(%limits, 0); + %maxPlayers = getWord(%limits, 1); + + if ((%minPlayers < 0 || %numPlayers >= %minPlayers) && (%maxPlayers < 0 || %numPlayers <= %maxPlayers)) + return %nextPotentialMission; + } + + //since we didn't return the mission, we must not have an acceptable number of players - check the next + %tempMission = %nextPotentialMission; + %failsafe++; + } +} + +function CycleMissions() +{ + echo( "cycling mission. " @ ClientGroup.getCount() @ " clients in game." ); + %nextMission = findNextCycleMission(); + messageAll( 'MsgClient', 'Loading %1 (%2)...', %nextMission, $MissionTypeDisplayName ); + loadMission( %nextMission, $CurrentMissionType ); +} + +function DestroyServer() +{ + $missionRunning = false; + allowConnections(false); + stopHeartbeat(); + if ( isObject( MissionGroup ) ) + MissionGroup.delete(); + if ( isObject( MissionCleanup ) ) + MissionCleanup.delete(); + if(isObject(game)) + { + game.deactivatePackages(); + game.delete(); + } + if(isObject($ServerGroup)) + $ServerGroup.delete(); + + // delete all the connections: + while(ClientGroup.getCount()) + { + %client = ClientGroup.getObject(0); + if (%client.isAIControlled()) + %client.drop(); + else + %client.delete(); + } + + // delete all the data blocks... + // this will cause problems if there are any connections + deleteDataBlocks(); + + // reset the target manager + resetTargetManager(); + + echo( "exporting server prefs..." ); + export( "$Host::*", "prefs/ServerPrefs.cs", false ); + purgeResources(); + + // z0dd - ZOD, 9/13/02. For TR2 compatability. + // This is a failsafe way of ensuring that default gravity is always restored + // if a game type (such as TR2) changes it. It is placed here so that listen + // servers will work after opening and closing different gametypes. + if ($DefaultGravity !$= "") + setGravity($DefaultGravity); +} + +function Disconnect() +{ + if ( isObject( ServerConnection ) ) + ServerConnection.delete(); + DisconnectedCleanup(); + DestroyServer(); +} + +function DisconnectedCleanup() +{ + $CurrentMissionType = ""; + $CurrentMission = ""; + + // Make sure we're not still waiting for the loading info: + cancelLoadInfoCheck(); + + // clear the chat hud message vector + HudMessageVector.clear(); + if ( isObject( PlayerListGroup ) ) + PlayerListGroup.delete(); + + // terminate all playing sounds + alxStopAll(); + + // clean up voting + voteHud.voting = false; + mainVoteHud.setvisible(0); + + // clear all print messages + clientCmdclearBottomPrint(); + clientCmdClearCenterPrint(); + + // clear the inventory and weapons hud + weaponsHud.clearAll(); + inventoryHud.clearAll(); + + // back to the launch screen + Canvas.setContent(LaunchGui); + if ( isObject( MusicPlayer ) ) + MusicPlayer.stop(); + clearTextureHolds(); + purgeResources(); + + if ( $PlayingOnline ) + { + // Restart the email check: + if ( !EmailGui.checkingEmail && EmailGui.checkSchedule $= "" ) + CheckEmail( true ); + + IRCClient::onLeaveGame(); + } +} + +// we pass the guid as well, in case this guy leaves the server. +function kick( %client, %admin, %guid ) +{ + if(%admin) + messageAll( 'MsgAdminForce', '\c2The Admin has kicked %1.', Game.kickClientName ); + else + messageAll( 'MsgVotePassed', '\c2%1 was kicked by vote.', Game.kickClientName ); + + messageClient(%client, 'onClientKicked', ""); + messageAllExcept( %client, -1, 'MsgClientDrop', "", Game.kickClientName, %client ); + + if( %client.isAIControlled() ) + { + $HostGameBotCount--; + %client.drop(); + } + else + { + if( $playingOnline ) // won games + { + %count = ClientGroup.getCount(); + %found = false; + for( %i = 0; %i < %count; %i++ ) // see if this guy is still here... + { + %cl = ClientGroup.getObject( %i ); + if( %cl.guid == %guid ) + { + %found = true; + + // kill and delete this client, their done in this server. + if( isObject( %cl.player ) ) + %cl.player.scriptKill(0); + + if ( isObject( %cl ) ) + { + %cl.setDisconnectReason( "You have been kicked out of the game." ); + %cl.schedule(700, "delete"); + } + + BanList::add( %guid, "0", $Host::KickBanTime ); + } + } + if( !%found ) + BanList::add( %guid, "0", $Host::KickBanTime ); // keep this guy out for a while since he left. + } + else // lan games + { + // kill and delete this client + if( isObject( %client.player ) ) + %client.player.scriptKill(0); + + if ( isObject( %client ) ) + { + %client.setDisconnectReason( "You have been kicked out of the game." ); + %client.schedule(700, "delete"); + } + + BanList::add( 0, %client.getAddress(), $Host::KickBanTime ); + } + } +} + +function ban( %client, %admin ) +{ + if ( %admin ) + messageAll('MsgAdminForce', '\c2%1 has banned %2.', %admin.name, %client.name); // z0dd - ZOD, 10/03/2. Tell who banned + else + messageAll( 'MsgVotePassed', '\c2%1 was banned by vote.', %client.name ); + + messageClient(%client, 'onClientBanned', ""); + messageAllExcept( %client, -1, 'MsgClientDrop', "", %client.name, %client ); + + // kill and delete this client + if( isObject(%client.player) ) + %client.player.scriptKill(0); + + if ( isObject( %client ) ) + { + %client.setDisconnectReason( %admin.nameBase @ " has banned you from this server." ); // z0dd - ZOD, 10/03/2. Tell who banned + %client.schedule(700, "delete"); + } + + BanList::add(%client.guid, %client.getAddress(), $Host::BanTime); +} + +function getValidVoicePitch(%voice, %voicePitch) +{ + if (%voicePitch < -1.0) + %voicePitch = -1.0; + else if (%voicePitch > 1.0) + %voicePitch = 1.0; + + //Voice pitch range is from 0.5 to 2.0, however, we should tighten the range to + //avoid players sounding like mickey mouse, etc... + //see if we're pitching down - clamp the min pitch at 0.875 + if (%voicePitch < 0) + return (1.0 + (0.125 * %voicePitch)); + + //max voice pitch is 1.125 + else if (%voicePitch > 0) + return 1.0 + (0.125 * %voicePitch); + + else + return 1.0; +} + +// z0dd - ZOD, 9/29/02. Removed T2 demo code from here + +function GameConnection::onConnect( %client, %name, %raceGender, %skin, %voice, %voicePitch ) +{ + %client.setMissionCRC($missionCRC); + sendLoadInfoToClient( %client ); + + //%client.setSimulatedNetParams(0.1, 30); + + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + + // --------------------------------------------------- + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + + // if hosting this server, set this client to superAdmin + if(%client.getAddress() $= "Local") + { + %client.isAdmin = true; + %client.isSuperAdmin = true; + } + // Get the client's unique id: + %authInfo = %client.getAuthInfo(); + %client.guid = getField( %authInfo, 3 ); + + // check admin and super admin list, and set status accordingly + if ( !%client.isSuperAdmin ) + { + if ( isOnSuperAdminList( %client ) ) + { + %client.isAdmin = true; + %client.isSuperAdmin = true; + } + else if( isOnAdminList( %client ) ) + { + %client.isAdmin = true; + } + } + + // Sex/Race defaults + switch$ ( %raceGender ) + { + case "Human Male": + %client.sex = "Male"; + %client.race = "Human"; + case "Human Female": + %client.sex = "Female"; + %client.race = "Human"; + case "Bioderm": + %client.sex = "Male"; + %client.race = "Bioderm"; + case "Draakan Male": + %client.sex = "Male"; + %client.race = "Draakan"; + case "Draakan Female": + // TODO: Make this value matter based on genetics + %client.sex = "Male"; + %client.race = "Draakan"; + case "Criollos": + %client.sex = "Male"; + %client.race = "Criollos"; + default: + error("Invalid race/gender combo passed: " @ %raceGender); + %client.sex = "Male"; + %client.race = "Human"; + } + %client.armor = "Light"; + + // Override the connect name if this server does not allow smurfs: + %realName = getField( %authInfo, 0 ); + if ( $PlayingOnline && $Host::NoSmurfs ) + %name = %realName; + + if ( strcmp( %name, %realName ) == 0 ) + { + %client.isSmurf = false; + + //make sure the name is unique - that a smurf isn't using this name... + %dup = -1; + %count = ClientGroup.getCount(); + for (%i = 0; %i < %count; %i++) + { + %test = ClientGroup.getObject( %i ); + if (%test != %client) + { + %rawName = stripChars( detag( getTaggedString( %test.name ) ), "\cp\co\c6\c7\c8\c9" ); + if (%realName $= %rawName) + { + %dup = %test; + %dupName = %rawName; + break; + } + } + } + + //see if we found a duplicate name + if (isObject(%dup)) + { + //change the name of the dup + %isUnique = false; + %suffixCount = 1; + while (!%isUnique) + { + %found = false; + %testName = %dupName @ "." @ %suffixCount; + for (%i = 0; %i < %count; %i++) + { + %cl = ClientGroup.getObject(%i); + %rawName = stripChars( detag( getTaggedString( %cl.name ) ), "\cp\co\c6\c7\c8\c9" ); + if (%rawName $= %testName) + { + %found = true; + break; + } + } + + if (%found) + %suffixCount++; + else + %isUnique = true; + } + + //%testName will now have the new unique name... + %oldName = %dupName; + %newName = %testName; + + MessageAll( 'MsgSmurfDupName', '\c2The real \"%1\" has joined the server.', %dupName ); + MessageAll( 'MsgClientNameChanged', '\c2The smurf \"%1\" is now called \"%2\".', %oldName, %newName, %dup ); + + %dup.name = addTaggedString(%newName); + setTargetName(%dup.target, %dup.name); + } + + // Add the tribal tag: + %tag = getField( %authInfo, 1 ); + %append = getField( %authInfo, 2 ); + if ( %append ) + %name = "\cp\c6" @ %name @ "\c7" @ %tag @ "\co"; + else + %name = "\cp\c7" @ %tag @ "\c6" @ %name @ "\co"; + + %client.sendGuid = %client.guid; + } + else + { + %client.isSmurf = true; + %client.sendGuid = 0; + %name = stripTrailingSpaces( strToPlayerName( %name ) ); + if ( strlen( %name ) < 3 ) + %name = "Poser"; + + // Make sure the alias is unique: + %isUnique = true; + %count = ClientGroup.getCount(); + for ( %i = 0; %i < %count; %i++ ) + { + %test = ClientGroup.getObject( %i ); + %rawName = stripChars( detag( getTaggedString( %test.name ) ), "\cp\co\c6\c7\c8\c9" ); + if ( strcmp( %name, %rawName ) == 0 ) + { + %isUnique = false; + break; + } + } + + // Append a number to make the alias unique: + if ( !%isUnique ) + { + %suffix = 1; + while ( !%isUnique ) + { + %nameTry = %name @ "." @ %suffix; + %isUnique = true; + + %count = ClientGroup.getCount(); + for ( %i = 0; %i < %count; %i++ ) + { + %test = ClientGroup.getObject( %i ); + %rawName = stripChars( detag( getTaggedString( %test.name ) ), "\cp\co\c6\c7\c8\c9" ); + if ( strcmp( %nameTry, %rawName ) == 0 ) + { + %isUnique = false; + break; + } + } + + %suffix++; + } + + // Success! + %name = %nameTry; + } + + %smurfName = %name; + // Tag the name with the "smurf" color: + %name = "\cp\c8" @ %name @ "\co"; + } + + %client.name = addTaggedString(%name); + if(%client.isSmurf) + %client.nameBase = %smurfName; + else + %client.nameBase = %realName; + + // Make sure that the connecting client is not trying to use a bot skin: + %temp = detag( %skin ); + if ( %temp $= "basebot" || %temp $= "basebbot" ) + %client.skin = addTaggedString( "base" ); + else + %client.skin = addTaggedString( %skin ); + + %client.voice = %voice; + %client.voiceTag = addtaggedString(%voice); + + //set the voice pitch based on a lookup table from their chosen voice + %client.voicePitch = getValidVoicePitch(%voice, %voicePitch); + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + // --------------------------------------------------- + + %client.justConnected = true; + %client.isReady = false; + + // full reset of client target manager + clientResetTargets(%client, false); + + %client.target = allocClientTarget(%client, %client.name, %client.skin, %client.voiceTag, '_ClientConnection', 0, 0, %client.voicePitch); + %client.score = 0; + %client.team = 0; + + $instantGroup = ServerGroup; + $instantGroup = MissionCleanup; + + echo("CADD: " @ %client @ " " @ %client.getAddress()); + + %count = ClientGroup.getCount(); + for(%cl = 0; %cl < %count; %cl++) + { + %recipient = ClientGroup.getObject(%cl); + if((%recipient != %client)) + { + // These should be "silent" versions of these messages... + messageClient(%client, 'MsgClientJoin', "", + %recipient.name, + %recipient, + %recipient.target, + %recipient.isAIControlled(), + %recipient.isAdmin, + %recipient.isSuperAdmin, + %recipient.isSmurf, + %recipient.sendGuid); + + messageClient(%client, 'MsgClientJoinTeam', "", %recipient.name, $teamName[%recipient.team], %recipient, %recipient.team ); + } + } + +// commandToClient(%client, 'getManagerID', %client); + + commandToClient(%client, 'setBeaconNames', "Target Beacon", "Marker Beacon", "Bomb Target"); + + if ( $CurrentMissionType !$= "SinglePlayer" ) + { + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + messageClient(%client, 'MsgClientJoin', '\c2Welcome to Tribes 2: Birth of Legend %1.', + %client.name, + %client, + %client.target, + false, // isBot + %client.isAdmin, + %client.isSuperAdmin, + %client.isSmurf, + %client.sendGuid ); + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + + messageAllExcept(%client, -1, 'MsgClientJoin', '\c1%1 joined the game.', + %client.name, + %client, + %client.target, + false, // isBot + %client.isAdmin, + %client.isSuperAdmin, + %client.isSmurf, + %client.sendGuid ); + } + else + messageClient(%client, 'MsgClientJoin', "\c0Mission Insertion complete...", + %client.name, + %client, + %client.target, + false, // isBot + false, // isAdmin + false, // isSuperAdmin + false, // isSmurf + %client.sendGuid ); + + //Game.missionStart(%client); + setDefaultInventory(%client); + + if($missionRunning) + %client.startMission(); + $HostGamePlayerCount++; + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + + // z0dd - ZOD 4/29/02. Activate the clients Classic Huds + // and start off with 0 SAD access attempts. + %client.SadAttempts = 0; + messageClient(%client, 'MsgBomberPilotHud', ""); // Activate the bomber pilot hud + + // z0dd - ZOD, 8/10/02. Get player hit sounds etc. + commandToClient(%client, 'GetClassicModSettings', 1); + + //--------------------------------------------------------- + // z0dd - ZOD, 7/12/02. New AutoPW server function. Sets + // server join password when server reaches x player count. + if($Host::ClassicAutoPWEnabled) + { + if(($Host::ClassicAutoPWPlayerCount != 0 && $Host::ClassicAutoPWPlayerCount !$= "") && ($HostGamePlayerCount >= $Host::ClassicAutoPWPlayerCount)) + AutoPWServer(1); + } +} + +function GameConnection::onDrop(%client, %reason) +{ + + if (!%client.isAIControlled()) //Bots disconnect left and right in this mod, ignore the client if it's a bot + saveGame(); + + if(isObject(Game)) + Game.onClientLeaveGame(%client); + + // make sure that tagged string of player name is not used + if (!%client.isAIControlled()) + { + if ( $CurrentMissionType $= "SinglePlayer" || $CurrentMissionType $= "SV") + messageAllExcept(%client, -1, 'MsgClientDrop', "", getTaggedString(%client.name), %client); + else + messageAllExcept(%client, -1, 'MsgClientDrop', '\c1%1 has left the game.', getTaggedString(%client.name), %client); + } + + if ( isObject( %client.camera ) ) + %client.camera.delete(); + + // z0dd - ZOD, 6/19/02. Strip the hit sound tags + removeTaggedString(%client.playerHitWav); + removeTaggedString(%client.vehicleHitWav); + + removeTaggedString(%client.name); + removeTaggedString(%client.voiceTag); + removeTaggedString(%client.skin); + freeClientTarget(%client); + + echo("CDROP: " @ %client @ " " @ %client.getAddress()); + $HostGamePlayerCount--; + + //--------------------------------------------------------- + // z0dd - ZOD, 7/12/02. New AutoPW server function. Sets + // server join password when server reaches x player count. + if($Host::ClassicAutoPWEnabled) + { + if($HostGamePlayerCount < $Host::ClassicAutoPWPlayerCount) + AutoPWServer(0); + } + // reset the server if everyone has left the game + //if( $HostGamePlayerCount - $HostGameBotCount == 0 && $Host::Dedicated && !$resettingServer && !$LoadingMission ) + // schedule(0, 0, "resetServerDefaults"); + + // ------------------------------------------------------------------------------------------------------------ + // z0dd - ZOD, 5/12/02. Reset the server if everyone has left the game and set this mission as startup mission. + // This helps with $Host::ClassicRandomMissions to keep the random more random. + if( $HostGamePlayerCount - $HostGameBotCount == 0 && $Host::Dedicated && !$resettingServer && !$LoadingMission && $CurrentMissionType !$= "RPG" ) //The server should never reset itself.. + { + $Host::Map = $CurrentMission; + export("$Host::*", "prefs/ServerPrefs.cs", false); + $Host::MissionType = $CurrentMissionType; + export("$Host::*", "prefs/ServerPrefs.cs", false); + schedule(10, 0, "resetServerDefaults"); + } + // ------------------------------------------------------------------------------------------------------------ +} + +function dismountPlayers() +{ + // make sure all palyers are dismounted from vehicles and have normal huds + %count = ClientGroup.getCount(); + for(%cl = 0; %cl < %count; %cl++) + { + %client = ClientGroup.getObject(%cl); + %player = %client.player; + if(%player.isMounted()) { + %player.unmount(); + commandToClient(%client, 'setHudMode', 'Standard', "", 0); + } + } +} + +function loadMission( %missionName, %missionType, %firstMission ) +{ + if ($AutoRestart) // z0dd - ZOD, 3/26/02. Auto restart server after a specified time. + { + $AutoRestart = 0; + messageAll( 'MsgServerRestart', '\c2SERVER IS AUTO REBOOTING! COME BACK IN 5 MINUTES.~wfx/misc/red_alert.wav'); + logEcho("Auto server restart commencing."); + //schedule(10000, 0, "CreateServer", %missionName, %missionType); // this wasn't working as a cure for servers with NULLs + schedule(10000, 0, quit ); + } + + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + + // z0dd - ZOD, 9/13/02. TR2 needs this. + if( %missionType $= "TR2" ) + { + $_Camera::movementSpeed = $Camera::movementSpeed; + $Camera::movementSpeed = 80; + } + else + { + %val = ($_Camera::movementSpeed $= "") ? $Classic::cameraSpeed : $_Camera::movementSpeed; // z0dd - ZOD, 9/13/02. Classic camera speed. + $Camera::movementSpeed = %val; + } + + $LoadingMission = true; + disableCyclingConnections(true); + if (!$pref::NoClearConsole) + cls(); + if ( isObject( LoadingGui ) ) + LoadingGui.gotLoadInfo = ""; + buildLoadInfo( %missionName, %missionType ); + + // reset all of these + ClearCenterPrintAll(); + ClearBottomPrintAll(); + + if( $Host::TournamentMode ) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + resetTournamentPlayers(); + + // Send load info to all the connected clients: + %count = ClientGroup.getCount(); + for ( %cl = 0; %cl < %count; %cl++ ) + { + %client = ClientGroup.getObject( %cl ); + if ( !%client.isAIControlled() ) + sendLoadInfoToClient( %client ); + } + + // allow load condition to exit out + schedule(0,ServerGroup,loadMissionStage1,%missionName,%missionType,%firstMission); +} + +function loadMissionStage1(%missionName, %missionType, %firstMission) +{ + // if a mission group was there, delete prior mission stuff + if(isObject(MissionGroup)) + { + // clear out the previous mission paths + for(%clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++) + { + // clear ghosts and paths from all clients + %cl = ClientGroup.getObject(%clientIndex); + %cl.resetGhosting(); + %cl.clearPaths(); + %cl.isReady = ""; + %cl.matchStartReady = false; + } + Game.endMission(); + $lastMissionTeamCount = Game.numTeams; + + MissionGroup.delete(); + MissionCleanup.delete(); + Game.deactivatePackages(); + Game.delete(); + $ServerGroup.delete(); + $ServerGroup = new SimGroup(ServerGroup); + } + + %oldMissionType = $CurrentMissionType; + //Ok, make sure we deactivate the mission package before loading a new one + deactivatePackage($CurrentMission); + $CurrentMission = %missionName; + $CurrentMissionType = %missionType; + + createInvBanCount(); + echo("LOADING MISSION: " @ %missionName); + + // increment the mission sequence (used for ghost sequencing) + $missionSequence++; + + // if this isn't the first mission, allow some time for the server + // to transmit information to the clients: + +// jff: $currentMission already being used for this purpose, used in 'finishLoadMission' + $MissionName = %missionName; + $missionRunning = false; + + if(!%firstMission) + schedule(15000, ServerGroup, loadMissionStage2); + else + loadMissionStage2(); +} + + +function loadMissionStage2() +{ + // create the mission group off the ServerGroup + echo("Stage 2 load"); + $instantGroup = ServerGroup; + + new SimGroup (MissionCleanup); + + if($CurrentMissionType $= "") + { + new ScriptObject(Game) { + class = DefaultGame; + }; + } + else + { + new ScriptObject(Game) { + class = $CurrentMissionType @ "Game"; + superClass = DefaultGame; + }; + } + // allow the game to activate any packages. + Game.activatePackages(); + + // reset the target manager + resetTargetManager(); + + %file = "missions/" @ $missionName @ ".mis"; + %script = "missions/" @ $missionName @ ".cs"; + + if(!isFile(%file)) + return; + + // send the mission file crc to the clients (used for mission lighting) + $missionCRC = getFileCRC(%file); + %count = ClientGroup.getCount(); + for(%i = 0; %i < %count; %i++) + { + %client = ClientGroup.getObject(%i); + if(!%client.isAIControlled()) + %client.setMissionCRC($missionCRC); + } + + $countDownStarted = false; + if (IsFile(%script)) //If the mission has a script.. + exec(%script); //execute + exec(%file); //Load our mission while we're at it + $instantGroup = MissionCleanup; + + // pre-game mission stuff + if(!isObject(MissionGroup)) + { + error("No 'MissionGroup' found in mission \"" @ $missionName @ "\"."); + schedule(3000, ServerGroup, CycleMissions); + return; + } + + MissionGroup.cleanNonType($CurrentMissionType); + + // construct paths + pathOnMissionLoadDone(); + + $ReadyCount = 0; + $MatchStarted = false; + $CountdownStarted = false; + AISystemEnabled( false ); + + // Set the team damage here so that the game type can override it: + + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + if ( $Host::TournamentMode ) + $TeamDamage = 1; + else + $TeamDamage = $Host::TeamDamageOn; + // ---------------------------------------- + + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + + // z0dd - ZOD, 8/4/02. Gravity change + if(getGravity() !$= $Classic::gravSetting) + setGravity($Classic::gravSetting); + // --------------------------------------------- + + Game.missionLoadDone(); + + // start all the clients in the mission + $missionRunning = true; + for(%clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++) + ClientGroup.getObject(%clientIndex).startMission(); + + if(!$MatchStarted && $LaunchMode !$= "NavBuild" && $LaunchMode !$= "SpnBuild" ) + { + if( $Host::TournamentMode ) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + checkTourneyMatchStart(); + else if( $currentMissionType !$= "SinglePlayer" ) + checkMissionStart(); + } + + // offline graph builder... + if( $LaunchMode $= "NavBuild" ) + buildNavigationGraph( "Nav" ); + + if( $LaunchMode $= "SpnBuild" ) + buildNavigationGraph( "Spn" ); + purgeResources(); + disableCyclingConnections(false); + $LoadingMission = false; + + //Ok, if the script exists, activate the package and load AI's for this map + if (IsFile(%script) && $CurrentMissionType $= "RPG") + { + activatePackage($missionName); + DefineGeneralAI(); //Load the AI's + + //Now, the game is pretty much done. We got to spawn our AI's + for (%i = 0; %i < $BotCount; %i++) + { + spawnGeneralBot(%i); + } + } + + serverThink(); //Start server think loop + + if (%oldMissionType !$= "RPG" && %missionType $= "RPG") //Going from some gamemode to RPG + disconnectAllBots(); + else if (%oldMissionType $= "RPG" && %missionType !$= "RPG") //Going from RPG to some gamemode + discconectAllBots(); + +} + +function ShapeBase::cleanNonType(%this, %type) +{ + if(%this.missionTypesList $= "") + return; + + for(%i = 0; (%typei = getWord(%this.missionTypesList, %i)) !$= ""; %i++) + if(%typei $= %type) + return; + + // first 32 targets are team targets (never allocated/freed) + // - must reallocate the target if unhiding + if(%this.getTarget() >= 32) + { + freeTarget(%this.getTarget()); + %this.setTarget(-1); + } + if(isObject(%this.trigger)) // z0dd - ZOD, 8/10/02. Clean them triggers too! + %this.trigger.delete(); + + %this.hide(true); +} + +function SimObject::cleanNonType(%this, %type) +{ +} + +function SimGroup::cleanNonType(%this, %type) +{ + for (%i = 0; %i < %this.getCount(); %i++) + %this.getObject(%i).cleanNonType(%type); +} + +function GameConnection::endMission(%this) +{ + commandToClient(%this, 'MissionEnd', $missionSequence); +} + +//-------------------------------------------------------------------------- +// client start phases: +// 0: start mission +// 1: got phase1 done +// 2: got datablocks done +// 3: got phase2 done +// 4: got phase3 done +function GameConnection::startMission(%this) +{ + // send over the information that will display the server info + // when we learn it got there, we'll send the data blocks + %this.currentPhase = 0; + + //Make sure the client is an RPG client.. + if ($CurrentMissionType $= "RPG") + commandToClient(%this, 'HandleScriptedCommand',5,true); //Send us the current time in military format + else + commandToClient(%this, 'HandleScriptedCommand',5,false); //Not running the RPG gamemode, so don't setup the clock & scoreScreen text change + + %this.team = getRaceTeam(%this.race); + + commandToClient(%this, 'MissionStartPhase1', $missionSequence, $MissionName, MissionGroup.musicTrack); +} + +function serverCmdInputDone(%client, %type, %value) //Used when creating/editing clans +{ + switch$(%type) + { + case "ClanN": + %client.clanN = %value; + case "ClanT": + %client.clanT = %value; + case "Desc": + %client.description = %value; + case "emailTitle": + %client.emailTitle = %value; + case "emailCont": + //Every 39 chars add a \t tag.. + %cont = %value; + %len = strLen(%value); + + if (%len > 39) + %value = subStrInsert(%value,"\t",39); + + %client.emailCont = %value; + } + if (%type $= "ClanN" || %type $= "ClanT" || %type $= "Desc") + forceScoreScreenOpen(%client,"CLNSTP"); + else + forceScoreScreenOpen(%client,"EMAILSEND"); +} + +function serverCmdMissionStartPhase1Done(%client, %seq) +{ + if(%seq != $missionSequence || !$MissionRunning) + return; + + if(%client.currentPhase != 0) + return; + %client.currentPhase = 1; + + // if (!%client.isValid && $RequiresClient[$CurrentMissionType]) //Did this person say he's a client and the gamemode requires //clientside stuff? +/// return clientDisconnect(%client,"You do not have a Tribes 2: Birth of Legend mod client running."); + + schedule(1000, 0, "debriefLoad", %client); + + // when the datablocks are transmitted, we'll send the ghost always objects + %client.transmitDataBlocks($missionSequence); +} + +function GameConnection::dataBlocksDone( %client, %missionSequence ) +{ + echo("GOT DATA BLOCKS DONE FOR: " @ %client); + if(%missionSequence != $missionSequence) + return; + + if(%client.currentPhase != 1) + return; + %client.currentPhase = 2; + + // only want to set this once... (targets will not be updated/sent until a + // client has this flag set) + if(!%client.getReceivedDataBlocks()) + { + %client.setReceivedDataBlocks(true); + sendTargetsToClient(%client); + } + + commandToClient(%client, 'MissionStartPhase2', $missionSequence); +} + +function serverCmdMissionStartPhase2Done(%client, %seq) +{ + if(%seq != $missionSequence || !$MissionRunning) + return; + + if(%client.currentPhase != 2) + return; + %client.currentPhase = 3; + + // when all this good love is over, we'll know that the mission lighting is done + %client.transmitPaths(); + + // setup the client team state + if ( $CurrentMissionType !$= "SinglePlayer" ) + serverSetClientTeamState( %client ); + + // start ghosting + %client.activateGhosting(); + %client.camera.scopeToClient(%client); + + // to the next phase... + commandToClient(%client, 'MissionStartPhase3', $missionSequence, $CurrentMission); +} + +function serverCmdMissionStartPhase3Done(%client, %seq) +{ + if(%seq != $missionSequence || !$MissionRunning) + return; + + if(%client.currentPhase != 3) + return; + %client.currentPhase = 4; + + %client.isReady = true; + Game.clientMissionDropReady(%client); +} + +function serverSetClientTeamState( %client ) +{ + // set all player states prior to mission drop ready + + // create a new camera for this client + %client.camera = new Camera() + { + dataBlock = Observer; + }; + + if( isObject( %client.rescheduleVote ) ) + Cancel( %client.rescheduleVote ); + %client.canVote = true; + %client.rescheduleVote = ""; + + MissionCleanup.add( %client.camera ); // we get automatic cleanup this way. + + %observer = false; + if( !$Host::TournamentMode ) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + { + if( %client.justConnected ) + { + %client.justConnected = false; + %client.camera.getDataBlock().setMode( %client.camera, "justJoined" ); + } + else + { + // server just changed maps - this guy was here before + if( %client.lastTeam !$= "" ) + { + // see if this guy was an observer from last game + if(%client.lastTeam == 0) + { + %observer = true; + + %client.camera.getDataBlock().setMode( %client.camera, "ObserverFly" ); + } + else // let this player join the team he was on last game + { + if(Game.numTeams > 1 && %client.lastTeam <= Game.numTeams ) + { + Game.clientJoinTeam( %client, %client.lastTeam, false ); + } + else + { + Game.assignClientTeam( %client ); + + // spawn the player + Game.spawnPlayer( %client, false ); + } + } + } + else + { + Game.assignClientTeam( %client ); + + // spawn the player + Game.spawnPlayer( %client, false ); + } + + if( !%observer ) + { + if(!$MatchStarted && !$CountdownStarted) + %client.camera.getDataBlock().setMode( %client.camera, "pre-game", %client.player ); + else if(!$MatchStarted && $CountdownStarted) + %client.camera.getDataBlock().setMode( %client.camera, "pre-game", %client.player ); + } + } + } + else + { + // don't need to do anything. MissionDrop will handle things from here. + } +} + +//function serverCmdPreviewDropReady( %client ) +//{ +// $MatchStarted = true; +// commandToClient( %client, 'SetMoveKeys', true); +// %markerObj = "0 0 0"; +// %client.camera.mode = "PreviewMode"; +// %client.camera.setTransform( %markerObj ); +// %client.camera.setFlyMode(); +// +// %client.setControlObject( %client.camera ); +//} + +function HideHudHACK(%visible) +{ + //compassHud.setVisible(%visible); + //enerDamgHud.setVisible(%visible); + retCenterHud.setVisible(%visible); + reticleFrameHud.setVisible(%visible); + //invPackHud.setVisible(%visible); + weaponsHud.setVisible(%visible); + outerChatHud.setVisible(%visible); + objectiveHud.setVisible(%visible); + chatHud.setVisible(%visible); + navHud.setVisible(%visible); + //watermarkHud.setVisible(%visible); + hudClusterBack.setVisible(%visible); + inventoryHud.setVisible(%visible); + clockHUD.setVisible(%visible); +} + +function ServerPlay2D(%profile) +{ + for(%idx = 0; %idx < ClientGroup.getCount(); %idx++) + ClientGroup.getObject(%idx).play2D(%profile); +} + +function ServerPlay3D(%profile,%transform) +{ + for(%idx = 0; %idx < ClientGroup.getCount(); %idx++) + ClientGroup.getObject(%idx).play3D(%profile,%transform); +} + +function clientCmdSetFirstPerson(%value) +{ + $firstPerson = %value; + if(%value) + ammoHud.setVisible(true); + else + ammoHud.setVisible(false); +} + +function clientCmdGetFirstPerson() +{ + commandToServer('FirstPersonValue', $firstPerson); +} + +function serverCmdFirstPersonValue(%client, %firstPerson) +{ + %client.player.firstPerson = %firstPerson; +} + +function clientCmdVehicleMount() +{ + if ( $pref::toggleVehicleView ) + { + $wasFirstPerson = $firstPerson; + $firstPerson = false; + } +} + +function clientCmdVehicleDismount() +{ + if ( $pref::toggleVehicleView ) + $firstPerson = $wasFirstPerson; +} + +//---------------------------------------------------- +// z0dd - ZOD, 3/09/02. Re-write. It's more flexible. +function serverCmdSAD(%client, %password) +{ + if(%password $= "") + { + messageClient(%client, 'MsgPasswordFailed', '\c2You did not supply a PW.'); + return; + } + %name = %client.name; + + switch$ (%password) + { + case $Host::ClassicSuperAdminPassword: + if(!%client.isSuperAdmin) + { + if(%password $= "changeme") + { + messageClient(%client, 'MsgPasswordFailed', '\c2Illegal SAD PW. You need to change the default \"$Host::ClassicSuperAdminPassword\" value in \"ServerPrefs.cs\"!'); + return; + } + %client.isAdmin = true; + %client.isSuperAdmin = true; + MessageAll( 'MsgSuperAdminPlayer', '\c2%2 has become a Super Admin by force.', %client, %name); + logEcho(%client.nameBase @ " has become a Super Admin by force."); + } + + case $Host::AdminPassword: + if(!%client.isAdmin) + { + if(%password $= "changethis") + { + messageClient(%client, 'MsgPasswordFailed', '\c2Illegal Admin PW. You need to change the default \"$Host::AdminPassword\" value in \"ServerPrefs.cs\"!'); + return; + } + %client.isAdmin = true; + %client.isSuperAdmin = false; + MessageAll( 'MsgAdminForce', '\c2%2 has become a Admin by force.', %client, %name); + logEcho(%client.nameBase @ " has become an Admin by force."); + } + default: + messageClient(%client, 'MsgPasswordFailed', '\c2Illegal SAD PW.'); + %client.SadAttempts++; + if(%client.SadAttempts >= 6 && !%client.isSuperAdmin) + { + %client.getAddress(); + %client.getAuthInfo(); + messageClient(%client, 'onClientBanned', 'For attempting to exploit SAD to gain unauthorized Admin by entering\ntoo many passwords, you are being Banned'); + if( isObject(%client.player) ) + { + %client.player.scriptKill(0); + %client.schedule(700, "delete"); + } + schedule(10, %client @ "ResetSadAttp", %client); + %client.setDisconnectReason( 'For attempting to exploit SAD to gain unauthorized Admin by entering\ntoo many passwords, you are being Banned.' ); + %client.schedule(700, "delete"); + BanList::add(%client.guid, %client.getAddress(), $Host::BanTime); + logEcho(%client.nameBase @ " " @ %client.guid @ " has been banned for excessive use of SAD"); + } + } +} + +function ResetSadAttp(%client) +{ + %client.SadAttempts = 0; +} + +//--------------------------------------------------------------- +// z0dd - ZOD, 8/13/02. Added this function. Writen by Writer +// +// Returns true if %text consists of nothing but digits and/or +// decimals. +// Note: rejects strings with more than one decimal, or with a + +// or - as anything but the first character (+ or - are only +// allowed as the first character in the string) +function isNumber(%text) +{ + for(%i = 0; (%char = getSubStr(%text, %i, 1)) !$= ""; %i++) + { + switch$(%char) + { + case "0": + continue; + case "1": + continue; + case "2": + continue; + case "3": + continue; + case "4": + continue; + case "5": + continue; + case "6": + continue; + case "7": + continue; + case "8": + continue; + case "9": + continue; + case ".": + if(%dot_count > 1) + return false; + + %dot_count++; + continue; + case "-": + if(%i) // only valid as first character + return false; + + continue; + case "+": + if(%i) // only valid as first character + return false; + + continue; + default: + return false; + } + } + // %text passed the test + return true; +} +//--------------------------------------------------------------- + +//--------------------------------------------------------- +// z0dd - ZOD, 3/10/02. New remote admin control function +function serverCmdSet(%client, %type, %val) +{ + // USAGE: commandToServer('Set', type, value); + %type = deTag(%type); + %val = deTag(%val); + + if(!%client.isSuperAdmin) + { + messageClient(%client, 'MsgNotSuperAdmin', '\c2Only Super Admins can use that command.'); + return; + } + if(%type $= "") + { + messageClient(%client, 'MsgTypeFailed', '\c2No Changes. You did not supply a type.'); + return; + } + //if( (%val $= "") && (%type !$= "joinpw") ) + if(%val $= "") + { + if(%type $= "joinpw") + messageClient(%client, 'MsgValueFailed', '\c2No Changes. You did not supply a value. Use \"remove\" to remove join pw.'); + else + messageClient(%client, 'MsgValueFailed', '\c2No Changes. You did not supply a value.'); + return; + } + %name = %client.name; + switch$ (%type) + { + case "superpw": + $Host::ClassicSuperAdminPassword = %val; + export( "$Host::*", "prefs/ServerPrefs.cs", false ); + messageClient(%client, 'MsgSuperPassword', '\c2\"Super Admin\" PW changed to: \c3%1\c2.', addTaggedString(%val)); + logEcho(%client.nameBase @ " changed the Super Admin password."); + + case "adminpw": + $Host::AdminPassword = %val; + export( "$Host::*", "prefs/ServerPrefs.cs", false ); + messageClient(%client, 'MsgAdminPassword', '\c2\"Admin\" PW changed to: \c3%1\c2.', addTaggedString(%val)); + logEcho(%client.nameBase @ " changed the Admin password."); + + case "joinpw": + if(%val $= "remove") + $Host::Password = ""; + else + $Host::Password = %val; + + export( "$Host::*", "prefs/ServerPrefs.cs", false ); + messageAll( 'MsgServerPassword', '\c3%1\c2: JOIN PASSWORD CHANGED.~wfx/misc/diagnostic_on.wav', %name); + if(%val $= "remove") + messageClient(%client, 'MsgServerPassword', '\c2Join PW removed.'); + else + messageClient(%client, 'MsgServerPassword', '\c2Join PW changed to: \c3%1\c2.', addTaggedString(%val)); + logEcho(%client.nameBase @ " changed the join password."); + + case "maxplayers": + + if(isNumber(%val) && (%val > 0)) + { + $Host::MaxPlayers = %val; + export( "$Host::*", "prefs/ServerPrefs.cs", false ); + messageAll( 'MsgMaxPlayersSet', '\c3%1\c2: PLAYER LIMIT CHANGED TO: \c3%2\c2.~wfx/misc/diagnostic_on.wav', %name, %val); + logEcho(%client.nameBase @ " changed the Player Limit."); + } + else + { + messageClient( %client, 'MsgAdmin', '\c2Value must be a positive number.' ); + } + + case "restart": + if (%val $= "0") + { + $AutoRestart = 0; + messageClient( %client, 'MsgAdmin', '\c2Server restart at mission end aborted.' ); + messageAll( 'MsgServerRestart', '\c3%1\c2: SERVER RESTART HAS BEEN CANCELED.~wfx/misc/diagnostic_on.wav', %name); + } + else if (%val $= "1") + { + messageAll( 'MsgServerRestart', '\c3%1\c2: SERVER WILL BE REBOOTING IN 30 SECONDS!.~wfx/misc/red_alert.wav', %name); + schedule(20000, 0, "messageAll", 'MsgServerRestart', '\c2SERVER WILL REBOOT IN 10 SECONDS!.~wfx/misc/hunters_10.wav'); + schedule(30000, 0, quit); + logEcho(%client.nameBase @ " forced a server restrart."); + } + else + { + messageClient( %client, 'MsgAdmin', '\c2Unknown restart value. 0 cancels restart, 1 forces restart.' ); + } + + case "random": + if(%val $= "0" || %val $= "1") + { + if($CurrentMissionType $= TR2) // z0dd - ZOD, 9/17/02. Check for Team Rabbit 2 + { + messageClient( %client, 'MsgAdmin', '\c2This feature is unavailable in Team Rabbit 2.' ); + return; + } + $Host::ClassicRandomizeTeams = %val; + export( "$Host::*", "prefs/ServerPrefs.cs", false ); + %detail = ($Host::ClassicRandomizeTeams ? "ENABLED" : "DISABLED"); + messageAll( 'MsgRandomTeams', '\c3%1\c2: RANDOM TEAMS %2. Changes will take place next mission.~wfx/misc/diagnostic_on.wav', %name, %detail); + logEcho(%client.nameBase @ " " @ %detail @ " random teams."); + } + else + { + messageClient( %client, 'MsgAdmin', '\c2Unknown input value. 0 disables Random Teams, 1 enables Random Teams.' ); + } + + case "fairteams": + if(%val $= "0" || %val $= "1") + { + if($CurrentMissionType $= TR2) // z0dd - ZOD, 9/17/02. Check for Team Rabbit 2 + { + messageClient( %client, 'MsgAdmin', '\c2This feature is unavailable in Team Rabbit 2.' ); + return; + } + $Host::ClassicFairTeams = %val; + export( "$Host::*", "prefs/ServerPrefs.cs", false ); + %detail = ($Host::ClassicFairTeams ? "ENABLED" : "DISABLED"); + messageAll( 'MsgRandomTeams', '\c3%1\c2: FAIR TEAMS %2.~wfx/misc/diagnostic_on.wav', %name, %detail ); + logEcho(%client.nameBase @ " " @ %detail @ " fair teams."); + } + else + { + messageClient( %client, 'MsgAdmin', '\c2Unknown input value. 0 disables Fair Teams, 1 enables Fair Teams.' ); + } + + default: + messageClient(%client, 'MsgValueFailed', '\c2No Changes. You did not specify a valid type.'); + } +} +//---------------------------------------------------------- +// z0dd - ZOD, 7/12/02. New AutoPW server functions. Sets +// server join password when server reaches x player count. +function AutoPWServer(%val) +{ + if(%val && ($Host::ClassicAutoPWPassword !$= "changeit")) + $Host::Password = $Host::ClassicAutoPWPassword; + else + $Host::Password = ""; + +// z0dd - ZOD, 9/27/02, Chat was being spammed every time someone joined if limit was hit or above +// %detail = (($Host::Password $= "") ? "removed" : "set"); +// messageAll( 'MsgAdmin', '\c2Join password %1 by Auto-password feature.', %detail ); +} + +function serverCmdAutoPWSetup(%client, %type, %val) +{ + // USAGE: commandToServer('AutoPWSetup', type, value); + %type = deTag(%type); + %val = deTag(%val); + if(!%client.isSuperAdmin) + { + messageClient(%client, 'MsgNotSuperAdmin', '\c2Only Super Admins can use this command.'); + return; + } + if(%type $= "") + { + messageClient(%client, 'MsgTypeFailed', '\c2No Changes. You did not supply a type.'); + return; + } + switch$ (%type) + { + case "autopw": + if (%val $= "0") + { + $Host::ClassicAutoPWEnabled = 0; + AutoPWServer(0); + messageClient( %client, 'MsgAdmin', '\c2Auto-password disabled.' ); + } + else if (%val $= "1") + { + $Host::ClassicAutoPWEnabled = 1; + messageClient( %client, 'MsgAdmin', '\c2Auto-password enabled.' ); + logEcho(%client.nameBase @ " enabled Auto-password."); + } + else + { + messageClient( %client, 'MsgAdmin', '\c2Unknown value. 0 disables Auto-password, 1 enables Auto-password.' ); + } + + case "autopwpass": + if(%val !$= "") + { + $Host::ClassicAutoPWPassword = %val; + } + else + { + messageClient( %client, 'MsgAdmin', '\c2You must specify a password.' ); + return; + } + export( "$Host::*", "prefs/ServerPrefs.cs", false ); + messageClient(%client, 'MsgServerPassword', '\c2Server Auto-password PW changed to: \c3%1\c2.', addTaggedString(%val)); + logEcho(%client.nameBase @ " changed the Auto-password PW."); + + case "autopwcount": + if(%val !$= "" && %val !$= "0") + { + $Host::ClassicAutoPWPlayerCount = %val; + } + else + { + messageClient( %client, 'MsgAdmin', '\c2You must specify a numerical value.' ); + return; + } + export( "$Host::*", "prefs/ServerPrefs.cs", false ); + messageClient(%client, 'MsgServerPassword', '\c2Server Auto-password player count changed to: \c3%1\c2.', addTaggedString(%val)); + logEcho(%client.nameBase @ " changed the Auto-password player count."); + } +} + +//--------------------------------------------------------------------------------------------------- +// z0dd - ZOD, 4-15-02. Pick spawn spot by killing self during tourney wait. Also addresses +// team switching to crash server exploit. New function +$WAIT_PERIOD = 20000; +$WAIT_MESSAGE = '\c3WAIT MESSAGE:\cr You must wait another %1 seconds'; + +function GameConnection::waitTimeout(%this) +{ + %this.isWaiting = false; +} + +function SpawnPosChange( %client ) +{ + if( isObject( Game ) && %client != Game.kickClient && $Host::TournamentMode && !$CountdownStarted) + { + if (!%client.isWaiting) + { + %client.isWaiting = true; + %client.waitStart = getSimTime(); + %client.schedule($WAIT_PERIOD, waitTimeout); + + clearBottomPrint(%client); + Game.clientChangeTeam( %client, %client.team, 0, true ); + + if(!$MatchStarted) + { + %client.observerMode = "pregame"; + %client.notReady = true; + %client.camera.getDataBlock().setMode( %client.camera, "pre-game", %client.player ); + %client.setControlObject( %client.camera ); + + if( !$CountdownStarted) + { + %client.notReady = true; + centerprint( %client, "\nPress FIRE when ready.", 0, 3 ); + } + } + else + { + commandToClient(%client, 'setHudMode', 'Standard', "", 0); + } + } + else + { + %wait = mFloor(($WAIT_PERIOD - (getSimTime() - %client.waitStart)) / 1000); + messageClient(%client, "", $WAIT_MESSAGE, %wait); + } + } +} +//--------------------------------------------------------------------------------------------------- + +function serverCmdSuicide(%client) +{ +if ($CurrentMissionType $= "RPG") //If it's RPG, stop here! +return; + + if(!isObject(%client.player)) // z0dd - ZOD, 4-15-02. Console spam fix. + return; + + // z0dd - ZOD, 4-15-02: Pick spawn spot by killing self during tourney wait + if( $MatchStarted ) + { + %client.player.scriptKill($DamageType::Suicide); + } + else + { + if($CurrentMissionType !$= TR2) // z0dd - ZOD, 9/17/02. Check for Team Rabbit 2 + SpawnPosChange( %client ); + } +} + +function serverCmdToggleCamera(%client) +{ + if ($testcheats || $CurrentMissionType $= "SinglePlayer") + { + %control = %client.getControlObject(); + if (%control == %client.player) + { + %control = %client.camera; + %control.mode = toggleCameraFly; + %control.setFlyMode(); + } + else + { + %control = %client.player; + %control.mode = observerFly; + %control.setFlyMode(); + } + %client.setControlObject(%control); + } +} + +function serverCmdDropPlayerAtCamera(%client) +{ + if ($testcheats) + { + %client.player.setTransform(%client.camera.getTransform()); + %client.player.setVelocity("0 0 0"); + %client.setControlObject(%client.player); + } +} + +function serverCmdDropCameraAtPlayer(%client) +{ + if ($testcheats) + { + %client.camera.setTransform(%client.player.getTransform()); + %client.camera.setVelocity("0 0 0"); + %client.setControlObject(%client.camera); + } +} + +function serverCmdToggleRace(%client) +{ + if ($testcheats) + { + if (%client.race $= "Human") + %client.race = "Bioderm"; + else + %client.race = "Human"; + %client.player.setArmor(%client.armor); + } +} + +function serverCmdToggleGender(%client) +{ + if ($testcheats) + { + if (%client.sex $= "Male") + %client.sex = "Female"; + else + %client.sex = "Male"; + %client.player.setArmor(%client.armor); + } +} + +function serverCmdToggleArmor(%client) +{ + if ($testcheats) + { + if (%client.armor $= "Light") + %client.armor = "Medium"; + else + if (%client.armor $= "Medium") + %client.armor = "Heavy"; + else + %client.armor = "Light"; + %client.player.setArmor(%client.armor); + } +} + +function serverCmdPlayCel(%client,%anim) +{ + if ($testcheats) + { + %anim = %client.player.celIdx; + if (%anim++ > 8) + %anim = 1; + %client.player.setActionThread("cel"@%anim); + %client.player.celIdx = %anim; + } +} + +// NOTENOTENOTE: Review +function PlayAnim(%client, %anim) // z0dd - ZOD, 8/15/02. Remove client direct requests to start animations. Was: serverCmdPlayAnim +{ + if( %anim $= "Death1" || %anim $= "Death2" || %anim $= "Death3" || %anim $= "Death4" || %anim $= "Death5" || + %anim $= "Death6" || %anim $= "Death7" || %anim $= "Death8" || %anim $= "Death9" || %anim $= "Death10" || %anim $= "Death11" ) + return; + + %player = %client.player; + + // don't play animations if player is in a vehicle + // z0dd - ZOD, 4-15-02. Console spam fix, check for player object. + if(%player.isMounted() || !isObject(%player)) + return; + + %weapon = ( %player.getMountedImage($WeaponSlot) == 0 ) ? "" : %player.getMountedImage($WeaponSlot).getName().item; + if(%weapon $= "MissileLauncher" || %weapon $= "SniperRifle") + { + %player.animResetWeapon = true; + %player.lastWeapon = %weapon; + %player.unmountImage($WeaponSlot); + %player.setArmThread(look); // z0dd - ZOD, 4-15-02. Dynamix used %obj. + } + %player.setActionThread(%anim); +} + +function serverCmdPlayDeath(%client,%anim) +{ + if ($testcheats) + { + %anim = %client.player.deathIdx; + if (%anim++ > 11) + %anim = 1; + %client.player.setActionThread("death"@%anim,true); + %client.player.deathIdx = %anim; + } +} + +// NOTENOTENOTE: Review these! +//------------------------------------------------------------ +// TODO - make this function specify a team to switch to... +function serverCmdClientTeamChange( %client ) +{ + // pass this to the game object to handle: + if ( isObject( Game ) && Game.kickClient != %client) + { + %fromObs = %client.team == 0; + + if(%fromObs) + clearBottomPrint(%client); + + Game.clientChangeTeam( %client, "", %fromObs ); + } +} + +function serverCanAddBot() +{ + //find out how many bots are already playing + %botCount = 0; + %numClients = ClientGroup.getCount(); + for (%i = 0; %i < %numClients; %i++) + { + %cl = ClientGroup.getObject(%i); + if (%cl.isAIcontrolled()) + %botCount++; + } + + //add only if we have less bots than the bot count, and if there would still be room for a + if ($HostGameBotCount > 0 && %botCount < $Host::botCount && %numClients < $Host::maxPlayers - 1) + return true; + else + return false; +} + +function serverCmdAddBot( %client ) +{ + //only admins can add bots... + if (%client.isAdmin) + { + if (serverCanAddBot()) + aiConnectMultiple( 1, $Host::MinBotDifficulty, $Host::MaxBotDifficulty, -1 ); + } +} + +// --------------------------------------------------------------------------------- +// z0dd - ZOD, 6/22/02. Changed function to use a waiting period when changing teams +// to prevent team change exploit to crash servers. Added admin varible so admins +// can teamchange whoever they want. +function serverCmdClientJoinTeam( %client, %team, %admin ) +{ + if( %team == -1 ) + { + if( %client.team == 1 ) + %team = 2; + else + %team = 1; + } + if ( isObject( Game ) && Game.kickClient != %client) + { + if(%client.team != %team) + { + // z0dd - ZOD, 9/17/02. Fair teams, check for Team Rabbit 2 as well. + if(($Host::ClassicFairTeams && !%client.isAdmin) && ($CurrentMissionType !$= TR2)) + { + %otherTeam = %team == 1 ? 2 : 1; + if(!%admin.isAdmin && %team != 0 && ($TeamRank[%team, count]+1) > $TeamRank[%otherTeam, count]) + { + messageClient(%client, 'MsgFairTeams', '\c2Teams will be uneven, please choose another team.'); + return; + } + } + + if(!%client.isWaiting || %admin.isAdmin) + { + %client.isWaiting = true; + %client.waitStart = getSimTime(); + %client.schedule($WAIT_PERIOD, waitTimeout); + + %fromObs = %client.team == 0; + + if(%fromObs) + clearBottomPrint(%client); + + if( %client.isAIControlled() ) + Game.AIChangeTeam( %client, %team ); + else + Game.clientChangeTeam( %client, %team, %fromObs ); + } + else + { + %wait = mFloor(($WAIT_PERIOD - (getSimTime() - %client.waitStart)) / 1000); + messageClient(%client, "", $WAIT_MESSAGE, %wait); + } + } + } +} +// --------------------------------------------------------------------------------- + +// this should only happen in single team games +function serverCmdClientAddToGame( %client, %targetClient ) +{ + if ( isObject( Game ) ) + Game.clientJoinTeam( %targetClient, 0, $matchstarted ); + + clearBottomPrint(%targetClient); + + if($matchstarted) + { + %targetClient.setControlObject( %targetClient.player ); + commandToClient(%targetClient, 'setHudMode', 'Standard'); + } + else + { + %targetClient.notReady = true; + %targetClient.camera.getDataBlock().setMode( %targetClient.camera, "pre-game", %targetClient.player ); + %targetClient.setControlObject( %targetClient.camera ); + } + + if( $Host::TournamentMode && !$CountdownStarted) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + { + %targetClient.notReady = true; + centerprint( %targetClient, "\nPress FIRE when ready.", 0, 3 ); + } +} + +function serverCmdClientJoinGame( %client ) +{ + if ( isObject( Game ) ) + Game.clientJoinTeam( %client, 0, 1 ); + + %client.setControlObject( %client.player ); + clearBottomPrint(%client); + commandToClient(%client, 'setHudMode', 'Standard'); +} + +function serverCmdClientMakeObserver( %client ) +{ + if ( isObject( Game ) && Game.kickClient != %client ) + Game.forceObserver( %client, "playerChoose" ); +} + +function serverCmdChangePlayersTeam( %clientRequesting, %client, %team) +{ + if( isObject( Game ) && %client != Game.kickClient && %clientRequesting.isAdmin) + { + // z0dd - ZOD, 6/22/02. Added admin varible to enable admins to teamchange + // even players under the Wait timer. + //serverCmdClientJoinTeam(%client, %team); + serverCmdClientJoinTeam(%client, %team, %clientRequesting); + + if(!$MatchStarted) + { + %client.observerMode = "pregame"; + %client.notReady = true; + %client.camera.getDataBlock().setMode( %client.camera, "pre-game", %client.player ); + %client.setControlObject( %client.camera ); + + if( $Host::TournamentMode && !$CountdownStarted) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + { + %client.notReady = true; + centerprint( %client, "\nPress FIRE when ready.", 0, 3 ); + } + } + else + commandToClient(%client, 'setHudMode', 'Standard', "", 0); + + %multiTeam = (Game.numTeams > 1); + + %aname = %clientRequesting.name; // z0dd - ZOD, 4-15-02. who did what + %name = %client.name; // z0dd - ZOD, 4-15-02. who did what + + if(%multiTeam) + { + messageClient( %client, 'MsgClient', '\c2%1 has changed your team.', %aname); // z0dd - ZOD, 4-15-02. who did what + messageAllExcept( %client, -1, 'MsgClient', '\c2%1 forced %2 to join the %3 team.', %aname, %name, game.getTeamName(%client.team) ); // z0dd - ZOD, 4-15-02. who did what + } + else + { + messageClient( %client, 'MsgClient', '\c2%1 has added you to the game.', %aname); // z0dd - ZOD, 4-15-02. who did what + messageAllExcept( %client, -1, 'MsgClient', '\c2%1 added %2 to the game.', %aname, %name); // z0dd - ZOD, 4-15-02. who did what + } + } +} + +//--------------------------------------------------------------------------------------------------------- +// z0dd - ZOD 4/18/02. Allow SuperAdmins to De-Admin normal Admins +function serverCmdStripAdmin(%client, %admin) +{ + if(!%admin.isAdmin) + return; + + if(%client.isSuperAdmin) + { + messageAll( 'MsgStripAdminPlayer', '\c2%1 removed %2\'s admin privledges.', %client.name, %admin.name, %admin ); + messageClient(%admin, 'MsgStripAdminPlayer', 'You are being stripped of your admin privledges by %1.', %client.name); + %admin.isAdmin = 0; + logEcho(%client.nameBase @ " stripped admin from " @ %admin.nameBase); + } + else + messageClient(%client, 'MsgError', '\c2Only Super Admins can use this command.'); +} + +// z0dd - ZOD 4/18/02. Allow Admins to warn players +function serverCmdWarnPlayer(%client, %target) +{ + if(%client.isAdmin) + { + messageAllExcept(%target, -1, 'MsgAdminForce', '%1 has been warned for inappropriate conduct by %2.', %target.name, %client.name); + messageClient(%target, 'MsgAdminForce', 'You are recieving this warning for inappropriate conduct by %1. Behave or you will be kicked..~wfx/misc/lightning_impact.wav', %client.name); + centerprint(%target, "You are recieving this warning for inappropriate conduct.\nBehave or you will be kicked.", 10, 2); + logEcho(%client.nameBase @ " sent warning to " @ %target.nameBase); + } + else + messageClient(%client, 'MsgError', '\c2Only Admins can use this command.'); +} + +//--------------------------------------------------------------------------------------------------------- + +function serverCmdForcePlayerToObserver( %clientRequesting, %client ) +{ + if( isObject( Game ) && %clientRequesting.isAdmin) + Game.forceObserver( %client, "adminForce" ); +} + +//-------------------------------------------------------------------------- + +function serverCmdTogglePlayerMute(%client, %who) +{ + if (%client.muted[%who]) + { + %client.muted[%who] = false; + messageClient(%client, 'MsgPlayerMuted', '%1 has been unmuted.', %who.name, %who, false); + } + else + { + %client.muted[%who] = true; + messageClient(%client, 'MsgPlayerMuted', '%1 has been muted.', %who.name, %who, true); + } +} + +//-------------------------------------------------------------------------- +// VOTE MENU FUNCTIONS: +function serverCmdGetVoteMenu( %client, %key ) +{ + if ( isObject( Game ) ) + Game.sendGameVoteMenu( %client, %key ); +} + +function serverCmdGetPlayerPopupMenu( %client, %targetClient, %key ) +{ + if ( isObject( Game ) ) + Game.sendGamePlayerPopupMenu( %client, %targetClient, %key ); +} + +function serverCmdGetTeamList( %client, %key ) +{ + if ( isObject( Game ) ) + Game.sendGameTeamList( %client, %key ); +} + +function serverCmdGetMissionTypes( %client, %key ) +{ + for ( %type = 0; %type < $HostTypeCount; %type++ ) + messageClient( %client, 'MsgVoteItem', "", %key, %type, "", $HostTypeDisplayName[%type], true ); +} + +function serverCmdGetMissionList( %client, %key, %type ) +{ + if ( %type < 0 || %type >= $HostTypeCount ) + return; + + for ( %i = $HostMissionCount[%type] - 1; %i >= 0; %i-- ) + { + %idx = $HostMission[%type, %i]; + + // If we have bots, don't change to a mission that doesn't support bots: + if ( $HostGameBotCount > 0 ) + { + if( !$BotEnabled[%idx] ) + continue; + } + + messageClient( %client, 'MsgVoteItem', "", %key, + %idx, // mission index, will be stored in $clVoteCmd + "", + $HostMissionName[%idx], + true ); + } +} + +function serverCmdGetTimeLimitList( %client, %key, %type ) +{ + if ( isObject( Game ) ) + Game.sendTimeLimitList( %client, %key ); +} + +function serverCmdClientPickedTeam( %client, %option ) +{ + // ------------------------------------------------------------------------------------- + // z0dd - ZOD 4/18/02. Tourney mode bug fix. Fix provided by FSB-AO + // Bug description: In tournament mode, If a player is teamchanged by an admin before + // they select a team, the server just changes their team and re-skins the player. They + // are not moved from their initial spawn point, meaning they could spawn very close to + // the other teams flag. This script kills the player if they are already teamed when + // they select an option and spawns them on the correct side of the map. + switch(%option) + { + case 1: + if ( isObject(%client.player) ) + { + %client.player.scriptKill(0); + Game.clientChangeTeam(%client, %option, 0); + } + else + Game.clientJoinTeam( %client, %option, false ); + case 2: + if ( isObject(%client.player) ) + { + %client.player.scriptKill(0); + Game.clientChangeTeam(%client, %option, 0); + } + else + Game.clientJoinTeam( %client, %option, false ); + case 3: + if( !isObject(%client.player) ) + { + Game.assignClientTeam( %client, $MatchStarted ); + Game.spawnPlayer( %client, false ); + } + default: + if( isObject(%client.player) ) + { + %client.player.scriptKill(0); + ClearBottomPrint(%client); + } + Game.forceObserver( %client, "playerChoose" ); + %client.observerMode = "observer"; + %client.notReady = false; + return; + } + // ------------------------------------------------------------------------------------- + + ClearBottomPrint(%client); + %client.observerMode = "pregame"; + %client.notReady = true; + %client.camera.getDataBlock().setMode( %client.camera, "pre-game", %client.player ); + commandToClient(%client, 'setHudMode', 'Observer'); + %client.setControlObject( %client.camera ); + centerprint( %client, "\nPress FIRE when ready.", 0, 3 ); +} + +function playerPickTeam( %client ) +{ + %numTeams = Game.numTeams; + + if(%numTeams > 1) + { + %client.camera.mode = "PickingTeam"; + schedule( 0, 0, "commandToClient", %client, 'pickTeamMenu', Game.getTeamName(1), Game.getTeamName(2)); + } + else + { + Game.clientJoinTeam(%client, 0, 0); + %client.observerMode = "pregame"; + %client.notReady = true; + %client.camera.getDataBlock().setMode( %client.camera, "pre-game", %client.player ); + centerprint( %client, "\nPress FIRE when ready.", 0, 3 ); + %client.setControlObject( %client.camera ); + } +} + +function serverCmdPlayContentSet( %client ) +{ + if( $Host::TournamentMode && !$CountdownStarted && !$MatchStarted ) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + playerPickTeam( %client ); +} + +//-------------------------------------------------------------------------- +// This will probably move elsewhere... +function getServerStatusString() +{ + return isObject(Game) ? Game.getServerStatusString() : "NoGame"; +} + + +function dumpGameString() +{ + error( getServerStatusString() ); +} + +function isOnAdminList(%client) +{ + if( !%totalRecords = getFieldCount( $Host::AdminList ) ) + { + return false; + } + + for(%i = 0; %i < %totalRecords; %i++) + { + %record = getField( getRecord( $Host::AdminList, 0 ), %i); + if(%record == %client.guid) + return true; + } + + return false; +} + +function isOnSuperAdminList(%client) +{ + if( !%totalRecords = getFieldCount( $Host::superAdminList ) ) + { + return false; + } + + for(%i = 0; %i < %totalRecords; %i++) + { + %record = getField( getRecord( $Host::superAdminList, 0 ), %i); + if(%record == %client.guid) + return true; + } + + return false; +} + +function ServerCmdAddToAdminList( %admin, %client ) +{ + if( !%admin.isSuperAdmin ) + return; + + %count = getFieldCount( $Host::AdminList ); + + for ( %i = 0; %i < %count; %i++ ) + { + %id = getField( $Host::AdminList, %i ); + if ( %id == %client.guid ) + { + return; // They're already there! + } + } + + if( %count == 0 ) + $Host::AdminList = %client.guid; + else + $Host::AdminList = $Host::AdminList TAB %client.guid; + + // z0dd - ZOD, 4/29/02. Was not exporting to serverPrefs and did not message admin + export( "$Host::*", "prefs/ServerPrefs.cs", false ); + messageClient(%admin, 'MsgAdmin', '\c3\"%1\"\c2 added to Admin list: \c3%2\c2.', %client.name, %client.guid); + logEcho(%admin.nameBase @ " added " @ %client.nameBase @ " " @ %client.guid @ " to Admin list."); +} + +function ServerCmdAddToSuperAdminList( %admin, %client ) +{ + if( !%admin.isSuperAdmin ) + return; + + %count = getFieldCount( $Host::SuperAdminList ); + + for ( %i = 0; %i < %count; %i++ ) + { + %id = getField( $Host::SuperAdminList, %i ); + if ( %id == %client.guid ) + return; // They're already there! + } + + if( %count == 0 ) + $Host::SuperAdminList = %client.guid; + else + $Host::SuperAdminList = $Host::SuperAdminList TAB %client.guid; + + // z0dd - ZOD, 4/29/02. Was not exporting to serverPrefs and did not message admin + export( "$Host::*", "prefs/ServerPrefs.cs", false ); + messageClient(%admin, 'MsgAdmin', '\c3\"%1\"\c2 added to Super Admin list: \c3%2\c2.', %client.name, %client.guid); + logEcho(%admin.nameBase @ " added " @ %client.nameBase @ " " @ %client.guid @ " to Super Admin list."); +} + +function resetTournamentPlayers() +{ + %count = ClientGroup.getCount(); + for( %i = 0; %i < %count; %i++ ) + { + %cl = ClientGroup.getObject(%i); + %cl.notready = 1; + %cl.notReadyCount = ""; + } +} + +function forceTourneyMatchStart() +{ + %playerCount = 0; + %count = ClientGroup.getCount(); + for( %i = 0; %i < %count; %i++ ) + { + %cl = ClientGroup.getObject(%i); + if(%cl.camera.Mode $= "pre-game") + %playerCount++; + } + + // don't start the mission until we have players + if(%playerCount == 0) + { + return false; + } + + %count = ClientGroup.getCount(); + for( %i = 0; %i < %count; %i++ ) + { + %cl = ClientGroup.getObject(%i); + if(%cl.camera.Mode $= "pickingTeam") + { + // throw these guys into observer mode + if(Game.numTeams > 1) + commandToClient( %cl, 'processPickTeam'); // clear the pickteam menu + Game.forceObserver( %cl, "adminForce" ); + } + } + return true; +} + +function startTourneyCountdown() +{ + %count = ClientGroup.getCount(); + for( %i = 0; %i < %count; %i++ ) + { + %cl = ClientGroup.getObject(%i); + ClearCenterPrint(%cl); + ClearBottomPrint(%cl); + } + + // lets get it on! + Countdown( 30 * 1000 ); +} + +function checkTourneyMatchStart() +{ + if( $CountdownStarted || $matchStarted ) + return; + + // loop through all the clients and see if any are still notready + %playerCount = 0; + %notReadyCount = 0; + + %count = ClientGroup.getCount(); + for( %i = 0; %i < %count; %i++ ) + { + %cl = ClientGroup.getObject(%i); + if(%cl.camera.mode $= "pickingTeam") + { + %notReady[%notReadyCount] = %cl; + %notReadyCount++; + } + else if(%cl.camera.Mode $= "pre-game") + { + if(%cl.notready) + { + %notReady[%notReadyCount] = %cl; + %notReadyCount++; + } + else + { + %playerCount++; + } + } + else if(%cl.camera.Mode $= "observer") + { + // this guy is watching + } + } + + if(%notReadyCount) + { + if(%notReadyCount == 1) + MessageAll( 'msgHoldingUp', '\c1%1 is holding things up!', %notReady[0].name); + else if(%notReadyCount < 4) + { + for(%i = 0; %i < %notReadyCount - 2; %i++) + %str = getTaggedString(%notReady[%i].name) @ ", " @ %str; + + %str = "\c2" @ %str @ getTaggedString(%notReady[%i].name) @ " and " @ getTaggedString(%notReady[%i+1].name) + @ " are holding things up!"; + MessageAll( 'msgHoldingUp', %str ); + } + return; + } + + if(%playerCount != 0) + { + %count = ClientGroup.getCount(); + for( %i = 0; %i < %count; %i++ ) + { + %cl = ClientGroup.getObject(%i); + %cl.notready = ""; + %cl.notReadyCount = ""; + ClearCenterPrint(%cl); + ClearBottomPrint(%cl); + } + + if ( Game.scheduleVote !$= "" && Game.voteType $= "VoteMatchStart") + { + messageAll('closeVoteHud', ""); + cancel(Game.scheduleVote); + Game.scheduleVote = ""; + } + + Countdown(30 * 1000); + } +} + +function checkMissionStart() +{ + %readyToStart = false; + for(%clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++) + { + %client = ClientGroup.getObject(%clientIndex); + if(%client.isReady) + { + %readyToStart = true; + break; + } + } + + if(%readyToStart || ClientGroup.getCount() < 1) + { + if($Host::warmupTime > 0 && $CurrentMissionType !$= "SinglePlayer") + countDown($Host::warmupTime * 1000); + else + Game.startMatch(); + + for(%x = 0; %x < $NumVehiclesDeploy; %x++) + $VehiclesDeploy[%x].getDataBlock().schedule(%timeMS / 2, "vehicleDeploy", $VehiclesDeploy[%x], 0, 1); + $NumVehiclesDeploy = 0; + } + else + { + schedule(2000, ServerGroup, "checkMissionStart"); + } +} + +function Countdown(%timeMS) +{ + if($countdownStarted) + return; + + echo("starting mission countdown..."); + + if(isObject(Game)) + %game = Game.getId(); + else + return; + + $countdownStarted = true; + Game.matchStart = Game.schedule( %timeMS, "StartMatch" ); + + if (%timeMS > 30000) + notifyMatchStart(%timeMS); + + if(%timeMS >= 30000) + Game.thirtyCount = schedule(%timeMS - 30000, Game, "notifyMatchStart", 30000); + if(%timeMS >= 15000) + Game.fifteenCount = schedule(%timeMS - 15000, Game, "notifyMatchStart", 15000); + if(%timeMS >= 10000) + Game.tenCount = schedule(%timeMS - 10000, Game, "notifyMatchStart", 10000); + if(%timeMS >= 5000) + Game.fiveCount = schedule(%timeMS - 5000, Game, "notifyMatchStart", 5000); + if(%timeMS >= 4000) + Game.fourCount = schedule(%timeMS - 4000, Game, "notifyMatchStart", 4000); + if(%timeMS >= 3000) + Game.threeCount = schedule(%timeMS - 3000, Game, "notifyMatchStart", 3000); + if(%timeMS >= 2000) + Game.twoCount = schedule(%timeMS - 2000, Game, "notifyMatchStart", 2000); + if(%timeMS >= 1000) + Game.oneCount = schedule(%timeMS - 1000, Game, "notifyMatchStart", 1000); +} + +function EndCountdown(%timeMS) +{ + echo("mission end countdown..."); + + if(isObject(Game)) + %game = Game.getId(); + else + return; + + if(%timeMS >= 60000) + Game.endsixtyCount = schedule(%timeMS - 60000, Game, "notifyMatchEnd", 60000); + if(%timeMS >= 30000) + Game.endthirtyCount = schedule(%timeMS - 30000, Game, "notifyMatchEnd", 30000); + if(%timeMS >= 10000) + Game.endtenCount = schedule(%timeMS - 10000, Game, "notifyMatchEnd", 10000); + if(%timeMS >= 5000) + Game.endfiveCount = schedule(%timeMS - 5000, Game, "notifyMatchEnd", 5000); + if(%timeMS >= 4000) + Game.endfourCount = schedule(%timeMS - 4000, Game, "notifyMatchEnd", 4000); + if(%timeMS >= 3000) + Game.endthreeCount = schedule(%timeMS - 3000, Game, "notifyMatchEnd", 3000); + if(%timeMS >= 2000) + Game.endtwoCount = schedule(%timeMS - 2000, Game, "notifyMatchEnd", 2000); + if(%timeMS >= 1000) + Game.endoneCount = schedule(%timeMS - 1000, Game, "notifyMatchEnd", 1000); +} + +function CancelCountdown() +{ + if(Game.sixtyCount !$= "") + cancel(Game.sixtyCount); + if(Game.thirtyCount !$= "") + cancel(Game.thirtyCount); + if(Game.fifteenCount !$= "") + cancel(Game.fifteenCount); + if(Game.tenCount !$= "") + cancel(Game.tenCount); + if(Game.fiveCount !$= "") + cancel(Game.fiveCount); + if(Game.fourCount !$= "") + cancel(Game.fourCount); + if(Game.threeCount !$= "") + cancel(Game.threeCount); + if(Game.twoCount !$= "") + cancel(Game.twoCount); + if(Game.oneCount !$= "") + cancel(Game.oneCount); + if(isObject(Game)) + cancel(Game.matchStart); + + Game.matchStart = ""; + Game.thirtyCount = ""; + Game.fifteenCount = ""; + Game.tenCount = ""; + Game.fiveCount = ""; + Game.fourCount = ""; + Game.threeCount = ""; + Game.twoCount = ""; + Game.oneCount = ""; + + $countdownStarted = false; +} + +function CancelEndCountdown() +{ + //cancel the mission end countdown... + if(Game.endsixtyCount !$= "") + cancel(Game.endsixtyCount); + if(Game.endthirtyCount !$= "") + cancel(Game.endthirtyCount); + if(Game.endtenCount !$= "") + cancel(Game.endtenCount); + if(Game.endfiveCount !$= "") + cancel(Game.endfiveCount); + if(Game.endfourCount !$= "") + cancel(Game.endfourCount); + if(Game.endthreeCount !$= "") + cancel(Game.endthreeCount); + if(Game.endtwoCount !$= "") + cancel(Game.endtwoCount); + if(Game.endoneCount !$= "") + cancel(Game.endoneCount); + + Game.endmatchStart = ""; + Game.endthirtyCount = ""; + Game.endtenCount = ""; + Game.endfiveCount = ""; + Game.endfourCount = ""; + Game.endthreeCount = ""; + Game.endtwoCount = ""; + Game.endoneCount = ""; +} + +function resetServerDefaults() +{ + $resettingServer = true; + echo( "Resetting server defaults..." ); + + if( isObject( Game ) ) + Game.gameOver(); + + // Override server defaults with prefs: + exec( "scripts/ServerDefaults.cs" ); + exec( $serverprefs ); + + // --------------------------------------------------- + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + //convert the team skin and name vars to tags... + %index = 0; + while ($Host::TeamSkin[%index] !$= "") + { + $TeamSkin[%index] = addTaggedString($Host::TeamSkin[%index]); + %index++; + } + + %index = 0; + while ($Host::TeamName[%index] !$= "") + { + $TeamName[%index] = addTaggedString($Host::TeamName[%index]); + %index++; + } + + // Get the hologram names from the prefs... + %index = 1; + while ( $Host::holoName[%index] !$= "" ) + { + $holoName[%index] = $Host::holoName[%index]; + %index++; + } + // --------------------------------------------------- + + // kick all bots... + removeAllBots(); + + // add bots back if they were there before.. + if( $Host::botsEnabled ) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + initGameBots( $Host::Map, $Host::MissionType ); + + // load the missions + loadMission( $Host::Map, $Host::MissionType ); + $resettingServer = false; + echo( "Server reset complete." ); +} + +function removeAllBots() //Wtf -- it crashes. +{ + while( ClientGroup.getCount() ) + { + %client = ClientGroup.getObject(0); + if(%client.isAIControlled()) + { + %client.drop(); + } + else + %client.delete(); + } +} +//------------------------------------------------------------------------------ +function getServerGUIDList() +{ + %count = ClientGroup.getCount(); + for ( %i = 0; %i < %count; %i++ ) + { + %cl = ClientGroup.getObject( %i ); + if ( isObject( %cl ) && !%cl.isSmurf && !%cl.isAIControlled() ) + { + %guid = getField( %cl.getAuthInfo(), 3 ); + if ( %guid != 0 ) + { + if ( %list $= "" ) + %list = %guid; + else + %list = %list TAB %guid; + } + } + } + + return( %list ); +} + +//------------------------------------------------------------------------------ +// will return the first admin found on the server +function getAdmin() +{ + %admin = 0; + for ( %clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++ ) + { + %cl = ClientGroup.getObject( %clientIndex ); + if(%cl.isAdmin || %cl.isSuperAdmin) + { + %admin = %cl; + break; + } + } + return %admin; +} + +function serverCmdSetPDAPose(%client, %val) +{ + if(!isObject(%client.player)) + return; + + // if client is in a vehicle, return + if(%client.player.isMounted()) + return; + + if(%val) + { + // play "PDA" animation thread on player + if (%client.race $="Bioderm" || %client.race $="Draakan" || %client.race $= "Criollos") //PDA pose hackery to allow the Bioderm PDA anim + %client.player.setActionThread("IdlePDA", true); + else + %client.player.setActionThread("PDA", true); + } + else + { + // cancel PDA animation thread with another one. + %client.player.setActionThread("light_recoil", false); + } +} + +function serverCmdProcessGameLink(%client, %arg1, %arg2, %arg3, %arg4, %arg5) +{ + Game.processGameLink(%client, %arg1, %arg2, %arg3, %arg4, %arg5); +} + +//----------------------------------------------------------------------------------- +// z0dd - ZOD, 6/03/02. New function. Impact hit sounds settings from clientprefs.cs. +function serverCmdSetHitSounds( %client, %playerHitsOn, %playerHitWav, %vehicleHitsOn, %vehicleHitWav ) +{ + %client.playerHitSound = %playerHitsOn; + %client.playerHitWav = addtaggedString(%playerHitWav); + + %client.vehicleHitSound = %vehicleHitsOn; + %client.vehicleHitWav = addtaggedString(%vehicleHitWav); +} +//----------------------------------------------------------------------------------- + +//----------------------------------------------------------------------------------- +// z0dd - ZOD, 6/03/02. New function. Get mod name from server. +function serverCMDgetMod(%client) +{ + %paths = getModPaths(); + commandToClient(%client, 'serverMod', %paths); +} +//----------------------------------------------------------------------------------- + +//----------------------------------------------------------------------------------- +// z0dd - ZOD, 10/03/02. New function. Admin HUD print feature +function serverCMDaprint(%client, %msg, %bottom) +{ + if(%client.isAdmin) + { + %name = getTaggedString(%client.name); + %message = %name @ ": " @ %msg; + if(%bottom) + bottomprintAll(%message, 8, 3); + else + centerprintAll(%message, 8, 3); + } +} //----------------------------------------------------------------------------------- \ No newline at end of file diff --git a/scripts/serverCommanderMap.cs b/scripts/serverCommanderMap.cs index a78e660..732c27a 100644 --- a/scripts/serverCommanderMap.cs +++ b/scripts/serverCommanderMap.cs @@ -1,299 +1,299 @@ -//------------------------------------------------------------------------------ -// Object control -//------------------------------------------------------------------------------ -function getControlObjectType(%obj) -{ - // turrets (camera is a turret) - if(%obj.getType() & $TypeMasks::TurretObjectType) - { - %barrel = %obj.getMountedImage(0); - if(isObject(%barrel)) - return(addTaggedString(%barrel.getName())); - } - - // unknown - return('Unknown'); -} - -function serverCmdControlObject(%client, %targetId) -{ - // match started: - if(!$MatchStarted) - { - commandToClient(%client, 'ControlObjectResponse', false, "mission has not started."); - return; - } - - // object: - %obj = getTargetObject(%targetId); - if(%obj == -1) - { - commandToClient(%client, 'ControlObjectResponse', false, "failed to find target object."); - return; - } - - // shapebase: - if(!(%obj.getType() & $TypeMasks::ShapeBaseObjectType)) - { - commandToClient(%client, 'ControlObjectResponse', false, "object cannot be controlled."); - return; - } - - // can control: - if(!%obj.getDataBlock().canControl || %obj.getMountedImage(0).getName() $= "MissileBarrelLarge") // z0dd - ZOD 4/18/02. Prevent missile barrels from being controlled - { - commandToClient(%client, 'ControlObjectResponse', false, "object cannot be controlled."); - return; - } - - // check damage: - if(%obj.getDamageState() !$= "Enabled") - { - commandToClient(%client, 'ControlObjectResponse', false, "object is " @ %obj.getDamageState()); - return; - } - - // powered: - if(!%obj.isPowered()) - { - commandToClient(%client, 'ControlObjectResponse', false, "object is not powered."); - return; - } - - // controlled already: - %control = %obj.getControllingClient(); - if(%control) - { - if(%control == %client) - commandToClient(%client, 'ControlObjectResponse', false, "you are already controlling that object."); - else - commandToClient(%client, 'ControlObjectResponse', false, "someone is already controlling that object."); - return; - } - - // same team? - if(getTargetSensorGroup(%targetId) != %client.getSensorGroup()) - { - commandToClient(%client, 'ControlObjectResonse', false, "cannot control enemy objects."); - return; - } - - // dead? - if(%client.player == 0) - { - commandToClient(%client, 'ControlObjectResponse', false, "dead people cannot control objects."); - return; - } - - //mounted in a vehicle? - if (%client.player.isMounted()) - { - commandToClient(%client, 'ControlObjectResponse', false, "can't control objects while mounted in a vehicle."); - return; - } - - %client.setControlObject(%obj); - commandToClient(%client, 'ControlObjectResponse', true, getControlObjectType(%obj)); - - // -------------------------------------------------------------------------------------------------------- - // z0dd - ZOD, 5/12/02. Change turrets name to controllers name. - if((%obj.getType() & $TypeMasks::TurretObjectType) && (!%client.isAIControlled())) - { - // Set this varible on the client so we can reset turret nameTag when client is done. - %client.TurretControl = %obj; - - if(%obj.nameTag !$= "") // Get the name tag for storage, this is created in the *.mis file. - { - %obj.oldTag = getTaggedString(%obj.nameTag); // Store this nameTag in a var on the turret. - removeTaggedString(%obj.nameTag); // Reset the turrets nameTag. - %obj.nameTag = ""; - } - else // This is either a deployed turret or the *.mis file has no nameTag for it. - { - %obj.oldTag = ""; // No nameTag to store on turret (paranoia). - - // Reset the turrets targetNameTag. This may cause problems - ZOD - //removeTaggedString(%obj.getDataBlock().targetNameTag); - //%obj.getDataBlock().targetNameTag = ""; - } - - // Reset the turrets target - freeTarget(%obj.getTarget()); - - // Set the turrets target and new nameTag. - %obj.nameTag = addTaggedString(%client.nameBase @ " controlling "); - %obj.target = createTarget(%obj, %obj.nameTag, "", "", %obj.getDatablock().targetTypeTag, %obj.team, 0); - setTargetSensorGroup(%obj.target, %obj.team); - } - // -------------------------------------------------------------------------------------------------------- -} - -//------------------------------------------------------------------------------ -// TV Functions -//------------------------------------------------------------------------------ -function resetControlObject(%client) -{ - if( isObject( %client.comCam ) ) - %client.comCam.delete(); - - if(isObject(%client.player) && !%client.player.isDestroyed() && $MatchStarted) - %client.setControlObject(%client.player); - else - %client.setControlObject(%client.camera); - - // ----------------------------------------------------------------------------------------------------------------------- - // z0dd - ZOD, 5/12/02. Reset the turrets nameTag back to its original. - if(%client.TurretControl !$= "") - %turret = %client.TurretControl; - else - return; - - if(isObject(%turret)) - { - // Reset the turrets target and nameTag - removeTaggedString(%turret.nameTag); - %turret.nameTag = ""; - freeTarget(%turret.getTarget()); - - // Set the turrets target and new nameTag - if(%turret.oldTag !$= "") - %turret.nameTag = addTaggedString(%turret.oldTag); - else - //%turret.nameTag = addTaggedString(getTaggedString(%turret.getDataBlock().targetNameTag)); - %turret.nameTag = %turret.getDataBlock().targetNameTag; // This should allready be a tagged string - - %turret.target = createTarget(%turret, %turret.nameTag, "", "", %turret.getDatablock().targetTypeTag, %turret.team, 0); - setTargetSensorGroup(%turret.target, %turret.team); - - // Reset the varible set on the client and turret - %turret.oldTag = ""; - %client.TurretControl = ""; - } - // ----------------------------------------------------------------------------------------------------------------------- -} - -function serverCmdResetControlObject(%client) -{ - resetControlObject(%client); - commandToClient(%client, 'ControlObjectReset'); - // z0dd - ZOD 6/04/02. Vehicle reticle fix. - if(isObject(%client.player)) - { - if(%client.player.isPilot() || %client.player.isWeaponOperator()) - { - return; - } - else - { - commandToClient(%client, 'RemoveReticle'); - %weapon = %client.player.getMountedImage($WeaponSlot); - %client.setWeaponsHudActive(%weapon.item); - } - } -} - -function serverCmdAttachCommanderCamera(%client, %target) -{ - // dont allow observing until match has started - if(!$MatchStarted) - { - commandToClient(%client, 'CameraAttachResponse', false); - return; - } - - %obj = getTargetObject(%target); - if((%obj == -1) || (%target == -1)) - { - commandToClient(%client, 'CameraAttachResponse', false); - return; - } - - // shape base object? - if(!(%obj.getType() & $TypeMasks::ShapeBaseObjectType)) - { - commandToClient(%client, 'CameraAttachResponse', false); - return; - } - - // can be observed? - if(!%obj.getDataBlock() || !%obj.getDataBlock().canObserve) - { - commandToClient(%client, 'CameraAttachResponse', false); - return; - } - - // same team? - if(getTargetSensorGroup(%target) != %client.getSensorGroup()) - { - commandToClient(%client, 'CameraAttachResponse', false); - return; - } - - // powered? - if(!%obj.isPowered()) - { - commandToClient(%client, 'CameraAttachResponse', false); - return; - } - - // client connection? - if(%obj.getClassName() $= "GameConnection") - { - %player = %obj.player; - if(%obj == %client) - { - if(isObject(%player) && !%player.isDestroyed()) - { - - %client.setControlObject(%player); - commandToClient(%client, 'CameraAttachResponse', true); - return; - } - } - - %obj = %player; - } - - if(!isObject(%obj) || %obj.isDestroyed()) - { - commandToClient(%client, 'CameraAttachResponse', false); - return; - } - - %data = %obj.getDataBlock(); - %obsData = %data.observeParameters; - %obsX = firstWord(%obsData); - %obsY = getWord(%obsData, 1); - %obsZ = getWord(%obsData, 2); - - // don't set the camera mode so that it does not interfere with spawning - %transform = %obj.getTransform(); - - // create a fresh camera to observe through... (could add to a list on - // the observed camera to be removed when that object dies/...) - if( !isObject( %client.comCam ) ) - { - %client.comCam = new Camera() - { - dataBlock = CommanderCamera; - }; - MissionCleanup.add(%client.comCam); - } - - %client.comCam.setTransform(%transform); - %client.comCam.setOrbitMode(%obj, %transform, %obsX, %obsY, %obsZ); - - %client.setControlObject(%client.comCam); - commandToClient(%client, 'CameraAttachResponse', true); -} - -//------------------------------------------------------------------------------ -// Scoping -function serverCmdScopeCommanderMap(%client, %scope) -{ - if(%scope) - resetControlObject(%client); - %client.scopeCommanderMap(%scope); - - commandToClient(%client, 'ScopeCommanderMap', %scope); -} +//------------------------------------------------------------------------------ +// Object control +//------------------------------------------------------------------------------ +function getControlObjectType(%obj) +{ + // turrets (camera is a turret) + if(%obj.getType() & $TypeMasks::TurretObjectType) + { + %barrel = %obj.getMountedImage(0); + if(isObject(%barrel)) + return(addTaggedString(%barrel.getName())); + } + + // unknown + return('Unknown'); +} + +function serverCmdControlObject(%client, %targetId) +{ + // match started: + if(!$MatchStarted) + { + commandToClient(%client, 'ControlObjectResponse', false, "mission has not started."); + return; + } + + // object: + %obj = getTargetObject(%targetId); + if(%obj == -1) + { + commandToClient(%client, 'ControlObjectResponse', false, "failed to find target object."); + return; + } + + // shapebase: + if(!(%obj.getType() & $TypeMasks::ShapeBaseObjectType)) + { + commandToClient(%client, 'ControlObjectResponse', false, "object cannot be controlled."); + return; + } + + // can control: + if(!%obj.getDataBlock().canControl || %obj.getMountedImage(0).getName() $= "MissileBarrelLarge") // z0dd - ZOD 4/18/02. Prevent missile barrels from being controlled + { + commandToClient(%client, 'ControlObjectResponse', false, "object cannot be controlled."); + return; + } + + // check damage: + if(%obj.getDamageState() !$= "Enabled") + { + commandToClient(%client, 'ControlObjectResponse', false, "object is " @ %obj.getDamageState()); + return; + } + + // powered: + if(!%obj.isPowered()) + { + commandToClient(%client, 'ControlObjectResponse', false, "object is not powered."); + return; + } + + // controlled already: + %control = %obj.getControllingClient(); + if(%control) + { + if(%control == %client) + commandToClient(%client, 'ControlObjectResponse', false, "you are already controlling that object."); + else + commandToClient(%client, 'ControlObjectResponse', false, "someone is already controlling that object."); + return; + } + + // same team? + if(getTargetSensorGroup(%targetId) != %client.getSensorGroup()) + { + commandToClient(%client, 'ControlObjectResonse', false, "cannot control enemy objects."); + return; + } + + // dead? + if(%client.player == 0) + { + commandToClient(%client, 'ControlObjectResponse', false, "dead people cannot control objects."); + return; + } + + //mounted in a vehicle? + if (%client.player.isMounted()) + { + commandToClient(%client, 'ControlObjectResponse', false, "can't control objects while mounted in a vehicle."); + return; + } + + %client.setControlObject(%obj); + commandToClient(%client, 'ControlObjectResponse', true, getControlObjectType(%obj)); + + // -------------------------------------------------------------------------------------------------------- + // z0dd - ZOD, 5/12/02. Change turrets name to controllers name. + if((%obj.getType() & $TypeMasks::TurretObjectType) && (!%client.isAIControlled())) + { + // Set this varible on the client so we can reset turret nameTag when client is done. + %client.TurretControl = %obj; + + if(%obj.nameTag !$= "") // Get the name tag for storage, this is created in the *.mis file. + { + %obj.oldTag = getTaggedString(%obj.nameTag); // Store this nameTag in a var on the turret. + removeTaggedString(%obj.nameTag); // Reset the turrets nameTag. + %obj.nameTag = ""; + } + else // This is either a deployed turret or the *.mis file has no nameTag for it. + { + %obj.oldTag = ""; // No nameTag to store on turret (paranoia). + + // Reset the turrets targetNameTag. This may cause problems - ZOD + //removeTaggedString(%obj.getDataBlock().targetNameTag); + //%obj.getDataBlock().targetNameTag = ""; + } + + // Reset the turrets target + freeTarget(%obj.getTarget()); + + // Set the turrets target and new nameTag. + %obj.nameTag = addTaggedString(%client.nameBase @ " controlling "); + %obj.target = createTarget(%obj, %obj.nameTag, "", "", %obj.getDatablock().targetTypeTag, %obj.team, 0); + setTargetSensorGroup(%obj.target, %obj.team); + } + // -------------------------------------------------------------------------------------------------------- +} + +//------------------------------------------------------------------------------ +// TV Functions +//------------------------------------------------------------------------------ +function resetControlObject(%client) +{ + if( isObject( %client.comCam ) ) + %client.comCam.delete(); + + if(isObject(%client.player) && !%client.player.isDestroyed() && $MatchStarted) + %client.setControlObject(%client.player); + else + %client.setControlObject(%client.camera); + + // ----------------------------------------------------------------------------------------------------------------------- + // z0dd - ZOD, 5/12/02. Reset the turrets nameTag back to its original. + if(%client.TurretControl !$= "") + %turret = %client.TurretControl; + else + return; + + if(isObject(%turret)) + { + // Reset the turrets target and nameTag + removeTaggedString(%turret.nameTag); + %turret.nameTag = ""; + freeTarget(%turret.getTarget()); + + // Set the turrets target and new nameTag + if(%turret.oldTag !$= "") + %turret.nameTag = addTaggedString(%turret.oldTag); + else + //%turret.nameTag = addTaggedString(getTaggedString(%turret.getDataBlock().targetNameTag)); + %turret.nameTag = %turret.getDataBlock().targetNameTag; // This should allready be a tagged string + + %turret.target = createTarget(%turret, %turret.nameTag, "", "", %turret.getDatablock().targetTypeTag, %turret.team, 0); + setTargetSensorGroup(%turret.target, %turret.team); + + // Reset the varible set on the client and turret + %turret.oldTag = ""; + %client.TurretControl = ""; + } + // ----------------------------------------------------------------------------------------------------------------------- +} + +function serverCmdResetControlObject(%client) +{ + resetControlObject(%client); + commandToClient(%client, 'ControlObjectReset'); + // z0dd - ZOD 6/04/02. Vehicle reticle fix. + if(isObject(%client.player)) + { + if(%client.player.isPilot() || %client.player.isWeaponOperator()) + { + return; + } + else + { + commandToClient(%client, 'RemoveReticle'); + %weapon = %client.player.getMountedImage($WeaponSlot); + %client.setWeaponsHudActive(%weapon.item); + } + } +} + +function serverCmdAttachCommanderCamera(%client, %target) +{ + // dont allow observing until match has started + if(!$MatchStarted) + { + commandToClient(%client, 'CameraAttachResponse', false); + return; + } + + %obj = getTargetObject(%target); + if((%obj == -1) || (%target == -1)) + { + commandToClient(%client, 'CameraAttachResponse', false); + return; + } + + // shape base object? + if(!(%obj.getType() & $TypeMasks::ShapeBaseObjectType)) + { + commandToClient(%client, 'CameraAttachResponse', false); + return; + } + + // can be observed? + if(!%obj.getDataBlock() || !%obj.getDataBlock().canObserve) + { + commandToClient(%client, 'CameraAttachResponse', false); + return; + } + + // same team? + if(getTargetSensorGroup(%target) != %client.getSensorGroup()) + { + commandToClient(%client, 'CameraAttachResponse', false); + return; + } + + // powered? + if(!%obj.isPowered()) + { + commandToClient(%client, 'CameraAttachResponse', false); + return; + } + + // client connection? + if(%obj.getClassName() $= "GameConnection") + { + %player = %obj.player; + if(%obj == %client) + { + if(isObject(%player) && !%player.isDestroyed()) + { + + %client.setControlObject(%player); + commandToClient(%client, 'CameraAttachResponse', true); + return; + } + } + + %obj = %player; + } + + if(!isObject(%obj) || %obj.isDestroyed()) + { + commandToClient(%client, 'CameraAttachResponse', false); + return; + } + + %data = %obj.getDataBlock(); + %obsData = %data.observeParameters; + %obsX = firstWord(%obsData); + %obsY = getWord(%obsData, 1); + %obsZ = getWord(%obsData, 2); + + // don't set the camera mode so that it does not interfere with spawning + %transform = %obj.getTransform(); + + // create a fresh camera to observe through... (could add to a list on + // the observed camera to be removed when that object dies/...) + if( !isObject( %client.comCam ) ) + { + %client.comCam = new Camera() + { + dataBlock = CommanderCamera; + }; + MissionCleanup.add(%client.comCam); + } + + %client.comCam.setTransform(%transform); + %client.comCam.setOrbitMode(%obj, %transform, %obsX, %obsY, %obsZ); + + %client.setControlObject(%client.comCam); + commandToClient(%client, 'CameraAttachResponse', true); +} + +//------------------------------------------------------------------------------ +// Scoping +function serverCmdScopeCommanderMap(%client, %scope) +{ + if(%scope) + resetControlObject(%client); + %client.scopeCommanderMap(%scope); + + commandToClient(%client, 'ScopeCommanderMap', %scope); +} diff --git a/scripts/serverDefaults.cs b/scripts/serverDefaults.cs index ab7529e..17e2f7c 100644 --- a/scripts/serverDefaults.cs +++ b/scripts/serverDefaults.cs @@ -1,153 +1,153 @@ -$Host::useCustomSkins = 0; - -$Host::teamSkin[0] = "blank"; -$Host::teamSkin[1] = "base"; -$Host::teamSkin[2] = "baseb"; -$Host::teamSkin[3] = "swolf"; -$Host::teamSkin[4] = "dsword"; -$Host::teamSkin[5] = "beagle"; -$Host::teamSkin[6] = "cotp"; - -$Host::teamName[0] = "Unassigned"; -$Host::teamName[1] = "Storm"; -$Host::teamName[2] = "Inferno"; -$Host::teamName[3] = "Starwolf"; -$Host::teamName[4] = "Diamond Sword"; -$Host::teamName[5] = "Blood Eagle"; -$Host::teamName[6] = "Phoenix"; - -$Host::holoName[0] = ""; -$Host::holoName[1] = "Storm"; -$Host::holoName[2] = "Inferno"; -$Host::holoName[3] = "Starwolf"; -$Host::holoName[4] = "DSword"; -$Host::holoName[5] = "BloodEagle"; -$Host::holoName[6] = "Harbinger"; - -// ----------------------------------------- -// z0dd - ZOD, 9/29/02. Removed T2 demo code -$Host::GameName = "T2BOL Server"; -$Host::Info = "This is a Tribes 2: Birth of Legend RPG (ver. "@$ModVersion@") server."; -$Host::Map = "AlphaSector"; -$Host::MaxPlayers = 64; -// ----------------------------------------- - -// ------------------------------------------------ -// z0dd - ZOD, 7/12/02. New admin feature variables -$Host::AdminPassword = "changethis"; -$Host::ClassicSuperAdminPassword = "changeme"; -$Host::ClassicAutoRestartServer = 0; // Automatically restart server, enable/disable -$Host::ClassicRestartTime = 12; // Time in hours to send quit to server -$Host::ClassicEchoChat = 0; // Print global chat to server console -$Host::ClassicTelnet = 0; // Enable/disable Telnet access to server -$Host::ClassicTelnetPort = 666; // Telnet port, must be open on host -$Host::ClassicTelnetPassword = "FullAccessPassword"; // Full access telnet password, can send commands to server -$Host::ClassicTelnetListenPass = "ListenOnyPassword"; // Read only telnet password, cannot send commands to server -$Host::ClassicLogEchoEnabled = 0; // Print special messages to server console -$Host::ClassicRandomMissions = 0; // Randomly load missions of the same type -$Host::ClassicMaxTelepads = 3; // How many special practice CTF pads each player gets -$Host::ClassicRandomizeTeams = 0; // Random team selection for players -$Host::ClassicFairTeams = 0; // Dissallow players from making teams uneven -$Host::ClassicAutoPWEnabled = 0; // Automatic join password setting of server after $Host::ClassicAutoPWPlayerCount is reached -$Host::ClassicAutoPWPassword = "changeit"; // $Host::Password changed to this if $Host::ClassicAutoPWEnabled is enabled -$Host::ClassicAutoPWPlayerCount = 30; // When server reaches this number of players, and $Host::ClassicAutoPWEnabled is enabled, join password set to $Host::ClassicAutoPWPassword -// ------------------------------------------------ - -$Host::AdminList = ""; // all players that will be automatically an admin upon joining server -$Host::SuperAdminList = ""; // all players that will be automatically a super admin upon joining server -$Host::BindAddress = ""; // set to an ip address if the server wants to specify which NIC/IP to use -$Host::Port = 28000; -$Host::Password = ""; -$Host::PureServer = 1; -$Host::Dedicated = 0; -$Host::MissionType = "RPG"; -$Host::TimeLimit = 30; -$Host::BotCount = 2; -$Host::BotsEnabled = 0; -$Host::MinBotDifficulty = 0.5; -$Host::MaxBotDifficulty = 0.75; -$Host::NoSmurfs = 0; -$Host::VoteTime = 30; // amount of time before votes are calculated -$Host::VotePassPercent = 60; // percent needed to pass a vote -$Host::KickBanTime = 300; // specified in seconds -$Host::BanTime = 1800; // specified in seconds -$Host::PlayerRespawnTimeout = 60; // time before a dead player is forced into observer mode -$Host::warmupTime = 20; -$Host::TournamentMode = 0; -$Host::allowAdminPlayerVotes = 1; -$Host::FloodProtectionEnabled = 1; -$Host::MaxMessageLen = 120; -$Host::VoteSpread = 20; -$Host::TeamDamageOn = 0; -$Host::Siege::Halftime = 20000; -$Host::CRCTextures = 0; - -// 0: .v12 (1.2 kbits/sec), 1: .v24 (2.4 kbits/sec), 2: .v29 (2.9kbits/sec) -// 3: GSM (6.6 kbits/sec) -$Audio::maxEncodingLevel = 3; -$Audio::maxVoiceChannels = 2; - -$Host::MapPlayerLimits["Abominable", "CnH"] = "-1 -1"; -$Host::MapPlayerLimits["AgentsOfFortune", "TeamHunters"] = "-1 32"; -$Host::MapPlayerLimits["Alcatraz", "Siege"] = "-1 48"; -$Host::MapPlayerLimits["Archipelago", "CTF"] = "16 -1"; -$Host::MapPlayerLimits["AshesToAshes", "CnH"] = "16 -1"; -$Host::MapPlayerLimits["BeggarsRun", "CTF"] = "-1 32"; -$Host::MapPlayerLimits["Caldera", "Siege"] = "-1 48"; -$Host::MapPlayerLimits["CasernCavite", "Hunters"] = "-1 32"; -$Host::MapPlayerLimits["CasernCavite", "DM"] = "-1 32"; -$Host::MapPlayerLimits["CasernCavite", "Bounty"] = "-1 32"; -$Host::MapPlayerLimits["Damnation", "CTF"] = "-1 32"; -$Host::MapPlayerLimits["DeathBirdsFly", "CTF"] = "8 -1"; -$Host::MapPlayerLimits["Desiccator", "CTF"] = "-1 -1"; -$Host::MapPlayerLimits["DustToDust", "CTF"] = "-1 32"; -$Host::MapPlayerLimits["DustToDust", "Hunters"] = "-1 32"; -$Host::MapPlayerLimits["DustToDust", "TeamHunters"] = "-1 32"; -$Host::MapPlayerLimits["Equinox", "CnH"] = "-1 -1"; -$Host::MapPlayerLimits["Equinox", "DM"] = "-1 32"; -$Host::MapPlayerLimits["Escalade", "Hunters"] = "8 -1"; -$Host::MapPlayerLimits["Escalade", "TeamHunters"] = "8 -1"; -$Host::MapPlayerLimits["Escalade", "DM"] = "16 -1"; -$Host::MapPlayerLimits["Escalade", "Bounty"] = "16 32"; -$Host::MapPlayerLimits["Escalade", "Rabbit"] = "16 -1"; -$Host::MapPlayerLimits["Firestorm", "CTF"] = "-1 24"; -$Host::MapPlayerLimits["Firestorm", "CnH"] = "-1 24"; -$Host::MapPlayerLimits["Flashpoint", "CnH"] = "-1 -1"; -$Host::MapPlayerLimits["Gauntlet", "Siege"] = "-1 32"; -$Host::MapPlayerLimits["Gehenna", "Hunters"] = "-1 -1"; -$Host::MapPlayerLimits["Gehenna", "TeamHunters"] = "-1 -1"; -$Host::MapPlayerLimits["Icebound", "Siege"] = "-1 -1"; -$Host::MapPlayerLimits["Insalubria", "CnH"] = "-1 32"; -$Host::MapPlayerLimits["JacobsLadder", "CnH"] = "-1 -1"; -$Host::MapPlayerLimits["Katabatic", "CTF"] = "-1 48"; -$Host::MapPlayerLimits["Masada", "Siege"] = "-1 32"; -$Host::MapPlayerLimits["Minotaur", "CTF"] = "-1 32"; -$Host::MapPlayerLimits["Myrkwood", "Hunters"] = "-1 32"; -$Host::MapPlayerLimits["Myrkwood", "DM"] = "-1 32"; -$Host::MapPlayerLimits["Myrkwood", "Rabbit"] = "-1 32"; -$Host::MapPlayerLimits["Oasis", "DM"] = "-1 32"; -$Host::MapPlayerLimits["Overreach", "CnH"] = "8 -1"; -$Host::MapPlayerLimits["Quagmire", "CTF"] = "-1 -1"; -$Host::MapPlayerLimits["Rasp", "TeamHunters"] = "-1 32"; -$Host::MapPlayerLimits["Rasp", "Bounty"] = "-1 32"; -$Host::MapPlayerLimits["Recalescence", "CTF"] = "16 -1"; -$Host::MapPlayerLimits["Respite", "Siege"] = "-1 32"; -$Host::MapPlayerLimits["Reversion", "CTF"] = "-1 -1"; -$Host::MapPlayerLimits["Rimehold", "Hunters"] = "8 -1"; -$Host::MapPlayerLimits["Rimehold", "Hunters"] = "8 -1"; -$Host::MapPlayerLimits["Riverdance", "CTF"] = "-1 -1"; -$Host::MapPlayerLimits["Sanctuary", "CTF"] = "-1 -1"; -$Host::MapPlayerLimits["Sirocco", "CnH"] = "8 -1"; -$Host::MapPlayerLimits["Slapdash", "CTF"] = "-1 -1"; -$Host::MapPlayerLimits["SunDried", "DM"] = "8 -1"; -$Host::MapPlayerLimits["SunDried", "Bounty"] = "8 -1"; -$Host::MapPlayerLimits["Talus", "Bounty"] = "-1 32"; -$Host::MapPlayerLimits["ThinIce", "CTF"] = "-1 -1"; -$Host::MapPlayerLimits["Tombstone", "CTF"] = "-1 -1"; -$Host::MapPlayerLimits["UltimaThule", "Siege"] = "8 -1"; -$Host::MapPlayerLimits["Underhill", "DM"] = "-1 -1"; -$Host::MapPlayerLimits["Underhill", "Bounty"] = "-1 32"; -$Host::MapPlayerLimits["Whiteout", "DM"] = "8 -1"; -$Host::MapPlayerLimits["Whiteout", "Bounty"] = "8 -1"; -//T2Bol vars -$Host::BurnTime = 40000; //How many miliseconds the burn from a Draakan will last before and after death. 30 seconds = 30000 MS +$Host::useCustomSkins = 0; + +$Host::teamSkin[0] = "blank"; +$Host::teamSkin[1] = "base"; +$Host::teamSkin[2] = "baseb"; +$Host::teamSkin[3] = "swolf"; +$Host::teamSkin[4] = "dsword"; +$Host::teamSkin[5] = "beagle"; +$Host::teamSkin[6] = "cotp"; + +$Host::teamName[0] = "Unassigned"; +$Host::teamName[1] = "Storm"; +$Host::teamName[2] = "Inferno"; +$Host::teamName[3] = "Starwolf"; +$Host::teamName[4] = "Diamond Sword"; +$Host::teamName[5] = "Blood Eagle"; +$Host::teamName[6] = "Phoenix"; + +$Host::holoName[0] = ""; +$Host::holoName[1] = "Storm"; +$Host::holoName[2] = "Inferno"; +$Host::holoName[3] = "Starwolf"; +$Host::holoName[4] = "DSword"; +$Host::holoName[5] = "BloodEagle"; +$Host::holoName[6] = "Harbinger"; + +// ----------------------------------------- +// z0dd - ZOD, 9/29/02. Removed T2 demo code +$Host::GameName = "T2BOL Server"; +$Host::Info = "This is a Tribes 2: Birth of Legend RPG (ver. "@$ModVersion@") server."; +$Host::Map = "AlphaSector"; +$Host::MaxPlayers = 64; +// ----------------------------------------- + +// ------------------------------------------------ +// z0dd - ZOD, 7/12/02. New admin feature variables +$Host::AdminPassword = "changethis"; +$Host::ClassicSuperAdminPassword = "changeme"; +$Host::ClassicAutoRestartServer = 0; // Automatically restart server, enable/disable +$Host::ClassicRestartTime = 12; // Time in hours to send quit to server +$Host::ClassicEchoChat = 0; // Print global chat to server console +$Host::ClassicTelnet = 0; // Enable/disable Telnet access to server +$Host::ClassicTelnetPort = 666; // Telnet port, must be open on host +$Host::ClassicTelnetPassword = "FullAccessPassword"; // Full access telnet password, can send commands to server +$Host::ClassicTelnetListenPass = "ListenOnyPassword"; // Read only telnet password, cannot send commands to server +$Host::ClassicLogEchoEnabled = 0; // Print special messages to server console +$Host::ClassicRandomMissions = 0; // Randomly load missions of the same type +$Host::ClassicMaxTelepads = 3; // How many special practice CTF pads each player gets +$Host::ClassicRandomizeTeams = 0; // Random team selection for players +$Host::ClassicFairTeams = 0; // Dissallow players from making teams uneven +$Host::ClassicAutoPWEnabled = 0; // Automatic join password setting of server after $Host::ClassicAutoPWPlayerCount is reached +$Host::ClassicAutoPWPassword = "changeit"; // $Host::Password changed to this if $Host::ClassicAutoPWEnabled is enabled +$Host::ClassicAutoPWPlayerCount = 30; // When server reaches this number of players, and $Host::ClassicAutoPWEnabled is enabled, join password set to $Host::ClassicAutoPWPassword +// ------------------------------------------------ + +$Host::AdminList = ""; // all players that will be automatically an admin upon joining server +$Host::SuperAdminList = ""; // all players that will be automatically a super admin upon joining server +$Host::BindAddress = ""; // set to an ip address if the server wants to specify which NIC/IP to use +$Host::Port = 28000; +$Host::Password = ""; +$Host::PureServer = 1; +$Host::Dedicated = 0; +$Host::MissionType = "RPG"; +$Host::TimeLimit = 30; +$Host::BotCount = 2; +$Host::BotsEnabled = 0; +$Host::MinBotDifficulty = 0.5; +$Host::MaxBotDifficulty = 0.75; +$Host::NoSmurfs = 0; +$Host::VoteTime = 30; // amount of time before votes are calculated +$Host::VotePassPercent = 60; // percent needed to pass a vote +$Host::KickBanTime = 300; // specified in seconds +$Host::BanTime = 1800; // specified in seconds +$Host::PlayerRespawnTimeout = 60; // time before a dead player is forced into observer mode +$Host::warmupTime = 20; +$Host::TournamentMode = 0; +$Host::allowAdminPlayerVotes = 1; +$Host::FloodProtectionEnabled = 1; +$Host::MaxMessageLen = 120; +$Host::VoteSpread = 20; +$Host::TeamDamageOn = 0; +$Host::Siege::Halftime = 20000; +$Host::CRCTextures = 0; + +// 0: .v12 (1.2 kbits/sec), 1: .v24 (2.4 kbits/sec), 2: .v29 (2.9kbits/sec) +// 3: GSM (6.6 kbits/sec) +$Audio::maxEncodingLevel = 3; +$Audio::maxVoiceChannels = 2; + +$Host::MapPlayerLimits["Abominable", "CnH"] = "-1 -1"; +$Host::MapPlayerLimits["AgentsOfFortune", "TeamHunters"] = "-1 32"; +$Host::MapPlayerLimits["Alcatraz", "Siege"] = "-1 48"; +$Host::MapPlayerLimits["Archipelago", "CTF"] = "16 -1"; +$Host::MapPlayerLimits["AshesToAshes", "CnH"] = "16 -1"; +$Host::MapPlayerLimits["BeggarsRun", "CTF"] = "-1 32"; +$Host::MapPlayerLimits["Caldera", "Siege"] = "-1 48"; +$Host::MapPlayerLimits["CasernCavite", "Hunters"] = "-1 32"; +$Host::MapPlayerLimits["CasernCavite", "DM"] = "-1 32"; +$Host::MapPlayerLimits["CasernCavite", "Bounty"] = "-1 32"; +$Host::MapPlayerLimits["Damnation", "CTF"] = "-1 32"; +$Host::MapPlayerLimits["DeathBirdsFly", "CTF"] = "8 -1"; +$Host::MapPlayerLimits["Desiccator", "CTF"] = "-1 -1"; +$Host::MapPlayerLimits["DustToDust", "CTF"] = "-1 32"; +$Host::MapPlayerLimits["DustToDust", "Hunters"] = "-1 32"; +$Host::MapPlayerLimits["DustToDust", "TeamHunters"] = "-1 32"; +$Host::MapPlayerLimits["Equinox", "CnH"] = "-1 -1"; +$Host::MapPlayerLimits["Equinox", "DM"] = "-1 32"; +$Host::MapPlayerLimits["Escalade", "Hunters"] = "8 -1"; +$Host::MapPlayerLimits["Escalade", "TeamHunters"] = "8 -1"; +$Host::MapPlayerLimits["Escalade", "DM"] = "16 -1"; +$Host::MapPlayerLimits["Escalade", "Bounty"] = "16 32"; +$Host::MapPlayerLimits["Escalade", "Rabbit"] = "16 -1"; +$Host::MapPlayerLimits["Firestorm", "CTF"] = "-1 24"; +$Host::MapPlayerLimits["Firestorm", "CnH"] = "-1 24"; +$Host::MapPlayerLimits["Flashpoint", "CnH"] = "-1 -1"; +$Host::MapPlayerLimits["Gauntlet", "Siege"] = "-1 32"; +$Host::MapPlayerLimits["Gehenna", "Hunters"] = "-1 -1"; +$Host::MapPlayerLimits["Gehenna", "TeamHunters"] = "-1 -1"; +$Host::MapPlayerLimits["Icebound", "Siege"] = "-1 -1"; +$Host::MapPlayerLimits["Insalubria", "CnH"] = "-1 32"; +$Host::MapPlayerLimits["JacobsLadder", "CnH"] = "-1 -1"; +$Host::MapPlayerLimits["Katabatic", "CTF"] = "-1 48"; +$Host::MapPlayerLimits["Masada", "Siege"] = "-1 32"; +$Host::MapPlayerLimits["Minotaur", "CTF"] = "-1 32"; +$Host::MapPlayerLimits["Myrkwood", "Hunters"] = "-1 32"; +$Host::MapPlayerLimits["Myrkwood", "DM"] = "-1 32"; +$Host::MapPlayerLimits["Myrkwood", "Rabbit"] = "-1 32"; +$Host::MapPlayerLimits["Oasis", "DM"] = "-1 32"; +$Host::MapPlayerLimits["Overreach", "CnH"] = "8 -1"; +$Host::MapPlayerLimits["Quagmire", "CTF"] = "-1 -1"; +$Host::MapPlayerLimits["Rasp", "TeamHunters"] = "-1 32"; +$Host::MapPlayerLimits["Rasp", "Bounty"] = "-1 32"; +$Host::MapPlayerLimits["Recalescence", "CTF"] = "16 -1"; +$Host::MapPlayerLimits["Respite", "Siege"] = "-1 32"; +$Host::MapPlayerLimits["Reversion", "CTF"] = "-1 -1"; +$Host::MapPlayerLimits["Rimehold", "Hunters"] = "8 -1"; +$Host::MapPlayerLimits["Rimehold", "Hunters"] = "8 -1"; +$Host::MapPlayerLimits["Riverdance", "CTF"] = "-1 -1"; +$Host::MapPlayerLimits["Sanctuary", "CTF"] = "-1 -1"; +$Host::MapPlayerLimits["Sirocco", "CnH"] = "8 -1"; +$Host::MapPlayerLimits["Slapdash", "CTF"] = "-1 -1"; +$Host::MapPlayerLimits["SunDried", "DM"] = "8 -1"; +$Host::MapPlayerLimits["SunDried", "Bounty"] = "8 -1"; +$Host::MapPlayerLimits["Talus", "Bounty"] = "-1 32"; +$Host::MapPlayerLimits["ThinIce", "CTF"] = "-1 -1"; +$Host::MapPlayerLimits["Tombstone", "CTF"] = "-1 -1"; +$Host::MapPlayerLimits["UltimaThule", "Siege"] = "8 -1"; +$Host::MapPlayerLimits["Underhill", "DM"] = "-1 -1"; +$Host::MapPlayerLimits["Underhill", "Bounty"] = "-1 32"; +$Host::MapPlayerLimits["Whiteout", "DM"] = "8 -1"; +$Host::MapPlayerLimits["Whiteout", "Bounty"] = "8 -1"; +//T2Bol vars +$Host::BurnTime = 40000; //How many miliseconds the burn from a Draakan will last before and after death. 30 seconds = 30000 MS diff --git a/scripts/shapes/MoneyBag.dts b/scripts/shapes/MoneyBag.dts deleted file mode 100644 index 8f24f42eae55c78be8000288f2685ad5e7008e60..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4926 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 qN|J^ZmQ9{sl3>C}ZHJv5)H%m8t8jkC, , );"); - return; - } - - %organicIndex = -1; - // -------------------------------------------------------- - // z0dd - ZOD, 5/8/02. Typo fix. - //for (%i = 0; %i < $NumAStaticTSObjects; %i++) { - for (%i = 0; %i < $NumStaticTSObjects; %i++) { - if (getWord($StaticTSObjects[%i], 1) $= %organicName) { - %organicIndex = %i; - break; - } - } - if (%organicIndex == -1) { - error("There is no static shape named" SPC %organicName); - return; - } - %shapeFileName = getWord($StaticTSObjects[%organicIndex], 2); - - %maxSlope = getWord($StaticTSObjects[%organicIndex], 3); - if (%maxSlope $= "") - %maxSlope = 40; - - %zOffset = getWord($StaticTSObjects[%organicIndex], 4); - if (%zOffset $= "") - %zOffset = 0; - - %slopeWithTerrain = getWord($StaticTSObjects[%organicIndex], 5); - if (%slopeWithTerrain $= "") - %slopeWithTerrain = false; - - %minScale = getWord($StaticTSObjects[%organicIndex], 6); - %maxScale = getWord($StaticTSObjects[%organicIndex], 7); - - //set up folders in mis file - $RandomOrganicsAdded++; //to keep track of groups - if(!isObject(RandomOrganics)) { - %randomOrgGroup = new simGroup(RandomOrganics); - MissionGroup.add(%randomOrgGroup); - } - %groupName = "Addition"@$RandomOrganicsAdded@%organicName; - %group = new simGroup(%groupName); - RandomOrganics.add(%group); - - - %ctr = LocalClientConnection.camera.getPosition(); - %areaX = getWord(%ctr, 0) - %radius; - %areaY = getWord(%ctr, 1) - %radius; - - %orgCount = %num; - while((%orgCount > 0) && (%retries < (15000 / %maxSlope))) //theoretically, a thorough number of retries - { - //find a tile - %x = (getRandom(mFloor(%areaX / 8), mFloor((%areaX + (%radius * 2)) / 8)) * 8) + 4; //tile center - %y = (getRandom(mFloor(%areaY / 8), mFloor((%areaY + (%radius * 2)) / 8)) * 8) + 4; - - %start = %x @ " " @ %y @ " 2000"; - %end = %x @ " " @ %y @ " -1"; - %ground = containerRayCast(%start, %end, $TypeMasks::TerrainObjectType, 0); - %z = getWord(%ground, 3); - %z += %zOffset; - %position = %x @ " " @ %y @ " " @ %z; - - - // get normal from both sides of the square - %start = %x + 2 @ " " @ %y @ " 2000"; - %end = %x + 2 @ " " @ %y @ " -1"; - %hit1 = containerRayCast(%start, %end, $TypeMasks::TerrainObjectType, 0); - - %start = %x - 2 @ " " @ %y @ " 2000"; - %end = %x - 2 @ " " @ %y @ " -1"; - %hit2 = containerRayCast(%start, %end, $TypeMasks::TerrainObjectType, 0); - - %norm1 = getWord(%hit1, 4) @ " " @ getWord(%hit1, 5) @ " " @ getWord(%hit1, 6); - %norm2 = getWord(%hit2, 4) @ " " @ getWord(%hit2, 5) @ " " @ getWord(%hit2, 6); - - //if either side of tile has greater slope than allowed, move on. - %angNorm1 = getTerrainAngle(%norm1); - %angNorm2 = getTerrainAngle(%norm2); - if ((getTerrainAngle(%norm1) > %maxSlope) || (getTerrainAngle(%norm2) > %maxslope)) - { - %retries++; - continue; - } - - %terrainNormal = VectorAdd(%norm1, %norm2); - %terrainNormal = VectorNormalize(%terrainNormal); - - //search surroundings for obstacles. If obstructed, move on. - InitContainerRadiusSearch(%position, %spacing, $TypeMasks::VehicleObjectType | - $TypeMasks::MoveableObjectType | - $TypeMasks::StaticShapeObjectType | - // ----------------------------- - // z0dd - ZOD, 5/8/02. Typo fix. - //$TypeMasks::TSStaticShapeObjectType | - $TypeMasks::StaticTSObjectType | - $TypeMasks::ForceFieldObjectType | - $TypeMasks::TurretObjectType | - $TypeMasks::InteriorObjectType | - $TypeMasks::ItemObjectType); - %this = containerSearchNext(); - if(%this) - { - %retries++; - continue; - } - - - //rotate it - if(%slopeWithTerrain) - { - %rotAxis = vectorCross(%terrainNormal, "0 0 1"); - %rotAxis = vectorNormalize(%rotAxis); - %rotation = %rotAxis @ " " @ getTerrainAngle(%terrainNormal); - } - else %rotation = "1 0 0 0"; - %randomAngle = getRandom(360); - %zrot = MatrixCreate("0 0 0", "0 0 1 " @ %randomAngle); - %orient = MatrixCreate(%position, %rotation); - %finalXForm = MatrixMultiply(%orient, %zrot); - - - //scale it - %scaleMin = 8; //default min - %scaleMax = 14; //default max - if(%minScale) - %scaleMin = %minScale * 10; - if(%maxScale) - %scaleMax = %maxScale * 10; - %scaleInt = getRandom(%scaleMin, %scaleMax); - %scale = %scaleInt/10; - %evenScale = %scale SPC %scale SPC %scale; - - //create it - %position = %x SPC %y SPC (%z += %zoffset); - %newOrganic = new TSStatic() { - position = %position; - rotation = %rotation; - scale = %evenScale; - shapeName = %shapeFileName; - }; - %group.add(%newOrganic); - %newOrganic.setTransform(%finalXForm); - - %orgCount--; //dec number of shapes left to place - %retries = 0; //reset retry counter - } - if (%orgCount > 0) - { - error("Unable to place all shapes, area saturated."); - error("Looking for clear area " @ (%spacing * 2) @ " meters in diameter, with a max slope of " @ %maxSlope); - } - echo("Placed " @ %num - %orgCount @ " of " @ %num); -} - -function getTerrainAngle(%point) -{ - %up = "0 0 1"; - %angleRad = mACos(vectorDot(%point, %up)); - %angleDeg = mRadToDeg(%angleRad); - //echo("angle is "@%angleDeg); - return %angleDeg; -} -function randomGrove(%organicName, %num, %radius) -{ - %minHeight = 0; - %maxHeight = 1000; - %SPACING = 1.5; //meters between center of organic and another object - - //return help info - if(%organicName $="" || !%num || !%radius) { - echo("randomOrg(, [, radius of grove desired]);"); - return; - } - - %organicIndex = -1; - for (%i = 0; %i < $NumStaticTSObjects; %i++) { - if (getWord($StaticTSObjects[%i], 1) $= %organicName) { - %organicIndex = %i; - break; - } - } - if (%organicIndex == -1) { - error("There is no static shape named" SPC %organicName); - return; - } - %shapeFileName = getWord($StaticTSObjects[%organicIndex], 2); - - %maxSlope = getWord($StaticTSObjects[%organicIndex], 3); - if (%maxSlope $= "") - %maxSlope = 40; - - %zOffset = getWord($StaticTSObjects[%organicIndex], 4); - if (%zOffset $= "") - %zOffset = 0; - - %slopeWithTerrain = getWord($StaticTSObjects[%organicIndex], 5); - if (%slopeWithTerrain $= "") - %slopeWithTerrain = false; - - %minScale = getWord($StaticTSObjects[%organicIndex], 6); - %maxScale = getWord($StaticTSObjects[%organicIndex], 7); - - //set up folders in mis file - $RandomOrganicsAdded++; //to keep track of groups - if(!isObject(RandomOrganics)) { - %randomOrgGroup = new simGroup(RandomOrganics); - MissionGroup.add(%randomOrgGroup); - } - %groupName = "Addition"@$RandomOrganicsAdded@%organicName; - %group = new simGroup(%groupName); - RandomOrganics.add(%group); - - - %ctr = LocalClientConnection.camera.getPosition(); - %areaX = getWord(%ctr, 0) - %radius; - %areaY = getWord(%ctr, 1) - %radius; - - %orgCount = %num; - while((%orgCount > 0) && (%retries < (15000 / %maxSlope))) //theoretically, a thorough number of retries - { - //find a tile - %x = (getRandom(mFloor(%areaX / 8), mFloor((%areaX + (%radius * 2)) / 8)) * 8) + 4; //tile center - %y = (getRandom(mFloor(%areaY / 8), mFloor((%areaY + (%radius * 2)) / 8)) * 8) + 4; - - %start = %x @ " " @ %y @ " 2000"; - %end = %x @ " " @ %y @ " -1"; - %ground = containerRayCast(%start, %end, $TypeMasks::TerrainObjectType, 0); - %z = getWord(%ground, 3); - - - // elevation test - if ((%z < %minHeight) || (%z > %maxHeight)) - { - echo("Broke height range rules. Readjust allowable elevations."); - %retries++; - echo("Z is " @ %z); - continue; - } - %z += %zOffset; - %position = %x @ " " @ %y @ " " @ %z; - - - // get normal from both sides of the square - %start = %x + 2 @ " " @ %y @ " 2000"; - %end = %x + 2 @ " " @ %y @ " -1"; - %hit1 = containerRayCast(%start, %end, $TypeMasks::TerrainObjectType, 0); - - %start = %x - 2 @ " " @ %y @ " 2000"; - %end = %x - 2 @ " " @ %y @ " -1"; - %hit2 = containerRayCast(%start, %end, $TypeMasks::TerrainObjectType, 0); - - %norm1 = getWord(%hit1, 4) @ " " @ getWord(%hit1, 5) @ " " @ getWord(%hit1, 6); - %norm2 = getWord(%hit2, 4) @ " " @ getWord(%hit2, 5) @ " " @ getWord(%hit2, 6); - - //if either side of tile has greater slope than allowed, move on. - %angNorm1 = getTerrainAngle(%norm1); - %angNorm2 = getTerrainAngle(%norm2); - if ((getTerrainAngle(%norm1) > %maxSlope) || (getTerrainAngle(%norm2) > %maxslope)) - { - %retries++; - continue; - } - - %terrainNormal = VectorAdd(%norm1, %norm2); - %terrainNormal = VectorNormalize(%terrainNormal); - - //search surroundings for obstacles. If obstructed, move on. - InitContainerRadiusSearch(%position, %spacing, $TypeMasks::VehicleObjectType | - $TypeMasks::MoveableObjectType | - $TypeMasks::StaticShapeObjectType | - // ----------------------------- - // z0dd - ZOD, 5/8/02. Typo fix. - //$TypeMasks::TSStaticShapeObjectType | - $TypeMasks::StaticTSObjectType | - $TypeMasks::ForceFieldObjectType | - $TypeMasks::TurretObjectType | - $TypeMasks::InteriorObjectType | - $TypeMasks::ItemObjectType); - %this = containerSearchNext(); - if(%this) - { - %retries++; - continue; - } - - - //rotate it - if(%slopeWithTerrain) - { - %rotAxis = vectorCross(%terrainNormal, "0 0 1"); - %rotAxis = vectorNormalize(%rotAxis); - %rotation = %rotAxis @ " " @ getTerrainAngle(%terrainNormal); - } - else %rotation = "1 0 0 0"; - %randomAngle = getRandom(360); - %zrot = MatrixCreate("0 0 0", "0 0 1 " @ %randomAngle); - %orient = MatrixCreate(%position, %rotation); - %finalXForm = MatrixMultiply(%orient, %zrot); - - - //scale it - %scaleMin = 8; //default min - %scaleMax = 14; //default max - if(%minScale) - %scaleMin = %minScale * 10; - if(%maxScale) - %scaleMax = %maxScale * 10; - %scaleInt = getRandom(%scaleMin, %scaleMax); - %scale = %scaleInt/10; - %evenScale = %scale SPC %scale SPC %scale; - - //create it - - %position = %x SPC %y SPC (%z += %zoffset); - %newOrganic = new TSStatic() { - position = %position; - rotation = %rotation; - scale = %evenScale; - shapeName = %shapeFileName; - }; - %group.add(%newOrganic); - %newOrganic.setTransform(%finalXForm); - - %orgCount--; //dec number of shapes left to place - %retries = 0; //reset retry counter - } - if (%orgCount > 0) - { - error("Unable to place all shapes, area saturated."); - error("Looking for clear area " @ (%spacing * 2) @ " meters in diameter, with a max slope of " @ %maxSlope); - } - echo("Placed " @ %num - %orgCount @ " of " @ %num); -} - - -function randomRock(%rock, %quantity, %radius, %maxElev) -{ - if (!%radius || !%quantity || !%rock) - { - echo("randomRock(, , , [maximum elevation]"); - return; - } - - if (!%maxElev) - %maxElev = 2000; - - - %rotation[0] = "0 0 1 0"; - %rotation[1] = "0.999378 -0.0145686 -0.0321219 194.406"; - %rotation[2] = "0.496802 0.867682 0.0177913 176.44"; - %rotation[3] = "0.991261 0.0933696 0.0931923 181.867"; - %rotation[4] = "0.246801 0.360329 -0.899584 92.3648"; - %rotation[5] = "1 0 0 82.59"; - %rotation[6] = "0.0546955 -0.629383 0.55201 116.103"; - - %spacing = 4.0; //check 4 meters around object for collisions before placing - %ctr = localClientConnection.camera.getPosition(); - %areaX = getWord(%ctr, 0) - %radius; - %areaY = getWord(%ctr, 1) - %radius; - - $RandomOrganicsAdded++; - if(!isObject(RandomRocks)) { - %randomOrgGroup = new simGroup(RandomRocks); - MissionGroup.add(%randomOrgGroup); - } - %groupName = "Addition"@$RandomOrganicsAdded@%rock; - %group = new simGroup(%groupName); - RandomRocks.add(%group); - - %orgCount = %quantity; - while((%orgCount > 0) && (%retries < (15000 / %maxSlope))) //theoretically, a thorough number of retries - { - //find a tile - %x = %areaX + getRandom(%radius * 2); - %y = %areaY + getRandom(%radius * 2); - - %start = %x @ " " @ %y @ " 2000"; - %end = %x @ " " @ %y @ " -1"; - %ground = containerRayCast(%start, %end, $TypeMasks::TerrainObjectType, 0); - %position = getWord(%ground, 1) @ " " @ getWord(%ground, 2) @ " " @ getWord(%ground, 3); - echo("position =*" @ %position @ "*"); - %z = getWord(%position, 2); - - - // elevation test - if (%z > %maxElev) //65 meters and above only - { - %retries++; - echo("Z is " @ %z); - continue; - } - - - //search surroundings for obstacles. If obstructed, move on. - InitContainerRadiusSearch(%position, %spacing, $TypeMasks::VehicleObjectType | - $TypeMasks::MoveableObjectType | - $TypeMasks::StaticShapeObjectType | - // ----------------------------- - // z0dd - ZOD, 5/8/02. Typo fix. - //$TypeMasks::TSStaticShapeObjectType | - $TypeMasks::StaticTSObjectType | - $TypeMasks::ForceFieldObjectType | - $TypeMasks::TurretObjectType | - $TypeMasks::InteriorObjectType | - $TypeMasks::ItemObjectType); - %this = containerSearchNext(); - if(%this) - { - %retries++; - continue; - } - %primaryRot = %rotation[getRandom(7)]; - - %randomAngle = mDegToRad(getRandom(360)); - %zrot = MatrixCreate("0 0 0", "0 0 1 " @ %randomAngle); - %orient = MatrixCreate(%position, %primaryRot); - - - %scale = getRandom(3); - %evenScale = %scale @ " " @ %scale @ " " @ %scale; - %newRock = new InteriorInstance() { - scale = %evenScale; - interiorFile = %rock @ ".dif"; - showTerrainInside = "0"; - }; - %group.add(%newRock); - %transfrm = MatrixMultiply(%orient, %zrot); - echo("Transform = *" @ %transfrm @ "*"); - %newRock.setTransform(%transfrm); - - %orgCount--; //dec number of shapes left to place - %retries = 0; //reset retry counter - } - if (%orgCount > 0) - { - error("Unable to place all shapes, area saturated."); - error("Looking for clear area " @ (%spacing * 2) @ " meters in diameter, with a max slope of " @ %maxSlope); - } - echo("Placed " @ %num - %orgCount @ " of " @ %num); -} - - -//-------------------------------------------------------------------------- -//-------------------------------------- Organics -//-------------------------------------------------------------------------- - - -//****************************************************************************** -//* Pulse Sensor - Data Blocks * -//****************************************************************************** - -datablock DebrisData( StaticShapeDebris ) -{ - explodeOnMaxBounce = false; - - elasticity = 0.20; - friction = 0.5; - - lifetime = 17.0; - lifetimeVariance = 0.0; - - minSpinSpeed = 60; - maxSpinSpeed = 600; - - numBounces = 10; - bounceVariance = 0; - - staticOnMaxBounce = true; - - useRadiusMass = true; - baseRadius = 0.4; - - velocity = 9.0; - velocityVariance = 4.5; -}; - -datablock DebrisData( SmallShapeDebris ) -{ - explodeOnMaxBounce = false; - - elasticity = 0.20; - friction = 0.5; - - lifetime = 17.0; - lifetimeVariance = 0.0; - - minSpinSpeed = 60; - maxSpinSpeed = 600; - - numBounces = 10; - bounceVariance = 0; - - staticOnMaxBounce = true; - - useRadiusMass = true; - baseRadius = 0.2; - - velocity = 5.0; - velocityVariance = 2.5; -}; - -datablock AudioProfile(SensorHumSound) -{ - filename = "fx/powered/sensor_hum.wav"; - description = CloseLooping3d; - preload = true; -}; - -datablock SensorData(SensorLgPulseObj) -{ - detects = true; - detectsUsingLOS = true; - detectsPassiveJammed = false; - detectsActiveJammed = false; - detectsCloaked = false; - detectionPings = true; - detectRadius = 300; -}; - -datablock StaticShapeData(SensorLargePulse) : StaticShapeDamageProfile -{ - className = Sensor; - catagory = "Sensors"; - shapeFile = "sensor_pulse_large.dts"; - maxDamage = 1.5; - destroyedLevel = 1.5; - disabledLevel = 0.85; - explosion = ShapeExplosion; - expDmgRadius = 10.0; - expDamage = 0.5; - expImpulse = 2000.0; - - dynamicType = $TypeMasks::SensorObjectType; - isShielded = true; - energyPerDamagePoint = 33; - maxEnergy = 110; - rechargeRate = 0.31; - ambientThreadPowered = true; - humSound = SensorHumSound; - - cmdCategory = "Support"; - cmdIcon = CMDSensorIcon; - cmdMiniIconName = "commander/MiniIcons/com_sensor_grey"; - targetNameTag = 'Large'; - targetTypeTag = 'Sensor'; - sensorData = SensorLgPulseObj; - sensorRadius = SensorLgPulseObj.detectRadius; - sensorColor = "255 194 9"; - - debrisShapeName = "debris_generic.dts"; - debris = StaticShapeDebris; -}; - -datablock SensorData(SensorMedPulseObj) -{ - detects = true; - detectsUsingLOS = true; - detectsPassiveJammed = false; - detectsActiveJammed = false; - detectsCloaked = false; - detectionPings = true; - detectRadius = 175; -}; - -datablock StaticShapeData(SensorMediumPulse) : StaticShapeDamageProfile -{ - className = Sensor; - catagory = "Sensors"; - shapeFile = "sensor_pulse_medium.dts"; - maxDamage = 1.2; - destroyedLevel = 1.2; - disabledLevel = 0.68; - explosion = ShapeExplosion; - expDmgRadius = 7.0; - expDamage = 0.4; - expImpulse = 1500; - - dynamicType = $TypeMasks::SensorObjectType; - isShielded = true; - energyPerDamagePoint = 33; - maxEnergy = 90; - rechargeRate = 0.31; - ambientThreadPowered = true; - humSound = SensorHumSound; - - cmdCategory = "Support"; - cmdIcon = CMDSensorIcon; - cmdMiniIconName = "commander/MiniIcons/com_sensor_grey"; - targetNameTag = 'Medium'; - targetTypeTag = 'Sensor'; - sensorData = SensorMedPulseObj; - sensorRadius = SensorMedPulseObj.detectRadius; - sensorColor = "255 194 9"; - - debrisShapeName = "debris_generic.dts"; - debris = StaticShapeDebris; -}; - -function Sensor::onGainPowerEnabled(%data, %obj) -{ - setTargetSensorData(%obj.target, %data.sensorData); - Parent::onGainPowerEnabled(%data, %obj); -} - -function Sensor::onLosePowerDisabled(%data, %obj) -{ - setTargetSensorData(%obj.target, 0); - Parent::onLosePowerDisabled(%data, %obj); -} - -//****************************************************************************** -//* Generator - Data Blocks * -//****************************************************************************** - -datablock AudioProfile(GeneratorHumSound) -{ - filename = "fx/powered/generator_hum.wav"; - description = CloseLooping3d; - preload = true; -}; - - -datablock StaticShapeData(GeneratorLarge) : StaticShapeDamageProfile -{ - className = Generator; - catagory = "Generators"; - shapeFile = "station_generator_large.dts"; - explosion = ShapeExplosion; - maxDamage = 1.5; - destroyedLevel = 1.5; - disabledLevel = 0.85; - expDmgRadius = 10.0; - expDamage = 0.5; - expImpulse = 1500.0; - noIndividualDamage = true; //flag to make these invulnerable for certain mission types - - dynamicType = $TypeMasks::GeneratorObjectType; - isShielded = true; - energyPerDamagePoint = 30; // z0dd - ZOD, 9/27/02. was 30 - maxEnergy = 70; // z0dd - ZOD, 09/20/02. Was 50 - rechargeRate = 0.15; // z0dd - ZOD, 09/20/02. Was 0.05 - humSound = GeneratorHumSound; - - cmdCategory = "Support"; - cmdIcon = "CMDGeneratorIcon"; - cmdMiniIconName = "commander/MiniIcons/com_generator"; - targetTypeTag = 'Generator'; - - debrisShapeName = "debris_generic.dts"; - debris = StaticShapeDebris; -}; - -datablock StaticShapeData(SolarPanel) : StaticShapeDamageProfile -{ - className = Generator; - catagory = "Generators"; - shapeFile = "solarpanel.dts"; - explosion = ShapeExplosion; - maxDamage = 1.00; - destroyedLevel = 1.00; - disabledLevel = 0.55; - expDmgRadius = 5.0; - expDamage = 0.3; - expImpulse = 1000.0; - noIndividualDamage = true; //flag to make these invulnerable for certain mission types - emap = true; - - isShielded = true; - energyPerDamagePoint = 30; - rechargeRate = 0.1; // z0dd - ZOD, 09/20/02. Was 0.05 - - dynamicType = $TypeMasks::GeneratorObjectType; - maxEnergy = 30; - humSound = GeneratorHumSound; - - cmdCategory = "Support"; - cmdIcon = CMDSolarGeneratorIcon; - cmdMiniIconName = "commander/MiniIcons/com_solargen_grey"; - targetTypeTag = 'Solar Panel'; - - debrisShapeName = "debris_generic.dts"; - debris = StaticShapeDebris; -}; - -function Generator::onDisabled(%data, %obj, %prevState) -{ - %obj.decPowerCount(); - Parent::onDisabled(%data, %obj, %prevState); -} - -function Generator::onEnabled(%data, %obj, %prevState) -{ - %obj.incPowerCount(); - Parent::onEnabled(%data, %obj, %prevState); -} - -//****************************************************************************** -//Nexus Effect (Hunters) -//****************************************************************************** - -datablock StaticShapeData(Nexus_Effect) -{ - catagory = "Objectives"; - shapefile = "nexus_effect.dts"; - mass = 10; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; -}; - - -datablock StaticShapeData(NexusBase) -{ - catagory = "Objectives"; - shapefile = "Nexusbase.dts"; - mass = 10; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; -}; - - -datablock StaticShapeData(NexusCap) -{ - catagory = "Objectives"; - shapefile = "Nexuscap.dts"; - mass = 10; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; -}; - -//****************************************************************************** -//* Static Shape - Functions * -//****************************************************************************** - -function StaticShapeData::create(%block) -{ - %obj = new StaticShape() - { - dataBlock = %block; - }; - return(%obj); -} - -function ShapeBase::damage(%this, %sourceObject, %position, %amount, %damageType) -{ - %this.getDataBlock().damageObject(%this, %sourceObject, %position, %amount, %damageType); -} - -function ShapeBaseData::damageObject(%data, %targetObject, %position, %sourceObject, %amount, %damageType) -{ - -} - -function ShapeBaseData::onDestroyed(%data, %obj, %prevState) -{ - -} - -function ShapeBaseData::checkShields(%data, %targetObject, %position, %amount, %damageType) -{ - %energy = %targetObject.getEnergyLevel(); - %strength = %energy / %data.energyPerDamagePoint; - %shieldScale = %data.shieldDamageScale[%damageType]; - if(%shieldScale $= "") - %shieldScale = 1; - - if (%amount * %shieldScale <= %strength) { - // Shield absorbs all - %lost = %amount * %shieldScale * %data.energyPerDamagePoint; - %energy -= %lost; - %targetObject.setEnergyLevel(%energy); - - %normal = "0.0 0.0 1.0"; - %targetObject.playShieldEffect( %normal ); - - return 0; - } - // Shield exhausted - %targetObject.setEnergyLevel(0); - return %amount - %strength / %shieldScale; -} - -function StaticShapeData::damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType) -{ - // if this is a non-team mission type and the object is "protected", don't damage it - if(%data.noIndividualDamage && Game.allowsProtectedStatics()) - return; - - // if this is a Siege mission and this object shouldn't take damage (e.g. vehicle stations) - if(%data.noDamageInSiege && Game.class $= "SiegeGame") - return; - - if(%sourceObject && %targetObject.isEnabled()) - { - if(%sourceObject.client) - { - %targetObject.lastDamagedBy = %sourceObject.client; - %targetObject.lastDamagedByTeam = %sourceObject.client.team; - %targetObject.damageTimeMS = GetSimTime(); - } - else - { - %targetObject.lastDamagedBy = %sourceObject; - %targetObject.lastDamagedByTeam = %sourceObject.team; - %targetObject.damageTimeMS = GetSimTime(); - } - } - - // Scale damage type & include shield calculations... - if (%data.isShielded) - %amount = %data.checkShields(%targetObject, %position, %amount, %damageType); - - %damageScale = %data.damageScale[%damageType]; - if(%damageScale !$= "") - %amount *= %damageScale; - - //if team damage is off, cap the amount of damage so as not to disable the object... - if (!$TeamDamage && !%targetObject.getDataBlock().deployedObject) - { - // ------------------------------------- - // z0dd - ZOD, 6/24/02. Console spam fix - if(isObject(%sourceObject)) - { - //see if the object is being shot by a friendly - if(%sourceObject.getDataBlock().catagory $= "Vehicles") - %attackerTeam = getVehicleAttackerTeam(%sourceObject); - else - %attackerTeam = %sourceObject.team; - } - if ((%targetObject.getTarget() != -1) && isTargetFriendly(%targetObject.getTarget(), %attackerTeam)) - { - %curDamage = %targetObject.getDamageLevel(); - %availableDamage = %targetObject.getDataBlock().disabledLevel - %curDamage - 0.05; - if (%amount > %availableDamage) - %amount = %availableDamage; - } - } - - // if there's still damage to apply - if (%amount > 0) - %targetObject.applyDamage(%amount); -} - -// little special casing for the above function -function getVehicleAttackerTeam(%vehicleId) -{ - %name = %vehicleId.getDataBlock().getName(); - if(%name $= "BomberFlyer" || %name $= "AssaultVehicle") - %gunner = %vehicleId.getMountNodeObject(1); - else - %gunner = %vehicleId.getMountNodeObject(0); - - if(%gunner) - return %gunner.team; - - return %vehicleId.team; -} - - -function StaticShapeData::onDamage(%this,%obj) -{ - // Set damage state based on current damage level - %damage = %obj.getDamageLevel(); - if(%damage >= %this.destroyedLevel) - { - if(%obj.getDamageState() !$= "Destroyed") - { - %obj.setDamageState(Destroyed); - // if object has an explosion damage radius associated with it, apply explosion damage - if(%this.expDmgRadius) - RadiusExplosion(%obj, %obj.getWorldBoxCenter(), %this.expDmgRadius, %this.expDamage, %this.expImpulse, %obj, $DamageType::Explosion); - %obj.setDamageLevel(%this.maxDamage); - } - } - else - { - if(%damage >= %this.disabledLevel) - { - if(%obj.getDamageState() !$= "Disabled") - %obj.setDamageState(Disabled); - } - else - { - if(%obj.getDamageState() !$= "Enabled") - %obj.setDamageState(Enabled); - } - } -} - -// -------------------------------------------------------------------- -// Team logos - only the logo projector should be placed in a mission - -datablock StaticShapeData(BaseLogo) //storm logo -{ - className = Logo; - shapeFile = "teamlogo_storm.dts"; - alwaysAmbient = true; -}; - -datablock StaticShapeData(BaseBLogo) //Inferno Logo -{ - className = Logo; - shapeFile = "teamlogo_inf.dts"; - alwaysAmbient = true; -}; - -datablock StaticShapeData(BiodermLogo) -{ - className = Logo; - shapeFile = "teamlogo_bd.dts"; - alwaysAmbient = true; -}; - -datablock StaticShapeData(BEagleLogo) -{ - className = Logo; - shapeFile = "teamlogo_be.dts"; - alwaysAmbient = true; -}; - -datablock StaticShapeData(DSwordLogo) -{ - className = Logo; - shapeFile = "teamlogo_ds.dts"; - alwaysAmbient = true; -}; - -datablock StaticShapeData(COTPLogo) -{ - className = Logo; - shapeFile = "teamlogo_hb.dts"; - alwaysAmbient = true; -}; - -datablock StaticShapeData(SwolfLogo) -{ - className = Logo; - shapeFile = "teamlogo_sw.dts"; - alwaysAmbient = true; -}; - -datablock StaticShapeData(LogoProjector) -{ - className = Projector; - catagory = "Objectives"; - shapeFile = "teamlogo_projector.dts"; - alwaysAmbient = true; - isInvincible = true; -}; - -function Projector::onAdd(%data, %obj) -{ - Parent::onAdd(%data, %obj); - %obj.holo = 0; -} - -//////////////////////////////////////////// -// Tapestries -/////////////////////////////////////////// -datablock StaticShapeData(Banner_Honor) -{ - catagory = "Eyecandy"; - shapefile = "banner_honor.dts"; -}; - -datablock StaticShapeData(Banner_Strength) -{ - catagory = "Eyecandy"; - shapefile = "banner_strength.dts"; -}; - -datablock StaticShapeData(Banner_Unity) -{ - catagory = "Eyecandy"; - shapefile = "banner_unity.dts"; -}; - -//////////////////////////////////////////////////////////////////////////////// -// - -//-------------------------------------------------------------------------- -// Totally static objects -// The format of these strings are: -// 0: Catagory -// 1: Name -// 2: File -// 3: MaxSlope [ only used with the randomOrg function ] -// 4: ZOffset [ only used with the randomOrg function ] -// 5: slopeWithTerrain [ only used with the randomOrg function ] -// 6: minScale [ only used with the randomOrg function ] -// 7: maxScale [ only used with the randomOrg function ] - - -$StaticTSObjects[0] = "Organics BiodermPlant3 xorg3.dts"; -$StaticTSObjects[1] = "Organics BiodermPlant4 xorg4.dts"; -$StaticTSObjects[2] = "Organics BiodermPlant5 xorg5.dts"; -$StaticTSObjects[3] = "Organics BiodermPlant20 xorg20.dts"; -$StaticTSObjects[4] = "Organics BiodermPlant21 xorg21.dts"; -$StaticTSObjects[5] = "Organics BiodermPlant22 xorg22.dts"; - -$StaticTSObjects[6] = "Organics BEPlant1 borg1.dts 40 0.35 1 0.5 2"; -$StaticTSObjects[7] = "Organics BEPlant5 borg5.dts 40 0.0 1 1 1.5"; -$StaticTSObjects[8] = "Organics BEPlant6 borg6.dts"; -$StaticTSObjects[9] = "Organics BEPlant7 borg7.dts"; - -$StaticTSObjects[10] = "Organics BEPlant12 borg12.dts"; -$StaticTSObjects[11] = "Organics BEPlant13 borg13.dts"; -$StaticTSObjects[12] = "Organics BELgTree16 borg16.dts 20 -3.0 0 0.8 1.5"; -$StaticTSObjects[13] = "Organics BESmTree17 borg17.dts 20 -3.0 1 0.8 1.5"; -$StaticTSObjects[14] = "Organics BELgTree18 borg18.dts 20 -3.0 0 0.8 1.5"; -$StaticTSObjects[15] = "Organics BELgTree19 borg19.dts 20 -3.0 0 0.8 1.5"; -$StaticTSObjects[16] = "Organics BEPlant20 borg20.dts"; - -$StaticTSObjects[17] = "Organics BEPlant23 borg23.dts"; -$StaticTSObjects[18] = "Organics BEPlant25 borg25.dts"; - -$StaticTSObjects[19] = "Organics BEPlant31 borg31.dts"; -$StaticTSObjects[20] = "Organics BEPlant32 borg32.dts"; -$StaticTSObjects[21] = "Organics BEPlant33 borg33.dts"; -$StaticTSObjects[22] = "Organics BEPlant34 borg34.dts"; - -$StaticTSObjects[23] = "Organics PhoenixPlant1 porg1.dts"; -$StaticTSObjects[24] = "Organics PhoenixPlant2 porg2.dts"; -$StaticTSObjects[25] = "Organics PhoenixPlant3 porg3.dts"; -$StaticTSObjects[26] = "Organics PhoenixPlant5 porg5.dts 25 -0.2 1 0.6 1.0"; -$StaticTSObjects[27] = "Organics PhoenixPlant6 porg6.dts"; -$StaticTSObjects[28] = "Organics PhoenixPlant20 porg20.dts"; - -$StaticTSObjects[29] = "Organics PhoenixPlant22 porg22.dts 25 0.1 1 0.8 1.4"; -$StaticTSObjects[30] = "Organics SWTree20 sorg20.dts"; -$StaticTSObjects[31] = "Organics SWShrub21 sorg21.dts"; -$StaticTSObjects[32] = "Organics SWTree22 sorg22.dts"; -$StaticTSObjects[33] = "Organics SWShrub23 sorg23.dts"; -$StaticTSObjects[34] = "Organics SWShrub24 sorg24.dts"; -$StaticTSObjects[35] = "Stackables Crate1 stackable1l.dts"; -$StaticTSObjects[36] = "Stackables Crate2 stackable1m.dts"; -$StaticTSObjects[37] = "Stackables Crate3 stackable1s.dts"; -$StaticTSObjects[38] = "Stackables Crate4 stackable2l.dts"; -$StaticTSObjects[39] = "Stackables Crate5 stackable2m.dts"; -$StaticTSObjects[40] = "Stackables Crate6 stackable2s.dts"; -$StaticTSObjects[41] = "Stackables Crate7 stackable3l.dts"; -$StaticTSObjects[42] = "Stackables Crate8 stackable3m.dts"; -$StaticTSObjects[43] = "Stackables Crate9 stackable3s.dts"; -$StaticTSObjects[44] = "Stackables Crate10 stackable4l.dts"; -$StaticTSObjects[45] = "Stackables Crate11 stackable4m.dts"; -$StaticTSObjects[46] = "Stackables Crate12 stackable5l.dts"; -$StaticTSObjects[47] = "Debris ScoutWreckageShape vehicle_air_scout_wreck.dts"; -$StaticTSObjects[48] = "Debris TankWreckageShape vehicle_land_assault_wreck.dts"; -$StaticTSObjects[49] = "Organics DSPlant16 dorg16.dts 20 -3.0 0 0.8 1.5"; -$StaticTSObjects[50] = "Organics DSPlant17 dorg17.dts 20 -3.0 1 0.8 1.5"; -$StaticTSObjects[51] = "Organics DSPlant18 dorg18.dts 20 -3.0 0 0.8 1.5"; -$StaticTSObjects[52] = "Organics DSPlant19 dorg19.dts 20 -3.0 0 0.8 1.5"; - -$StaticTSObjects[53] = "PlayerArmors LightMaleHumanArmorImage light_male.dts"; -$StaticTSObjects[54] = "PlayerArmors MediumMaleHumanArmorImage medium_male.dts"; -$StaticTSObjects[55] = "PlayerArmors HeavyMaleHumanArmorImage heavy_male.dts"; -$StaticTSObjects[56] = "PlayerArmors LightFemaleHumanArmorImage light_female.dts"; -$StaticTSObjects[57] = "PlayerArmors MediumFemaleHumanArmorImage medium_female.dts"; -$StaticTSObjects[58] = "PlayerArmors HeavyFemaleHumanArmorImage heavy_male.dts"; -$StaticTSObjects[59] = "PlayerArmors LightMaleBiodermArmorImage bioderm_light.dts"; -$StaticTSObjects[60] = "PlayerArmors MediumMaleBiodermArmorImage bioderm_medium.dts"; -$StaticTSObjects[61] = "PlayerArmors HeavyMaleBiodermArmorImage bioderm_heavy.dts"; - -$StaticTSObjects[62] = "Organics BEGrass1 Borg6.dts"; - -$StaticTSObjects[63] = "Plugs bePlug bmiscf.dts"; -$StaticTSObjects[64] = "Plugs dsPlug dmiscf.dts"; -$StaticTSObjects[65] = "Plugs xPlug xmiscf.dts"; -$StaticTSObjects[66] = "Plugs hPlug pmiscf.dts"; -$StaticTSObjects[67] = "Plugs swPlug smiscf.dts"; - -$StaticTSObjects[68] = "Statues Base statue_base.dts"; -$StaticTSObjects[69] = "Statues HeavyMaleStatue statue_hmale.dts"; -$StaticTSObjects[70] = "Statues LightFemaleStatue statue_lfemale.dts"; -$StaticTSObjects[71] = "Statues LightMaleStatue statue_lmale.dts"; -$StaticTSObjects[72] = "Statues Plaque statue_plaque.dts"; - -$StaticTSObjects[73] = "Debris BomberDebris1 bdb1.dts"; -$StaticTSObjects[74] = "Debris BomberDebris2 bdb2.dts"; -$StaticTSObjects[75] = "Debris BomberDebris3 bdb3.dts"; -$StaticTSObjects[76] = "Debris BomberDebris4 bdb4.dts"; -$StaticTSObjects[77] = "Debris BomberDebris5 bdb5.dts"; -$StaticTSObjects[78] = "Debris HavocDebris1 hdb1.dts"; -$StaticTSObjects[79] = "Debris HavocDebris2 hdb2.dts"; -$StaticTSObjects[80] = "Debris HavocDebris3 hdb3.dts"; -$StaticTSObjects[81] = "Debris IDebris1 idb.dts"; -$StaticTSObjects[82] = "Debris MPBDebris1 mpbdb1.dts"; -$StaticTSObjects[83] = "Debris MPBDebris2 mpbdb2.dts"; -$StaticTSObjects[84] = "Debris MPBDebris3 mpbdb3.dts"; -$StaticTSObjects[85] = "Debris MPBDebris4 mpbdb4.dts"; -$StaticTSObjects[86] = "Debris ScoutDebris1 sdb1.dts"; -$StaticTSObjects[87] = "Debris TankDebris1 tdb1.dts"; -$StaticTSObjects[88] = "Debris TankDebris2 tdb2.dts"; -$StaticTSObjects[89] = "Debris TankDebris3 tdb3.dts"; -$StaticTSObjects[90] = "Debris GraveMarker1 gravemarker1.dts"; -$StaticTSObjects[91] = "Test Test1 test1.dts"; -$StaticTSObjects[92] = "Test Test2 test2.dts"; -$StaticTSObjects[93] = "Test Test3 test3.dts"; -$StaticTSObjects[94] = "Test Test4 test4.dts"; -$StaticTSObjects[95] = "Test Test5 test5.dts"; - - - -$NumStaticTSObjects = 96; - -function TSStatic::create(%shapeName) -{ - //echo("Foo:" SPC %shapeName); - %obj = new TSStatic() - { - shapeName = %shapeName; - }; - return(%obj); -} - -function TSStatic::damage(%this) -{ - // prevent console error spam -} - -function stripFields(%this) -{ - if(%this $= "") - %this = MissionGroup; - for (%i = 0; %i < %this.getCount(); %i++){ - %obj = %this.getObject(%i); - if (%obj.getClassName() $= SimGroup) - { - %obj.powerCount = ""; - %obj.team = ""; - stripFields(%obj); - } - else - { - %obj.threshold = ""; - %obj.team = ""; - %obj.powerCount = ""; - %obj.trigger = ""; - %obj.hidden = ""; - %obj.locked = "true"; - %obj.notReady = ""; - %obj.inUse = ""; - %obj.triggeredBy = ""; - %obj.lastDamagedBy = ""; - %obj.lastDamagedByTeam =""; - %obj.isHome = ""; - %obj.originalPosition = ""; - %obj.objectiveCompleted = ""; - %obj.number = ""; - %obj.target = ""; - %obj.lockCount = ""; - %obj.homingCount = ""; - %obj.projector = ""; - %obj.holo = ""; - %obj.waypoint = ""; - %obj.scoreValue =""; - %obj.damageTimeMS = ""; - %obj.station = ""; - %homingCount = ""; - } - } -} +//****************************************************************************** +//* Default StaticShape functions +//****************************************************************************** + +function StaticShapeData::onGainPowerEnabled(%data, %obj) +{ + if(%data.ambientThreadPowered) + %obj.playThread($AmbientThread, "ambient"); + // if it's a deployed object, schedule the power thread; else play it immediately + if(%data.deployAmbientThread) + %obj.schedule(750, "playThread", $PowerThread, "Power"); + else + %obj.playThread($PowerThread,"Power"); + // deployable objects get their recharge rate set right away -- don't set it again unless + // the object has just been re-enabled + if(%obj.initDeploy) + %obj.initDeploy = false; + else + { + if(%obj.getRechargeRate() <= 0) + { + %oldERate = %obj.getRechargeRate(); + %obj.setRechargeRate(%oldERate + %data.rechargeRate); + } + } + if(%data.humSound !$= "") + %obj.playAudio($HumSound, %data.humSound); + %obj.setPoweredState(true); +} + +function StaticShapeData::onLosePowerDisabled(%data, %obj) +{ + %client = %obj.getControllingClient(); + if(%client != 0) + serverCmdResetControlObject(%client); + + if(%data.ambientThreadPowered) + %obj.pauseThread($AmbientThread); + if(!%data.alwaysAmbient) + { + %obj.stopThread($PowerThread); + // MES -- drop shields and stop them from regenerating after power loss + %obj.setRechargeRate(0.0); + %obj.setEnergyLevel(0.0); + } + if(%data.humSound !$= "") + %obj.stopAudio($HumSound); + %obj.setPoweredState(false); +} + +function StaticShapeData::gainPower(%data, %obj) +{ + if(%obj.isEnabled()) + %data.onGainPowerEnabled(%obj); + Parent::gainPower(%data, %obj); +} + +function StaticShapeData::losePower(%data, %obj) +{ + if(%obj.isEnabled()) + %data.onLosePowerDisabled(%obj); + Parent::losePower(%data, %obj); +} + +function ShapeBaseData::onEnabled() +{ +} + +function ShapeBaseData::onDisabled() +{ +} + +function StaticShapeData::onEnabled(%data, %obj, %prevState) +{ + if(%obj.isPowered()) + %data.onGainPowerEnabled(%obj); + Parent::onEnabled(%data, %obj, %prevState); +} + +function StaticShapeData::onDisabled(%data, %obj, %prevState) +{ + if(%obj.isPowered() || (%data.className $= "Generator")) + %data.onLosePowerDisabled(%obj); + Parent::onDisabled(%data, %obj, %prevState); +} + +function StaticShape::deploy(%this) +{ + %this.playThread($DeployThread, "deploy"); +} + +function StaticShapeData::onEndSequence(%data, %obj, %thread) +{ + if(%thread == $DeployThread) + %obj.setSelfPowered(); + Parent::onEndSequence(%data, %obj, %thread); +} + +function ShapeBaseData::onGetHP(%data, %obj) //Get current HP +{ +%db = %obj.getDataBlock().getName(); //%data probably is the same thing, but I trust this more +%maxDMG = %db.maxDamage; +return %maxDMG - %obj.getDamageLevel(); +} + +function ShapeBaseData::onEndSequence() +{ +} + +//****************************************************************************** +//* Example explosion +//****************************************************************************** + +datablock EffectProfile(ShapeExplosionEffect) +{ + effectname = "explosions/explosion.xpl03"; + minDistance = 10; + maxDistance = 50; +}; + +datablock AudioProfile(ShapeExplosionSound) +{ + filename = "fx/explosions/explosion.xpl03.wav"; + description = AudioExplosion3d; + preload = true; + effect = ShapeExplosionEffect; +}; + +datablock ExplosionData(ShapeExplosion) +{ + explosionShape = "disc_explosion.dts"; + soundProfile = ShapeExplosionSound; + faceViewer = true; +}; + +//****************************************************************************** +//* Player Armors - Data Blocks (live players are now StaticTSObjects) +//****************************************************************************** + +datablock StaticShapeData(HeavyMaleHuman_Dead) +{ + className = "deadArmor"; + catagory = "Player Armors"; + shapeFile = "heavy_male_dead.dts"; + isInvincible = true; +}; + +datablock StaticShapeData(MediumMaleHuman_Dead) +{ + className = "deadArmor"; + catagory = "Player Armors"; + shapeFile = "medium_male_dead.dts"; + isInvincible = true; +}; + +datablock StaticShapeData(LightMaleHuman_Dead) +{ + className = "deadArmor"; + catagory = "Player Armors"; + shapeFile = "light_male_dead.dts"; + isInvincible = true; +}; + +function deadArmor::onAdd(%data, %obj) +{ + Parent::onAdd(%data, %obj); +} + +//***************************************************************************** +//* Flagstands - Data Blocks +//***************************************************************************** +datablock StaticShapeData(InteriorFlagStand) +{ + className = "FlagIntStand"; + catagory = "Objectives"; + shapefile = "int_flagstand.dts"; + isInvincible = true; + needsNoPower = true; +}; + +datablock StaticShapeData(ExteriorFlagStand) +{ + className = "FlagIntStand"; + catagory = "Objectives"; + shapefile = "ext_flagstand.dts"; + isInvincible = true; + needsNoPower = true; +}; + +/////////////////////////////////////////// +//flagIntStand::onAdd(%this, %obj) +//%this: objects datablock +//%obj: the actual object being added +/////////////////////////////////////////// + +function ExteriorFlagStand::onAdd(%this, %obj) +{ + Parent::onAdd(%this, %obj); + %obj.playThread($ActivateThread, "activate"); +} + +function ExteriorFlagStand::onFlagTaken(%this, %obj) +{ + %obj.setThreadDir($ActivateThread, 0); +} + +function ExteriorFlagStand::onFlagReturn(%this, %obj) +{ + %obj.setThreadDir($ActivateThread, 1); +} + +function ExteriorFlagStand::onCollision(%this, %obj, %colObj) +{ + game.flagStandCollision(%this, %obj, %colObj); +} + +function InteriorFlagStand::onCollision(%this, %obj, %colObj) +{ + game.flagStandCollision(%this, %obj, %colObj); +} + +/////////////////////////////////////////////// +//end flag stand functions +/////////////////////////////////////////////// + +datablock StaticShapeData(FlipFlop) +{ + catagory = "Objectives"; + shapefile = "switch.dts"; + + isInvincible = true; + cmdCategory = "Objectives"; + cmdIcon = "CMDSwitchIcon"; + cmdMiniIconName = "commander/MiniIcons/com_switch_grey"; + targetTypeTag = 'Switch'; + alwaysAmbient = true; + needsNoPower = true; + emap = true; +}; + +function FlipFlop::onCollision(%data,%obj,%col) +{ + if (%col.getDataBlock().className $= Armor && %col.getState() !$= "Dead") + %data.playerTouch(%obj, %col); +} + +function FlipFlop::playerTouch(%data,%obj,%col) +{ + messageAll('MsgPlayerTouchSwitch', 'Player %1 touched switch %2', %col, %obj); +} + +//****************************************************************************** +//* Organics - * +//****************************************************************************** + +//function to add random Organics to mission pre-creation +//(could be used to add other things...its cool with bioderm armors ;) ) + +function randomOrg(%organicName, %num, %radius) +{ + %SPACING = 1.0; //meters between center of organic and another object + + //return help info + if(%organicName $="" || !%num || !%radius) { + echo("randomOrg(, , );"); + return; + } + + %organicIndex = -1; + // -------------------------------------------------------- + // z0dd - ZOD, 5/8/02. Typo fix. + //for (%i = 0; %i < $NumAStaticTSObjects; %i++) { + for (%i = 0; %i < $NumStaticTSObjects; %i++) { + if (getWord($StaticTSObjects[%i], 1) $= %organicName) { + %organicIndex = %i; + break; + } + } + if (%organicIndex == -1) { + error("There is no static shape named" SPC %organicName); + return; + } + %shapeFileName = getWord($StaticTSObjects[%organicIndex], 2); + + %maxSlope = getWord($StaticTSObjects[%organicIndex], 3); + if (%maxSlope $= "") + %maxSlope = 40; + + %zOffset = getWord($StaticTSObjects[%organicIndex], 4); + if (%zOffset $= "") + %zOffset = 0; + + %slopeWithTerrain = getWord($StaticTSObjects[%organicIndex], 5); + if (%slopeWithTerrain $= "") + %slopeWithTerrain = false; + + %minScale = getWord($StaticTSObjects[%organicIndex], 6); + %maxScale = getWord($StaticTSObjects[%organicIndex], 7); + + //set up folders in mis file + $RandomOrganicsAdded++; //to keep track of groups + if(!isObject(RandomOrganics)) { + %randomOrgGroup = new simGroup(RandomOrganics); + MissionGroup.add(%randomOrgGroup); + } + %groupName = "Addition"@$RandomOrganicsAdded@%organicName; + %group = new simGroup(%groupName); + RandomOrganics.add(%group); + + + %ctr = LocalClientConnection.camera.getPosition(); + %areaX = getWord(%ctr, 0) - %radius; + %areaY = getWord(%ctr, 1) - %radius; + + %orgCount = %num; + while((%orgCount > 0) && (%retries < (15000 / %maxSlope))) //theoretically, a thorough number of retries + { + //find a tile + %x = (getRandom(mFloor(%areaX / 8), mFloor((%areaX + (%radius * 2)) / 8)) * 8) + 4; //tile center + %y = (getRandom(mFloor(%areaY / 8), mFloor((%areaY + (%radius * 2)) / 8)) * 8) + 4; + + %start = %x @ " " @ %y @ " 2000"; + %end = %x @ " " @ %y @ " -1"; + %ground = containerRayCast(%start, %end, $TypeMasks::TerrainObjectType, 0); + %z = getWord(%ground, 3); + %z += %zOffset; + %position = %x @ " " @ %y @ " " @ %z; + + + // get normal from both sides of the square + %start = %x + 2 @ " " @ %y @ " 2000"; + %end = %x + 2 @ " " @ %y @ " -1"; + %hit1 = containerRayCast(%start, %end, $TypeMasks::TerrainObjectType, 0); + + %start = %x - 2 @ " " @ %y @ " 2000"; + %end = %x - 2 @ " " @ %y @ " -1"; + %hit2 = containerRayCast(%start, %end, $TypeMasks::TerrainObjectType, 0); + + %norm1 = getWord(%hit1, 4) @ " " @ getWord(%hit1, 5) @ " " @ getWord(%hit1, 6); + %norm2 = getWord(%hit2, 4) @ " " @ getWord(%hit2, 5) @ " " @ getWord(%hit2, 6); + + //if either side of tile has greater slope than allowed, move on. + %angNorm1 = getTerrainAngle(%norm1); + %angNorm2 = getTerrainAngle(%norm2); + if ((getTerrainAngle(%norm1) > %maxSlope) || (getTerrainAngle(%norm2) > %maxslope)) + { + %retries++; + continue; + } + + %terrainNormal = VectorAdd(%norm1, %norm2); + %terrainNormal = VectorNormalize(%terrainNormal); + + //search surroundings for obstacles. If obstructed, move on. + InitContainerRadiusSearch(%position, %spacing, $TypeMasks::VehicleObjectType | + $TypeMasks::MoveableObjectType | + $TypeMasks::StaticShapeObjectType | + // ----------------------------- + // z0dd - ZOD, 5/8/02. Typo fix. + //$TypeMasks::TSStaticShapeObjectType | + $TypeMasks::StaticTSObjectType | + $TypeMasks::ForceFieldObjectType | + $TypeMasks::TurretObjectType | + $TypeMasks::InteriorObjectType | + $TypeMasks::ItemObjectType); + %this = containerSearchNext(); + if(%this) + { + %retries++; + continue; + } + + + //rotate it + if(%slopeWithTerrain) + { + %rotAxis = vectorCross(%terrainNormal, "0 0 1"); + %rotAxis = vectorNormalize(%rotAxis); + %rotation = %rotAxis @ " " @ getTerrainAngle(%terrainNormal); + } + else %rotation = "1 0 0 0"; + %randomAngle = getRandom(360); + %zrot = MatrixCreate("0 0 0", "0 0 1 " @ %randomAngle); + %orient = MatrixCreate(%position, %rotation); + %finalXForm = MatrixMultiply(%orient, %zrot); + + + //scale it + %scaleMin = 8; //default min + %scaleMax = 14; //default max + if(%minScale) + %scaleMin = %minScale * 10; + if(%maxScale) + %scaleMax = %maxScale * 10; + %scaleInt = getRandom(%scaleMin, %scaleMax); + %scale = %scaleInt/10; + %evenScale = %scale SPC %scale SPC %scale; + + //create it + %position = %x SPC %y SPC (%z += %zoffset); + %newOrganic = new TSStatic() { + position = %position; + rotation = %rotation; + scale = %evenScale; + shapeName = %shapeFileName; + }; + %group.add(%newOrganic); + %newOrganic.setTransform(%finalXForm); + + %orgCount--; //dec number of shapes left to place + %retries = 0; //reset retry counter + } + if (%orgCount > 0) + { + error("Unable to place all shapes, area saturated."); + error("Looking for clear area " @ (%spacing * 2) @ " meters in diameter, with a max slope of " @ %maxSlope); + } + echo("Placed " @ %num - %orgCount @ " of " @ %num); +} + +function getTerrainAngle(%point) +{ + %up = "0 0 1"; + %angleRad = mACos(vectorDot(%point, %up)); + %angleDeg = mRadToDeg(%angleRad); + //echo("angle is "@%angleDeg); + return %angleDeg; +} +function randomGrove(%organicName, %num, %radius) +{ + %minHeight = 0; + %maxHeight = 1000; + %SPACING = 1.5; //meters between center of organic and another object + + //return help info + if(%organicName $="" || !%num || !%radius) { + echo("randomOrg(, [, radius of grove desired]);"); + return; + } + + %organicIndex = -1; + for (%i = 0; %i < $NumStaticTSObjects; %i++) { + if (getWord($StaticTSObjects[%i], 1) $= %organicName) { + %organicIndex = %i; + break; + } + } + if (%organicIndex == -1) { + error("There is no static shape named" SPC %organicName); + return; + } + %shapeFileName = getWord($StaticTSObjects[%organicIndex], 2); + + %maxSlope = getWord($StaticTSObjects[%organicIndex], 3); + if (%maxSlope $= "") + %maxSlope = 40; + + %zOffset = getWord($StaticTSObjects[%organicIndex], 4); + if (%zOffset $= "") + %zOffset = 0; + + %slopeWithTerrain = getWord($StaticTSObjects[%organicIndex], 5); + if (%slopeWithTerrain $= "") + %slopeWithTerrain = false; + + %minScale = getWord($StaticTSObjects[%organicIndex], 6); + %maxScale = getWord($StaticTSObjects[%organicIndex], 7); + + //set up folders in mis file + $RandomOrganicsAdded++; //to keep track of groups + if(!isObject(RandomOrganics)) { + %randomOrgGroup = new simGroup(RandomOrganics); + MissionGroup.add(%randomOrgGroup); + } + %groupName = "Addition"@$RandomOrganicsAdded@%organicName; + %group = new simGroup(%groupName); + RandomOrganics.add(%group); + + + %ctr = LocalClientConnection.camera.getPosition(); + %areaX = getWord(%ctr, 0) - %radius; + %areaY = getWord(%ctr, 1) - %radius; + + %orgCount = %num; + while((%orgCount > 0) && (%retries < (15000 / %maxSlope))) //theoretically, a thorough number of retries + { + //find a tile + %x = (getRandom(mFloor(%areaX / 8), mFloor((%areaX + (%radius * 2)) / 8)) * 8) + 4; //tile center + %y = (getRandom(mFloor(%areaY / 8), mFloor((%areaY + (%radius * 2)) / 8)) * 8) + 4; + + %start = %x @ " " @ %y @ " 2000"; + %end = %x @ " " @ %y @ " -1"; + %ground = containerRayCast(%start, %end, $TypeMasks::TerrainObjectType, 0); + %z = getWord(%ground, 3); + + + // elevation test + if ((%z < %minHeight) || (%z > %maxHeight)) + { + echo("Broke height range rules. Readjust allowable elevations."); + %retries++; + echo("Z is " @ %z); + continue; + } + %z += %zOffset; + %position = %x @ " " @ %y @ " " @ %z; + + + // get normal from both sides of the square + %start = %x + 2 @ " " @ %y @ " 2000"; + %end = %x + 2 @ " " @ %y @ " -1"; + %hit1 = containerRayCast(%start, %end, $TypeMasks::TerrainObjectType, 0); + + %start = %x - 2 @ " " @ %y @ " 2000"; + %end = %x - 2 @ " " @ %y @ " -1"; + %hit2 = containerRayCast(%start, %end, $TypeMasks::TerrainObjectType, 0); + + %norm1 = getWord(%hit1, 4) @ " " @ getWord(%hit1, 5) @ " " @ getWord(%hit1, 6); + %norm2 = getWord(%hit2, 4) @ " " @ getWord(%hit2, 5) @ " " @ getWord(%hit2, 6); + + //if either side of tile has greater slope than allowed, move on. + %angNorm1 = getTerrainAngle(%norm1); + %angNorm2 = getTerrainAngle(%norm2); + if ((getTerrainAngle(%norm1) > %maxSlope) || (getTerrainAngle(%norm2) > %maxslope)) + { + %retries++; + continue; + } + + %terrainNormal = VectorAdd(%norm1, %norm2); + %terrainNormal = VectorNormalize(%terrainNormal); + + //search surroundings for obstacles. If obstructed, move on. + InitContainerRadiusSearch(%position, %spacing, $TypeMasks::VehicleObjectType | + $TypeMasks::MoveableObjectType | + $TypeMasks::StaticShapeObjectType | + // ----------------------------- + // z0dd - ZOD, 5/8/02. Typo fix. + //$TypeMasks::TSStaticShapeObjectType | + $TypeMasks::StaticTSObjectType | + $TypeMasks::ForceFieldObjectType | + $TypeMasks::TurretObjectType | + $TypeMasks::InteriorObjectType | + $TypeMasks::ItemObjectType); + %this = containerSearchNext(); + if(%this) + { + %retries++; + continue; + } + + + //rotate it + if(%slopeWithTerrain) + { + %rotAxis = vectorCross(%terrainNormal, "0 0 1"); + %rotAxis = vectorNormalize(%rotAxis); + %rotation = %rotAxis @ " " @ getTerrainAngle(%terrainNormal); + } + else %rotation = "1 0 0 0"; + %randomAngle = getRandom(360); + %zrot = MatrixCreate("0 0 0", "0 0 1 " @ %randomAngle); + %orient = MatrixCreate(%position, %rotation); + %finalXForm = MatrixMultiply(%orient, %zrot); + + + //scale it + %scaleMin = 8; //default min + %scaleMax = 14; //default max + if(%minScale) + %scaleMin = %minScale * 10; + if(%maxScale) + %scaleMax = %maxScale * 10; + %scaleInt = getRandom(%scaleMin, %scaleMax); + %scale = %scaleInt/10; + %evenScale = %scale SPC %scale SPC %scale; + + //create it + + %position = %x SPC %y SPC (%z += %zoffset); + %newOrganic = new TSStatic() { + position = %position; + rotation = %rotation; + scale = %evenScale; + shapeName = %shapeFileName; + }; + %group.add(%newOrganic); + %newOrganic.setTransform(%finalXForm); + + %orgCount--; //dec number of shapes left to place + %retries = 0; //reset retry counter + } + if (%orgCount > 0) + { + error("Unable to place all shapes, area saturated."); + error("Looking for clear area " @ (%spacing * 2) @ " meters in diameter, with a max slope of " @ %maxSlope); + } + echo("Placed " @ %num - %orgCount @ " of " @ %num); +} + + +function randomRock(%rock, %quantity, %radius, %maxElev) +{ + if (!%radius || !%quantity || !%rock) + { + echo("randomRock(, , , [maximum elevation]"); + return; + } + + if (!%maxElev) + %maxElev = 2000; + + + %rotation[0] = "0 0 1 0"; + %rotation[1] = "0.999378 -0.0145686 -0.0321219 194.406"; + %rotation[2] = "0.496802 0.867682 0.0177913 176.44"; + %rotation[3] = "0.991261 0.0933696 0.0931923 181.867"; + %rotation[4] = "0.246801 0.360329 -0.899584 92.3648"; + %rotation[5] = "1 0 0 82.59"; + %rotation[6] = "0.0546955 -0.629383 0.55201 116.103"; + + %spacing = 4.0; //check 4 meters around object for collisions before placing + %ctr = localClientConnection.camera.getPosition(); + %areaX = getWord(%ctr, 0) - %radius; + %areaY = getWord(%ctr, 1) - %radius; + + $RandomOrganicsAdded++; + if(!isObject(RandomRocks)) { + %randomOrgGroup = new simGroup(RandomRocks); + MissionGroup.add(%randomOrgGroup); + } + %groupName = "Addition"@$RandomOrganicsAdded@%rock; + %group = new simGroup(%groupName); + RandomRocks.add(%group); + + %orgCount = %quantity; + while((%orgCount > 0) && (%retries < (15000 / %maxSlope))) //theoretically, a thorough number of retries + { + //find a tile + %x = %areaX + getRandom(%radius * 2); + %y = %areaY + getRandom(%radius * 2); + + %start = %x @ " " @ %y @ " 2000"; + %end = %x @ " " @ %y @ " -1"; + %ground = containerRayCast(%start, %end, $TypeMasks::TerrainObjectType, 0); + %position = getWord(%ground, 1) @ " " @ getWord(%ground, 2) @ " " @ getWord(%ground, 3); + echo("position =*" @ %position @ "*"); + %z = getWord(%position, 2); + + + // elevation test + if (%z > %maxElev) //65 meters and above only + { + %retries++; + echo("Z is " @ %z); + continue; + } + + + //search surroundings for obstacles. If obstructed, move on. + InitContainerRadiusSearch(%position, %spacing, $TypeMasks::VehicleObjectType | + $TypeMasks::MoveableObjectType | + $TypeMasks::StaticShapeObjectType | + // ----------------------------- + // z0dd - ZOD, 5/8/02. Typo fix. + //$TypeMasks::TSStaticShapeObjectType | + $TypeMasks::StaticTSObjectType | + $TypeMasks::ForceFieldObjectType | + $TypeMasks::TurretObjectType | + $TypeMasks::InteriorObjectType | + $TypeMasks::ItemObjectType); + %this = containerSearchNext(); + if(%this) + { + %retries++; + continue; + } + %primaryRot = %rotation[getRandom(7)]; + + %randomAngle = mDegToRad(getRandom(360)); + %zrot = MatrixCreate("0 0 0", "0 0 1 " @ %randomAngle); + %orient = MatrixCreate(%position, %primaryRot); + + + %scale = getRandom(3); + %evenScale = %scale @ " " @ %scale @ " " @ %scale; + %newRock = new InteriorInstance() { + scale = %evenScale; + interiorFile = %rock @ ".dif"; + showTerrainInside = "0"; + }; + %group.add(%newRock); + %transfrm = MatrixMultiply(%orient, %zrot); + echo("Transform = *" @ %transfrm @ "*"); + %newRock.setTransform(%transfrm); + + %orgCount--; //dec number of shapes left to place + %retries = 0; //reset retry counter + } + if (%orgCount > 0) + { + error("Unable to place all shapes, area saturated."); + error("Looking for clear area " @ (%spacing * 2) @ " meters in diameter, with a max slope of " @ %maxSlope); + } + echo("Placed " @ %num - %orgCount @ " of " @ %num); +} + + +//-------------------------------------------------------------------------- +//-------------------------------------- Organics +//-------------------------------------------------------------------------- + + +//****************************************************************************** +//* Pulse Sensor - Data Blocks * +//****************************************************************************** + +datablock DebrisData( StaticShapeDebris ) +{ + explodeOnMaxBounce = false; + + elasticity = 0.20; + friction = 0.5; + + lifetime = 17.0; + lifetimeVariance = 0.0; + + minSpinSpeed = 60; + maxSpinSpeed = 600; + + numBounces = 10; + bounceVariance = 0; + + staticOnMaxBounce = true; + + useRadiusMass = true; + baseRadius = 0.4; + + velocity = 9.0; + velocityVariance = 4.5; +}; + +datablock DebrisData( SmallShapeDebris ) +{ + explodeOnMaxBounce = false; + + elasticity = 0.20; + friction = 0.5; + + lifetime = 17.0; + lifetimeVariance = 0.0; + + minSpinSpeed = 60; + maxSpinSpeed = 600; + + numBounces = 10; + bounceVariance = 0; + + staticOnMaxBounce = true; + + useRadiusMass = true; + baseRadius = 0.2; + + velocity = 5.0; + velocityVariance = 2.5; +}; + +datablock AudioProfile(SensorHumSound) +{ + filename = "fx/powered/sensor_hum.wav"; + description = CloseLooping3d; + preload = true; +}; + +datablock SensorData(SensorLgPulseObj) +{ + detects = true; + detectsUsingLOS = true; + detectsPassiveJammed = false; + detectsActiveJammed = false; + detectsCloaked = false; + detectionPings = true; + detectRadius = 300; +}; + +datablock StaticShapeData(SensorLargePulse) : StaticShapeDamageProfile +{ + className = Sensor; + catagory = "Sensors"; + shapeFile = "sensor_pulse_large.dts"; + maxDamage = 1.5; + destroyedLevel = 1.5; + disabledLevel = 0.85; + explosion = ShapeExplosion; + expDmgRadius = 10.0; + expDamage = 0.5; + expImpulse = 2000.0; + + dynamicType = $TypeMasks::SensorObjectType; + isShielded = true; + energyPerDamagePoint = 33; + maxEnergy = 110; + rechargeRate = 0.31; + ambientThreadPowered = true; + humSound = SensorHumSound; + + cmdCategory = "Support"; + cmdIcon = CMDSensorIcon; + cmdMiniIconName = "commander/MiniIcons/com_sensor_grey"; + targetNameTag = 'Large'; + targetTypeTag = 'Sensor'; + sensorData = SensorLgPulseObj; + sensorRadius = SensorLgPulseObj.detectRadius; + sensorColor = "255 194 9"; + + debrisShapeName = "debris_generic.dts"; + debris = StaticShapeDebris; +}; + +datablock SensorData(SensorMedPulseObj) +{ + detects = true; + detectsUsingLOS = true; + detectsPassiveJammed = false; + detectsActiveJammed = false; + detectsCloaked = false; + detectionPings = true; + detectRadius = 175; +}; + +datablock StaticShapeData(SensorMediumPulse) : StaticShapeDamageProfile +{ + className = Sensor; + catagory = "Sensors"; + shapeFile = "sensor_pulse_medium.dts"; + maxDamage = 1.2; + destroyedLevel = 1.2; + disabledLevel = 0.68; + explosion = ShapeExplosion; + expDmgRadius = 7.0; + expDamage = 0.4; + expImpulse = 1500; + + dynamicType = $TypeMasks::SensorObjectType; + isShielded = true; + energyPerDamagePoint = 33; + maxEnergy = 90; + rechargeRate = 0.31; + ambientThreadPowered = true; + humSound = SensorHumSound; + + cmdCategory = "Support"; + cmdIcon = CMDSensorIcon; + cmdMiniIconName = "commander/MiniIcons/com_sensor_grey"; + targetNameTag = 'Medium'; + targetTypeTag = 'Sensor'; + sensorData = SensorMedPulseObj; + sensorRadius = SensorMedPulseObj.detectRadius; + sensorColor = "255 194 9"; + + debrisShapeName = "debris_generic.dts"; + debris = StaticShapeDebris; +}; + +function Sensor::onGainPowerEnabled(%data, %obj) +{ + setTargetSensorData(%obj.target, %data.sensorData); + Parent::onGainPowerEnabled(%data, %obj); +} + +function Sensor::onLosePowerDisabled(%data, %obj) +{ + setTargetSensorData(%obj.target, 0); + Parent::onLosePowerDisabled(%data, %obj); +} + +//****************************************************************************** +//* Generator - Data Blocks * +//****************************************************************************** + +datablock AudioProfile(GeneratorHumSound) +{ + filename = "fx/powered/generator_hum.wav"; + description = CloseLooping3d; + preload = true; +}; + + +datablock StaticShapeData(GeneratorLarge) : StaticShapeDamageProfile +{ + className = Generator; + catagory = "Generators"; + shapeFile = "station_generator_large.dts"; + explosion = ShapeExplosion; + maxDamage = 1.5; + destroyedLevel = 1.5; + disabledLevel = 0.85; + expDmgRadius = 10.0; + expDamage = 0.5; + expImpulse = 1500.0; + noIndividualDamage = true; //flag to make these invulnerable for certain mission types + + dynamicType = $TypeMasks::GeneratorObjectType; + isShielded = true; + energyPerDamagePoint = 30; // z0dd - ZOD, 9/27/02. was 30 + maxEnergy = 70; // z0dd - ZOD, 09/20/02. Was 50 + rechargeRate = 0.15; // z0dd - ZOD, 09/20/02. Was 0.05 + humSound = GeneratorHumSound; + + cmdCategory = "Support"; + cmdIcon = "CMDGeneratorIcon"; + cmdMiniIconName = "commander/MiniIcons/com_generator"; + targetTypeTag = 'Generator'; + + debrisShapeName = "debris_generic.dts"; + debris = StaticShapeDebris; +}; + +datablock StaticShapeData(SolarPanel) : StaticShapeDamageProfile +{ + className = Generator; + catagory = "Generators"; + shapeFile = "solarpanel.dts"; + explosion = ShapeExplosion; + maxDamage = 1.00; + destroyedLevel = 1.00; + disabledLevel = 0.55; + expDmgRadius = 5.0; + expDamage = 0.3; + expImpulse = 1000.0; + noIndividualDamage = true; //flag to make these invulnerable for certain mission types + emap = true; + + isShielded = true; + energyPerDamagePoint = 30; + rechargeRate = 0.1; // z0dd - ZOD, 09/20/02. Was 0.05 + + dynamicType = $TypeMasks::GeneratorObjectType; + maxEnergy = 30; + humSound = GeneratorHumSound; + + cmdCategory = "Support"; + cmdIcon = CMDSolarGeneratorIcon; + cmdMiniIconName = "commander/MiniIcons/com_solargen_grey"; + targetTypeTag = 'Solar Panel'; + + debrisShapeName = "debris_generic.dts"; + debris = StaticShapeDebris; +}; + +function Generator::onDisabled(%data, %obj, %prevState) +{ + %obj.decPowerCount(); + Parent::onDisabled(%data, %obj, %prevState); +} + +function Generator::onEnabled(%data, %obj, %prevState) +{ + %obj.incPowerCount(); + Parent::onEnabled(%data, %obj, %prevState); +} + +//****************************************************************************** +//Nexus Effect (Hunters) +//****************************************************************************** + +datablock StaticShapeData(Nexus_Effect) +{ + catagory = "Objectives"; + shapefile = "nexus_effect.dts"; + mass = 10; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 2; +}; + + +datablock StaticShapeData(NexusBase) +{ + catagory = "Objectives"; + shapefile = "Nexusbase.dts"; + mass = 10; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 2; +}; + + +datablock StaticShapeData(NexusCap) +{ + catagory = "Objectives"; + shapefile = "Nexuscap.dts"; + mass = 10; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 2; +}; + +//****************************************************************************** +//* Static Shape - Functions * +//****************************************************************************** + +function StaticShapeData::create(%block) +{ + %obj = new StaticShape() + { + dataBlock = %block; + }; + return(%obj); +} + +function ShapeBase::damage(%this, %sourceObject, %position, %amount, %damageType) +{ + %this.getDataBlock().damageObject(%this, %sourceObject, %position, %amount, %damageType); +} + +function ShapeBaseData::damageObject(%data, %targetObject, %position, %sourceObject, %amount, %damageType) +{ + +} + +function ShapeBaseData::onDestroyed(%data, %obj, %prevState) +{ + +} + +function ShapeBaseData::checkShields(%data, %targetObject, %position, %amount, %damageType) +{ + %energy = %targetObject.getEnergyLevel(); + %strength = %energy / %data.energyPerDamagePoint; + %shieldScale = %data.shieldDamageScale[%damageType]; + if(%shieldScale $= "") + %shieldScale = 1; + + if (%amount * %shieldScale <= %strength) { + // Shield absorbs all + %lost = %amount * %shieldScale * %data.energyPerDamagePoint; + %energy -= %lost; + %targetObject.setEnergyLevel(%energy); + + %normal = "0.0 0.0 1.0"; + %targetObject.playShieldEffect( %normal ); + + return 0; + } + // Shield exhausted + %targetObject.setEnergyLevel(0); + return %amount - %strength / %shieldScale; +} + +function StaticShapeData::damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType) +{ + // if this is a non-team mission type and the object is "protected", don't damage it + if(%data.noIndividualDamage && Game.allowsProtectedStatics()) + return; + + // if this is a Siege mission and this object shouldn't take damage (e.g. vehicle stations) + if(%data.noDamageInSiege && Game.class $= "SiegeGame") + return; + + if(%sourceObject && %targetObject.isEnabled()) + { + if(%sourceObject.client) + { + %targetObject.lastDamagedBy = %sourceObject.client; + %targetObject.lastDamagedByTeam = %sourceObject.client.team; + %targetObject.damageTimeMS = GetSimTime(); + } + else + { + %targetObject.lastDamagedBy = %sourceObject; + %targetObject.lastDamagedByTeam = %sourceObject.team; + %targetObject.damageTimeMS = GetSimTime(); + } + } + + // Scale damage type & include shield calculations... + if (%data.isShielded) + %amount = %data.checkShields(%targetObject, %position, %amount, %damageType); + + %damageScale = %data.damageScale[%damageType]; + if(%damageScale !$= "") + %amount *= %damageScale; + + //if team damage is off, cap the amount of damage so as not to disable the object... + if (!$TeamDamage && !%targetObject.getDataBlock().deployedObject) + { + // ------------------------------------- + // z0dd - ZOD, 6/24/02. Console spam fix + if(isObject(%sourceObject)) + { + //see if the object is being shot by a friendly + if(%sourceObject.getDataBlock().catagory $= "Vehicles") + %attackerTeam = getVehicleAttackerTeam(%sourceObject); + else + %attackerTeam = %sourceObject.team; + } + if ((%targetObject.getTarget() != -1) && isTargetFriendly(%targetObject.getTarget(), %attackerTeam)) + { + %curDamage = %targetObject.getDamageLevel(); + %availableDamage = %targetObject.getDataBlock().disabledLevel - %curDamage - 0.05; + if (%amount > %availableDamage) + %amount = %availableDamage; + } + } + + // if there's still damage to apply + if (%amount > 0) + %targetObject.applyDamage(%amount); +} + +// little special casing for the above function +function getVehicleAttackerTeam(%vehicleId) +{ + %name = %vehicleId.getDataBlock().getName(); + if(%name $= "BomberFlyer" || %name $= "AssaultVehicle") + %gunner = %vehicleId.getMountNodeObject(1); + else + %gunner = %vehicleId.getMountNodeObject(0); + + if(%gunner) + return %gunner.team; + + return %vehicleId.team; +} + + +function StaticShapeData::onDamage(%this,%obj) +{ + // Set damage state based on current damage level + %damage = %obj.getDamageLevel(); + if(%damage >= %this.destroyedLevel) + { + if(%obj.getDamageState() !$= "Destroyed") + { + %obj.setDamageState(Destroyed); + // if object has an explosion damage radius associated with it, apply explosion damage + if(%this.expDmgRadius) + RadiusExplosion(%obj, %obj.getWorldBoxCenter(), %this.expDmgRadius, %this.expDamage, %this.expImpulse, %obj, $DamageType::Explosion); + %obj.setDamageLevel(%this.maxDamage); + } + } + else + { + if(%damage >= %this.disabledLevel) + { + if(%obj.getDamageState() !$= "Disabled") + %obj.setDamageState(Disabled); + } + else + { + if(%obj.getDamageState() !$= "Enabled") + %obj.setDamageState(Enabled); + } + } +} + +// -------------------------------------------------------------------- +// Team logos - only the logo projector should be placed in a mission + +datablock StaticShapeData(BaseLogo) //storm logo +{ + className = Logo; + shapeFile = "teamlogo_storm.dts"; + alwaysAmbient = true; +}; + +datablock StaticShapeData(BaseBLogo) //Inferno Logo +{ + className = Logo; + shapeFile = "teamlogo_inf.dts"; + alwaysAmbient = true; +}; + +datablock StaticShapeData(BiodermLogo) +{ + className = Logo; + shapeFile = "teamlogo_bd.dts"; + alwaysAmbient = true; +}; + +datablock StaticShapeData(BEagleLogo) +{ + className = Logo; + shapeFile = "teamlogo_be.dts"; + alwaysAmbient = true; +}; + +datablock StaticShapeData(DSwordLogo) +{ + className = Logo; + shapeFile = "teamlogo_ds.dts"; + alwaysAmbient = true; +}; + +datablock StaticShapeData(COTPLogo) +{ + className = Logo; + shapeFile = "teamlogo_hb.dts"; + alwaysAmbient = true; +}; + +datablock StaticShapeData(SwolfLogo) +{ + className = Logo; + shapeFile = "teamlogo_sw.dts"; + alwaysAmbient = true; +}; + +datablock StaticShapeData(LogoProjector) +{ + className = Projector; + catagory = "Objectives"; + shapeFile = "teamlogo_projector.dts"; + alwaysAmbient = true; + isInvincible = true; +}; + +function Projector::onAdd(%data, %obj) +{ + Parent::onAdd(%data, %obj); + %obj.holo = 0; +} + +//////////////////////////////////////////// +// Tapestries +/////////////////////////////////////////// +datablock StaticShapeData(Banner_Honor) +{ + catagory = "Eyecandy"; + shapefile = "banner_honor.dts"; +}; + +datablock StaticShapeData(Banner_Strength) +{ + catagory = "Eyecandy"; + shapefile = "banner_strength.dts"; +}; + +datablock StaticShapeData(Banner_Unity) +{ + catagory = "Eyecandy"; + shapefile = "banner_unity.dts"; +}; + +//////////////////////////////////////////////////////////////////////////////// +// + +//-------------------------------------------------------------------------- +// Totally static objects +// The format of these strings are: +// 0: Catagory +// 1: Name +// 2: File +// 3: MaxSlope [ only used with the randomOrg function ] +// 4: ZOffset [ only used with the randomOrg function ] +// 5: slopeWithTerrain [ only used with the randomOrg function ] +// 6: minScale [ only used with the randomOrg function ] +// 7: maxScale [ only used with the randomOrg function ] + + +$StaticTSObjects[0] = "Organics BiodermPlant3 xorg3.dts"; +$StaticTSObjects[1] = "Organics BiodermPlant4 xorg4.dts"; +$StaticTSObjects[2] = "Organics BiodermPlant5 xorg5.dts"; +$StaticTSObjects[3] = "Organics BiodermPlant20 xorg20.dts"; +$StaticTSObjects[4] = "Organics BiodermPlant21 xorg21.dts"; +$StaticTSObjects[5] = "Organics BiodermPlant22 xorg22.dts"; + +$StaticTSObjects[6] = "Organics BEPlant1 borg1.dts 40 0.35 1 0.5 2"; +$StaticTSObjects[7] = "Organics BEPlant5 borg5.dts 40 0.0 1 1 1.5"; +$StaticTSObjects[8] = "Organics BEPlant6 borg6.dts"; +$StaticTSObjects[9] = "Organics BEPlant7 borg7.dts"; + +$StaticTSObjects[10] = "Organics BEPlant12 borg12.dts"; +$StaticTSObjects[11] = "Organics BEPlant13 borg13.dts"; +$StaticTSObjects[12] = "Organics BELgTree16 borg16.dts 20 -3.0 0 0.8 1.5"; +$StaticTSObjects[13] = "Organics BESmTree17 borg17.dts 20 -3.0 1 0.8 1.5"; +$StaticTSObjects[14] = "Organics BELgTree18 borg18.dts 20 -3.0 0 0.8 1.5"; +$StaticTSObjects[15] = "Organics BELgTree19 borg19.dts 20 -3.0 0 0.8 1.5"; +$StaticTSObjects[16] = "Organics BEPlant20 borg20.dts"; + +$StaticTSObjects[17] = "Organics BEPlant23 borg23.dts"; +$StaticTSObjects[18] = "Organics BEPlant25 borg25.dts"; + +$StaticTSObjects[19] = "Organics BEPlant31 borg31.dts"; +$StaticTSObjects[20] = "Organics BEPlant32 borg32.dts"; +$StaticTSObjects[21] = "Organics BEPlant33 borg33.dts"; +$StaticTSObjects[22] = "Organics BEPlant34 borg34.dts"; + +$StaticTSObjects[23] = "Organics PhoenixPlant1 porg1.dts"; +$StaticTSObjects[24] = "Organics PhoenixPlant2 porg2.dts"; +$StaticTSObjects[25] = "Organics PhoenixPlant3 porg3.dts"; +$StaticTSObjects[26] = "Organics PhoenixPlant5 porg5.dts 25 -0.2 1 0.6 1.0"; +$StaticTSObjects[27] = "Organics PhoenixPlant6 porg6.dts"; +$StaticTSObjects[28] = "Organics PhoenixPlant20 porg20.dts"; + +$StaticTSObjects[29] = "Organics PhoenixPlant22 porg22.dts 25 0.1 1 0.8 1.4"; +$StaticTSObjects[30] = "Organics SWTree20 sorg20.dts"; +$StaticTSObjects[31] = "Organics SWShrub21 sorg21.dts"; +$StaticTSObjects[32] = "Organics SWTree22 sorg22.dts"; +$StaticTSObjects[33] = "Organics SWShrub23 sorg23.dts"; +$StaticTSObjects[34] = "Organics SWShrub24 sorg24.dts"; +$StaticTSObjects[35] = "Stackables Crate1 stackable1l.dts"; +$StaticTSObjects[36] = "Stackables Crate2 stackable1m.dts"; +$StaticTSObjects[37] = "Stackables Crate3 stackable1s.dts"; +$StaticTSObjects[38] = "Stackables Crate4 stackable2l.dts"; +$StaticTSObjects[39] = "Stackables Crate5 stackable2m.dts"; +$StaticTSObjects[40] = "Stackables Crate6 stackable2s.dts"; +$StaticTSObjects[41] = "Stackables Crate7 stackable3l.dts"; +$StaticTSObjects[42] = "Stackables Crate8 stackable3m.dts"; +$StaticTSObjects[43] = "Stackables Crate9 stackable3s.dts"; +$StaticTSObjects[44] = "Stackables Crate10 stackable4l.dts"; +$StaticTSObjects[45] = "Stackables Crate11 stackable4m.dts"; +$StaticTSObjects[46] = "Stackables Crate12 stackable5l.dts"; +$StaticTSObjects[47] = "Debris ScoutWreckageShape vehicle_air_scout_wreck.dts"; +$StaticTSObjects[48] = "Debris TankWreckageShape vehicle_land_assault_wreck.dts"; +$StaticTSObjects[49] = "Organics DSPlant16 dorg16.dts 20 -3.0 0 0.8 1.5"; +$StaticTSObjects[50] = "Organics DSPlant17 dorg17.dts 20 -3.0 1 0.8 1.5"; +$StaticTSObjects[51] = "Organics DSPlant18 dorg18.dts 20 -3.0 0 0.8 1.5"; +$StaticTSObjects[52] = "Organics DSPlant19 dorg19.dts 20 -3.0 0 0.8 1.5"; + +$StaticTSObjects[53] = "PlayerArmors LightMaleHumanArmorImage light_male.dts"; +$StaticTSObjects[54] = "PlayerArmors MediumMaleHumanArmorImage medium_male.dts"; +$StaticTSObjects[55] = "PlayerArmors HeavyMaleHumanArmorImage heavy_male.dts"; +$StaticTSObjects[56] = "PlayerArmors LightFemaleHumanArmorImage light_female.dts"; +$StaticTSObjects[57] = "PlayerArmors MediumFemaleHumanArmorImage medium_female.dts"; +$StaticTSObjects[58] = "PlayerArmors HeavyFemaleHumanArmorImage heavy_male.dts"; +$StaticTSObjects[59] = "PlayerArmors LightMaleBiodermArmorImage bioderm_light.dts"; +$StaticTSObjects[60] = "PlayerArmors MediumMaleBiodermArmorImage bioderm_medium.dts"; +$StaticTSObjects[61] = "PlayerArmors HeavyMaleBiodermArmorImage bioderm_heavy.dts"; + +$StaticTSObjects[62] = "Organics BEGrass1 Borg6.dts"; + +$StaticTSObjects[63] = "Plugs bePlug bmiscf.dts"; +$StaticTSObjects[64] = "Plugs dsPlug dmiscf.dts"; +$StaticTSObjects[65] = "Plugs xPlug xmiscf.dts"; +$StaticTSObjects[66] = "Plugs hPlug pmiscf.dts"; +$StaticTSObjects[67] = "Plugs swPlug smiscf.dts"; + +$StaticTSObjects[68] = "Statues Base statue_base.dts"; +$StaticTSObjects[69] = "Statues HeavyMaleStatue statue_hmale.dts"; +$StaticTSObjects[70] = "Statues LightFemaleStatue statue_lfemale.dts"; +$StaticTSObjects[71] = "Statues LightMaleStatue statue_lmale.dts"; +$StaticTSObjects[72] = "Statues Plaque statue_plaque.dts"; + +$StaticTSObjects[73] = "Debris BomberDebris1 bdb1.dts"; +$StaticTSObjects[74] = "Debris BomberDebris2 bdb2.dts"; +$StaticTSObjects[75] = "Debris BomberDebris3 bdb3.dts"; +$StaticTSObjects[76] = "Debris BomberDebris4 bdb4.dts"; +$StaticTSObjects[77] = "Debris BomberDebris5 bdb5.dts"; +$StaticTSObjects[78] = "Debris HavocDebris1 hdb1.dts"; +$StaticTSObjects[79] = "Debris HavocDebris2 hdb2.dts"; +$StaticTSObjects[80] = "Debris HavocDebris3 hdb3.dts"; +$StaticTSObjects[81] = "Debris IDebris1 idb.dts"; +$StaticTSObjects[82] = "Debris MPBDebris1 mpbdb1.dts"; +$StaticTSObjects[83] = "Debris MPBDebris2 mpbdb2.dts"; +$StaticTSObjects[84] = "Debris MPBDebris3 mpbdb3.dts"; +$StaticTSObjects[85] = "Debris MPBDebris4 mpbdb4.dts"; +$StaticTSObjects[86] = "Debris ScoutDebris1 sdb1.dts"; +$StaticTSObjects[87] = "Debris TankDebris1 tdb1.dts"; +$StaticTSObjects[88] = "Debris TankDebris2 tdb2.dts"; +$StaticTSObjects[89] = "Debris TankDebris3 tdb3.dts"; +$StaticTSObjects[90] = "Debris GraveMarker1 gravemarker1.dts"; +$StaticTSObjects[91] = "Test Test1 test1.dts"; +$StaticTSObjects[92] = "Test Test2 test2.dts"; +$StaticTSObjects[93] = "Test Test3 test3.dts"; +$StaticTSObjects[94] = "Test Test4 test4.dts"; +$StaticTSObjects[95] = "Test Test5 test5.dts"; + + + +$NumStaticTSObjects = 96; + +function TSStatic::create(%shapeName) +{ + //echo("Foo:" SPC %shapeName); + %obj = new TSStatic() + { + shapeName = %shapeName; + }; + return(%obj); +} + +function TSStatic::damage(%this) +{ + // prevent console error spam +} + +function stripFields(%this) +{ + if(%this $= "") + %this = MissionGroup; + for (%i = 0; %i < %this.getCount(); %i++){ + %obj = %this.getObject(%i); + if (%obj.getClassName() $= SimGroup) + { + %obj.powerCount = ""; + %obj.team = ""; + stripFields(%obj); + } + else + { + %obj.threshold = ""; + %obj.team = ""; + %obj.powerCount = ""; + %obj.trigger = ""; + %obj.hidden = ""; + %obj.locked = "true"; + %obj.notReady = ""; + %obj.inUse = ""; + %obj.triggeredBy = ""; + %obj.lastDamagedBy = ""; + %obj.lastDamagedByTeam =""; + %obj.isHome = ""; + %obj.originalPosition = ""; + %obj.objectiveCompleted = ""; + %obj.number = ""; + %obj.target = ""; + %obj.lockCount = ""; + %obj.homingCount = ""; + %obj.projector = ""; + %obj.holo = ""; + %obj.waypoint = ""; + %obj.scoreValue =""; + %obj.damageTimeMS = ""; + %obj.station = ""; + %homingCount = ""; + } + } +} diff --git a/scripts/station.cs b/scripts/station.cs index b0693b9..25fef43 100644 --- a/scripts/station.cs +++ b/scripts/station.cs @@ -1,1159 +1,1159 @@ -//****************************************************************************** -//* Station - Data Blocks * -//****************************************************************************** -datablock EffectProfile(StationInventoryActivateEffect) -{ - effectname = "powered/inv_pad_on"; - minDistance = 5.0; - maxDistance = 7.5; -}; - -datablock EffectProfile(StationVehicleActivateEffect) -{ - effectname = "powered/vehicle_screen_on2"; - minDistance = 3.0; - maxDistance = 5.0; -}; - -datablock EffectProfile(StationVehicleDeactivateEffect) -{ - effectname = "powered/vehicle_screen_off"; - minDistance = 3.0; - maxDistance = 5.0; -}; - -//datablock EffectProfile(MobileBaseInventoryActivateEffect) -//{ -// effectname = "misc/diagnostic_on"; -// minDistance = 3.0; -//}; - -datablock EffectProfile(StationAccessDeniedEffect) -{ - effectname = "powered/station_denied"; - minDistance = 3.0; - maxDistance = 5.0; -}; - -datablock AudioProfile(StationInventoryActivateSound) -{ - filename = "fx/powered/inv_pad_on.wav"; - description = AudioClose3d; - preload = true; - effect = StationInventoryActivateEffect; -}; - -datablock AudioProfile(MobileBaseInventoryActivateSound) -{ - filename = "fx/vehicles/mpb_inv_station.wav"; - description = AudioClose3d; - preload = true; - effect = StationInventoryActivateEffect; -}; - -datablock AudioProfile(DepInvActivateSound) -{ - filename = "fx/powered/dep_inv_station.wav"; - description = AudioClose3d; - preload = true; - effect = StationInventoryActivateEffect; -}; - -datablock AudioProfile(StationVehicleActivateSound) -{ - filename = "fx/powered/vehicle_screen_on2.wav"; - description = AudioClosest3d; - preload = true; - effect = StationVehicleActivateEffect; -}; - -datablock AudioProfile(StationVehicleDeactivateSound) -{ - filename = "fx/powered/vehicle_screen_off.wav"; - description = AudioClose3d; - preload = true; - effect = StationVehicleDeactivateEffect; -}; - -datablock AudioProfile(StationAccessDeniedSound) -{ - filename = "fx/powered/station_denied.wav"; - description = AudioClosest3d; - preload = true; - effect = StationAccessDeniedEffect; -}; - -datablock AudioProfile(StationVehicleHumSound) -{ - filename = "fx/powered/station_hum.wav"; - description = CloseLooping3d; - preload = true; -}; - -datablock AudioProfile(StationInventoryHumSound) -{ - filename = "fx/powered/station_hum.wav"; - description = CloseLooping3d; - preload = true; -}; - -datablock StationFXPersonalData( PersonalInvFX ) -{ - delay = 0; - fadeDelay = 0.5; - lifetime = 1.2; - height = 2.5; - numArcSegments = 10.0; - numDegrees = 180.0; - trailFadeTime = 0.5; - leftRadius = 1.85; - rightRadius = 1.85; - leftNodeName = "FX1"; - rightNodeName = "FX2"; - - texture[0] = "special/stationLight"; -}; - - -datablock DebrisData( StationDebris ) -{ - explodeOnMaxBounce = false; - - elasticity = 0.40; - friction = 0.5; - - lifetime = 17.0; - lifetimeVariance = 0.0; - - minSpinSpeed = 60; - maxSpinSpeed = 600; - - numBounces = 10; - bounceVariance = 0; - - staticOnMaxBounce = true; - - useRadiusMass = true; - baseRadius = 0.4; - - velocity = 9.0; - velocityVariance = 4.5; - -}; - -datablock StaticShapeData(StationInventory) : StaticShapeDamageProfile -{ - className = Station; - catagory = "Stations"; - shapeFile = "station_inv_human.dts"; - maxDamage = 1.00; - destroyedLevel = 1.00; - disabledLevel = 0.70; - explosion = ShapeExplosion; - expDmgRadius = 8.0; - expDamage = 0.4; - expImpulse = 1500.0; - // don't allow this object to be damaged in non-team-based - // mission types (DM, Rabbit, Bounty, Hunters) - noIndividualDamage = true; - - dynamicType = $TypeMasks::StationObjectType; - isShielded = true; - energyPerDamagePoint = 75; - maxEnergy = 50; - rechargeRate = 0.35; - doesRepair = true; - humSound = StationInventoryHumSound; - - cmdCategory = "Support"; - cmdIcon = CMDStationIcon; - cmdMiniIconName = "commander/MiniIcons/com_inventory_grey"; - targetNameTag = 'Inventory'; - targetTypeTag = 'Station'; - - debrisShapeName = "debris_generic.dts"; - debris = StationDebris; -}; - -datablock StaticShapeData(StationAmmo) : StaticShapeDamageProfile -{ - className = Station; - catagory = "Stations"; -// shapeFile = "station_ammo.dts"; - shapeFile = "station_inv_human.dts"; - maxDamage = 1.00; - destroyedLevel = 1.00; - disabledLevel = 0.70; - explosion = ShapeExplosion; - expDmgRadius = 8.0; - expDamage = 0.4; - expImpulse = 1500.0; - // don't allow this object to be damaged in non-team-based - // mission types (DM, Rabbit, Bounty, Hunters) - noIndividualDamage = true; - - dynamicType = $TypeMasks::StationObjectType; - isShielded = true; - energyPerDamagePoint = 75; - maxEnergy = 50; - rechargeRate = 0.35; - doesRepair = true; - humSound = StationInventoryHumSound; - - cmdCategory = "Support"; - cmdIcon = CMDStationIcon; - cmdMiniIconName = "commander/MiniIcons/com_inventory_grey"; - targetNameTag = 'Ammo'; - targetTypeTag = 'Station'; - - debrisShapeName = "debris_generic.dts"; - debris = StationDebris; -}; - -datablock StaticShapeData(StationVehicle) : StaticShapeDamageProfile -{ - className = Station; - catagory = "Stations"; - shapeFile = "vehicle_pad_station.dts"; - maxDamage = 1.20; - destroyedLevel = 1.20; - disabledLevel = 0.84; - explosion = ShapeExplosion; - expDmgRadius = 10.0; - expDamage = 0.4; - expImpulse = 1500.0; - dynamicType = $TypeMasks::StationObjectType; - isShielded = true; - energyPerDamagePoint = 33; - maxEnergy = 250; - rechargeRate = 0.31; - humSound = StationVehicleHumSound; - // don't let these be damaged in Siege missions - noDamageInSiege = true; - - cmdCategory = "Support"; - cmdIcon = CMDVehicleStationIcon; - cmdMiniIconName = "commander/MiniIcons/com_vehicle_pad_inventory"; - targetTypeTag = 'Vehicle Station'; - - debrisShapeName = "debris_generic.dts"; - debris = StationDebris; -}; - -datablock StaticShapeData(StationVehiclePad) -{ - className = Station; - catagory = "Stations"; - shapeFile = "vehicle_pad.dts"; - isInvincible = true; - dynamicType = $TypeMasks::StaticObjectType; - rechargeRate = 0.05; - - targetTypeTag = 'Vehicle Pad'; // z0dd - ZOD, 4/20/02. Bug fix, need this var. -}; - -//datablock StaticShapeData(StationAmmo) -//{ -// className = Station; -// catagory = "Stations"; -// shapeFile = "station_ammo.dts"; -// maxDamage = 1.0; -// disabledLevel = 0.6; -// destroyedLevel = 0.8; -// icon = "CMDStationIcon"; -// dynamicType = $TypeMasks::StationObjectType; -//}; - -datablock StaticShapeData(MobileInvStation) -{ - className = Station; - catagory = "Stations"; - shapeFile = "station_inv_mpb.dts"; - icon = "CMDStationIcon"; - // don't allow this object to be damaged in non-team-based - // mission types (DM, Rabbit, Bounty, Hunters) - noIndividualDamage = true; - - dynamicType = $TypeMasks::StationObjectType; - rechargeRate = 0.256; - doesRepair = true; -}; - - -//****************************************************************************** -//* Station - Functions * -//****************************************************************************** - -//////////////////////////////////////////////////////////////////////////////// -/// -Inventory- //////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// - -/// -Inventory- //////////////////////////////////////////////////////////////// -//Function -- onAdd (%this, %obj) -// %this = Object data block -// %obj = Object being added -//Decription -- Called when the object is added to the mission -//////////////////////////////////////////////////////////////////////////////// -function StationInventory::onAdd(%this, %obj) -{ - Parent::onAdd(%this, %obj); - - %obj.setRechargeRate(%obj.getDatablock().rechargeRate); - %trigger = new Trigger() - { - dataBlock = stationTrigger; - polyhedron = "-0.75 0.75 0.1 1.5 0.0 0.0 0.0 -1.5 0.0 0.0 0.0 2.3"; - }; - MissionCleanup.add(%trigger); - %trigger.setTransform(%obj.getTransform()); - - %trigger.station = %obj; - %trigger.mainObj = %obj; - %trigger.disableObj = %obj; - %obj.trigger = %trigger; -} - -/// -Inventory- //////////////////////////////////////////////////////////////// -//Function -- stationReady(%data, %obj) -// %data = Station Data Block -// %obj = Station Object -//Decription -- Called when station has been triggered and animation is -// completed -//////////////////////////////////////////////////////////////////////////////// -function StationInventory::stationReady(%data, %obj) -{ - //Display the Inventory Station GUI here - %obj.notReady = 1; - %obj.inUse = "Down"; - %obj.schedule(500,"playThread",$ActivateThread,"activate1"); - %player = %obj.triggeredBy; - %energy = %player.getEnergyLevel(); - %max = %player.getDatablock().maxEnergy; // z0dd - ZOD, 4/20/02. Inv energy bug fix - %player.setCloaked(true); - %player.schedule(500, "setCloaked", false); - if (!%player.client.isAIControlled()) - buyFavorites(%player.client); - - %player.setEnergyLevel(mFloor(%player.getDatablock().maxEnergy * %energy / %max)); // z0dd - ZOD, 4/20/02. Inv energy bug fix - - %data.schedule( 500, "beginPersonalInvEffect", %obj ); -} - -function StationInventory::beginPersonalInvEffect( %data, %obj ) -{ - if (!%obj.isDisabled()) - { - %fx = new StationFXPersonal() - { - dataBlock = PersonalInvFX; - stationObject = %obj; - }; - } -} - -/// -Inventory- //////////////////////////////////////////////////////////////// -//Function -- stationFinished(%data, %obj) -// %data = Station Data Block -// %obj = Station Object -//Decription -- Called when player has left the station -//////////////////////////////////////////////////////////////////////////////// -function StationInventory::stationFinished(%data, %obj) -{ - //Hide the Inventory Station GUI -} - -/// -Inventory- //////////////////////////////////////////////////////////////// -//Function -- getSound(%data, %forward) -// %data = Station Data Block -// %forward = direction the animation is playing -//Decription -- This sound will be played at the same time as the activate -// animation. -//////////////////////////////////////////////////////////////////////////////// -function StationInventory::getSound(%data, %forward) -{ - if(%forward) - return "StationInventoryActivateSound"; - else - return false; -} - -/// -Inventory- //////////////////////////////////////////////////////////////// -//Function -- setPlayerPosition(%data, %obj, %trigger, %colObj) -// %data = Station Data Block -// %obj = Station Object -// %trigger = Stations trigger -// %colObj = Object that is at the station -//Decription -- Called when player enters the trigger. Used to set the player -// in the center of the station. -//////////////////////////////////////////////////////////////////////////////// -function StationInventory::setPlayersPosition(%data, %obj, %trigger, %colObj) -{ - %vel = getWords(%colObj.getVelocity(), 0, 1) @ " 0"; - if((VectorLen(%vel) < 22) && (%obj.triggeredBy != %colObj)) - { - %pos = %trigger.position; - %colObj.setvelocity("0 0 0"); - %rot = getWords(%colObj.getTransform(),3, 6); - %colObj.setTransform(getWord(%pos,0) @ " " @ getWord(%pos,1) @ " " @ getWord(%pos,2) + 0.8 @ " " @ %rot);//center player on object - %colObj.setMoveState(true); - %colObj.schedule(1600,"setMoveState", false); - %colObj.setvelocity("0 0 0"); - return true; - } - return false; -} - - -/////////////////////////////////////////////////////////////////////////////// -/// -Ammo- //////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - -function StationAmmo::onAdd(%this, %obj) -{ - Parent::onAdd(%this, %obj); - - %obj.setRechargeRate(%obj.getDatablock().rechargeRate); - %trigger = new Trigger() - { - dataBlock = stationTrigger; - polyhedron = "-0.75 0.75 0.1 1.5 0.0 0.0 0.0 -1.5 0.0 0.0 0.0 2.3"; - }; - MissionCleanup.add(%trigger); - %trigger.setTransform(%obj.getTransform()); - - %trigger.station = %obj; - %trigger.mainObj = %obj; - %trigger.disableObj = %obj; - %obj.trigger = %trigger; -} - -//------------------------------------------------------------------------------- -function StationAmmo::stationReady(%data, %obj) -{ - //error("StationAmmo::stationReady"); - %obj.notReady = 1; - %obj.inUse = "Down"; - %obj.setThreadDir($ActivateThread, true); - %obj.schedule(100, "playThread", $ActivateThread, "activate1"); - %player = %obj.triggeredBy; - %energy = %player.getEnergyLevel(); - //%player.setCloaked(true); - //%player.schedule(500, "setCloaked", false); - - - if (!%player.client.isAIControlled()) - getAmmoStationLovin(%player.client); - //%data.schedule( 500, "beginPersonalInvEffect", %obj ); -} - -//------------------------------------------------------------------------------- -function StationAmmo::onEndSequence(%data, %obj, %thread) -{ - if(%thread == $ActivateThread) - { - %obj.setThreadDir($ActivateThread, false); - %obj.playThread( $ActivateThread, "activate1"); - if(%obj.inUse $= "Up") - { - %data.stationReady(%obj); - %player = %obj.triggeredBy; - if(%data.doesRepair && !%player.stationRepairing && %player.getDamageLevel() != 0) { - %oldRate = %player.getRepairRate(); - %player.setRepairRate(%oldRate + 0.00625); - %player.stationRepairing = 1; - } - } - } - //Parent::onEndSequence(%data, %obj, %thread); -} - -//------------------------------------------------------------------------------- -function StationAmmo::stationFinished(%data, %obj) -{ - //Hide the Inventory Station GUI -} - -//------------------------------------------------------------------------------- -function StationAmmo::getSound(%data, %forward) -{ - if(%forward) - return "StationInventoryActivateSound"; - else - return false; -} - -//------------------------------------------------------------------------------- -function StationAmmo::setPlayersPosition(%data, %obj, %trigger, %colObj) -{ - %vel = getWords(%colObj.getVelocity(), 0, 1) @ " 0"; - if((VectorLen(%vel) < 22) && (%obj.triggeredBy != %colObj)) - { - %pos = %trigger.position; - %colObj.setvelocity("0 0 0"); - %rot = getWords(%colObj.getTransform(),3, 6); - %colObj.setTransform(getWord(%pos,0) @ " " @ getWord(%pos,1) @ " " @ getWord(%pos,2) + 0.8 @ " " @ %rot);//center player on object - %colObj.setMoveState(true); - %colObj.schedule(1600,"setMoveState", false); - %colObj.setvelocity("0 0 0"); - return true; - } - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -/// -Vehicle- ////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// - -/// -Vehicle- ////////////////////////////////////////////////////////////////// -//Function -- onAdd (%this, %obj) -// %this = Object data block -// %obj = Object being added -//Decription -- Called when the object is added to the mission -//////////////////////////////////////////////////////////////////////////////// - -// z0dd - ZOD, 4/20/02. Not required, automatic parent call -//function StationVehicle::onAdd(%this, %obj) -//{ -// Parent::onAdd(%this, %obj); -//} - -function StationVehicle::createTrigger(%this, %obj) -{ - // z0dd - ZOD, 4/20/02. This function used to be named "StationVehicle::onAdd" - // and was changed as part of the power bug fix. - - %trigger = new Trigger() - { - dataBlock = stationTrigger; - polyhedron = "-0.75 0.75 0.0 1.5 0.0 0.0 0.0 -1.5 0.0 0.0 0.0 2.0"; - }; - MissionCleanup.add(%trigger); - %trigger.setTransform(%obj.getTransform()); - %trigger.station = %obj; - %obj.trigger = %trigger; -} - -/// -Vehicle- ////////////////////////////////////////////////////////////////// -//Function -- stationReady(%data, %obj) -// %data = Station Data Block -// %obj = Station Object -//Decription -- Called when station has been triggered and animation is -// completed -//////////////////////////////////////////////////////////////////////////////// -function StationVehicle::stationReady(%data, %obj) -{ - // Make sure none of the other popup huds are active: - // ------------------------------------------------------------------------------------ - // z0dd - ZOD, 6/20/03. done elsewhere as a result of popping up veh station hud sooner - //messageClient( %obj.triggeredBy.client, 'CloseHud', "", 'scoreScreen' ); - //messageClient( %obj.triggeredBy.client, 'CloseHud', "", 'inventoryScreen' ); - - //Display the Vehicle Station GUI - //commandToClient(%obj.triggeredBy.client, 'StationVehicleShowHud'); - // ------------------------------------------------------------------------------------ -} - -/// -Vehicle- ////////////////////////////////////////////////////////////////// -//Function -- stationFinished(%data, %obj) -// %data = Station Data Block -// %obj = Station Object -//Decription -- Called when player has left the station -//////////////////////////////////////////////////////////////////////////////// -function StationVehicle::stationFinished(%data, %obj) -{ - //Hide the Vehicle Station GUI - if(!%obj.triggeredBy.isMounted()) - commandToClient(%obj.triggeredBy.client, 'StationVehicleHideHud'); - else - commandToClient(%obj.triggeredBy.client, 'StationVehicleHideJustHud'); - -} - -/// -Vehicle- ////////////////////////////////////////////////////////////////// -//Function -- getSound(%data, %forward) -// %data = Station Data Block -// %forward = direction the animation is playing -//Decription -- This sound will be played at the same time as the activate -// animation. -//////////////////////////////////////////////////////////////////////////////// -function StationVehicle::getSound(%data, %forward) -{ - if(%forward) - return "StationVehicleActivateSound"; - else - return "StationVehicleDeactivateSound"; -} - -/// -Vehicle- ////////////////////////////////////////////////////////////////// -//Function -- setPlayerPosition(%data, %obj, %trigger, %colObj) -// %data = Station Data Block -// %obj = Station Object -// %trigger = Stations trigger -// %colObj = Object that is at the station -//Decription -- Called when player enters the trigger. Used to set the player -// in the center of the station. -//////////////////////////////////////////////////////////////////////////////// -function StationVehicle::setPlayersPosition(%data, %obj, %trigger, %colObj) -{ - %vel = getWords(%colObj.getVelocity(), 0, 1) @ " 0"; - if((VectorLen(%vel) < 22) && (%obj.triggeredBy != %colObj)) - { - %posXY = getWords(%trigger.getTransform(),0 ,1); - %posZ = getWord(%trigger.getTransform(), 2); - %rotZ = getWord(%obj.getTransform(), 5); - %angle = getWord(%obj.getTransform(), 6); - %angle += 3.141592654; - if(%angle > 6.283185308) - %angle = %angle - 6.283185308; - %colObj.setvelocity("0 0 0"); - %colObj.setTransform(%posXY @ " " @ %posZ + 0.2 @ " " @ "0 0 " @ %rotZ @ " " @ %angle );//center player on object - return true; - } - return false; -} - -function StationVehiclePad::onAdd(%this, %obj) -{ - Parent::onAdd(%this, %obj); - - %obj.ready = true; - %obj.setRechargeRate(%obj.getDatablock().rechargeRate); - - //------------------------------------------------------------------------- - // z0dd - ZOD - Founder(founder@mechina.com), 4/20/02. - // Total rewrite, schedule the vehicle station creation. - // Don't create the station if the pad is hidden by the current mission type. - //error("CURRENT MISSION TYPE: " @ $CurrentMissionType @ ", ALLOWED TYPE: " @ %obj.missionTypesList); - if($CurrentMissionType $= %obj.missionTypesList || %obj.missionTypesList $="") - %this.schedule(0, "createStationVehicle", %obj); - //------------------------------------------------------------------------- -} - -function StationVehiclePad::createStationVehicle(%data, %obj) -{ - // z0dd - ZOD - Founder(founder@mechina.com), 4/20/02 - // This code used to be called from StationVehiclePad::onAdd - // This was changed so we can add the station to the mission group - // so it gets powered properly and auto cleaned up at mission end - - // Get the v-pads mission group so we can place the station in it. - %group = %obj.getGroup(); - - // Set the default transform based on the vehicle pads slot - %xform = %obj.getSlotTransform(0); - %position = getWords(%xform, 0, 2); - %rotation = getWords(%xform, 3, 5); - %angle = (getWord(%xform, 6) * 180) / 3.14159; - - // Place these parameter's in the v-pad datablock located in mis file. - // If the mapper doesn't move the station, use the default location. - if(%obj.stationPos $= "" || %obj.stationRot $= "") - { - %pos = %position; - %rot = %rotation @ " " @ %angle; - } - else - { - %pos = %obj.stationPos; - %rot = %obj.stationRot; - } - - %sv = new StaticShape() { - scale = "1 1 1"; - dataBlock = "StationVehicle"; - lockCount = "0"; - homingCount = "0"; - team = %obj.team; - position = %pos; - rotation = %rot; - }; - - // Add the station to the v-pads mission group for cleanup and power. - %group.add(%sv); - %sv.setPersistent(false); // set the station to not save. - - // Apparently called to early on mission load done, call it now. - %sv.getDataBlock().gainPower(%sv); - - // Create the trigger - %sv.getDataBlock().createTrigger(%sv); - %sv.pad = %obj; - %obj.station = %sv; - %sv.trigger.mainObj = %obj; - %sv.trigger.disableObj = %sv; - - // Set the sensor group. - if(%sv.getTarget() != -1) - setTargetSensorGroup(%sv.getTarget(), %obj.team); - - //Remove unwanted vehicles - if(%obj.scoutVehicle !$= "Removed") - %sv.vehicle[scoutvehicle] = true; - if(%obj.assaultVehicle !$= "Removed") - %sv.vehicle[assaultVehicle] = true; - if(%obj.mobileBaseVehicle !$= "Removed") - { - %sv.vehicle[mobileBasevehicle] = true; - // z0dd - ZOD, 4/20/02. Enable MPB Teleporter. - %sv.getDataBlock().createTeleporter(%sv, %group); - } - if(%obj.scoutFlyer !$= "Removed") - %sv.vehicle[scoutFlyer] = true; - if(%obj.bomberFlyer !$= "Removed") - %sv.vehicle[bomberFlyer] = true; - if(%obj.hapcFlyer !$= "Removed") - %sv.vehicle[hapcFlyer] = true; -} - -function StationVehiclePad::onEndSequence(%data, %obj, %thread) -{ - if(%thread == $ActivateThread) - { - %obj.ready = true; - %obj.stopThread($ActivateThread); - } - Parent::onEndSequence(%data, %obj, %thread); -} - -//////////////////////////////////////////////////////////////////////////////// -/// -Mobile Base Inventory- //////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// - -/// -Mobile Base- ////////////////////////////////////////////////////////////// -//Function -- onAdd (%this, %obj) -// %this = Object data block -// %obj = Object being added -//Decription -- Called when the object is added to the mission -//////////////////////////////////////////////////////////////////////////////// -function MobileInvStation::onAdd(%this, %obj) -{ -} - -function MobileInvStation::createTrigger(%this, %obj) -{ - Parent::onAdd(%this, %obj); - - %obj.setRechargeRate(%obj.getDatablock().rechargeRate); - %trigger = new Trigger() - { - dataBlock = stationTrigger; - polyhedron = "-0.75 0.75 0.1 1.5 0.0 0.0 0.0 -1.5 0.0 0.0 0.0 2.3"; - }; - MissionCleanup.add(%trigger); - %trigger.setTransform(%obj.vehicle.getSlotTransform(2)); - - %trigger.station = %obj; - %trigger.mainObj = %obj; - %trigger.disableObj = %obj; - - %obj.trigger = %trigger; -// createTarget(%obj, 'Inventory Station', "", "", 'Station', 0, 0); -} - -/// -Mobile Base- ////////////////////////////////////////////////////////////// -//Function -- stationReady(%data, %obj) -// %data = Station Data Block -// %obj = Station Object -//Decription -- Called when station has been triggered and animation is -// completed -//////////////////////////////////////////////////////////////////////////////// -function MobileInvStation::stationReady(%data, %obj) -{ - //Display the Inventory Station GUI here - %obj.notReady = 1; - %obj.inUse = "Down"; - %obj.schedule(200,"playThread",$ActivateThread,"activate1"); - %obj.getObjectMount().playThread($ActivateThread,"Activate"); - %player = %obj.triggeredBy; - %energy = %player.getEnergyLevel(); - %player.setCloaked(true); - %player.schedule(900, "setCloaked", false); - if (!%player.client.isAIControlled()) - buyFavorites(%player.client); - - %player.setEnergyLevel(%energy); -} - -/// -Mobile Base- ////////////////////////////////////////////////////////////// -//Function -- stationFinished(%data, %obj) -// %data = Station Data Block -// %obj = Station Object -//Decription -- Called when player has left the station -//////////////////////////////////////////////////////////////////////////////// -function MobileInvStation::stationFinished(%data, %obj) -{ - //Hide the Inventory Station GUI -} - -/// -Mobile Base- ////////////////////////////////////////////////////////////// -//Function -- getSound(%data, %forward) -// %data = Station Data Block -// %forward = direction the animation is playing -//Decription -- This sound will be played at the same time as the activate -// animation. -//////////////////////////////////////////////////////////////////////////////// -function MobileInvStation::getSound(%data, %forward) -{ - if(%forward) - return "MobileBaseInventoryActivateSound"; - else - return false; -} - -/// -Mobile Base- ////////////////////////////////////////////////////////////// -//Function -- setPlayerPosition(%data, %obj, %trigger, %colObj) -// %data = Station Data Block -// %obj = Station Object -// %trigger = Stations trigger -// %colObj = Object that is at the station -//Decription -- Called when player enters the trigger. Used to set the player -// in the center of the station. -//////////////////////////////////////////////////////////////////////////////// -function MobileInvStation::setPlayersPosition(%data, %obj, %trigger, %colObj) -{ - %vel = getWords(%colObj.getVelocity(), 0, 1) @ " 0"; - if((VectorLen(%vel) < 22) && (%obj.triggeredBy != %colObj)) - { - %pos = %trigger.position; - %colObj.setvelocity("0 0 0"); - %rot = getWords(%colObj.getTransform(),3, 6); -// %colObj.setTransform(getWord(%pos,0) @ " " @ getWord(%pos,1) - 0.75 @ " " @ getWord(%pos,2)+0.7 @ " " @ %rot);//center player on object - %colObj.setTransform(getWord(%pos,0) @ " " @ getWord(%pos,1) @ " " @ getWord(%pos,2)+0.8 @ " " @ %rot);//center player on object - %colObj.setMoveState(true); - %colObj.schedule(1600,"setMoveState", false); - %colObj.setvelocity("0 0 0"); - return true; - } - return false; -} - -function MobileInvStation::onDamage() -{ -} - -function MobileInvStation::damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType) -{ - //If vehicle station is hit then apply damage to the vehicle - %targetObject.getObjectMount().damage(%sourceObject, %position, %amount, %damageType); -} - -//////////////////////////////////////////////////////////////////////////////// -/// -Station Trigger- ////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// - -////-Station Trigger-/////////////////////////////////////////////////////////// -//Function -- onEnterTrigger (%data, %obj, %colObj) -// %data = Trigger Data Block -// %obj = Trigger Object -// %colObj = Object that collided with the trigger -//Decription -- Called when trigger has been triggered -//////////////////////////////////////////////////////////////////////////////// -function stationTrigger::onEnterTrigger(%data, %obj, %colObj) //Did a shitty RPG hack to ask if the player wants to pay before actually running the inv.. -{ - //make sure it's a player object, and that that object is still alive - if(%colObj.getDataBlock().className !$= "Armor" || %colObj.getState() $= "Dead") - return; - - %colObj.client.isAtInv = true; - %colObj.obj = %obj; - %colObj.data = %data; - - if ($CurrentMissionType $= "RPG") - { - if (%colObj.client.money > 100) - commandToClient(%colObj.client,'HandleScriptedCommand',1,"Refill","To refill your inventory, you must pay $100.","commandToServer('DoRefill');"); - else - messageClient(%colObj.client,'msgNotEnoughCashForRefill',"\c3You do not have enough money to refill your inventory."); - } - else - serverCmdDoRefill(%colObj.client); - return; -} - -////-Station Trigger-/////////////////////////////////////////////////////////// -//Function -- onLeaveTrigger (%data, %obj, %colObj) -// %data = Trigger Data Block -// %obj = Trigger Object -// %colObj = Object that collided with the trigger -//Decription -- Called when trigger has been untriggered -//////////////////////////////////////////////////////////////////////////////// -function stationTrigger::onLeaveTrigger(%data, %obj, %colObj) -{ - if(%colObj.getDataBlock().className !$= "Armor") - return; - - // z0dd - ZOD, 7/13/02 Part of hack to keep people from mounting - // vehicles in disallowed armors. - %colObj.client.inInv = false; - - %colObj.inStation = false; - commandToClient(%colObj.client,'setStationKeys', false); - commandToClient(%colObj.client,'HandleScriptedCommand',0,"MessageBoxYesNoDLG"); - if(%obj.station) - { - if(%obj.station.triggeredBy == %colObj) - { - %obj.station.getDataBlock().stationFinished(%obj.station); - %obj.station.getDataBlock().endRepairing(%obj.station); - %obj.station.triggeredBy = ""; - %obj.station.getDataBlock().stationTriggered(%obj.station, 0); - - if(!%colObj.teleporting) - %colObj.station = ""; - if(%colObj.getMountedImage($WeaponSlot) == 0 && !%colObj.teleporting) - { - if(%colObj.inv[%colObj.lastWeapon]) - %colObj.use(%colObj.lastWeapon); - - if(%colObj.getMountedImage($WeaponSlot) == 0) - %colObj.selectWeaponSlot( 0 ); - } - } - } -} - -////-Station Trigger-/////////////////////////////////////////////////////////// -//Function -- stationTriggered(%data, %obj, %isTriggered) -// %data = Station Data Block -// %obj = Station Object -// %isTriggered = 1 if triggered; 0 if status changed to -// untriggered -//Decription -- Called when a "station trigger" has been triggered or -// untriggered -//////////////////////////////////////////////////////////////////////////////// -function Station::stationTriggered(%data, %obj, %isTriggered) -{ - if(%isTriggered) - { - // ---------------------------------------------------------------------------- - // z0dd - ZOD, 6/20/03. Pop up veh station hud when player steps on veh pad - if(%obj.getDataBlock().getName() $= StationVehicle) - { - messageClient( %obj.triggeredBy.client, 'CloseHud', "", 'scoreScreen' ); - messageClient( %obj.triggeredBy.client, 'CloseHud', "", 'inventoryScreen' ); - commandToClient(%obj.triggeredBy.client, 'StationVehicleShowHud'); - } - // ---------------------------------------------------------------------------- - - %obj.setThreadDir($ActivateThread, TRUE); - %obj.playThread($ActivateThread,"activate"); - %obj.playAudio($ActivateSound, %data.getSound(true)); - %obj.inUse = "Up"; - } - else - { - if(%obj.getDataBlock().getName() !$= StationVehicle) - { - %obj.stopThread($ActivateThread); - if(%obj.getObjectMount()) - %obj.getObjectMount().stopThread($ActivateThread); - %obj.inUse = "Down"; - } - else - { - %obj.setThreadDir($ActivateThread, FALSE); - %obj.playThread($ActivateThread,"activate"); - %obj.playAudio($ActivateSound, %data.getSound(false)); - %obj.inUse = "Down"; - } - } -} - -////-Station-/////////////////////////////////////////////////////////////////// -//Function -- onEndSequence(%data, %obj, %thread) -// %data = Station Data Block -// %obj = Station Object -// %thread = Thread number that the animation is associated -// with / running on. -//Decription -- Called when an animation sequence is finished playing -//////////////////////////////////////////////////////////////////////////////// -function Station::onEndSequence(%data, %obj, %thread) -{ - if(%thread == $ActivateThread) - { - if(%obj.inUse $= "Up") - { - %data.stationReady(%obj); - %player = %obj.triggeredBy; - if(%data.doesRepair && !%player.stationRepairing && %player.getDamageLevel() != 0) { - %oldRate = %player.getRepairRate(); - %player.setRepairRate(%oldRate + 0.00625); - %player.stationRepairing = 1; - } - } - else - { - if(%obj.getDataBlock().getName() !$= MobileInvStation) - { - %obj.stopThread($ActivateThread); - %obj.inUse = "Down"; - } - } - } - Parent::onEndSequence(%data, %obj, %thread); -} - -////-Station-/////////////////////////////////////////////////////////////////// -//Function -- onCollision(%data, %obj, %colObj) -// %data = Station Data Block -// %obj = Station Object -// %colObj = Object that collided with the station -//Decription -- Called when an object collides with a station -//////////////////////////////////////////////////////////////////////////////// -function Station::onCollision(%data, %obj, %colObj) -{ - // Currently Not Needed -} - -////-Station-/////////////////////////////////////////////////////////////////// -//Function -- endRepairing(%data, %obj) -// %data = Station Data Block -// %obj = Station Object -//Decription -- Called to stop repairing the object -//////////////////////////////////////////////////////////////////////////////// -function Station::endRepairing(%data, %obj) -{ - if(%obj.triggeredBy.stationRepairing) - { - %oldRate = %obj.triggeredBy.getRepairRate(); - %obj.triggeredBy.setRepairRate(%oldRate - 0.00625); - %obj.triggeredBy.stationRepairing = 0; - } -} - -////-Station Trigger-/////////////////////////////////////////////////////////// -//Function -- onTickTrigger(%data, %obj) -// %data = Trigger Data Block -// %obj = Trigger Object -//Decription -- Called every tick if triggered -//////////////////////////////////////////////////////////////////////////////// -function stationTrigger::onTickTrigger(%data, %obj) -{ -} - -//****************************************************************************** -//* Station General - Functions * -//****************************************************************************** - -//function Station::onGainPowerEnabled(%data, %obj) - -function Station::onLosePowerDisabled(%data, %obj) -{ - Parent::onLosePowerDisabled(%data, %obj); - - // check to see if a player was using this station - %occupied = %obj.triggeredBy; - if(%occupied > 0) - { - if(%data.doesRepair) - %data.endRepairing(%obj); - // if it's a deployed station, stop "flashing panels" thread - if(%data.getName() $= DeployedStationInventory) - %obj.stopThread($ActivateThread); - // reset some attributes - %occupied.setCloaked(false); - %occupied.station = ""; - %occupied.inStation = false; - %obj.triggeredBy = ""; - // restore "toggle inventory hud" key - commandToClient(%occupied.client,'setStationKeys', false); - // re-mount last weapon or weapon slot 0 - if(%occupied.getMountedImage($WeaponSlot) == 0) - { - if(%occupied.inv[%occupied.lastWeapon]) - %occupied.use(%occupied.lastWeapon); - if(%occupied.getMountedImage($WeaponSlot) == 0) - %occupied.selectWeaponSlot( 0 ); - } - } -} - -// z0dd - ZOD, 4/20/02 -// Pull these functions, they are unneeded because we changed the way -// Vehicle stations are added to the game, they are now treated the -// same as any other mapper added object. -//function StationVehiclePad::gainPower(%data, %obj) -//{ -// %obj.station.setSelfPowered(); - // z0dd - ZOD, 4/20/02 Repower the MPB Teleporter -// if(isObject(%obj.station.teleporter)) -// %obj.station.teleporter.setSelfPowered(); -// Parent::gainPower(%data, %obj); -//} - -//function StationVehiclePad::losePower(%data, %obj) -//{ -// %obj.station.clearSelfPowered(); - // z0dd - ZOD, 4/20/02 Kill the telepoters power too -// if(isObject(%obj.station.teleporter)) -// %obj.station.teleporter.clearSelfPowered(); -// Parent::losePower(%data, %obj); -//} - -//--------------------------------------------------------------------------- -// DeployedStationInventory: -//--------------------------------------------------------------------------- - -function DeployedStationInventory::stationReady(%data, %obj) -{ - %obj.notReady = 1; - %player = %obj.triggeredBy; - %obj.playThread($ActivateThread,"activate1"); - // function below found in inventoryHud.cs - if (!%player.client.isAIControlled()) - buyDeployableFavorites(%player.client); -} - -function DeployedStationInventory::stationFinished(%data, %obj) -{ -} - -function DeployedStationInventory::setPlayersPosition(%data, %obj, %trigger, %colObj) -{ - %vel = getWords(%colObj.getVelocity(), 0, 1) @ " 0"; - if((VectorLen(%vel) < 28) && (%obj.triggeredBy != %colObj)) // z0dd - ZOD, 4/27/02. Can engage deployed inv at higher speeds. Was 22. Now ~100kph - { - // ------------------------------------------------- - // z0dd - ZOD, 4/14/02. No view change at remote inv - %colObj.setvelocity("0 0 0"); - %colObj.setMoveState(true); - %colObj.schedule(400,"setMoveState", false); // z0dd - ZOD, 4/27/02. Equip at remote inv in 1/4 base time. Was 1600 - return true; - // ------------------------------------------------- - } - return false; -} - -function DeployedStationInventory::onDestroyed(%data, %obj, %prevState) -{ - %obj.trigger.delete(); - // decrement team deployed count for this item - $TeamDeployedCount[%obj.team, InventoryDeployable]--; - - // when a station is destroyed, we don't need its trigger any more - %obj.schedule(700, "delete"); - - Parent::onDestroyed(%data, %obj, %prevState); -} - -/// -Deployable Inventory- ////////////////////////////////////////////////////////////// -//Function -- getSound(%data, %forward) -// %data = Station Data Block -// %forward = direction the animation is playing -//Decription -- This sound will be played at the same time as the activate -// animation. -//////////////////////////////////////////////////////////////////////////////// -function DeployedStationInventory::getSound(%data, %forward) -{ - if(%forward) - return "DepInvActivateSound"; - else - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -/// z0dd - ZOD: Execute the MPB Teleporter code - ////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// - - -exec("scripts/mpbTeleporter.cs"); +//****************************************************************************** +//* Station - Data Blocks * +//****************************************************************************** +datablock EffectProfile(StationInventoryActivateEffect) +{ + effectname = "powered/inv_pad_on"; + minDistance = 5.0; + maxDistance = 7.5; +}; + +datablock EffectProfile(StationVehicleActivateEffect) +{ + effectname = "powered/vehicle_screen_on2"; + minDistance = 3.0; + maxDistance = 5.0; +}; + +datablock EffectProfile(StationVehicleDeactivateEffect) +{ + effectname = "powered/vehicle_screen_off"; + minDistance = 3.0; + maxDistance = 5.0; +}; + +//datablock EffectProfile(MobileBaseInventoryActivateEffect) +//{ +// effectname = "misc/diagnostic_on"; +// minDistance = 3.0; +//}; + +datablock EffectProfile(StationAccessDeniedEffect) +{ + effectname = "powered/station_denied"; + minDistance = 3.0; + maxDistance = 5.0; +}; + +datablock AudioProfile(StationInventoryActivateSound) +{ + filename = "fx/powered/inv_pad_on.wav"; + description = AudioClose3d; + preload = true; + effect = StationInventoryActivateEffect; +}; + +datablock AudioProfile(MobileBaseInventoryActivateSound) +{ + filename = "fx/vehicles/mpb_inv_station.wav"; + description = AudioClose3d; + preload = true; + effect = StationInventoryActivateEffect; +}; + +datablock AudioProfile(DepInvActivateSound) +{ + filename = "fx/powered/dep_inv_station.wav"; + description = AudioClose3d; + preload = true; + effect = StationInventoryActivateEffect; +}; + +datablock AudioProfile(StationVehicleActivateSound) +{ + filename = "fx/powered/vehicle_screen_on2.wav"; + description = AudioClosest3d; + preload = true; + effect = StationVehicleActivateEffect; +}; + +datablock AudioProfile(StationVehicleDeactivateSound) +{ + filename = "fx/powered/vehicle_screen_off.wav"; + description = AudioClose3d; + preload = true; + effect = StationVehicleDeactivateEffect; +}; + +datablock AudioProfile(StationAccessDeniedSound) +{ + filename = "fx/powered/station_denied.wav"; + description = AudioClosest3d; + preload = true; + effect = StationAccessDeniedEffect; +}; + +datablock AudioProfile(StationVehicleHumSound) +{ + filename = "fx/powered/station_hum.wav"; + description = CloseLooping3d; + preload = true; +}; + +datablock AudioProfile(StationInventoryHumSound) +{ + filename = "fx/powered/station_hum.wav"; + description = CloseLooping3d; + preload = true; +}; + +datablock StationFXPersonalData( PersonalInvFX ) +{ + delay = 0; + fadeDelay = 0.5; + lifetime = 1.2; + height = 2.5; + numArcSegments = 10.0; + numDegrees = 180.0; + trailFadeTime = 0.5; + leftRadius = 1.85; + rightRadius = 1.85; + leftNodeName = "FX1"; + rightNodeName = "FX2"; + + texture[0] = "special/stationLight"; +}; + + +datablock DebrisData( StationDebris ) +{ + explodeOnMaxBounce = false; + + elasticity = 0.40; + friction = 0.5; + + lifetime = 17.0; + lifetimeVariance = 0.0; + + minSpinSpeed = 60; + maxSpinSpeed = 600; + + numBounces = 10; + bounceVariance = 0; + + staticOnMaxBounce = true; + + useRadiusMass = true; + baseRadius = 0.4; + + velocity = 9.0; + velocityVariance = 4.5; + +}; + +datablock StaticShapeData(StationInventory) : StaticShapeDamageProfile +{ + className = Station; + catagory = "Stations"; + shapeFile = "station_inv_human.dts"; + maxDamage = 1.00; + destroyedLevel = 1.00; + disabledLevel = 0.70; + explosion = ShapeExplosion; + expDmgRadius = 8.0; + expDamage = 0.4; + expImpulse = 1500.0; + // don't allow this object to be damaged in non-team-based + // mission types (DM, Rabbit, Bounty, Hunters) + noIndividualDamage = true; + + dynamicType = $TypeMasks::StationObjectType; + isShielded = true; + energyPerDamagePoint = 75; + maxEnergy = 50; + rechargeRate = 0.35; + doesRepair = true; + humSound = StationInventoryHumSound; + + cmdCategory = "Support"; + cmdIcon = CMDStationIcon; + cmdMiniIconName = "commander/MiniIcons/com_inventory_grey"; + targetNameTag = 'Inventory'; + targetTypeTag = 'Station'; + + debrisShapeName = "debris_generic.dts"; + debris = StationDebris; +}; + +datablock StaticShapeData(StationAmmo) : StaticShapeDamageProfile +{ + className = Station; + catagory = "Stations"; +// shapeFile = "station_ammo.dts"; + shapeFile = "station_inv_human.dts"; + maxDamage = 1.00; + destroyedLevel = 1.00; + disabledLevel = 0.70; + explosion = ShapeExplosion; + expDmgRadius = 8.0; + expDamage = 0.4; + expImpulse = 1500.0; + // don't allow this object to be damaged in non-team-based + // mission types (DM, Rabbit, Bounty, Hunters) + noIndividualDamage = true; + + dynamicType = $TypeMasks::StationObjectType; + isShielded = true; + energyPerDamagePoint = 75; + maxEnergy = 50; + rechargeRate = 0.35; + doesRepair = true; + humSound = StationInventoryHumSound; + + cmdCategory = "Support"; + cmdIcon = CMDStationIcon; + cmdMiniIconName = "commander/MiniIcons/com_inventory_grey"; + targetNameTag = 'Ammo'; + targetTypeTag = 'Station'; + + debrisShapeName = "debris_generic.dts"; + debris = StationDebris; +}; + +datablock StaticShapeData(StationVehicle) : StaticShapeDamageProfile +{ + className = Station; + catagory = "Stations"; + shapeFile = "vehicle_pad_station.dts"; + maxDamage = 1.20; + destroyedLevel = 1.20; + disabledLevel = 0.84; + explosion = ShapeExplosion; + expDmgRadius = 10.0; + expDamage = 0.4; + expImpulse = 1500.0; + dynamicType = $TypeMasks::StationObjectType; + isShielded = true; + energyPerDamagePoint = 33; + maxEnergy = 250; + rechargeRate = 0.31; + humSound = StationVehicleHumSound; + // don't let these be damaged in Siege missions + noDamageInSiege = true; + + cmdCategory = "Support"; + cmdIcon = CMDVehicleStationIcon; + cmdMiniIconName = "commander/MiniIcons/com_vehicle_pad_inventory"; + targetTypeTag = 'Vehicle Station'; + + debrisShapeName = "debris_generic.dts"; + debris = StationDebris; +}; + +datablock StaticShapeData(StationVehiclePad) +{ + className = Station; + catagory = "Stations"; + shapeFile = "vehicle_pad.dts"; + isInvincible = true; + dynamicType = $TypeMasks::StaticObjectType; + rechargeRate = 0.05; + + targetTypeTag = 'Vehicle Pad'; // z0dd - ZOD, 4/20/02. Bug fix, need this var. +}; + +//datablock StaticShapeData(StationAmmo) +//{ +// className = Station; +// catagory = "Stations"; +// shapeFile = "station_ammo.dts"; +// maxDamage = 1.0; +// disabledLevel = 0.6; +// destroyedLevel = 0.8; +// icon = "CMDStationIcon"; +// dynamicType = $TypeMasks::StationObjectType; +//}; + +datablock StaticShapeData(MobileInvStation) +{ + className = Station; + catagory = "Stations"; + shapeFile = "station_inv_mpb.dts"; + icon = "CMDStationIcon"; + // don't allow this object to be damaged in non-team-based + // mission types (DM, Rabbit, Bounty, Hunters) + noIndividualDamage = true; + + dynamicType = $TypeMasks::StationObjectType; + rechargeRate = 0.256; + doesRepair = true; +}; + + +//****************************************************************************** +//* Station - Functions * +//****************************************************************************** + +//////////////////////////////////////////////////////////////////////////////// +/// -Inventory- //////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +/// -Inventory- //////////////////////////////////////////////////////////////// +//Function -- onAdd (%this, %obj) +// %this = Object data block +// %obj = Object being added +//Decription -- Called when the object is added to the mission +//////////////////////////////////////////////////////////////////////////////// +function StationInventory::onAdd(%this, %obj) +{ + Parent::onAdd(%this, %obj); + + %obj.setRechargeRate(%obj.getDatablock().rechargeRate); + %trigger = new Trigger() + { + dataBlock = stationTrigger; + polyhedron = "-0.75 0.75 0.1 1.5 0.0 0.0 0.0 -1.5 0.0 0.0 0.0 2.3"; + }; + MissionCleanup.add(%trigger); + %trigger.setTransform(%obj.getTransform()); + + %trigger.station = %obj; + %trigger.mainObj = %obj; + %trigger.disableObj = %obj; + %obj.trigger = %trigger; +} + +/// -Inventory- //////////////////////////////////////////////////////////////// +//Function -- stationReady(%data, %obj) +// %data = Station Data Block +// %obj = Station Object +//Decription -- Called when station has been triggered and animation is +// completed +//////////////////////////////////////////////////////////////////////////////// +function StationInventory::stationReady(%data, %obj) +{ + //Display the Inventory Station GUI here + %obj.notReady = 1; + %obj.inUse = "Down"; + %obj.schedule(500,"playThread",$ActivateThread,"activate1"); + %player = %obj.triggeredBy; + %energy = %player.getEnergyLevel(); + %max = %player.getDatablock().maxEnergy; // z0dd - ZOD, 4/20/02. Inv energy bug fix + %player.setCloaked(true); + %player.schedule(500, "setCloaked", false); + if (!%player.client.isAIControlled()) + buyFavorites(%player.client); + + %player.setEnergyLevel(mFloor(%player.getDatablock().maxEnergy * %energy / %max)); // z0dd - ZOD, 4/20/02. Inv energy bug fix + + %data.schedule( 500, "beginPersonalInvEffect", %obj ); +} + +function StationInventory::beginPersonalInvEffect( %data, %obj ) +{ + if (!%obj.isDisabled()) + { + %fx = new StationFXPersonal() + { + dataBlock = PersonalInvFX; + stationObject = %obj; + }; + } +} + +/// -Inventory- //////////////////////////////////////////////////////////////// +//Function -- stationFinished(%data, %obj) +// %data = Station Data Block +// %obj = Station Object +//Decription -- Called when player has left the station +//////////////////////////////////////////////////////////////////////////////// +function StationInventory::stationFinished(%data, %obj) +{ + //Hide the Inventory Station GUI +} + +/// -Inventory- //////////////////////////////////////////////////////////////// +//Function -- getSound(%data, %forward) +// %data = Station Data Block +// %forward = direction the animation is playing +//Decription -- This sound will be played at the same time as the activate +// animation. +//////////////////////////////////////////////////////////////////////////////// +function StationInventory::getSound(%data, %forward) +{ + if(%forward) + return "StationInventoryActivateSound"; + else + return false; +} + +/// -Inventory- //////////////////////////////////////////////////////////////// +//Function -- setPlayerPosition(%data, %obj, %trigger, %colObj) +// %data = Station Data Block +// %obj = Station Object +// %trigger = Stations trigger +// %colObj = Object that is at the station +//Decription -- Called when player enters the trigger. Used to set the player +// in the center of the station. +//////////////////////////////////////////////////////////////////////////////// +function StationInventory::setPlayersPosition(%data, %obj, %trigger, %colObj) +{ + %vel = getWords(%colObj.getVelocity(), 0, 1) @ " 0"; + if((VectorLen(%vel) < 22) && (%obj.triggeredBy != %colObj)) + { + %pos = %trigger.position; + %colObj.setvelocity("0 0 0"); + %rot = getWords(%colObj.getTransform(),3, 6); + %colObj.setTransform(getWord(%pos,0) @ " " @ getWord(%pos,1) @ " " @ getWord(%pos,2) + 0.8 @ " " @ %rot);//center player on object + %colObj.setMoveState(true); + %colObj.schedule(1600,"setMoveState", false); + %colObj.setvelocity("0 0 0"); + return true; + } + return false; +} + + +/////////////////////////////////////////////////////////////////////////////// +/// -Ammo- //////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +function StationAmmo::onAdd(%this, %obj) +{ + Parent::onAdd(%this, %obj); + + %obj.setRechargeRate(%obj.getDatablock().rechargeRate); + %trigger = new Trigger() + { + dataBlock = stationTrigger; + polyhedron = "-0.75 0.75 0.1 1.5 0.0 0.0 0.0 -1.5 0.0 0.0 0.0 2.3"; + }; + MissionCleanup.add(%trigger); + %trigger.setTransform(%obj.getTransform()); + + %trigger.station = %obj; + %trigger.mainObj = %obj; + %trigger.disableObj = %obj; + %obj.trigger = %trigger; +} + +//------------------------------------------------------------------------------- +function StationAmmo::stationReady(%data, %obj) +{ + //error("StationAmmo::stationReady"); + %obj.notReady = 1; + %obj.inUse = "Down"; + %obj.setThreadDir($ActivateThread, true); + %obj.schedule(100, "playThread", $ActivateThread, "activate1"); + %player = %obj.triggeredBy; + %energy = %player.getEnergyLevel(); + //%player.setCloaked(true); + //%player.schedule(500, "setCloaked", false); + + + if (!%player.client.isAIControlled()) + getAmmoStationLovin(%player.client); + //%data.schedule( 500, "beginPersonalInvEffect", %obj ); +} + +//------------------------------------------------------------------------------- +function StationAmmo::onEndSequence(%data, %obj, %thread) +{ + if(%thread == $ActivateThread) + { + %obj.setThreadDir($ActivateThread, false); + %obj.playThread( $ActivateThread, "activate1"); + if(%obj.inUse $= "Up") + { + %data.stationReady(%obj); + %player = %obj.triggeredBy; + if(%data.doesRepair && !%player.stationRepairing && %player.getDamageLevel() != 0) { + %oldRate = %player.getRepairRate(); + %player.setRepairRate(%oldRate + 0.00625); + %player.stationRepairing = 1; + } + } + } + //Parent::onEndSequence(%data, %obj, %thread); +} + +//------------------------------------------------------------------------------- +function StationAmmo::stationFinished(%data, %obj) +{ + //Hide the Inventory Station GUI +} + +//------------------------------------------------------------------------------- +function StationAmmo::getSound(%data, %forward) +{ + if(%forward) + return "StationInventoryActivateSound"; + else + return false; +} + +//------------------------------------------------------------------------------- +function StationAmmo::setPlayersPosition(%data, %obj, %trigger, %colObj) +{ + %vel = getWords(%colObj.getVelocity(), 0, 1) @ " 0"; + if((VectorLen(%vel) < 22) && (%obj.triggeredBy != %colObj)) + { + %pos = %trigger.position; + %colObj.setvelocity("0 0 0"); + %rot = getWords(%colObj.getTransform(),3, 6); + %colObj.setTransform(getWord(%pos,0) @ " " @ getWord(%pos,1) @ " " @ getWord(%pos,2) + 0.8 @ " " @ %rot);//center player on object + %colObj.setMoveState(true); + %colObj.schedule(1600,"setMoveState", false); + %colObj.setvelocity("0 0 0"); + return true; + } + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +/// -Vehicle- ////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +/// -Vehicle- ////////////////////////////////////////////////////////////////// +//Function -- onAdd (%this, %obj) +// %this = Object data block +// %obj = Object being added +//Decription -- Called when the object is added to the mission +//////////////////////////////////////////////////////////////////////////////// + +// z0dd - ZOD, 4/20/02. Not required, automatic parent call +//function StationVehicle::onAdd(%this, %obj) +//{ +// Parent::onAdd(%this, %obj); +//} + +function StationVehicle::createTrigger(%this, %obj) +{ + // z0dd - ZOD, 4/20/02. This function used to be named "StationVehicle::onAdd" + // and was changed as part of the power bug fix. + + %trigger = new Trigger() + { + dataBlock = stationTrigger; + polyhedron = "-0.75 0.75 0.0 1.5 0.0 0.0 0.0 -1.5 0.0 0.0 0.0 2.0"; + }; + MissionCleanup.add(%trigger); + %trigger.setTransform(%obj.getTransform()); + %trigger.station = %obj; + %obj.trigger = %trigger; +} + +/// -Vehicle- ////////////////////////////////////////////////////////////////// +//Function -- stationReady(%data, %obj) +// %data = Station Data Block +// %obj = Station Object +//Decription -- Called when station has been triggered and animation is +// completed +//////////////////////////////////////////////////////////////////////////////// +function StationVehicle::stationReady(%data, %obj) +{ + // Make sure none of the other popup huds are active: + // ------------------------------------------------------------------------------------ + // z0dd - ZOD, 6/20/03. done elsewhere as a result of popping up veh station hud sooner + //messageClient( %obj.triggeredBy.client, 'CloseHud', "", 'scoreScreen' ); + //messageClient( %obj.triggeredBy.client, 'CloseHud', "", 'inventoryScreen' ); + + //Display the Vehicle Station GUI + //commandToClient(%obj.triggeredBy.client, 'StationVehicleShowHud'); + // ------------------------------------------------------------------------------------ +} + +/// -Vehicle- ////////////////////////////////////////////////////////////////// +//Function -- stationFinished(%data, %obj) +// %data = Station Data Block +// %obj = Station Object +//Decription -- Called when player has left the station +//////////////////////////////////////////////////////////////////////////////// +function StationVehicle::stationFinished(%data, %obj) +{ + //Hide the Vehicle Station GUI + if(!%obj.triggeredBy.isMounted()) + commandToClient(%obj.triggeredBy.client, 'StationVehicleHideHud'); + else + commandToClient(%obj.triggeredBy.client, 'StationVehicleHideJustHud'); + +} + +/// -Vehicle- ////////////////////////////////////////////////////////////////// +//Function -- getSound(%data, %forward) +// %data = Station Data Block +// %forward = direction the animation is playing +//Decription -- This sound will be played at the same time as the activate +// animation. +//////////////////////////////////////////////////////////////////////////////// +function StationVehicle::getSound(%data, %forward) +{ + if(%forward) + return "StationVehicleActivateSound"; + else + return "StationVehicleDeactivateSound"; +} + +/// -Vehicle- ////////////////////////////////////////////////////////////////// +//Function -- setPlayerPosition(%data, %obj, %trigger, %colObj) +// %data = Station Data Block +// %obj = Station Object +// %trigger = Stations trigger +// %colObj = Object that is at the station +//Decription -- Called when player enters the trigger. Used to set the player +// in the center of the station. +//////////////////////////////////////////////////////////////////////////////// +function StationVehicle::setPlayersPosition(%data, %obj, %trigger, %colObj) +{ + %vel = getWords(%colObj.getVelocity(), 0, 1) @ " 0"; + if((VectorLen(%vel) < 22) && (%obj.triggeredBy != %colObj)) + { + %posXY = getWords(%trigger.getTransform(),0 ,1); + %posZ = getWord(%trigger.getTransform(), 2); + %rotZ = getWord(%obj.getTransform(), 5); + %angle = getWord(%obj.getTransform(), 6); + %angle += 3.141592654; + if(%angle > 6.283185308) + %angle = %angle - 6.283185308; + %colObj.setvelocity("0 0 0"); + %colObj.setTransform(%posXY @ " " @ %posZ + 0.2 @ " " @ "0 0 " @ %rotZ @ " " @ %angle );//center player on object + return true; + } + return false; +} + +function StationVehiclePad::onAdd(%this, %obj) +{ + Parent::onAdd(%this, %obj); + + %obj.ready = true; + %obj.setRechargeRate(%obj.getDatablock().rechargeRate); + + //------------------------------------------------------------------------- + // z0dd - ZOD - Founder(founder@mechina.com), 4/20/02. + // Total rewrite, schedule the vehicle station creation. + // Don't create the station if the pad is hidden by the current mission type. + //error("CURRENT MISSION TYPE: " @ $CurrentMissionType @ ", ALLOWED TYPE: " @ %obj.missionTypesList); + if($CurrentMissionType $= %obj.missionTypesList || %obj.missionTypesList $="") + %this.schedule(0, "createStationVehicle", %obj); + //------------------------------------------------------------------------- +} + +function StationVehiclePad::createStationVehicle(%data, %obj) +{ + // z0dd - ZOD - Founder(founder@mechina.com), 4/20/02 + // This code used to be called from StationVehiclePad::onAdd + // This was changed so we can add the station to the mission group + // so it gets powered properly and auto cleaned up at mission end + + // Get the v-pads mission group so we can place the station in it. + %group = %obj.getGroup(); + + // Set the default transform based on the vehicle pads slot + %xform = %obj.getSlotTransform(0); + %position = getWords(%xform, 0, 2); + %rotation = getWords(%xform, 3, 5); + %angle = (getWord(%xform, 6) * 180) / 3.14159; + + // Place these parameter's in the v-pad datablock located in mis file. + // If the mapper doesn't move the station, use the default location. + if(%obj.stationPos $= "" || %obj.stationRot $= "") + { + %pos = %position; + %rot = %rotation @ " " @ %angle; + } + else + { + %pos = %obj.stationPos; + %rot = %obj.stationRot; + } + + %sv = new StaticShape() { + scale = "1 1 1"; + dataBlock = "StationVehicle"; + lockCount = "0"; + homingCount = "0"; + team = %obj.team; + position = %pos; + rotation = %rot; + }; + + // Add the station to the v-pads mission group for cleanup and power. + %group.add(%sv); + %sv.setPersistent(false); // set the station to not save. + + // Apparently called to early on mission load done, call it now. + %sv.getDataBlock().gainPower(%sv); + + // Create the trigger + %sv.getDataBlock().createTrigger(%sv); + %sv.pad = %obj; + %obj.station = %sv; + %sv.trigger.mainObj = %obj; + %sv.trigger.disableObj = %sv; + + // Set the sensor group. + if(%sv.getTarget() != -1) + setTargetSensorGroup(%sv.getTarget(), %obj.team); + + //Remove unwanted vehicles + if(%obj.scoutVehicle !$= "Removed") + %sv.vehicle[scoutvehicle] = true; + if(%obj.assaultVehicle !$= "Removed") + %sv.vehicle[assaultVehicle] = true; + if(%obj.mobileBaseVehicle !$= "Removed") + { + %sv.vehicle[mobileBasevehicle] = true; + // z0dd - ZOD, 4/20/02. Enable MPB Teleporter. + %sv.getDataBlock().createTeleporter(%sv, %group); + } + if(%obj.scoutFlyer !$= "Removed") + %sv.vehicle[scoutFlyer] = true; + if(%obj.bomberFlyer !$= "Removed") + %sv.vehicle[bomberFlyer] = true; + if(%obj.hapcFlyer !$= "Removed") + %sv.vehicle[hapcFlyer] = true; +} + +function StationVehiclePad::onEndSequence(%data, %obj, %thread) +{ + if(%thread == $ActivateThread) + { + %obj.ready = true; + %obj.stopThread($ActivateThread); + } + Parent::onEndSequence(%data, %obj, %thread); +} + +//////////////////////////////////////////////////////////////////////////////// +/// -Mobile Base Inventory- //////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +/// -Mobile Base- ////////////////////////////////////////////////////////////// +//Function -- onAdd (%this, %obj) +// %this = Object data block +// %obj = Object being added +//Decription -- Called when the object is added to the mission +//////////////////////////////////////////////////////////////////////////////// +function MobileInvStation::onAdd(%this, %obj) +{ +} + +function MobileInvStation::createTrigger(%this, %obj) +{ + Parent::onAdd(%this, %obj); + + %obj.setRechargeRate(%obj.getDatablock().rechargeRate); + %trigger = new Trigger() + { + dataBlock = stationTrigger; + polyhedron = "-0.75 0.75 0.1 1.5 0.0 0.0 0.0 -1.5 0.0 0.0 0.0 2.3"; + }; + MissionCleanup.add(%trigger); + %trigger.setTransform(%obj.vehicle.getSlotTransform(2)); + + %trigger.station = %obj; + %trigger.mainObj = %obj; + %trigger.disableObj = %obj; + + %obj.trigger = %trigger; +// createTarget(%obj, 'Inventory Station', "", "", 'Station', 0, 0); +} + +/// -Mobile Base- ////////////////////////////////////////////////////////////// +//Function -- stationReady(%data, %obj) +// %data = Station Data Block +// %obj = Station Object +//Decription -- Called when station has been triggered and animation is +// completed +//////////////////////////////////////////////////////////////////////////////// +function MobileInvStation::stationReady(%data, %obj) +{ + //Display the Inventory Station GUI here + %obj.notReady = 1; + %obj.inUse = "Down"; + %obj.schedule(200,"playThread",$ActivateThread,"activate1"); + %obj.getObjectMount().playThread($ActivateThread,"Activate"); + %player = %obj.triggeredBy; + %energy = %player.getEnergyLevel(); + %player.setCloaked(true); + %player.schedule(900, "setCloaked", false); + if (!%player.client.isAIControlled()) + buyFavorites(%player.client); + + %player.setEnergyLevel(%energy); +} + +/// -Mobile Base- ////////////////////////////////////////////////////////////// +//Function -- stationFinished(%data, %obj) +// %data = Station Data Block +// %obj = Station Object +//Decription -- Called when player has left the station +//////////////////////////////////////////////////////////////////////////////// +function MobileInvStation::stationFinished(%data, %obj) +{ + //Hide the Inventory Station GUI +} + +/// -Mobile Base- ////////////////////////////////////////////////////////////// +//Function -- getSound(%data, %forward) +// %data = Station Data Block +// %forward = direction the animation is playing +//Decription -- This sound will be played at the same time as the activate +// animation. +//////////////////////////////////////////////////////////////////////////////// +function MobileInvStation::getSound(%data, %forward) +{ + if(%forward) + return "MobileBaseInventoryActivateSound"; + else + return false; +} + +/// -Mobile Base- ////////////////////////////////////////////////////////////// +//Function -- setPlayerPosition(%data, %obj, %trigger, %colObj) +// %data = Station Data Block +// %obj = Station Object +// %trigger = Stations trigger +// %colObj = Object that is at the station +//Decription -- Called when player enters the trigger. Used to set the player +// in the center of the station. +//////////////////////////////////////////////////////////////////////////////// +function MobileInvStation::setPlayersPosition(%data, %obj, %trigger, %colObj) +{ + %vel = getWords(%colObj.getVelocity(), 0, 1) @ " 0"; + if((VectorLen(%vel) < 22) && (%obj.triggeredBy != %colObj)) + { + %pos = %trigger.position; + %colObj.setvelocity("0 0 0"); + %rot = getWords(%colObj.getTransform(),3, 6); +// %colObj.setTransform(getWord(%pos,0) @ " " @ getWord(%pos,1) - 0.75 @ " " @ getWord(%pos,2)+0.7 @ " " @ %rot);//center player on object + %colObj.setTransform(getWord(%pos,0) @ " " @ getWord(%pos,1) @ " " @ getWord(%pos,2)+0.8 @ " " @ %rot);//center player on object + %colObj.setMoveState(true); + %colObj.schedule(1600,"setMoveState", false); + %colObj.setvelocity("0 0 0"); + return true; + } + return false; +} + +function MobileInvStation::onDamage() +{ +} + +function MobileInvStation::damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType) +{ + //If vehicle station is hit then apply damage to the vehicle + %targetObject.getObjectMount().damage(%sourceObject, %position, %amount, %damageType); +} + +//////////////////////////////////////////////////////////////////////////////// +/// -Station Trigger- ////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +////-Station Trigger-/////////////////////////////////////////////////////////// +//Function -- onEnterTrigger (%data, %obj, %colObj) +// %data = Trigger Data Block +// %obj = Trigger Object +// %colObj = Object that collided with the trigger +//Decription -- Called when trigger has been triggered +//////////////////////////////////////////////////////////////////////////////// +function stationTrigger::onEnterTrigger(%data, %obj, %colObj) //Did a shitty RPG hack to ask if the player wants to pay before actually running the inv.. +{ + //make sure it's a player object, and that that object is still alive + if(%colObj.getDataBlock().className !$= "Armor" || %colObj.getState() $= "Dead") + return; + + %colObj.client.isAtInv = true; + %colObj.obj = %obj; + %colObj.data = %data; + + if ($CurrentMissionType $= "RPG") + { + if (%colObj.client.money > 100) + commandToClient(%colObj.client,'HandleScriptedCommand',1,"Refill","To refill your inventory, you must pay $100.","commandToServer('DoRefill');"); + else + messageClient(%colObj.client,'msgNotEnoughCashForRefill',"\c3You do not have enough money to refill your inventory."); + } + else + serverCmdDoRefill(%colObj.client); + return; +} + +////-Station Trigger-/////////////////////////////////////////////////////////// +//Function -- onLeaveTrigger (%data, %obj, %colObj) +// %data = Trigger Data Block +// %obj = Trigger Object +// %colObj = Object that collided with the trigger +//Decription -- Called when trigger has been untriggered +//////////////////////////////////////////////////////////////////////////////// +function stationTrigger::onLeaveTrigger(%data, %obj, %colObj) +{ + if(%colObj.getDataBlock().className !$= "Armor") + return; + + // z0dd - ZOD, 7/13/02 Part of hack to keep people from mounting + // vehicles in disallowed armors. + %colObj.client.inInv = false; + + %colObj.inStation = false; + commandToClient(%colObj.client,'setStationKeys', false); + commandToClient(%colObj.client,'HandleScriptedCommand',0,"MessageBoxYesNoDLG"); + if(%obj.station) + { + if(%obj.station.triggeredBy == %colObj) + { + %obj.station.getDataBlock().stationFinished(%obj.station); + %obj.station.getDataBlock().endRepairing(%obj.station); + %obj.station.triggeredBy = ""; + %obj.station.getDataBlock().stationTriggered(%obj.station, 0); + + if(!%colObj.teleporting) + %colObj.station = ""; + if(%colObj.getMountedImage($WeaponSlot) == 0 && !%colObj.teleporting) + { + if(%colObj.inv[%colObj.lastWeapon]) + %colObj.use(%colObj.lastWeapon); + + if(%colObj.getMountedImage($WeaponSlot) == 0) + %colObj.selectWeaponSlot( 0 ); + } + } + } +} + +////-Station Trigger-/////////////////////////////////////////////////////////// +//Function -- stationTriggered(%data, %obj, %isTriggered) +// %data = Station Data Block +// %obj = Station Object +// %isTriggered = 1 if triggered; 0 if status changed to +// untriggered +//Decription -- Called when a "station trigger" has been triggered or +// untriggered +//////////////////////////////////////////////////////////////////////////////// +function Station::stationTriggered(%data, %obj, %isTriggered) +{ + if(%isTriggered) + { + // ---------------------------------------------------------------------------- + // z0dd - ZOD, 6/20/03. Pop up veh station hud when player steps on veh pad + if(%obj.getDataBlock().getName() $= StationVehicle) + { + messageClient( %obj.triggeredBy.client, 'CloseHud', "", 'scoreScreen' ); + messageClient( %obj.triggeredBy.client, 'CloseHud', "", 'inventoryScreen' ); + commandToClient(%obj.triggeredBy.client, 'StationVehicleShowHud'); + } + // ---------------------------------------------------------------------------- + + %obj.setThreadDir($ActivateThread, TRUE); + %obj.playThread($ActivateThread,"activate"); + %obj.playAudio($ActivateSound, %data.getSound(true)); + %obj.inUse = "Up"; + } + else + { + if(%obj.getDataBlock().getName() !$= StationVehicle) + { + %obj.stopThread($ActivateThread); + if(%obj.getObjectMount()) + %obj.getObjectMount().stopThread($ActivateThread); + %obj.inUse = "Down"; + } + else + { + %obj.setThreadDir($ActivateThread, FALSE); + %obj.playThread($ActivateThread,"activate"); + %obj.playAudio($ActivateSound, %data.getSound(false)); + %obj.inUse = "Down"; + } + } +} + +////-Station-/////////////////////////////////////////////////////////////////// +//Function -- onEndSequence(%data, %obj, %thread) +// %data = Station Data Block +// %obj = Station Object +// %thread = Thread number that the animation is associated +// with / running on. +//Decription -- Called when an animation sequence is finished playing +//////////////////////////////////////////////////////////////////////////////// +function Station::onEndSequence(%data, %obj, %thread) +{ + if(%thread == $ActivateThread) + { + if(%obj.inUse $= "Up") + { + %data.stationReady(%obj); + %player = %obj.triggeredBy; + if(%data.doesRepair && !%player.stationRepairing && %player.getDamageLevel() != 0) { + %oldRate = %player.getRepairRate(); + %player.setRepairRate(%oldRate + 0.00625); + %player.stationRepairing = 1; + } + } + else + { + if(%obj.getDataBlock().getName() !$= MobileInvStation) + { + %obj.stopThread($ActivateThread); + %obj.inUse = "Down"; + } + } + } + Parent::onEndSequence(%data, %obj, %thread); +} + +////-Station-/////////////////////////////////////////////////////////////////// +//Function -- onCollision(%data, %obj, %colObj) +// %data = Station Data Block +// %obj = Station Object +// %colObj = Object that collided with the station +//Decription -- Called when an object collides with a station +//////////////////////////////////////////////////////////////////////////////// +function Station::onCollision(%data, %obj, %colObj) +{ + // Currently Not Needed +} + +////-Station-/////////////////////////////////////////////////////////////////// +//Function -- endRepairing(%data, %obj) +// %data = Station Data Block +// %obj = Station Object +//Decription -- Called to stop repairing the object +//////////////////////////////////////////////////////////////////////////////// +function Station::endRepairing(%data, %obj) +{ + if(%obj.triggeredBy.stationRepairing) + { + %oldRate = %obj.triggeredBy.getRepairRate(); + %obj.triggeredBy.setRepairRate(%oldRate - 0.00625); + %obj.triggeredBy.stationRepairing = 0; + } +} + +////-Station Trigger-/////////////////////////////////////////////////////////// +//Function -- onTickTrigger(%data, %obj) +// %data = Trigger Data Block +// %obj = Trigger Object +//Decription -- Called every tick if triggered +//////////////////////////////////////////////////////////////////////////////// +function stationTrigger::onTickTrigger(%data, %obj) +{ +} + +//****************************************************************************** +//* Station General - Functions * +//****************************************************************************** + +//function Station::onGainPowerEnabled(%data, %obj) + +function Station::onLosePowerDisabled(%data, %obj) +{ + Parent::onLosePowerDisabled(%data, %obj); + + // check to see if a player was using this station + %occupied = %obj.triggeredBy; + if(%occupied > 0) + { + if(%data.doesRepair) + %data.endRepairing(%obj); + // if it's a deployed station, stop "flashing panels" thread + if(%data.getName() $= DeployedStationInventory) + %obj.stopThread($ActivateThread); + // reset some attributes + %occupied.setCloaked(false); + %occupied.station = ""; + %occupied.inStation = false; + %obj.triggeredBy = ""; + // restore "toggle inventory hud" key + commandToClient(%occupied.client,'setStationKeys', false); + // re-mount last weapon or weapon slot 0 + if(%occupied.getMountedImage($WeaponSlot) == 0) + { + if(%occupied.inv[%occupied.lastWeapon]) + %occupied.use(%occupied.lastWeapon); + if(%occupied.getMountedImage($WeaponSlot) == 0) + %occupied.selectWeaponSlot( 0 ); + } + } +} + +// z0dd - ZOD, 4/20/02 +// Pull these functions, they are unneeded because we changed the way +// Vehicle stations are added to the game, they are now treated the +// same as any other mapper added object. +//function StationVehiclePad::gainPower(%data, %obj) +//{ +// %obj.station.setSelfPowered(); + // z0dd - ZOD, 4/20/02 Repower the MPB Teleporter +// if(isObject(%obj.station.teleporter)) +// %obj.station.teleporter.setSelfPowered(); +// Parent::gainPower(%data, %obj); +//} + +//function StationVehiclePad::losePower(%data, %obj) +//{ +// %obj.station.clearSelfPowered(); + // z0dd - ZOD, 4/20/02 Kill the telepoters power too +// if(isObject(%obj.station.teleporter)) +// %obj.station.teleporter.clearSelfPowered(); +// Parent::losePower(%data, %obj); +//} + +//--------------------------------------------------------------------------- +// DeployedStationInventory: +//--------------------------------------------------------------------------- + +function DeployedStationInventory::stationReady(%data, %obj) +{ + %obj.notReady = 1; + %player = %obj.triggeredBy; + %obj.playThread($ActivateThread,"activate1"); + // function below found in inventoryHud.cs + if (!%player.client.isAIControlled()) + buyDeployableFavorites(%player.client); +} + +function DeployedStationInventory::stationFinished(%data, %obj) +{ +} + +function DeployedStationInventory::setPlayersPosition(%data, %obj, %trigger, %colObj) +{ + %vel = getWords(%colObj.getVelocity(), 0, 1) @ " 0"; + if((VectorLen(%vel) < 28) && (%obj.triggeredBy != %colObj)) // z0dd - ZOD, 4/27/02. Can engage deployed inv at higher speeds. Was 22. Now ~100kph + { + // ------------------------------------------------- + // z0dd - ZOD, 4/14/02. No view change at remote inv + %colObj.setvelocity("0 0 0"); + %colObj.setMoveState(true); + %colObj.schedule(400,"setMoveState", false); // z0dd - ZOD, 4/27/02. Equip at remote inv in 1/4 base time. Was 1600 + return true; + // ------------------------------------------------- + } + return false; +} + +function DeployedStationInventory::onDestroyed(%data, %obj, %prevState) +{ + %obj.trigger.delete(); + // decrement team deployed count for this item + $TeamDeployedCount[%obj.team, InventoryDeployable]--; + + // when a station is destroyed, we don't need its trigger any more + %obj.schedule(700, "delete"); + + Parent::onDestroyed(%data, %obj, %prevState); +} + +/// -Deployable Inventory- ////////////////////////////////////////////////////////////// +//Function -- getSound(%data, %forward) +// %data = Station Data Block +// %forward = direction the animation is playing +//Decription -- This sound will be played at the same time as the activate +// animation. +//////////////////////////////////////////////////////////////////////////////// +function DeployedStationInventory::getSound(%data, %forward) +{ + if(%forward) + return "DepInvActivateSound"; + else + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +/// z0dd - ZOD: Execute the MPB Teleporter code - ////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + +exec("scripts/mpbTeleporter.cs"); diff --git a/scripts/supportClassic.cs b/scripts/supportClassic.cs index 4618457..5da4c22 100644 --- a/scripts/supportClassic.cs +++ b/scripts/supportClassic.cs @@ -1,215 +1,215 @@ -///////////////////////////////////////////////////////////////////////////////////////// -// z0dd - ZOD: Generic Console Spam fixes /////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////// - -function Projectile::isMounted(%this) -{ - return 0; -} - -function VehicleBlocker::getDataBlock(%this) -{ - return %this; -} - -function VehicleBlocker::getName(%this) -{ - return %this; -} - -function WaterBlock::damage(%this) -{ - // Do nothing -} - -function InteriorInstance::getDataBlock(%this) -{ - return %this; -} - -function InteriorInstance::getName(%this) -{ - return "InteriorInstance"; -} - -function TerrainBlock::getDataBlock(%this) -{ - return %this; -} - -function TerrainBlock::getName(%this) -{ - return "Terrain"; -} - -function AIConnection::isMounted(%client) -{ - %vehicle = %client.getControlObject(); - %className = %vehicle.getDataBlock().className; - if(%className $= WheeledVehicleData || %className $= FlyingVehicleData || %className $= HoverVehicleData) - return true; - else - return false; -} - -function ForceFieldBareData::isMounted(%obj) -{ - // created to prevent console errors -} - -function ForceFieldBareData::damageObject(%data, %targetObject, %position, %sourceObject, %amount, %damageType) -{ - // created to prevent console errors -} - -function ItemData::onPickup(%this, %obj, %player, %amount) -{ - // %this = Object datablock - // %obj = Object ID number - // %player = player - // %amount = amount picked up (1) - - // Created to prevent console errors related to picking up items -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Random Teams code by Founder (founder@mechina.com) 6/13/02 /////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////// - -// Couple other files edited for Random Teams. -// Hud.cs and DefaultGame.cs -function AIConnection::startMission(%client) -{ - // assign the team - if (%client.team <= 0) - Game.assignClientTeam(%client); - - if(%client.lastTeam !$= "") - { - if(%client.team != %client.lastTeam) - Game.AIChangeTeam( %client, %client.lastTeam ); - } - // set the client's sensor group... - setTargetSensorGroup( %client.target, %client.team ); - %client.setSensorGroup( %client.team ); - - // sends a message so everyone know the bot is in the game... - Game.AIHasJoined(%client); - %client.matchStartReady = true; - - // spawn the bot... - onAIRespawn(%client); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// z0dd - ZOD: Universal functions ////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////// - -function stripTaggedVar(%var) -{ - return stripChars( detag( getTaggedString( %var ) ), "\cp\co\c6\c7\c8\c9" ); -} - -// Removes triggers from Siege when players switch sides, also used in practiceCTF -function cleanTriggers(%group) -{ - if (%group > 0) - %depCount = %group.getCount(); - else - return; - - for(%i = 0; %i < %depCount; %i++) - { - %deplObj = %group.getObject(%i); - if(isObject(%deplObj)) - { - if(%deplObj.trigger !$= "") - %deplObj.trigger.schedule(0, "delete"); - } - } -} - -// ----------------------------------------------------- -// z0dd - ZOD, 6/22/02. Hack to eliminate texture cheats -package cloaking -{ - function ShapeBase::setCloaked(%obj, %bool) - { - parent::setCloaked(%obj, %bool); - if(%bool) - %obj.startFade(0, 800, true); - else - %obj.startFade(0, 0, false); - } -}; -activatePackage(cloaking); - -function VehicleData::onCollision( %data, %obj, %col ) -{ - // Keep vehicle ghost from harming players? - if(%obj.getDamageState() $= "Destroyed") - return; - - if(!isObject(%obj) || !isObject(%col)) - return; - - // Will cause vehicles to take damage when they collide with armors - //if(%col.getDataBlock().className $= "Armor") - //{ - // %vel = %obj.getVelocity(); - // %vecLen = vectorDot(%vel, vectorNormalize(%vel)); - - // if(%vecLen > %data.collDamageThresholdVel) - // %data.damageObject(%obj, 0, VectorAdd(%vec, %obj.getPosition()), - // %vecLen * %data.collDamageMultiplier, $DamageType::Impact); - - // %obj.playAudio(0, %data.hardImpactSound); -} - -function serverCmdPrivateMessageSent(%client, %target, %text) -{ - // Client side: - //commandToServer('PrivateMessageSent', %target, %text); - - if((%text $= "") || spamAlert(%client)) - return; - - if(%client.isAdmin) - { - %snd = '~wfx/misc/diagnostic_on.wav'; - if(strlen(%text) >= $Host::MaxMessageLen) - %text = getSubStr(%text, 0, $Host::MaxMessageLen); - - messageClient(%target, 'MsgPrivate', '\c5Message from %1: \c3%2%3', %client.name, %text, %snd); - } - else - messageClient(%client, 'MsgError', '\c4Only admins can send private messages'); -} - -////////////////////////////////////////////////////////////////////////////// -// z0dd - ZOD, 10/03/02. Part of flag collision bug hack. -////////////////////////////////////////////////////////////////////////////// - -datablock TriggerData(flagTrigger) -{ - tickPeriodMS = 10; -}; - -function flagTrigger::onEnterTrigger(%data, %obj, %colObj) -{ - %flag = %obj.flag; - if($flagStatus[%flag.team] $= "") - %flag.getDataBlock().onCollision(%flag, %colObj); - else - return; -} - -function flagTrigger::onLeaveTrigger(%data, %obj, %colObj) -{ - // Thou shalt not spam -} - -function flagTrigger::onTickTrigger(%data, %obj) -{ - // Thou shalt not spam -} +///////////////////////////////////////////////////////////////////////////////////////// +// z0dd - ZOD: Generic Console Spam fixes /////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// + +function Projectile::isMounted(%this) +{ + return 0; +} + +function VehicleBlocker::getDataBlock(%this) +{ + return %this; +} + +function VehicleBlocker::getName(%this) +{ + return %this; +} + +function WaterBlock::damage(%this) +{ + // Do nothing +} + +function InteriorInstance::getDataBlock(%this) +{ + return %this; +} + +function InteriorInstance::getName(%this) +{ + return "InteriorInstance"; +} + +function TerrainBlock::getDataBlock(%this) +{ + return %this; +} + +function TerrainBlock::getName(%this) +{ + return "Terrain"; +} + +function AIConnection::isMounted(%client) +{ + %vehicle = %client.getControlObject(); + %className = %vehicle.getDataBlock().className; + if(%className $= WheeledVehicleData || %className $= FlyingVehicleData || %className $= HoverVehicleData) + return true; + else + return false; +} + +function ForceFieldBareData::isMounted(%obj) +{ + // created to prevent console errors +} + +function ForceFieldBareData::damageObject(%data, %targetObject, %position, %sourceObject, %amount, %damageType) +{ + // created to prevent console errors +} + +function ItemData::onPickup(%this, %obj, %player, %amount) +{ + // %this = Object datablock + // %obj = Object ID number + // %player = player + // %amount = amount picked up (1) + + // Created to prevent console errors related to picking up items +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Random Teams code by Founder (founder@mechina.com) 6/13/02 /////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// + +// Couple other files edited for Random Teams. +// Hud.cs and DefaultGame.cs +function AIConnection::startMission(%client) +{ + // assign the team + if (%client.team <= 0) + Game.assignClientTeam(%client); + + if(%client.lastTeam !$= "") + { + if(%client.team != %client.lastTeam) + Game.AIChangeTeam( %client, %client.lastTeam ); + } + // set the client's sensor group... + setTargetSensorGroup( %client.target, %client.team ); + %client.setSensorGroup( %client.team ); + + // sends a message so everyone know the bot is in the game... + Game.AIHasJoined(%client); + %client.matchStartReady = true; + + // spawn the bot... + onAIRespawn(%client); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// z0dd - ZOD: Universal functions ////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// + +function stripTaggedVar(%var) +{ + return stripChars( detag( getTaggedString( %var ) ), "\cp\co\c6\c7\c8\c9" ); +} + +// Removes triggers from Siege when players switch sides, also used in practiceCTF +function cleanTriggers(%group) +{ + if (%group > 0) + %depCount = %group.getCount(); + else + return; + + for(%i = 0; %i < %depCount; %i++) + { + %deplObj = %group.getObject(%i); + if(isObject(%deplObj)) + { + if(%deplObj.trigger !$= "") + %deplObj.trigger.schedule(0, "delete"); + } + } +} + +// ----------------------------------------------------- +// z0dd - ZOD, 6/22/02. Hack to eliminate texture cheats +package cloaking +{ + function ShapeBase::setCloaked(%obj, %bool) + { + parent::setCloaked(%obj, %bool); + if(%bool) + %obj.startFade(0, 800, true); + else + %obj.startFade(0, 0, false); + } +}; +activatePackage(cloaking); + +function VehicleData::onCollision( %data, %obj, %col ) +{ + // Keep vehicle ghost from harming players? + if(%obj.getDamageState() $= "Destroyed") + return; + + if(!isObject(%obj) || !isObject(%col)) + return; + + // Will cause vehicles to take damage when they collide with armors + //if(%col.getDataBlock().className $= "Armor") + //{ + // %vel = %obj.getVelocity(); + // %vecLen = vectorDot(%vel, vectorNormalize(%vel)); + + // if(%vecLen > %data.collDamageThresholdVel) + // %data.damageObject(%obj, 0, VectorAdd(%vec, %obj.getPosition()), + // %vecLen * %data.collDamageMultiplier, $DamageType::Impact); + + // %obj.playAudio(0, %data.hardImpactSound); +} + +function serverCmdPrivateMessageSent(%client, %target, %text) +{ + // Client side: + //commandToServer('PrivateMessageSent', %target, %text); + + if((%text $= "") || spamAlert(%client)) + return; + + if(%client.isAdmin) + { + %snd = '~wfx/misc/diagnostic_on.wav'; + if(strlen(%text) >= $Host::MaxMessageLen) + %text = getSubStr(%text, 0, $Host::MaxMessageLen); + + messageClient(%target, 'MsgPrivate', '\c5Message from %1: \c3%2%3', %client.name, %text, %snd); + } + else + messageClient(%client, 'MsgError', '\c4Only admins can send private messages'); +} + +////////////////////////////////////////////////////////////////////////////// +// z0dd - ZOD, 10/03/02. Part of flag collision bug hack. +////////////////////////////////////////////////////////////////////////////// + +datablock TriggerData(flagTrigger) +{ + tickPeriodMS = 10; +}; + +function flagTrigger::onEnterTrigger(%data, %obj, %colObj) +{ + %flag = %obj.flag; + if($flagStatus[%flag.team] $= "") + %flag.getDataBlock().onCollision(%flag, %colObj); + else + return; +} + +function flagTrigger::onLeaveTrigger(%data, %obj, %colObj) +{ + // Thou shalt not spam +} + +function flagTrigger::onTickTrigger(%data, %obj) +{ + // Thou shalt not spam +} diff --git a/scripts/turret.cs b/scripts/turret.cs index 3a705a4..a6cbe0e 100644 --- a/scripts/turret.cs +++ b/scripts/turret.cs @@ -1,359 +1,356 @@ -// sounds and effects -/////////////////////// -datablock EffectProfile(DeployableExplosionEffect) -{ - effectname = "explosions/explosion.xpl10"; - minDistance = 10; - maxDistance = 50; -}; - -datablock AudioProfile(DeployablesExplosionSound) -{ - filename = "fx/explosions/deployables_explosion.wav"; - description = AudioExplosion3d; - preload = true; - effect = DeployableExplosionEffect; -}; - -//-------------------------------------------------------------------------- -// Shockwave -//-------------------------------------------------------------------------- -datablock ShockwaveData(TurretShockwave) -{ - width = 6.0; - numSegments = 20; - numVertSegments = 2; - velocity = 8; - acceleration = 20.0; - lifetimeMS = 1500; - height = 1.0; - verticalCurve = 0.5; - - mapToTerrain = false; - renderBottom = true; - - texture[0] = "special/shockwave4"; - texture[1] = "special/gradient"; - texWrap = 6.0; - - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - - colors[0] = "0.8 0.8 0.8 1.00"; - colors[1] = "0.8 0.5 0.2 0.20"; - colors[2] = "1.0 0.5 0.5 0.0"; -}; - -//-------------------------------------------------------------------------- -// Explosion -//-------------------------------------------------------------------------- -datablock ExplosionData(TurretExplosion) -{ - explosionShape = "effect_plasma_explosion.dts"; - soundProfile = ShapeExplosionSound; - faceViewer = true; - shockwave = TurretShockwave; -}; - -datablock ExplosionData(SmallTurretExplosion) -{ - soundProfile = DeployablesExplosionSound; - faceViewer = true; - - explosionShape = "effect_plasma_explosion.dts"; - sizes[0] = "0.3 0.3 0.3"; - sizes[1] = "0.3 0.3 0.3"; - times[0] = 0; - times[1] = 1; -}; - - -//-------------------------------------------------------------------------- -// Turret Debris -//-------------------------------------------------------------------------- -datablock DebrisData( TurretDebris ) -{ - explodeOnMaxBounce = false; - - elasticity = 0.20; - friction = 0.5; - - lifetime = 17.0; - lifetimeVariance = 0.0; - - minSpinSpeed = 60; - maxSpinSpeed = 600; - - numBounces = 10; - bounceVariance = 0; - - staticOnMaxBounce = true; - - useRadiusMass = true; - baseRadius = 0.4; - - velocity = 9.0; - velocityVariance = 4.5; -}; - -datablock DebrisData( TurretDebrisSmall ) -{ - explodeOnMaxBounce = false; - - elasticity = 0.20; - friction = 0.5; - - lifetime = 17.0; - lifetimeVariance = 0.0; - - minSpinSpeed = 60; - maxSpinSpeed = 600; - - numBounces = 10; - bounceVariance = 0; - - staticOnMaxBounce = true; - - useRadiusMass = true; - baseRadius = 0.2; - - velocity = 5.0; - velocityVariance = 2.5; -}; - - -//-------------------------------------------------------------------------- -// Turret base class functionality. Barrels are in scripts/weapons/*.cs -// -// -//-------------------------------------------------------------------------- - -function TurretData::create(%block) -{ - %obj = new Turret() { - dataBlock = %block; - }; - - return %obj; -} - -datablock SensorData(TurretBaseSensorObj) -{ - detects = true; - detectsUsingLOS = true; - detectsPassiveJammed = false; - detectsActiveJammed = false; - detectsCloaked = false; - detectionPings = true; - detectRadius = 80; -}; - - -datablock TurretData(TurretBaseLarge) : TurretDamageProfile -{ - className = TurretBase; - catagory = "Turrets"; - shapeFile = "turret_base_large.dts"; - preload = true; - - mass = 1.0; // Not really relevant - - maxDamage = 2.25; - destroyedLevel = 2.25; - disabledLevel = 1.35; - explosion = TurretExplosion; - expDmgRadius = 15.0; - expDamage = 0.66; - expImpulse = 2000.0; - repairRate = 0; - emap = true; - - thetaMin = 15; - thetaMax = 140; - - isShielded = true; - energyPerDamagePoint = 50; - maxEnergy = 150; - rechargeRate = 0.31; - humSound = SensorHumSound; - pausePowerThread = true; - - canControl = true; - cmdCategory = "Tactical"; - cmdIcon = CMDTurretIcon; - cmdMiniIconName = "commander/MiniIcons/com_turretbase_grey"; - targetNameTag = 'Base'; - targetTypeTag = 'Turret'; - sensorData = TurretBaseSensorObj; - sensorRadius = TurretBaseSensorObj.detectRadius; - sensorColor = "0 212 45"; - - firstPersonOnly = true; - - debrisShapeName = "debris_generic.dts"; - debris = TurretDebris; -}; - -function TurretData::onGainPowerEnabled(%data, %obj) -{ - Parent::onGainPowerEnabled(%data, %obj); - setTargetSensorData(%obj.target, %data.sensorData); -} - -function TurretData::onLosePowerDisabled(%data, %obj) -{ - // Must kick players out of turret - - Parent::onLosePowerDisabled(%data, %obj); - %obj.clearTarget(); - setTargetSensorData(%obj.target, 0); -} - -function TurretData::selectTarget(%this, %turret) -{ - %turretTarg = %turret.getTarget(); - - if(%turretTarg == -1) - return; - - // if the turret isn't on a team, don't fire at anyone - if(getTargetSensorGroup(%turretTarg) == 0) - { - %turret.clearTarget(); - return; - } - - // stop firing if turret is disabled or if it needs power and isn't powered - if((!%turret.isPowered()) && (!%turret.needsNoPower)) - { - %turret.clearTarget(); - return; - } - - %TargetSearchMask = $TypeMasks::PlayerObjectType | $TypeMasks::VehicleObjectType; - - InitContainerRadiusSearch(%turret.getMuzzlePoint(0), - %turret.getMountedImage(0).attackRadius, - %TargetSearchMask); - - while ((%potentialTarget = ContainerSearchNext()) != 0) - { - %potTargTarg = %potentialTarget.getTarget(); - if (%turret.isValidTarget(%potentialTarget) && (getTargetSensorGroup(%turretTarg) != getTargetSensorGroup(%potTargTarg))) - { - %turret.setTargetObject(%potentialTarget); - return; - } - } -} - -function TurretData::replaceCallback(%this, %turret, %engineer) -{ - // This is a valid replacement. First, let's see if the engineer - // still has the correct pack in place... - if (%engineer.getMountedImage($BackPackSlot) != 0) - { - %barrel = %engineer.getMountedImage($BackPackSlot).turretBarrel; - if (%barrel !$= "") - { - // if there was a barrel there before, get rid of it - %turret.unmountImage(0); - // remove the turret barrel pack - %engineer.setInventory(%engineer.getMountedImage($BackPackSlot).item, 0); - // mount new barrel on base - %turret.mountImage(%barrel, 0, false); - - // ------------------------------------------ - // z0dd - ZOD, 4/20/02. modular MPB turret - %turname = %turret.getDatablock().getName(); - if(%turname $= "MobileTurretBase") - { - %turret.getObjectMount().barrel = %barrel; - } - // ------------------------------------------ - } - else - { - // Player doesn't have the correct pack on... - } - } - else - { - // Player doesn't have any pack on... - } -} - -function TurretData::onDestroyed(%this, %turret, %prevState) -{ - if( isObject( %turret.lastProjectile ) ) - %turret.lastProjectile.delete(); - - Parent::onDestroyed(%this, %turret, %prevState); -} - -function checkTurretMount(%data, %obj, %slot) -{ - // search for a turret base in player's LOS - %eyeVec = VectorNormalize(%obj.getEyeVector()); - %srchRange = VectorScale(%eyeVec, 5.0); // look 5m for a turret base - %plTm = %obj.getEyeTransform(); - %plyrLoc = firstWord(%plTm) @ " " @ getWord(%plTm, 1) @ " " @ getWord(%plTm, 2); - %srchEnd = VectorAdd(%plyrLoc, %srchRange); - %potTurret = ContainerRayCast(%obj.getEyeTransform(), %srchEnd, $TypeMasks::TurretObjectType); - if(%potTurret != 0) - { - %otherMountObj = "foo"; - - %name = %potTurret.getDatablock().getName(); // z0dd - ZOD, 4/20/02. modular MPB turret - if(%name $= "TurretBaseLarge" || %name $= "MobileTurretBase" || %name $= %otherMountObj) // z0dd - ZOD, 4/20/02. modular MPB turret - { - // found a turret base, what team is it on? - if(%potTurret.team == %obj.client.team) - { - if(%potTurret.getDamageState() !$= "Enabled") - { - // the base is destroyed - messageClient(%obj.client, 'MsgBaseDestroyed', "\c2Turret is disabled, cannot mount barrel."); // z0dd - ZOD, 4/20/02. modular MPB turret - %obj.setImageTrigger($BackpackSlot, false); - } - else - { - // it's a functional turret base on our team! stick the barrel on it - messageClient(%obj.client, 'MsgTurretMount', "\c2Mounting barrel pack on turret."); // z0dd - ZOD, 4/20/02. modular MPB turret - serverPlay3D(TurretPackActivateSound, %potTurret.getTransform()); - %potTurret.initiateBarrelSwap(%obj); - } - } - else - { - // whoops, wrong team - messageClient(%obj.client, 'MsgTryEnemyTurretMount', "\c2Cannot mount a barrel on an enemy turret base!"); - %obj.setImageTrigger($BackpackSlot, false); - } - } - else - { - // tried to mount barrel on some other turret type - messageClient(%obj.client, 'MsgNotTurretBase', "\c2Can only mount a barrel on a turret base."); - %obj.setImageTrigger($BackpackSlot, false); - } - } - else - { - // I don't see any turret - messageClient(%obj.client, 'MsgNoTurretBase', "\c2No turret within range."); - %obj.setImageTrigger($BackpackSlot, false); - } -} - -//-------------------------------------- Load Barrel Images -// -exec("scripts/turrets/mortarBarrelLarge.cs"); -exec("scripts/turrets/aaBarrelLarge.cs"); -exec("scripts/turrets/missileBarrelLarge.cs"); -exec("scripts/turrets/plasmaBarrelLarge.cs"); -exec("scripts/turrets/ELFBarrelLarge.cs"); -exec("scripts/turrets/outdoorDeployableBarrel.cs"); -exec("scripts/turrets/indoorDeployableBarrel.cs"); +// sounds and effects +/////////////////////// +datablock EffectProfile(DeployableExplosionEffect) +{ + effectname = "explosions/explosion.xpl10"; + minDistance = 10; + maxDistance = 50; +}; + +datablock AudioProfile(DeployablesExplosionSound) +{ + filename = "fx/explosions/deployables_explosion.wav"; + description = AudioExplosion3d; + preload = true; + effect = DeployableExplosionEffect; +}; + +//-------------------------------------------------------------------------- +// Shockwave +//-------------------------------------------------------------------------- +datablock ShockwaveData(TurretShockwave) +{ + width = 6.0; + numSegments = 20; + numVertSegments = 2; + velocity = 8; + acceleration = 20.0; + lifetimeMS = 1500; + height = 1.0; + verticalCurve = 0.5; + + mapToTerrain = false; + renderBottom = true; + + texture[0] = "special/shockwave4"; + texture[1] = "special/gradient"; + texWrap = 6.0; + + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; + + colors[0] = "0.8 0.8 0.8 1.00"; + colors[1] = "0.8 0.5 0.2 0.20"; + colors[2] = "1.0 0.5 0.5 0.0"; +}; + +//-------------------------------------------------------------------------- +// Explosion +//-------------------------------------------------------------------------- +datablock ExplosionData(TurretExplosion) +{ + explosionShape = "effect_plasma_explosion.dts"; + soundProfile = ShapeExplosionSound; + faceViewer = true; + shockwave = TurretShockwave; +}; + +datablock ExplosionData(SmallTurretExplosion) +{ + soundProfile = DeployablesExplosionSound; + faceViewer = true; + + explosionShape = "effect_plasma_explosion.dts"; + sizes[0] = "0.3 0.3 0.3"; + sizes[1] = "0.3 0.3 0.3"; + times[0] = 0; + times[1] = 1; +}; + + +//-------------------------------------------------------------------------- +// Turret Debris +//-------------------------------------------------------------------------- +datablock DebrisData( TurretDebris ) +{ + explodeOnMaxBounce = false; + + elasticity = 0.20; + friction = 0.5; + + lifetime = 17.0; + lifetimeVariance = 0.0; + + minSpinSpeed = 60; + maxSpinSpeed = 600; + + numBounces = 10; + bounceVariance = 0; + + staticOnMaxBounce = true; + + useRadiusMass = true; + baseRadius = 0.4; + + velocity = 9.0; + velocityVariance = 4.5; +}; + +datablock DebrisData( TurretDebrisSmall ) +{ + explodeOnMaxBounce = false; + + elasticity = 0.20; + friction = 0.5; + + lifetime = 17.0; + lifetimeVariance = 0.0; + + minSpinSpeed = 60; + maxSpinSpeed = 600; + + numBounces = 10; + bounceVariance = 0; + + staticOnMaxBounce = true; + + useRadiusMass = true; + baseRadius = 0.2; + + velocity = 5.0; + velocityVariance = 2.5; +}; + + +//-------------------------------------------------------------------------- +// Turret base class functionality. Barrels are in scripts/weapons/*.cs +// +// +//-------------------------------------------------------------------------- + +function TurretData::create(%block) +{ + %obj = new Turret() { + dataBlock = %block; + }; + + return %obj; +} + +datablock SensorData(TurretBaseSensorObj) +{ + detects = true; + detectsUsingLOS = true; + detectsPassiveJammed = false; + detectsActiveJammed = false; + detectsCloaked = false; + detectionPings = true; + detectRadius = 80; +}; + + +datablock TurretData(TurretBaseLarge) : TurretDamageProfile +{ + className = TurretBase; + catagory = "Turrets"; + shapeFile = "turret_base_large.dts"; + preload = true; + + mass = 1.0; // Not really relevant + + maxDamage = 2.25; + destroyedLevel = 2.25; + disabledLevel = 1.35; + explosion = TurretExplosion; + expDmgRadius = 15.0; + expDamage = 0.66; + expImpulse = 2000.0; + repairRate = 0; + emap = true; + + thetaMin = 15; + thetaMax = 140; + + isShielded = true; + energyPerDamagePoint = 50; + maxEnergy = 150; + rechargeRate = 0.31; + humSound = SensorHumSound; + pausePowerThread = true; + + canControl = true; + cmdCategory = "Tactical"; + cmdIcon = CMDTurretIcon; + cmdMiniIconName = "commander/MiniIcons/com_turretbase_grey"; + targetNameTag = 'Base'; + targetTypeTag = 'Turret'; + sensorData = TurretBaseSensorObj; + sensorRadius = TurretBaseSensorObj.detectRadius; + sensorColor = "0 212 45"; + + firstPersonOnly = true; + + debrisShapeName = "debris_generic.dts"; + debris = TurretDebris; +}; + +function TurretData::onGainPowerEnabled(%data, %obj) +{ + Parent::onGainPowerEnabled(%data, %obj); + setTargetSensorData(%obj.target, %data.sensorData); +} + +function TurretData::onLosePowerDisabled(%data, %obj) +{ + // Must kick players out of turret + + Parent::onLosePowerDisabled(%data, %obj); + %obj.clearTarget(); + setTargetSensorData(%obj.target, 0); +} + +function TurretData::selectTarget(%this, %turret) +{ + %turretTarg = %turret.getTarget(); + + if(%turretTarg == -1) + return; + + // if the turret isn't on a team, don't fire at anyone + if(getTargetSensorGroup(%turretTarg) == 0) + { + %turret.clearTarget(); + return; + } + + // stop firing if turret is disabled or if it needs power and isn't powered + if((!%turret.isPowered()) && (!%turret.needsNoPower)) + { + %turret.clearTarget(); + return; + } + + %TargetSearchMask = $TypeMasks::PlayerObjectType | $TypeMasks::VehicleObjectType; + + InitContainerRadiusSearch(%turret.getMuzzlePoint(0), + %turret.getMountedImage(0).attackRadius, + %TargetSearchMask); + + while ((%potentialTarget = ContainerSearchNext()) != 0) + { + %potTargTarg = %potentialTarget.getTarget(); + if (%turret.isValidTarget(%potentialTarget) && (getTargetSensorGroup(%turretTarg) != getTargetSensorGroup(%potTargTarg))) + { + %turret.setTargetObject(%potentialTarget); + return; + } + } +} + +function TurretData::replaceCallback(%this, %turret, %engineer) +{ + // This is a valid replacement. First, let's see if the engineer + // still has the correct pack in place... + if (%engineer.getMountedImage($BackPackSlot) != 0) + { + %barrel = %engineer.getMountedImage($BackPackSlot).turretBarrel; + if (%barrel !$= "") + { + // if there was a barrel there before, get rid of it + %turret.unmountImage(0); + // remove the turret barrel pack + %engineer.setInventory(%engineer.getMountedImage($BackPackSlot).item, 0); + // mount new barrel on base + %turret.mountImage(%barrel, 0, false); + + // ------------------------------------------ + // z0dd - ZOD, 4/20/02. modular MPB turret + %turname = %turret.getDatablock().getName(); + if(%turname $= "MobileTurretBase") + { + %turret.getObjectMount().barrel = %barrel; + } + // ------------------------------------------ + } + else + { + // Player doesn't have the correct pack on... + } + } + else + { + // Player doesn't have any pack on... + } +} + +function TurretData::onDestroyed(%this, %turret, %prevState) +{ + Parent::onDestroyed(%this, %turret, %prevState); +} + +function checkTurretMount(%data, %obj, %slot) +{ + // search for a turret base in player's LOS + %eyeVec = VectorNormalize(%obj.getEyeVector()); + %srchRange = VectorScale(%eyeVec, 5.0); // look 5m for a turret base + %plTm = %obj.getEyeTransform(); + %plyrLoc = firstWord(%plTm) @ " " @ getWord(%plTm, 1) @ " " @ getWord(%plTm, 2); + %srchEnd = VectorAdd(%plyrLoc, %srchRange); + %potTurret = ContainerRayCast(%obj.getEyeTransform(), %srchEnd, $TypeMasks::TurretObjectType); + if(%potTurret != 0) + { + %otherMountObj = "foo"; + + %name = %potTurret.getDatablock().getName(); // z0dd - ZOD, 4/20/02. modular MPB turret + if(%name $= "TurretBaseLarge" || %name $= "MobileTurretBase" || %name $= %otherMountObj) // z0dd - ZOD, 4/20/02. modular MPB turret + { + // found a turret base, what team is it on? + if(%potTurret.team == %obj.client.team) + { + if(%potTurret.getDamageState() !$= "Enabled") + { + // the base is destroyed + messageClient(%obj.client, 'MsgBaseDestroyed', "\c2Turret is disabled, cannot mount barrel."); // z0dd - ZOD, 4/20/02. modular MPB turret + %obj.setImageTrigger($BackpackSlot, false); + } + else + { + // it's a functional turret base on our team! stick the barrel on it + messageClient(%obj.client, 'MsgTurretMount', "\c2Mounting barrel pack on turret."); // z0dd - ZOD, 4/20/02. modular MPB turret + serverPlay3D(TurretPackActivateSound, %potTurret.getTransform()); + %potTurret.initiateBarrelSwap(%obj); + } + } + else + { + // whoops, wrong team + messageClient(%obj.client, 'MsgTryEnemyTurretMount', "\c2Cannot mount a barrel on an enemy turret base!"); + %obj.setImageTrigger($BackpackSlot, false); + } + } + else + { + // tried to mount barrel on some other turret type + messageClient(%obj.client, 'MsgNotTurretBase', "\c2Can only mount a barrel on a turret base."); + %obj.setImageTrigger($BackpackSlot, false); + } + } + else + { + // I don't see any turret + messageClient(%obj.client, 'MsgNoTurretBase', "\c2No turret within range."); + %obj.setImageTrigger($BackpackSlot, false); + } +} + +//-------------------------------------- Load Barrel Images +// +exec("scripts/turrets/mortarBarrelLarge.cs"); +exec("scripts/turrets/aaBarrelLarge.cs"); +exec("scripts/turrets/missileBarrelLarge.cs"); +exec("scripts/turrets/plasmaBarrelLarge.cs"); +exec("scripts/turrets/ELFBarrelLarge.cs"); +exec("scripts/turrets/outdoorDeployableBarrel.cs"); +exec("scripts/turrets/indoorDeployableBarrel.cs"); exec("scripts/turrets/sentryTurret.cs"); \ No newline at end of file diff --git a/scripts/turrets/ELFBarrelLarge.cs b/scripts/turrets/ELFBarrelLarge.cs index 5d8579a..1779301 100644 --- a/scripts/turrets/ELFBarrelLarge.cs +++ b/scripts/turrets/ELFBarrelLarge.cs @@ -1,156 +1,156 @@ -//-------------------------------------------------------------------------- -// ELF Turret barrel -//-------------------------------------------------------------------------- - -//-------------------------------------------------------------------------- -// Sounds -//-------------------------------------------------------------------------- -datablock EffectProfile(EBLSwitchEffect) -{ - effectname = "powered/turret_light_activate"; - minDistance = 2.5; - maxDistance = 5.0; -}; - -datablock EffectProfile(EBLFireEffect) -{ - effectname = "weapons/ELF_fire"; - minDistance = 2.5; - maxDistance = 5.0; -}; - -datablock AudioProfile(EBLSwitchSound) -{ - filename = "fx/powered/turret_light_activate.wav"; - description = AudioClose3d; - preload = true; - effect = EBLSwitchEffect; -}; - -datablock AudioProfile(EBLFireSound) -{ - filename = "fx/weapons/ELF_fire.wav"; - description = AudioDefaultLooping3d; - preload = true; - effect = EBLFireEffect; -}; - -//-------------------------------------------------------------------------- -// Projectile -//-------------------------------------- - -datablock ELFProjectileData(ELFTurretBolt) -{ - beamRange = 75; - numControlPoints = 8; - restorativeFactor = 3.75; - dragFactor = 4.5; - endFactor = 2.25; - randForceFactor = 2; - randForceTime = 0.125; - drainEnergy = 1.0; - drainHealth = 0.0015; - directDamageType = $DamageType::ELFTurret; - - mainBeamWidth = 0.1; // width of blue wave beam - mainBeamSpeed = 9.0; // speed that the beam travels forward - mainBeamRepeat = 0.25; // number of times the texture repeats - lightningWidth = 0.1; - lightningDist = 0.15; // distance of lightning from main beam - - fireSound = EBLFireSound; - - textures[0] = "special/ELFBeam"; - textures[1] = "special/ELFLightning"; - textures[2] = "special/BlueImpact"; - - // -------------------------------------------------------------------- - // z0dd - ZOD, 4/04/02. Was missing this parameter, (console spam fix). - emitter = ELFSparksEmitter; - // ------------------------ -}; - -//-------------------------------------------------------------------------- -// ELF Turret Image -//-------------------------------------------------------------------------- - -datablock TurretImageData(ELFBarrelLarge) -{ - shapeFile = "turret_elf_large.dts"; - item = ELFBarrelPack; // z0dd - ZOD, 4/25/02. Was wrong: ELFBarrelLargePack - - projectile = ELFTurretBolt; - projectileType = ELFProjectile; - deleteLastProjectile = true; - usesEnergy = true; - fireEnergy = 0.0; - minEnergy = 0.0; - - // Turret parameters - activationMS = 350; // z0dd - ZOD, 3/27/02. Was 500. Amount of time it takes turret to unfold - deactivateDelayMS = 100; - thinkTimeMS = 70; // z0dd - ZOD, 3/27/02. Was 100. Amount of time before turret starts to unfold (activate) - degPerSecTheta = 580; - degPerSecPhi = 960; - attackRadius = 75; - - yawVariance = 30.0; // these will smooth out the elf tracking code. - pitchVariance = 30.0; // more or less just tolerances - - // State transiltions - stateName[0] = "Activate"; - stateTransitionOnNotLoaded[0] = "Dead"; - stateTransitionOnLoaded[0] = "ActivateReady"; - - stateName[1] = "ActivateReady"; - stateSequence[1] = "Activate"; - stateSound[1] = EBLSwitchSound; - stateTimeoutValue[1] = 1; - stateTransitionOnTimeout[1] = "Ready"; - stateTransitionOnNotLoaded[1] = "Deactivate"; - stateTransitionOnNoAmmo[1] = "NoAmmo"; - - stateName[2] = "Ready"; - stateTransitionOnNotLoaded[2] = "Deactivate"; - stateTransitionOnTriggerDown[2] = "Fire"; - stateTransitionOnNoAmmo[2] = "NoAmmo"; - - stateName[3] = "Fire"; - stateFire[3] = true; - stateRecoil[3] = LightRecoil; - stateAllowImageChange[3] = false; - stateSequence[3] = "Fire"; - stateSound[3] = EBLFireSound; - stateScript[3] = "onFire"; - stateTransitionOnTriggerUp[3] = "Deconstruction"; - stateTransitionOnNoAmmo[3] = "Deconstruction"; - - stateName[4] = "Reload"; - stateTimeoutValue[4] = 0.01; - stateAllowImageChange[4] = false; - stateSequence[4] = "Reload"; - stateTransitionOnTimeout[4] = "Ready"; - stateTransitionOnNotLoaded[4] = "Deactivate"; - stateTransitionOnNoAmmo[4] = "NoAmmo"; - - stateName[5] = "Deactivate"; - stateSequence[5] = "Activate"; - stateDirection[5] = false; - stateTimeoutValue[5] = 1; - stateTransitionOnLoaded[5] = "ActivateReady"; - stateTransitionOnTimeout[5] = "Dead"; - - stateName[6] = "Dead"; - stateTransitionOnLoaded[6] = "ActivateReady"; - - stateName[7] = "NoAmmo"; - stateTransitionOnAmmo[7] = "Reload"; - stateSequence[7] = "NoAmmo"; - - stateName[8] = "Deconstruction"; - stateScript[8] = "deconstruct"; - stateTransitionOnNoAmmo[8] = "NoAmmo"; - stateTransitionOnTimeout[8] = "Reload"; - stateTimeoutValue[8] = 0.1; -}; - +//-------------------------------------------------------------------------- +// ELF Turret barrel +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +// Sounds +//-------------------------------------------------------------------------- +datablock EffectProfile(EBLSwitchEffect) +{ + effectname = "powered/turret_light_activate"; + minDistance = 2.5; + maxDistance = 5.0; +}; + +datablock EffectProfile(EBLFireEffect) +{ + effectname = "weapons/ELF_fire"; + minDistance = 2.5; + maxDistance = 5.0; +}; + +datablock AudioProfile(EBLSwitchSound) +{ + filename = "fx/powered/turret_light_activate.wav"; + description = AudioClose3d; + preload = true; + effect = EBLSwitchEffect; +}; + +datablock AudioProfile(EBLFireSound) +{ + filename = "fx/weapons/ELF_fire.wav"; + description = AudioDefaultLooping3d; + preload = true; + effect = EBLFireEffect; +}; + +//-------------------------------------------------------------------------- +// Projectile +//-------------------------------------- + +datablock ELFProjectileData(ELFTurretBolt) +{ + beamRange = 75; + numControlPoints = 8; + restorativeFactor = 3.75; + dragFactor = 4.5; + endFactor = 2.25; + randForceFactor = 2; + randForceTime = 0.125; + drainEnergy = 1.0; + drainHealth = 0.0015; + directDamageType = $DamageType::ELFTurret; + + mainBeamWidth = 0.1; // width of blue wave beam + mainBeamSpeed = 9.0; // speed that the beam travels forward + mainBeamRepeat = 0.25; // number of times the texture repeats + lightningWidth = 0.1; + lightningDist = 0.15; // distance of lightning from main beam + + fireSound = EBLFireSound; + + textures[0] = "special/ELFBeam"; + textures[1] = "special/ELFLightning"; + textures[2] = "special/BlueImpact"; + + // -------------------------------------------------------------------- + // z0dd - ZOD, 4/04/02. Was missing this parameter, (console spam fix). + emitter = ELFSparksEmitter; + // ------------------------ +}; + +//-------------------------------------------------------------------------- +// ELF Turret Image +//-------------------------------------------------------------------------- + +datablock TurretImageData(ELFBarrelLarge) +{ + shapeFile = "turret_elf_large.dts"; + item = ELFBarrelPack; // z0dd - ZOD, 4/25/02. Was wrong: ELFBarrelLargePack + + projectile = ELFTurretBolt; + projectileType = ELFProjectile; + deleteLastProjectile = true; + usesEnergy = true; + fireEnergy = 0.0; + minEnergy = 0.0; + + // Turret parameters + activationMS = 350; // z0dd - ZOD, 3/27/02. Was 500. Amount of time it takes turret to unfold + deactivateDelayMS = 100; + thinkTimeMS = 70; // z0dd - ZOD, 3/27/02. Was 100. Amount of time before turret starts to unfold (activate) + degPerSecTheta = 580; + degPerSecPhi = 960; + attackRadius = 75; + + yawVariance = 30.0; // these will smooth out the elf tracking code. + pitchVariance = 30.0; // more or less just tolerances + + // State transiltions + stateName[0] = "Activate"; + stateTransitionOnNotLoaded[0] = "Dead"; + stateTransitionOnLoaded[0] = "ActivateReady"; + + stateName[1] = "ActivateReady"; + stateSequence[1] = "Activate"; + stateSound[1] = EBLSwitchSound; + stateTimeoutValue[1] = 1; + stateTransitionOnTimeout[1] = "Ready"; + stateTransitionOnNotLoaded[1] = "Deactivate"; + stateTransitionOnNoAmmo[1] = "NoAmmo"; + + stateName[2] = "Ready"; + stateTransitionOnNotLoaded[2] = "Deactivate"; + stateTransitionOnTriggerDown[2] = "Fire"; + stateTransitionOnNoAmmo[2] = "NoAmmo"; + + stateName[3] = "Fire"; + stateFire[3] = true; + stateRecoil[3] = LightRecoil; + stateAllowImageChange[3] = false; + stateSequence[3] = "Fire"; + stateSound[3] = EBLFireSound; + stateScript[3] = "onFire"; + stateTransitionOnTriggerUp[3] = "Deconstruction"; + stateTransitionOnNoAmmo[3] = "Deconstruction"; + + stateName[4] = "Reload"; + stateTimeoutValue[4] = 0.01; + stateAllowImageChange[4] = false; + stateSequence[4] = "Reload"; + stateTransitionOnTimeout[4] = "Ready"; + stateTransitionOnNotLoaded[4] = "Deactivate"; + stateTransitionOnNoAmmo[4] = "NoAmmo"; + + stateName[5] = "Deactivate"; + stateSequence[5] = "Activate"; + stateDirection[5] = false; + stateTimeoutValue[5] = 1; + stateTransitionOnLoaded[5] = "ActivateReady"; + stateTransitionOnTimeout[5] = "Dead"; + + stateName[6] = "Dead"; + stateTransitionOnLoaded[6] = "ActivateReady"; + + stateName[7] = "NoAmmo"; + stateTransitionOnAmmo[7] = "Reload"; + stateSequence[7] = "NoAmmo"; + + stateName[8] = "Deconstruction"; + stateScript[8] = "deconstruct"; + stateTransitionOnNoAmmo[8] = "NoAmmo"; + stateTransitionOnTimeout[8] = "Reload"; + stateTimeoutValue[8] = 0.1; +}; + diff --git a/scripts/turrets/aaBarrelLarge.cs b/scripts/turrets/aaBarrelLarge.cs index 50fe6ef..d080798 100644 --- a/scripts/turrets/aaBarrelLarge.cs +++ b/scripts/turrets/aaBarrelLarge.cs @@ -1,263 +1,263 @@ -//-------------------------------------- -// Default blaster -//-------------------------------------- - -//-------------------------------------------------------------------------- -// Sounds and feedback effects -//-------------------------------------- - -datablock EffectProfile(AASwitchEffect) -{ - effectname = "powered/turret_light_activate"; - minDistance = 2.5; - maxDistance = 5.0; -}; - -datablock EffectProfile(AAFireEffect) -{ - effectname = "powered/turret_aa_fire"; - minDistance = 2.5; - maxDistance = 5.0; -}; - -datablock AudioProfile(AASwitchSound) -{ - filename = "fx/powered/turret_aa_activate.wav"; - description = AudioClose3d; - preload = true; - effect = AASwitchEffect; -}; - -datablock AudioProfile(AAFireSound) -{ - filename = "fx/powered/turret_aa_fire.wav"; - description = AudioDefault3d; - preload = true; - effect = AAFireEffect; -}; - -//-------------------------------------------------------------------------- -// Particle effects -//-------------------------------------- -//-------------------------------------------------------------------------- -// Explosion -//-------------------------------------- -datablock ParticleData(AABulletExplosionParticle1) -{ - dragCoefficient = 2; - gravityCoefficient = 0.0; - inheritedVelFactor = 0.2; - constantAcceleration = -0.0; - lifetimeMS = 600; - lifetimeVarianceMS = 000; - textureName = "special/crescent4"; - colors[0] = "0.57 0.41 1.0 1.0"; - colors[1] = "0.57 0.41 1.0 1.0"; - colors[2] = "0.57 0.41 0.0 0.0"; - sizes[0] = 0.25; - sizes[1] = 0.5; - sizes[2] = 1.0; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData(AABulletExplosionEmitter) -{ - ejectionPeriodMS = 7; - periodVarianceMS = 0; - ejectionVelocity = 2; - velocityVariance = 1.5; - ejectionOffset = 0.0; - thetaMin = 70; - thetaMax = 80; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - orientParticles = true; - lifetimeMS = 200; - particles = "AABulletExplosionParticle1"; -}; - -datablock ParticleData(AABulletExplosionParticle2) -{ - dragCoefficient = 2; - gravityCoefficient = 0.0; - inheritedVelFactor = 0.2; - constantAcceleration = -0.0; - lifetimeMS = 600; - lifetimeVarianceMS = 000; - textureName = "special/blasterHit"; - colors[0] = "0.57 0.41 1.0 0.6"; - colors[1] = "0.57 0.41 1.0 0.6"; - colors[2] = "0.57 0.41 0.0 0.0"; - sizes[0] = 0.3; - sizes[1] = 0.90; - sizes[2] = 1.50; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData(AABulletExplosionEmitter2) -{ - ejectionPeriodMS = 30; - periodVarianceMS = 0; - ejectionVelocity = 1; - velocityVariance = 0.0; - ejectionOffset = 0.0; - thetaMin = 0; - thetaMax = 80; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - orientParticles = false; - lifetimeMS = 200; - particles = "AABulletExplosionParticle2"; -}; - -datablock ExplosionData(AABulletExplosion) -{ - soundProfile = blasterExpSound; - emitter[0] = AABulletExplosionEmitter; - emitter[1] = AABulletExplosionEmitter2; -}; - - -//-------------------------------------------------------------------------- -// Projectile -//-------------------------------------- -datablock TracerProjectileData(AABullet) -{ - doDynamicClientHits = true; - - projectileShapeName = "energy_bolt.dts"; - directDamage = 0.25; - directDamageType = $DamageType::AATurret; - explosion = "AABulletExplosion"; - splash = ChaingunSplash; - - dryVelocity = 150.0; - wetVelocity = 100.0; - velInheritFactor = 1.0; - fizzleTimeMS = 3000; - lifetimeMS = 3000; - explodeOnDeath = false; - reflectOnWaterImpactAngle = 0.0; - explodeOnWaterImpact = false; - deflectionOnWaterImpact = 0.0; - fizzleUnderwaterMS = 3000; - - tracerLength = 20; - tracerAlpha = false; - tracerMinPixels = 3; - tracerColor = "1 1 1 1"; - tracerTex[0] = "special/shrikeBolt"; - tracerTex[1] = "special/shrikeBoltCross"; - tracerWidth = 0.55; - crossSize = 0.99; - crossViewAng = 0.990; - renderCross = true; - emap = true; -}; - -//-------------------------------------------------------------------------- -// Weapon -//-------------------------------------- -datablock TurretImageData(AABarrelLarge) -{ - shapeFile = "turret_aa_large.dts"; - item = AABarrelPack; // z0dd - ZOD, 4/25/02. Was wrong: AABarrelLargePack - - projectileType = TracerProjectile; - projectile = AABullet; - usesEnergy = true; - fireEnergy = 4.0; - minEnergy = 4.0; - emap = true; - isSeeker = true; - seekRadius = 200; - maxSeekAngle = 6; - seekTime = 1.0; - minSeekHeat = 0.6; - useTargetAudio = false; - - // Turret parameters - activationMS = 175; // z0dd - ZOD, 3/27/02. Was 250. Amount of time it takes turret to unfold - deactivateDelayMS = 500; - thinkTimeMS = 140; // z0dd - ZOD, 3/27/02. Was 200. Amount of time before turret starts to unfold (activate) - degPerSecTheta = 600; - degPerSecPhi = 1080; - attackRadius = 200; - - // State transitions - stateName[0] = "Activate"; - stateTransitionOnNotLoaded[0] = "Dead"; - stateTransitionOnLoaded[0] = "ActivateReady"; - - stateName[1] = "ActivateReady"; - stateSequence[1] = "Activate"; - stateSound[1] = AASwitchSound; - stateTimeoutValue[1] = 1.0; - stateTransitionOnTimeout[1] = "Ready"; - stateTransitionOnNotLoaded[1] = "Deactivate"; - stateTransitionOnNoAmmo[1] = "NoAmmo"; - stateScript[1] = "AAActivateReady"; - - stateName[2] = "Ready"; - stateTransitionOnNotLoaded[2] = "Deactivate"; - stateTransitionOnTriggerDown[2] = "Fire1"; - stateTransitionOnNoAmmo[2] = "NoAmmo"; - stateScript[2] = "AAReady"; - - stateName[3] = "Fire1"; - stateTransitionOnTimeout[3] = "Reload1"; - stateTimeoutValue[3] = 0.15; - stateFire[3] = true; - stateRecoil[3] = LightRecoil; - stateAllowImageChange[3] = false; - stateSequence[3] = "Fire1"; - stateSound[3] = AAFireSound; - stateScript[3] = "onFire"; - - stateName[4] = "Reload1"; - stateTimeoutValue[4] = 0.2; - stateAllowImageChange[4] = false; - stateSequence[4] = "Reload"; - stateTransitionOnTimeout[4] = "Fire2"; - stateTransitionOnNotLoaded[4] = "Deactivate"; - stateTransitionOnNoAmmo[4] = "NoAmmo"; - - stateName[5] = "Fire2"; - stateTransitionOnTimeout[5] = "Reload2"; - stateTimeoutValue[5] = 0.15; - stateFire[5] = true; - stateRecoil[5] = LightRecoil; - stateAllowImageChange[5] = false; - stateSequence[5] = "Fire2"; - stateSound[5] = AAFireSound; - stateScript[5] = "onFire"; - - stateName[6] = "Reload2"; - stateTimeoutValue[6] = 0.2; - stateAllowImageChange[6] = false; - stateSequence[6] = "Reload"; - stateTransitionOnTimeout[6] = "Ready"; - stateTransitionOnNotLoaded[6] = "Deactivate"; - stateTransitionOnNoAmmo[6] = "NoAmmo"; - - stateName[7] = "Deactivate"; - stateSequence[7] = "Activate"; - stateDirection[7] = false; - stateTimeoutValue[7] = 1.0; - stateTransitionOnLoaded[7] = "ActivateReady"; - stateTransitionOnTimeout[7] = "Dead"; - - stateName[8] = "Dead"; - stateTransitionOnLoaded[8] = "ActivateReady"; - - stateName[9] = "NoAmmo"; - stateTransitionOnAmmo[9] = "Reload2"; - stateSequence[9] = "NoAmmo"; -}; - +//-------------------------------------- +// Default blaster +//-------------------------------------- + +//-------------------------------------------------------------------------- +// Sounds and feedback effects +//-------------------------------------- + +datablock EffectProfile(AASwitchEffect) +{ + effectname = "powered/turret_light_activate"; + minDistance = 2.5; + maxDistance = 5.0; +}; + +datablock EffectProfile(AAFireEffect) +{ + effectname = "powered/turret_aa_fire"; + minDistance = 2.5; + maxDistance = 5.0; +}; + +datablock AudioProfile(AASwitchSound) +{ + filename = "fx/powered/turret_aa_activate.wav"; + description = AudioClose3d; + preload = true; + effect = AASwitchEffect; +}; + +datablock AudioProfile(AAFireSound) +{ + filename = "fx/powered/turret_aa_fire.wav"; + description = AudioDefault3d; + preload = true; + effect = AAFireEffect; +}; + +//-------------------------------------------------------------------------- +// Particle effects +//-------------------------------------- +//-------------------------------------------------------------------------- +// Explosion +//-------------------------------------- +datablock ParticleData(AABulletExplosionParticle1) +{ + dragCoefficient = 2; + gravityCoefficient = 0.0; + inheritedVelFactor = 0.2; + constantAcceleration = -0.0; + lifetimeMS = 600; + lifetimeVarianceMS = 000; + textureName = "special/crescent4"; + colors[0] = "0.57 0.41 1.0 1.0"; + colors[1] = "0.57 0.41 1.0 1.0"; + colors[2] = "0.57 0.41 0.0 0.0"; + sizes[0] = 0.25; + sizes[1] = 0.5; + sizes[2] = 1.0; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; +}; + +datablock ParticleEmitterData(AABulletExplosionEmitter) +{ + ejectionPeriodMS = 7; + periodVarianceMS = 0; + ejectionVelocity = 2; + velocityVariance = 1.5; + ejectionOffset = 0.0; + thetaMin = 70; + thetaMax = 80; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + orientParticles = true; + lifetimeMS = 200; + particles = "AABulletExplosionParticle1"; +}; + +datablock ParticleData(AABulletExplosionParticle2) +{ + dragCoefficient = 2; + gravityCoefficient = 0.0; + inheritedVelFactor = 0.2; + constantAcceleration = -0.0; + lifetimeMS = 600; + lifetimeVarianceMS = 000; + textureName = "special/blasterHit"; + colors[0] = "0.57 0.41 1.0 0.6"; + colors[1] = "0.57 0.41 1.0 0.6"; + colors[2] = "0.57 0.41 0.0 0.0"; + sizes[0] = 0.3; + sizes[1] = 0.90; + sizes[2] = 1.50; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; +}; + +datablock ParticleEmitterData(AABulletExplosionEmitter2) +{ + ejectionPeriodMS = 30; + periodVarianceMS = 0; + ejectionVelocity = 1; + velocityVariance = 0.0; + ejectionOffset = 0.0; + thetaMin = 0; + thetaMax = 80; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + orientParticles = false; + lifetimeMS = 200; + particles = "AABulletExplosionParticle2"; +}; + +datablock ExplosionData(AABulletExplosion) +{ + soundProfile = blasterExpSound; + emitter[0] = AABulletExplosionEmitter; + emitter[1] = AABulletExplosionEmitter2; +}; + + +//-------------------------------------------------------------------------- +// Projectile +//-------------------------------------- +datablock TracerProjectileData(AABullet) +{ + doDynamicClientHits = true; + + projectileShapeName = "energy_bolt.dts"; + directDamage = 0.25; + directDamageType = $DamageType::AATurret; + explosion = "AABulletExplosion"; + splash = ChaingunSplash; + + dryVelocity = 150.0; + wetVelocity = 100.0; + velInheritFactor = 1.0; + fizzleTimeMS = 3000; + lifetimeMS = 3000; + explodeOnDeath = false; + reflectOnWaterImpactAngle = 0.0; + explodeOnWaterImpact = false; + deflectionOnWaterImpact = 0.0; + fizzleUnderwaterMS = 3000; + + tracerLength = 20; + tracerAlpha = false; + tracerMinPixels = 3; + tracerColor = "1 1 1 1"; + tracerTex[0] = "special/shrikeBolt"; + tracerTex[1] = "special/shrikeBoltCross"; + tracerWidth = 0.55; + crossSize = 0.99; + crossViewAng = 0.990; + renderCross = true; + emap = true; +}; + +//-------------------------------------------------------------------------- +// Weapon +//-------------------------------------- +datablock TurretImageData(AABarrelLarge) +{ + shapeFile = "turret_aa_large.dts"; + item = AABarrelPack; // z0dd - ZOD, 4/25/02. Was wrong: AABarrelLargePack + + projectileType = TracerProjectile; + projectile = AABullet; + usesEnergy = true; + fireEnergy = 4.0; + minEnergy = 4.0; + emap = true; + isSeeker = true; + seekRadius = 200; + maxSeekAngle = 6; + seekTime = 1.0; + minSeekHeat = 0.6; + useTargetAudio = false; + + // Turret parameters + activationMS = 175; // z0dd - ZOD, 3/27/02. Was 250. Amount of time it takes turret to unfold + deactivateDelayMS = 500; + thinkTimeMS = 140; // z0dd - ZOD, 3/27/02. Was 200. Amount of time before turret starts to unfold (activate) + degPerSecTheta = 600; + degPerSecPhi = 1080; + attackRadius = 200; + + // State transitions + stateName[0] = "Activate"; + stateTransitionOnNotLoaded[0] = "Dead"; + stateTransitionOnLoaded[0] = "ActivateReady"; + + stateName[1] = "ActivateReady"; + stateSequence[1] = "Activate"; + stateSound[1] = AASwitchSound; + stateTimeoutValue[1] = 1.0; + stateTransitionOnTimeout[1] = "Ready"; + stateTransitionOnNotLoaded[1] = "Deactivate"; + stateTransitionOnNoAmmo[1] = "NoAmmo"; + stateScript[1] = "AAActivateReady"; + + stateName[2] = "Ready"; + stateTransitionOnNotLoaded[2] = "Deactivate"; + stateTransitionOnTriggerDown[2] = "Fire1"; + stateTransitionOnNoAmmo[2] = "NoAmmo"; + stateScript[2] = "AAReady"; + + stateName[3] = "Fire1"; + stateTransitionOnTimeout[3] = "Reload1"; + stateTimeoutValue[3] = 0.15; + stateFire[3] = true; + stateRecoil[3] = LightRecoil; + stateAllowImageChange[3] = false; + stateSequence[3] = "Fire1"; + stateSound[3] = AAFireSound; + stateScript[3] = "onFire"; + + stateName[4] = "Reload1"; + stateTimeoutValue[4] = 0.2; + stateAllowImageChange[4] = false; + stateSequence[4] = "Reload"; + stateTransitionOnTimeout[4] = "Fire2"; + stateTransitionOnNotLoaded[4] = "Deactivate"; + stateTransitionOnNoAmmo[4] = "NoAmmo"; + + stateName[5] = "Fire2"; + stateTransitionOnTimeout[5] = "Reload2"; + stateTimeoutValue[5] = 0.15; + stateFire[5] = true; + stateRecoil[5] = LightRecoil; + stateAllowImageChange[5] = false; + stateSequence[5] = "Fire2"; + stateSound[5] = AAFireSound; + stateScript[5] = "onFire"; + + stateName[6] = "Reload2"; + stateTimeoutValue[6] = 0.2; + stateAllowImageChange[6] = false; + stateSequence[6] = "Reload"; + stateTransitionOnTimeout[6] = "Ready"; + stateTransitionOnNotLoaded[6] = "Deactivate"; + stateTransitionOnNoAmmo[6] = "NoAmmo"; + + stateName[7] = "Deactivate"; + stateSequence[7] = "Activate"; + stateDirection[7] = false; + stateTimeoutValue[7] = 1.0; + stateTransitionOnLoaded[7] = "ActivateReady"; + stateTransitionOnTimeout[7] = "Dead"; + + stateName[8] = "Dead"; + stateTransitionOnLoaded[8] = "ActivateReady"; + + stateName[9] = "NoAmmo"; + stateTransitionOnAmmo[9] = "Reload2"; + stateSequence[9] = "NoAmmo"; +}; + diff --git a/scripts/turrets/indoorDeployableBarrel.cs b/scripts/turrets/indoorDeployableBarrel.cs index 95d7dbe..a0f75dd 100644 --- a/scripts/turrets/indoorDeployableBarrel.cs +++ b/scripts/turrets/indoorDeployableBarrel.cs @@ -1,325 +1,325 @@ -datablock EffectProfile(IBLSwitchEffect) -{ - effectname = "powered/turret_light_activate"; - minDistance = 5.0; - maxDistance = 5.0; -}; - -datablock EffectProfile(IBLFireEffect) -{ - effectname = "powered/turret_indoor_fire"; - minDistance = 2.5; - maxDistance = 5.0; -}; - -datablock AudioProfile(IBLSwitchSound) -{ - filename = "fx/powered/turret_light_activate.wav"; - description = AudioClose3d; - preload = true; - effect = IBLSwitchEffect; -}; - -datablock AudioProfile(IBLFireSound) -{ - filename = "fx/powered/turret_indoor_fire.wav"; - description = AudioDefault3d; - preload = true; - effect = IBLFireEffect; -}; - -datablock SensorData(DeployedIndoorTurretSensor) -{ - detects = true; - detectsUsingLOS = true; - detectsPassiveJammed = false; - detectsActiveJammed = false; - detectsCloaked = false; - detectionPings = true; - detectRadius = 40; -}; - -datablock ShockwaveData(IndoorTurretMuzzleFlash) -{ - width = 0.5; - numSegments = 13; - numVertSegments = 1; - velocity = 2.0; - acceleration = -1.0; - lifetimeMS = 300; - height = 0.1; - verticalCurve = 0.5; - - mapToTerrain = false; - renderBottom = false; - orientToNormal = true; - renderSquare = true; - - texture[0] = "special/blasterHit"; - texture[1] = "special/gradient"; - texWrap = 3.0; - - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - - colors[0] = "1.0 0.3 0.3 1.0"; - colors[1] = "1.0 0.3 0.3 1.0"; - colors[2] = "1.0 0.3 0.3 0.0"; -}; - -datablock TurretData(TurretDeployedFloorIndoor) : TurretDamageProfile -{ - className = DeployedTurret; - shapeFile = "turret_indoor_deployf.dts"; - - mass = 5.0; - maxDamage = 0.5; - destroyedLevel = 0.5; - disabledLevel = 0.21; - explosion = SmallTurretExplosion; - expDmgRadius = 5.0; - expDamage = 0.25; - expImpulse = 500.0; - repairRate = 0; - heatSignature = 0.0; - - deployedObject = true; - - thetaMin = 5; - thetaMax = 145; - thetaNull = 90; - - primaryAxis = zaxis; - - isShielded = true; - energyPerDamagePoint = 110; - maxEnergy = 30; - rechargeRate = 0.10; - barrel = DeployableIndoorBarrel; - - canControl = true; - cmdCategory = "DTactical"; - cmdIcon = CMDTurretIcon; - cmdMiniIconName = "commander/MiniIcons/com_turret_grey"; - targetNameTag = 'Spider Clamp'; - targetTypeTag = 'Turret'; - sensorData = DeployedIndoorTurretSensor; - sensorRadius = DeployedIndoorTurretSensor.detectRadius; - sensorColor = "191 0 226"; - - firstPersonOnly = true; - renderWhenDestroyed = false; - - debrisShapeName = "debris_generic_small.dts"; - debris = TurretDebrisSmall; -}; - -datablock TurretData(TurretDeployedWallIndoor) : TurretDamageProfile -{ - className = DeployedTurret; - shapeFile = "turret_indoor_deployw.dts"; - - mass = 5.0; - maxDamage = 0.5; - destroyedLevel = 0.5; - disabledLevel = 0.21; - explosion = SmallTurretExplosion; - expDmgRadius = 5.0; - expDamage = 0.25; - expImpulse = 500.0; - repairRate = 0; - heatSignature = 0.0; - - thetaMin = 5; - thetaMax = 145; - thetaNull = 90; - - deployedObject = true; - - primaryAxis = yaxis; - - isShielded = true; - energyPerDamagePoint = 110; - maxEnergy = 30; - rechargeRate = 0.10; - barrel = DeployableIndoorBarrel; - - canControl = true; - cmdCategory = "DTactical"; - cmdIcon = CMDTurretIcon; - cmdMiniIconName = "commander/MiniIcons/com_turret_grey"; - targetNameTag = 'Spider Clamp'; - targetTypeTag = 'Turret'; - sensorData = DeployedIndoorTurretSensor; - sensorRadius = DeployedIndoorTurretSensor.detectRadius; - sensorColor = "191 0 226"; - - firstPersonOnly = true; - renderWhenDestroyed = false; - - debrisShapeName = "debris_generic_small.dts"; - debris = TurretDebrisSmall; -}; - -datablock TurretData(TurretDeployedCeilingIndoor) : TurretDamageProfile -{ - className = DeployedTurret; - shapeFile = "turret_indoor_deployc.dts"; - - mass = 5.0; - maxDamage = 0.5; - destroyedLevel = 0.5; - disabledLevel = 0.21; - explosion = SmallTurretExplosion; - expDmgRadius = 5.0; - expDamage = 0.25; - expImpulse = 500.0; - repairRate = 0; - explosion = SmallTurretExplosion; - - //thetaMin = 5; - //thetaMax = 145; - thetaMin = 35; - thetaMax = 175; - thetaNull = 90; - heatSignature = 0.0; - - deployedObject = true; - - primaryAxis = revzaxis; - - isShielded = true; - energyPerDamagePoint = 110; - maxEnergy = 30; - rechargeRate = 0.10; - barrel = DeployableIndoorBarrel; - - canControl = true; - cmdCategory = "DTactical"; - cmdIcon = CMDTurretIcon; - cmdMiniIconName = "commander/MiniIcons/com_turret_grey"; - targetNameTag = 'Spider Clamp'; - targetTypeTag = 'Turret'; - sensorData = DeployedIndoorTurretSensor; - sensorRadius = DeployedIndoorTurretSensor.detectRadius; - sensorColor = "191 0 226"; - - firstPersonOnly = true; - renderWhenDestroyed = false; - - debrisShapeName = "debris_generic_small.dts"; - debris = TurretDebrisSmall; -}; - -datablock LinearFlareProjectileData(IndoorTurretBolt) -{ - directDamage = 0.14; - directDamageType = $DamageType::IndoorDepTurret; - explosion = "BlasterExplosion"; - kickBackStrength = 0.0; - - dryVelocity = 120.0; - wetVelocity = 40.0; - velInheritFactor = 0.5; - fizzleTimeMS = 2000; - lifetimeMS = 3000; - explodeOnDeath = false; - reflectOnWaterImpactAngle = 0.0; - explodeOnWaterImpact = false; - deflectionOnWaterImpact = 0.0; - fizzleUnderwaterMS = 3000; - - numFlares = 20; - size = 0.45; - flareColor = "1 0.35 0.35"; - flareModTexture = "flaremod"; - flareBaseTexture = "flarebase"; - - sound = BlasterProjectileSound; - - hasLight = true; - lightRadius = 3.0; - lightColor = "1 0.35 0.35"; -}; - -datablock TurretImageData(DeployableIndoorBarrel) -{ - shapeFile = "turret_muzzlepoint.dts"; - item = TurretIndoorDeployable; // z0dd - ZOD, 4/25/02. Was wrong: IndoorTurretBarrel - - projectile = IndoorTurretBolt; - projectileType = LinearFlareProjectile; - - usesEnergy = true; - fireEnergy = 4.5; - minEnergy = 4.5; - - lightType = "WeaponFireLight"; - lightColor = "0.25 0.15 0.15 1.0"; - lightTime = "1000"; - lightRadius = "2"; - - muzzleFlash = IndoorTurretMuzzleFlash; - - // Turret parameters - activationMS = 105; // z0dd - ZOD, 3/27/02. Was 150. Amount of time it takes turret to unfold - deactivateDelayMS = 300; - thinkTimeMS = 105; // z0dd - ZOD, 3/27/02. Was 150. Amount of time before turret starts to unfold (activate) - degPerSecTheta = 580; - degPerSecPhi = 960; - attackRadius = 60; - - // State transitions - stateName[0] = "Activate"; - stateTransitionOnNotLoaded[0] = "Dead"; - stateTransitionOnLoaded[0] = "ActivateReady"; - - stateName[1] = "ActivateReady"; - stateSequence[1] = "Activate"; - stateSound[1] = IBLSwitchSound; - stateTimeoutValue[1] = 1; - stateTransitionOnTimeout[1] = "Ready"; - stateTransitionOnNotLoaded[1] = "Deactivate"; - stateTransitionOnNoAmmo[1] = "NoAmmo"; - - stateName[2] = "Ready"; - stateTransitionOnNotLoaded[2] = "Deactivate"; - stateTransitionOnTriggerDown[2] = "Fire"; - stateTransitionOnNoAmmo[2] = "NoAmmo"; - - stateName[3] = "Fire"; - stateTransitionOnTimeout[3] = "Reload"; - stateTimeoutValue[3] = 0.3; - stateFire[3] = true; - stateShockwave[3] = true; - stateRecoil[3] = LightRecoil; - stateAllowImageChange[3] = false; - stateSequence[3] = "Fire"; - stateSound[3] = IBLFireSound; - stateScript[3] = "onFire"; - - stateName[4] = "Reload"; - stateTimeoutValue[4] = 0.8; - stateAllowImageChange[4] = false; - stateSequence[4] = "Reload"; - stateTransitionOnTimeout[4] = "Ready"; - stateTransitionOnNotLoaded[4] = "Deactivate"; - stateTransitionOnNoAmmo[4] = "NoAmmo"; - - stateName[5] = "Deactivate"; - stateSequence[5] = "Activate"; - stateDirection[5] = false; - stateTimeoutValue[5] = 1; - stateTransitionOnLoaded[5] = "ActivateReady"; - stateTransitionOnTimeout[5] = "Dead"; - - stateName[6] = "Dead"; - stateTransitionOnLoaded[6] = "ActivateReady"; - - stateName[7] = "NoAmmo"; - stateTransitionOnAmmo[7] = "Reload"; - stateSequence[7] = "NoAmmo"; -}; - - +datablock EffectProfile(IBLSwitchEffect) +{ + effectname = "powered/turret_light_activate"; + minDistance = 5.0; + maxDistance = 5.0; +}; + +datablock EffectProfile(IBLFireEffect) +{ + effectname = "powered/turret_indoor_fire"; + minDistance = 2.5; + maxDistance = 5.0; +}; + +datablock AudioProfile(IBLSwitchSound) +{ + filename = "fx/powered/turret_light_activate.wav"; + description = AudioClose3d; + preload = true; + effect = IBLSwitchEffect; +}; + +datablock AudioProfile(IBLFireSound) +{ + filename = "fx/powered/turret_indoor_fire.wav"; + description = AudioDefault3d; + preload = true; + effect = IBLFireEffect; +}; + +datablock SensorData(DeployedIndoorTurretSensor) +{ + detects = true; + detectsUsingLOS = true; + detectsPassiveJammed = false; + detectsActiveJammed = false; + detectsCloaked = false; + detectionPings = true; + detectRadius = 40; +}; + +datablock ShockwaveData(IndoorTurretMuzzleFlash) +{ + width = 0.5; + numSegments = 13; + numVertSegments = 1; + velocity = 2.0; + acceleration = -1.0; + lifetimeMS = 300; + height = 0.1; + verticalCurve = 0.5; + + mapToTerrain = false; + renderBottom = false; + orientToNormal = true; + renderSquare = true; + + texture[0] = "special/blasterHit"; + texture[1] = "special/gradient"; + texWrap = 3.0; + + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; + + colors[0] = "1.0 0.3 0.3 1.0"; + colors[1] = "1.0 0.3 0.3 1.0"; + colors[2] = "1.0 0.3 0.3 0.0"; +}; + +datablock TurretData(TurretDeployedFloorIndoor) : TurretDamageProfile +{ + className = DeployedTurret; + shapeFile = "turret_indoor_deployf.dts"; + + mass = 5.0; + maxDamage = 0.5; + destroyedLevel = 0.5; + disabledLevel = 0.21; + explosion = SmallTurretExplosion; + expDmgRadius = 5.0; + expDamage = 0.25; + expImpulse = 500.0; + repairRate = 0; + heatSignature = 0.0; + + deployedObject = true; + + thetaMin = 5; + thetaMax = 145; + thetaNull = 90; + + primaryAxis = zaxis; + + isShielded = true; + energyPerDamagePoint = 110; + maxEnergy = 30; + rechargeRate = 0.10; + barrel = DeployableIndoorBarrel; + + canControl = true; + cmdCategory = "DTactical"; + cmdIcon = CMDTurretIcon; + cmdMiniIconName = "commander/MiniIcons/com_turret_grey"; + targetNameTag = 'Spider Clamp'; + targetTypeTag = 'Turret'; + sensorData = DeployedIndoorTurretSensor; + sensorRadius = DeployedIndoorTurretSensor.detectRadius; + sensorColor = "191 0 226"; + + firstPersonOnly = true; + renderWhenDestroyed = false; + + debrisShapeName = "debris_generic_small.dts"; + debris = TurretDebrisSmall; +}; + +datablock TurretData(TurretDeployedWallIndoor) : TurretDamageProfile +{ + className = DeployedTurret; + shapeFile = "turret_indoor_deployw.dts"; + + mass = 5.0; + maxDamage = 0.5; + destroyedLevel = 0.5; + disabledLevel = 0.21; + explosion = SmallTurretExplosion; + expDmgRadius = 5.0; + expDamage = 0.25; + expImpulse = 500.0; + repairRate = 0; + heatSignature = 0.0; + + thetaMin = 5; + thetaMax = 145; + thetaNull = 90; + + deployedObject = true; + + primaryAxis = yaxis; + + isShielded = true; + energyPerDamagePoint = 110; + maxEnergy = 30; + rechargeRate = 0.10; + barrel = DeployableIndoorBarrel; + + canControl = true; + cmdCategory = "DTactical"; + cmdIcon = CMDTurretIcon; + cmdMiniIconName = "commander/MiniIcons/com_turret_grey"; + targetNameTag = 'Spider Clamp'; + targetTypeTag = 'Turret'; + sensorData = DeployedIndoorTurretSensor; + sensorRadius = DeployedIndoorTurretSensor.detectRadius; + sensorColor = "191 0 226"; + + firstPersonOnly = true; + renderWhenDestroyed = false; + + debrisShapeName = "debris_generic_small.dts"; + debris = TurretDebrisSmall; +}; + +datablock TurretData(TurretDeployedCeilingIndoor) : TurretDamageProfile +{ + className = DeployedTurret; + shapeFile = "turret_indoor_deployc.dts"; + + mass = 5.0; + maxDamage = 0.5; + destroyedLevel = 0.5; + disabledLevel = 0.21; + explosion = SmallTurretExplosion; + expDmgRadius = 5.0; + expDamage = 0.25; + expImpulse = 500.0; + repairRate = 0; + explosion = SmallTurretExplosion; + + //thetaMin = 5; + //thetaMax = 145; + thetaMin = 35; + thetaMax = 175; + thetaNull = 90; + heatSignature = 0.0; + + deployedObject = true; + + primaryAxis = revzaxis; + + isShielded = true; + energyPerDamagePoint = 110; + maxEnergy = 30; + rechargeRate = 0.10; + barrel = DeployableIndoorBarrel; + + canControl = true; + cmdCategory = "DTactical"; + cmdIcon = CMDTurretIcon; + cmdMiniIconName = "commander/MiniIcons/com_turret_grey"; + targetNameTag = 'Spider Clamp'; + targetTypeTag = 'Turret'; + sensorData = DeployedIndoorTurretSensor; + sensorRadius = DeployedIndoorTurretSensor.detectRadius; + sensorColor = "191 0 226"; + + firstPersonOnly = true; + renderWhenDestroyed = false; + + debrisShapeName = "debris_generic_small.dts"; + debris = TurretDebrisSmall; +}; + +datablock LinearFlareProjectileData(IndoorTurretBolt) +{ + directDamage = 0.14; + directDamageType = $DamageType::IndoorDepTurret; + explosion = "BlasterExplosion"; + kickBackStrength = 0.0; + + dryVelocity = 120.0; + wetVelocity = 40.0; + velInheritFactor = 0.5; + fizzleTimeMS = 2000; + lifetimeMS = 3000; + explodeOnDeath = false; + reflectOnWaterImpactAngle = 0.0; + explodeOnWaterImpact = false; + deflectionOnWaterImpact = 0.0; + fizzleUnderwaterMS = 3000; + + numFlares = 20; + size = 0.45; + flareColor = "1 0.35 0.35"; + flareModTexture = "flaremod"; + flareBaseTexture = "flarebase"; + + sound = BlasterProjectileSound; + + hasLight = true; + lightRadius = 3.0; + lightColor = "1 0.35 0.35"; +}; + +datablock TurretImageData(DeployableIndoorBarrel) +{ + shapeFile = "turret_muzzlepoint.dts"; + item = TurretIndoorDeployable; // z0dd - ZOD, 4/25/02. Was wrong: IndoorTurretBarrel + + projectile = IndoorTurretBolt; + projectileType = LinearFlareProjectile; + + usesEnergy = true; + fireEnergy = 4.5; + minEnergy = 4.5; + + lightType = "WeaponFireLight"; + lightColor = "0.25 0.15 0.15 1.0"; + lightTime = "1000"; + lightRadius = "2"; + + muzzleFlash = IndoorTurretMuzzleFlash; + + // Turret parameters + activationMS = 105; // z0dd - ZOD, 3/27/02. Was 150. Amount of time it takes turret to unfold + deactivateDelayMS = 300; + thinkTimeMS = 105; // z0dd - ZOD, 3/27/02. Was 150. Amount of time before turret starts to unfold (activate) + degPerSecTheta = 580; + degPerSecPhi = 960; + attackRadius = 60; + + // State transitions + stateName[0] = "Activate"; + stateTransitionOnNotLoaded[0] = "Dead"; + stateTransitionOnLoaded[0] = "ActivateReady"; + + stateName[1] = "ActivateReady"; + stateSequence[1] = "Activate"; + stateSound[1] = IBLSwitchSound; + stateTimeoutValue[1] = 1; + stateTransitionOnTimeout[1] = "Ready"; + stateTransitionOnNotLoaded[1] = "Deactivate"; + stateTransitionOnNoAmmo[1] = "NoAmmo"; + + stateName[2] = "Ready"; + stateTransitionOnNotLoaded[2] = "Deactivate"; + stateTransitionOnTriggerDown[2] = "Fire"; + stateTransitionOnNoAmmo[2] = "NoAmmo"; + + stateName[3] = "Fire"; + stateTransitionOnTimeout[3] = "Reload"; + stateTimeoutValue[3] = 0.3; + stateFire[3] = true; + stateShockwave[3] = true; + stateRecoil[3] = LightRecoil; + stateAllowImageChange[3] = false; + stateSequence[3] = "Fire"; + stateSound[3] = IBLFireSound; + stateScript[3] = "onFire"; + + stateName[4] = "Reload"; + stateTimeoutValue[4] = 0.8; + stateAllowImageChange[4] = false; + stateSequence[4] = "Reload"; + stateTransitionOnTimeout[4] = "Ready"; + stateTransitionOnNotLoaded[4] = "Deactivate"; + stateTransitionOnNoAmmo[4] = "NoAmmo"; + + stateName[5] = "Deactivate"; + stateSequence[5] = "Activate"; + stateDirection[5] = false; + stateTimeoutValue[5] = 1; + stateTransitionOnLoaded[5] = "ActivateReady"; + stateTransitionOnTimeout[5] = "Dead"; + + stateName[6] = "Dead"; + stateTransitionOnLoaded[6] = "ActivateReady"; + + stateName[7] = "NoAmmo"; + stateTransitionOnAmmo[7] = "Reload"; + stateSequence[7] = "NoAmmo"; +}; + + diff --git a/scripts/turrets/missileBarrelLarge.cs b/scripts/turrets/missileBarrelLarge.cs index ed3e114..7c4903b 100644 --- a/scripts/turrets/missileBarrelLarge.cs +++ b/scripts/turrets/missileBarrelLarge.cs @@ -1,176 +1,176 @@ -//-------------------------------------------------------------------------- -// Large Missile Turret -// -// z0dd - ZOD, 4/25/02. Labels for sound datablocks were wrong. -//------------------------------------------------------------- - -//-------------------------------------------------------------------------- -// Sounds -//-------------------------------------- -datablock EffectProfile(MILSwitchEffect) -{ - effectname = "powered/turret_heavy_activate"; - minDistance = 2.5; - maxDistance = 5.0; -}; - -datablock EffectProfile(MILFireEffect) -{ - effectname = "powered/turret_missile_fire"; - minDistance = 2.5; - maxDistance = 5.0; -}; - -datablock AudioProfile(MILSwitchSound) -{ - filename = "fx/powered/turret_missile_activate.wav"; - description = AudioClose3d; - preload = true; - effect = MILSwitchEffect; -}; - -datablock AudioProfile(MILFireSound) -{ - filename = "fx/powered/turret_missile_fire.wav"; - description = AudioDefault3d; - preload = true; - effect = MILFireEffect; -}; - - -//-------------------------------------------------------------------------- -// Particle effects: Note that we pull the below datablocks from -// scripts/weapons/missileLauncher.cs -//-------------------------------------- -//datablock ParticleData(MissileSmokeParticle) -//datablock ParticleEmitterData(MissileSmokeEmitter) - - -//-------------------------------------------------------------------------- -// Explosion: from scripts/weapons/disc.cs -//-------------------------------------- -//dataBlock ExplosionData(DiscExplosion) - -//-------------------------------------------------------------------------- -// Projectile -//-------------------------------------- -datablock SeekerProjectileData(TurretMissile) -{ - casingShapeName = "weapon_missile_casement.dts"; - projectileShapeName = "weapon_missile_projectile.dts"; - hasDamageRadius = true; - indirectDamage = 1.0; - damageRadius = 4.0; - radiusDamageType = $DamageType::MissileTurret; - kickBackStrength = 2500; - - flareDistance = 200; - flareAngle = 30; - minSeekHeat = 0.6; - - explosion = "MissileExplosion"; - velInheritFactor = 0.2; - - splash = MissileSplash; - baseEmitter = MissileSmokeEmitter; - delayEmitter = MissileFireEmitter; - puffEmitter = MissilePuffEmitter; - - lifetimeMS = 20000; - muzzleVelocity = 90.0; // z0dd - ZOD, 3/27/02. Was 80. Velocity of projectile - turningSpeed = 90.0; - - proximityRadius = 4; - - terrainAvoidanceSpeed = 180; - terrainScanAhead = 25; - terrainHeightFail = 12; - terrainAvoidanceRadius = 100; - - useFlechette = true; - flechetteDelayMs = 550; - casingDeb = FlechetteDebris; -}; - -//-------------------------------------------------------------------------- -//-------------------------------------- Fusion Turret Image -// -datablock TurretImageData(MissileBarrelLarge) -{ - shapeFile = "turret_missile_large.dts"; - item = MissileBarrelPack; // z0dd - ZOD, 4/25/02. Was wrong: MissileBarrelLargePack - - projectile = TurretMissile; - projectileType = SeekerProjectile; - - usesEnergy = true; - fireEnergy = 60.0; - minEnergy = 60.0; - - isSeeker = true; - seekRadius = 300; - maxSeekAngle = 30; - seekTime = 1.0; - minSeekHeat = 0.6; - emap = true; - minTargetingDistance = 40; - - // Turret parameters - activationMS = 175; // z0dd - ZOD, 3/27/02. Was 250. Amount of time it takes turret to unfold - deactivateDelayMS = 500; - thinkTimeMS = 140; // z0dd - ZOD, 3/27/02. Was 200. Amount of time before turret starts to unfold (activate) - degPerSecTheta = 580; - degPerSecPhi = 1080; - attackRadius = 250; - - // State transitions - stateName[0] = "Activate"; - stateTransitionOnNotLoaded[0] = "Dead"; - stateTransitionOnLoaded[0] = "ActivateReady"; - - stateName[1] = "ActivateReady"; - stateSequence[1] = "Activate"; - stateSound[1] = MILSwitchSound; // z0dd - ZOD, 3/27/02. Was MBLSwitchSound, changed for sound fix. - stateTimeoutValue[1] = 2; - stateTransitionOnTimeout[1] = "Ready"; - stateTransitionOnNotLoaded[1] = "Deactivate"; - stateTransitionOnNoAmmo[1] = "NoAmmo"; - - stateName[2] = "Ready"; - stateTransitionOnNotLoaded[2] = "Deactivate"; - stateTransitionOnTriggerDown[2] = "Fire"; - stateTransitionOnNoAmmo[2] = "NoAmmo"; - - stateName[3] = "Fire"; - stateTransitionOnTimeout[3] = "Reload"; - stateTimeoutValue[3] = 0.3; - stateFire[3] = true; - stateRecoil[3] = LightRecoil; - stateAllowImageChange[3] = false; - stateSequence[3] = "Fire"; - stateSound[3] = MILFireSound; // z0dd - ZOD, 3/27/02. Was MBLFireSound, changed for sound fix. - stateScript[3] = "onFire"; - - stateName[4] = "Reload"; - stateTimeoutValue[4] = 3.5; - stateAllowImageChange[4] = false; - stateSequence[4] = "Reload"; - stateTransitionOnTimeout[4] = "Ready"; - stateTransitionOnNotLoaded[4] = "Deactivate"; - stateTransitionOnNoAmmo[4] = "NoAmmo"; - - stateName[5] = "Deactivate"; - stateSequence[5] = "Activate"; - stateDirection[5] = false; - stateTimeoutValue[5] = 2; - stateTransitionOnLoaded[5] = "ActivateReady"; - stateTransitionOnTimeout[5] = "Dead"; - - stateName[6] = "Dead"; - stateTransitionOnLoaded[6] = "ActivateReady"; - - stateName[7] = "NoAmmo"; - stateTransitionOnAmmo[7] = "Reload"; - stateSequence[7] = "NoAmmo"; -}; - +//-------------------------------------------------------------------------- +// Large Missile Turret +// +// z0dd - ZOD, 4/25/02. Labels for sound datablocks were wrong. +//------------------------------------------------------------- + +//-------------------------------------------------------------------------- +// Sounds +//-------------------------------------- +datablock EffectProfile(MILSwitchEffect) +{ + effectname = "powered/turret_heavy_activate"; + minDistance = 2.5; + maxDistance = 5.0; +}; + +datablock EffectProfile(MILFireEffect) +{ + effectname = "powered/turret_missile_fire"; + minDistance = 2.5; + maxDistance = 5.0; +}; + +datablock AudioProfile(MILSwitchSound) +{ + filename = "fx/powered/turret_missile_activate.wav"; + description = AudioClose3d; + preload = true; + effect = MILSwitchEffect; +}; + +datablock AudioProfile(MILFireSound) +{ + filename = "fx/powered/turret_missile_fire.wav"; + description = AudioDefault3d; + preload = true; + effect = MILFireEffect; +}; + + +//-------------------------------------------------------------------------- +// Particle effects: Note that we pull the below datablocks from +// scripts/weapons/missileLauncher.cs +//-------------------------------------- +//datablock ParticleData(MissileSmokeParticle) +//datablock ParticleEmitterData(MissileSmokeEmitter) + + +//-------------------------------------------------------------------------- +// Explosion: from scripts/weapons/disc.cs +//-------------------------------------- +//dataBlock ExplosionData(DiscExplosion) + +//-------------------------------------------------------------------------- +// Projectile +//-------------------------------------- +datablock SeekerProjectileData(TurretMissile) +{ + casingShapeName = "weapon_missile_casement.dts"; + projectileShapeName = "weapon_missile_projectile.dts"; + hasDamageRadius = true; + indirectDamage = 1.0; + damageRadius = 4.0; + radiusDamageType = $DamageType::MissileTurret; + kickBackStrength = 2500; + + flareDistance = 200; + flareAngle = 30; + minSeekHeat = 0.6; + + explosion = "MissileExplosion"; + velInheritFactor = 0.2; + + splash = MissileSplash; + baseEmitter = MissileSmokeEmitter; + delayEmitter = MissileFireEmitter; + puffEmitter = MissilePuffEmitter; + + lifetimeMS = 20000; + muzzleVelocity = 90.0; // z0dd - ZOD, 3/27/02. Was 80. Velocity of projectile + turningSpeed = 90.0; + + proximityRadius = 4; + + terrainAvoidanceSpeed = 180; + terrainScanAhead = 25; + terrainHeightFail = 12; + terrainAvoidanceRadius = 100; + + useFlechette = true; + flechetteDelayMs = 550; + casingDeb = FlechetteDebris; +}; + +//-------------------------------------------------------------------------- +//-------------------------------------- Fusion Turret Image +// +datablock TurretImageData(MissileBarrelLarge) +{ + shapeFile = "turret_missile_large.dts"; + item = MissileBarrelPack; // z0dd - ZOD, 4/25/02. Was wrong: MissileBarrelLargePack + + projectile = TurretMissile; + projectileType = SeekerProjectile; + + usesEnergy = true; + fireEnergy = 60.0; + minEnergy = 60.0; + + isSeeker = true; + seekRadius = 300; + maxSeekAngle = 30; + seekTime = 1.0; + minSeekHeat = 0.6; + emap = true; + minTargetingDistance = 40; + + // Turret parameters + activationMS = 175; // z0dd - ZOD, 3/27/02. Was 250. Amount of time it takes turret to unfold + deactivateDelayMS = 500; + thinkTimeMS = 140; // z0dd - ZOD, 3/27/02. Was 200. Amount of time before turret starts to unfold (activate) + degPerSecTheta = 580; + degPerSecPhi = 1080; + attackRadius = 250; + + // State transitions + stateName[0] = "Activate"; + stateTransitionOnNotLoaded[0] = "Dead"; + stateTransitionOnLoaded[0] = "ActivateReady"; + + stateName[1] = "ActivateReady"; + stateSequence[1] = "Activate"; + stateSound[1] = MILSwitchSound; // z0dd - ZOD, 3/27/02. Was MBLSwitchSound, changed for sound fix. + stateTimeoutValue[1] = 2; + stateTransitionOnTimeout[1] = "Ready"; + stateTransitionOnNotLoaded[1] = "Deactivate"; + stateTransitionOnNoAmmo[1] = "NoAmmo"; + + stateName[2] = "Ready"; + stateTransitionOnNotLoaded[2] = "Deactivate"; + stateTransitionOnTriggerDown[2] = "Fire"; + stateTransitionOnNoAmmo[2] = "NoAmmo"; + + stateName[3] = "Fire"; + stateTransitionOnTimeout[3] = "Reload"; + stateTimeoutValue[3] = 0.3; + stateFire[3] = true; + stateRecoil[3] = LightRecoil; + stateAllowImageChange[3] = false; + stateSequence[3] = "Fire"; + stateSound[3] = MILFireSound; // z0dd - ZOD, 3/27/02. Was MBLFireSound, changed for sound fix. + stateScript[3] = "onFire"; + + stateName[4] = "Reload"; + stateTimeoutValue[4] = 3.5; + stateAllowImageChange[4] = false; + stateSequence[4] = "Reload"; + stateTransitionOnTimeout[4] = "Ready"; + stateTransitionOnNotLoaded[4] = "Deactivate"; + stateTransitionOnNoAmmo[4] = "NoAmmo"; + + stateName[5] = "Deactivate"; + stateSequence[5] = "Activate"; + stateDirection[5] = false; + stateTimeoutValue[5] = 2; + stateTransitionOnLoaded[5] = "ActivateReady"; + stateTransitionOnTimeout[5] = "Dead"; + + stateName[6] = "Dead"; + stateTransitionOnLoaded[6] = "ActivateReady"; + + stateName[7] = "NoAmmo"; + stateTransitionOnAmmo[7] = "Reload"; + stateSequence[7] = "NoAmmo"; +}; + diff --git a/scripts/turrets/mortarBarrelLarge.cs b/scripts/turrets/mortarBarrelLarge.cs index fd4922a..17a75b5 100644 --- a/scripts/turrets/mortarBarrelLarge.cs +++ b/scripts/turrets/mortarBarrelLarge.cs @@ -1,161 +1,161 @@ -//-------------------------------------------------------------------------- -// Large Mortar Turret -// -// -//-------------------------------------------------------------------------- - -//-------------------------------------------------------------------------- -// Sounds -//-------------------------------------- -datablock EffectProfile(MBLSwitchEffect) -{ - effectname = "powered/turret_heavy_activate"; - minDistance = 2.5; - maxDistance = 5.0; -}; - -datablock EffectProfile(MBLFireEffect) -{ - effectname = "powered/turret_mortar_fire"; - minDistance = 2.5; - maxDistance = 5.0; -}; - -datablock AudioProfile(MBLSwitchSound) -{ - filename = "fx/powered/turret_heavy_activate.wav"; - description = AudioClose3d; - preload = true; - effect = MBLSwitchEffect; -}; - -datablock AudioProfile(MBLFireSound) -{ - filename = "fx/powered/turret_mortar_fire.wav"; - description = AudioDefault3d; - preload = true; - effect = MBLFireEffect; -}; - -//-------------------------------------------------------------------------- -// Projectile -//-------------------------------------- - -datablock AudioProfile(MortarTurretProjectileSound) -{ - filename = "fx/weapons/mortar_projectile.wav"; - description = ProjectileLooping3d; - preload = true; -}; - -datablock GrenadeProjectileData(MortarTurretShot) -{ - projectileShapeName = "mortar_projectile.dts"; - emitterDelay = -1; - directDamage = 0.0; - hasDamageRadius = true; - indirectDamage = 1.32; - damageRadius = 30.0; - radiusDamageType = $DamageType::MortarTurret; - kickBackStrength = 3000; - - explosion = "MortarExplosion"; - velInheritFactor = 0.5; - splash = MortarSplash; - - baseEmitter = MortarSmokeEmitter; - bubbleEmitter = MortarBubbleEmitter; - - grenadeElasticity = 0.25; - grenadeFriction = 0.4; - armingDelayMS = 1500; // z0dd - ZOD, 4/25/02. Was 2000 - gravityMod = 1.2; // z0dd - ZOD, 5/18/02. Make mortar projectile heavier, less floaty - muzzleVelocity = 75.95; // z0dd - ZOD, 8/13/02. More speed to compensate for higher gravity. Was 63.7 - drag = 0.1; - - sound = MortarTurretProjectileSound; - - hasLight = true; - lightRadius = 3; - lightColor = "0.05 0.2 0.05"; -}; - -//-------------------------------------------------------------------------- -//-------------------------------------- Fusion Turret Image -// -datablock TurretImageData(MortarBarrelLarge) -{ - shapeFile = "turret_mortar_large.dts"; - item = MortarBarrelPack; // z0dd - ZOD, 4/25/02. Was wrong: MortarBarrelLargePack - - projectile = MortarTurretShot; - projectileType = GrenadeProjectile; - usesEnergy = true; - fireEnergy = 30; - minEnergy = 30; - emap = true; - - // don't let a mortar turret blow itself up - dontFireInsideDamageRadius = true; - damageRadius = 40; - - // Turret parameters - activationMS = 700; // z0dd - ZOD, 4/25/02. Was 1000. Amount of time it takes turret to unfold - deactivateDelayMS = 1500; - thinkTimeMS = 140; // z0dd - ZOD, 4/25/02. Was 200. Amount of time before turret starts to unfold (activate) - degPerSecTheta = 580; - degPerSecPhi = 960; - attackRadius = 400; // z0dd - ZOD, 4/25/02. Was 160 - - // State transitions - stateName[0] = "Activate"; - stateTransitionOnNotLoaded[0] = "Dead"; - stateTransitionOnLoaded[0] = "ActivateReady"; - - stateName[1] = "ActivateReady"; - stateSequence[1] = "Activate"; - stateSound[1] = MBLSwitchSound; - stateTimeoutValue[1] = 1; - stateTransitionOnTimeout[1] = "Ready"; - stateTransitionOnNotLoaded[1] = "Deactivate"; - stateTransitionOnNoAmmo[1] = "NoAmmo"; - - stateName[2] = "Ready"; - stateTransitionOnNotLoaded[2] = "Deactivate"; - stateTransitionOnTriggerDown[2] = "Fire"; - stateTransitionOnNoAmmo[2] = "NoAmmo"; - - stateName[3] = "Fire"; - stateTransitionOnTimeout[3] = "Reload"; - stateTimeoutValue[3] = 0.3; - stateFire[3] = true; - stateRecoil[3] = LightRecoil; - stateAllowImageChange[3] = false; - stateSequence[3] = "Fire"; - stateSound[3] = MBLFireSound; - stateScript[3] = "onFire"; - - stateName[4] = "Reload"; - stateTimeoutValue[4] = 1.5; - stateAllowImageChange[4] = false; - stateSequence[4] = "Reload"; - stateTransitionOnTimeout[4] = "Ready"; - stateTransitionOnNotLoaded[4] = "Deactivate"; - stateTransitionOnNoAmmo[4] = "NoAmmo"; - - stateName[5] = "Deactivate"; - stateSequence[5] = "Activate"; - stateDirection[5] = false; - stateTimeoutValue[5] = 1; - stateTransitionOnLoaded[5] = "ActivateReady"; - stateTransitionOnTimeout[5] = "Dead"; - - stateName[6] = "Dead"; - stateTransitionOnLoaded[6] = "ActivateReady"; - - stateName[7] = "NoAmmo"; - stateTransitionOnAmmo[7] = "Reload"; - stateSequence[7] = "NoAmmo"; -}; - - +//-------------------------------------------------------------------------- +// Large Mortar Turret +// +// +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +// Sounds +//-------------------------------------- +datablock EffectProfile(MBLSwitchEffect) +{ + effectname = "powered/turret_heavy_activate"; + minDistance = 2.5; + maxDistance = 5.0; +}; + +datablock EffectProfile(MBLFireEffect) +{ + effectname = "powered/turret_mortar_fire"; + minDistance = 2.5; + maxDistance = 5.0; +}; + +datablock AudioProfile(MBLSwitchSound) +{ + filename = "fx/powered/turret_heavy_activate.wav"; + description = AudioClose3d; + preload = true; + effect = MBLSwitchEffect; +}; + +datablock AudioProfile(MBLFireSound) +{ + filename = "fx/powered/turret_mortar_fire.wav"; + description = AudioDefault3d; + preload = true; + effect = MBLFireEffect; +}; + +//-------------------------------------------------------------------------- +// Projectile +//-------------------------------------- + +datablock AudioProfile(MortarTurretProjectileSound) +{ + filename = "fx/weapons/mortar_projectile.wav"; + description = ProjectileLooping3d; + preload = true; +}; + +datablock GrenadeProjectileData(MortarTurretShot) +{ + projectileShapeName = "mortar_projectile.dts"; + emitterDelay = -1; + directDamage = 0.0; + hasDamageRadius = true; + indirectDamage = 1.32; + damageRadius = 30.0; + radiusDamageType = $DamageType::MortarTurret; + kickBackStrength = 3000; + + explosion = "MortarExplosion"; + velInheritFactor = 0.5; + splash = MortarSplash; + + baseEmitter = MortarSmokeEmitter; + bubbleEmitter = MortarBubbleEmitter; + + grenadeElasticity = 0.25; + grenadeFriction = 0.4; + armingDelayMS = 1500; // z0dd - ZOD, 4/25/02. Was 2000 + gravityMod = 1.2; // z0dd - ZOD, 5/18/02. Make mortar projectile heavier, less floaty + muzzleVelocity = 75.95; // z0dd - ZOD, 8/13/02. More speed to compensate for higher gravity. Was 63.7 + drag = 0.1; + + sound = MortarTurretProjectileSound; + + hasLight = true; + lightRadius = 3; + lightColor = "0.05 0.2 0.05"; +}; + +//-------------------------------------------------------------------------- +//-------------------------------------- Fusion Turret Image +// +datablock TurretImageData(MortarBarrelLarge) +{ + shapeFile = "turret_mortar_large.dts"; + item = MortarBarrelPack; // z0dd - ZOD, 4/25/02. Was wrong: MortarBarrelLargePack + + projectile = MortarTurretShot; + projectileType = GrenadeProjectile; + usesEnergy = true; + fireEnergy = 30; + minEnergy = 30; + emap = true; + + // don't let a mortar turret blow itself up + dontFireInsideDamageRadius = true; + damageRadius = 40; + + // Turret parameters + activationMS = 700; // z0dd - ZOD, 4/25/02. Was 1000. Amount of time it takes turret to unfold + deactivateDelayMS = 1500; + thinkTimeMS = 140; // z0dd - ZOD, 4/25/02. Was 200. Amount of time before turret starts to unfold (activate) + degPerSecTheta = 580; + degPerSecPhi = 960; + attackRadius = 400; // z0dd - ZOD, 4/25/02. Was 160 + + // State transitions + stateName[0] = "Activate"; + stateTransitionOnNotLoaded[0] = "Dead"; + stateTransitionOnLoaded[0] = "ActivateReady"; + + stateName[1] = "ActivateReady"; + stateSequence[1] = "Activate"; + stateSound[1] = MBLSwitchSound; + stateTimeoutValue[1] = 1; + stateTransitionOnTimeout[1] = "Ready"; + stateTransitionOnNotLoaded[1] = "Deactivate"; + stateTransitionOnNoAmmo[1] = "NoAmmo"; + + stateName[2] = "Ready"; + stateTransitionOnNotLoaded[2] = "Deactivate"; + stateTransitionOnTriggerDown[2] = "Fire"; + stateTransitionOnNoAmmo[2] = "NoAmmo"; + + stateName[3] = "Fire"; + stateTransitionOnTimeout[3] = "Reload"; + stateTimeoutValue[3] = 0.3; + stateFire[3] = true; + stateRecoil[3] = LightRecoil; + stateAllowImageChange[3] = false; + stateSequence[3] = "Fire"; + stateSound[3] = MBLFireSound; + stateScript[3] = "onFire"; + + stateName[4] = "Reload"; + stateTimeoutValue[4] = 1.5; + stateAllowImageChange[4] = false; + stateSequence[4] = "Reload"; + stateTransitionOnTimeout[4] = "Ready"; + stateTransitionOnNotLoaded[4] = "Deactivate"; + stateTransitionOnNoAmmo[4] = "NoAmmo"; + + stateName[5] = "Deactivate"; + stateSequence[5] = "Activate"; + stateDirection[5] = false; + stateTimeoutValue[5] = 1; + stateTransitionOnLoaded[5] = "ActivateReady"; + stateTransitionOnTimeout[5] = "Dead"; + + stateName[6] = "Dead"; + stateTransitionOnLoaded[6] = "ActivateReady"; + + stateName[7] = "NoAmmo"; + stateTransitionOnAmmo[7] = "Reload"; + stateSequence[7] = "NoAmmo"; +}; + + diff --git a/scripts/turrets/outdoorDeployableBarrel.cs b/scripts/turrets/outdoorDeployableBarrel.cs index d65ae51..55bbe7d 100644 --- a/scripts/turrets/outdoorDeployableBarrel.cs +++ b/scripts/turrets/outdoorDeployableBarrel.cs @@ -1,251 +1,251 @@ -// -------------------------------------------------------------- -// Outdoor Deployable Turret barrel -// -------------------------------------------------------------- - -// -------------------------------------------------------------- -// Sound datablocks -// -------------------------------------------------------------- -datablock EffectProfile(OBLSwitchEffect) -{ - effectname = "powered/turret_light_activate"; - minDistance = 2.5; - maxDistance = 5.0; -}; - -datablock EffectProfile(OBLFireEffect) -{ - effectname = "powered/turret_outdoor_fire"; - minDistance = 2.5; - maxDistance = 5.0; -}; - -datablock AudioProfile(OBLSwitchSound) -{ - filename = "fx/powered/turret_light_activate.wav"; - description = AudioClose3d; - preload = true; - effect = OBLSwitchEffect; -}; - -datablock AudioProfile(OBLFireSound) -{ - filename = "fx/powered/turret_outdoor_fire.wav"; - description = AudioDefault3d; - preload = true; - effect = OBLFireEffect; -}; - -// -------------------------------------------------------------- -// Projectile data -// -------------------------------------------------------------- - -datablock TracerProjectileData(FusionBolt) -{ - doDynamicClientHits = true; - - projectileShapeName = ""; - directDamage = 0.0; - directDamageType = $DamageType::OutdoorDepTurret; - hasDamageRadius = true; - indirectDamage = 0.24; - damageRadius = 4.0; - kickBackStrength = 0.0; - radiusDamageType = $DamageType::OutdoorDepTurret; - sound = BlasterProjectileSound; - explosion = PlasmaBoltExplosion; - - dryVelocity = 60.0; - wetVelocity = 40.0; - velInheritFactor = 1.0; - fizzleTimeMS = 4000; - lifetimeMS = 6000; - explodeOnDeath = false; - reflectOnWaterImpactAngle = 0.0; - explodeOnWaterImpact = true; - deflectionOnWaterImpact = 0.0; - fizzleUnderwaterMS = -1; - - activateDelayMS = 100; - - tracerLength = 5; - tracerAlpha = false; - tracerMinPixels = 3; - tracerColor = "1 0 0 1"; - tracerTex[0] = "special/landSpikeBolt"; - tracerTex[1] = "special/landSpikeBoltCross"; - tracerWidth = 0.35; - crossSize = 0.79; - crossViewAng = 0.990; - renderCross = true; - emap = true; -}; - -// -------------------------------------------------------------- - -datablock SensorData(DeployedOutdoorTurretSensor) -{ - detects = true; - detectsUsingLOS = true; - detectsPassiveJammed = false; - detectsActiveJammed = false; - detectsCloaked = false; - detectionPings = true; - detectRadius = 60; -}; - -datablock ShockwaveData(OutdoorTurretMuzzleFlash) -{ - width = 0.5; - numSegments = 13; - numVertSegments = 1; - velocity = 2.0; - acceleration = -1.0; - lifetimeMS = 300; - height = 0.1; - verticalCurve = 0.5; - - mapToTerrain = false; - renderBottom = false; - orientToNormal = true; - renderSquare = true; - - texture[0] = "special/blasterHit"; - texture[1] = "special/gradient"; - texWrap = 3.0; - - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - - colors[0] = "1.0 0.8 0.5 1.0"; - colors[1] = "1.0 0.8 0.5 1.0"; - colors[2] = "1.0 0.8 0.5 0.0"; -}; - -datablock TurretData(TurretDeployedOutdoor) : TurretDamageProfile -{ - className = DeployedTurret; - shapeFile = "turret_outdoor_deploy.dts"; - - rechargeRate = 0.15; - - mass = 5.0; - maxDamage = 0.80; - destroyedLevel = 0.80; - disabledLevel = 0.35; - explosion = HandGrenadeExplosion; - expDmgRadius = 5.0; - expDamage = 0.3; - expImpulse = 500.0; - repairRate = 0; - - deployedObject = true; - - thetaMin = 0; - thetaMax = 145; - thetaNull = 90; - - yawVariance = 30.0; // these will smooth out the elf tracking code. - pitchVariance = 30.0; // more or less just tolerances - - isShielded = true; - energyPerDamagePoint = 110; - maxEnergy = 60; - renderWhenDestroyed = false; - barrel = DeployableOutdoorBarrel; - heatSignature = 0; - - canControl = true; - cmdCategory = "DTactical"; - cmdIcon = CMDTurretIcon; - cmdMiniIconName = "commander/MiniIcons/com_turret_grey"; - targetNameTag = 'Landspike'; - targetTypeTag = 'Turret'; - sensorData = DeployedOutdoorTurretSensor; - sensorRadius = DeployedOutdoorTurretSensor.detectRadius; - sensorColor = "191 0 226"; - - firstPersonOnly = true; - - debrisShapeName = "debris_generic_small.dts"; - debris = TurretDebrisSmall; -}; - -datablock TurretImageData(DeployableOutdoorBarrel) -{ - shapeFile = "turret_muzzlepoint.dts"; - item = TurretOutdoorDeployable; // z0dd - ZOD, 4/25/02. Was wrong: OutdoorTurretBarrel - - projectileType = TracerProjectile; - projectile = FusionBolt; - usesEnergy = true; - fireEnergy = 11.0; - minEnergy = 11.0; - - lightType = "WeaponFireLight"; - lightColor = "0.25 0.25 0.15 0.2"; - lightTime = "1000"; - lightRadius = "2"; - - muzzleFlash = OutdoorTurretMuzzleFlash; - - // Turret parameters - activationMS = 210; // z0dd - ZOD, 3/27/02. Was 300. Amount of time it takes turret to unfold - deactivateDelayMS = 600; - thinkTimeMS = 140; // z0dd - ZOD, 3/27/02. Was 200. Amount of time before turret starts to unfold (activate) - degPerSecTheta = 580; - degPerSecPhi = 960; - attackRadius = 100; - - // State transitions - stateName[0] = "Activate"; - stateTransitionOnNotLoaded[0] = "Dead"; - stateTransitionOnLoaded[0] = "ActivateReady"; - - stateName[1] = "ActivateReady"; - stateSequence[1] = "Activate"; - stateSound[1] = OBLSwitchSound; - stateTimeoutValue[1] = 1; - stateTransitionOnTimeout[1] = "Ready"; - stateTransitionOnNotLoaded[1] = "Deactivate"; - stateTransitionOnNoAmmo[1] = "NoAmmo"; - - stateName[2] = "Ready"; - stateTransitionOnNotLoaded[2] = "Deactivate"; - stateTransitionOnTriggerDown[2] = "Fire"; - stateTransitionOnNoAmmo[2] = "NoAmmo"; - - stateName[3] = "Fire"; - stateTransitionOnTimeout[3] = "Reload"; - stateTimeoutValue[3] = 0.3; - stateFire[3] = true; - stateShockwave[3] = true; - stateRecoil[3] = LightRecoil; - stateAllowImageChange[3] = false; - stateSequence[3] = "Fire"; - stateSound[3] = OBLFireSound; - stateScript[3] = "onFire"; - - stateName[4] = "Reload"; - stateTimeoutValue[4] = 1.2; - stateAllowImageChange[4] = false; - stateSequence[4] = "Reload"; - stateTransitionOnTimeout[4] = "Ready"; - stateTransitionOnNotLoaded[4] = "Deactivate"; - stateTransitionOnNoAmmo[4] = "NoAmmo"; - - stateName[5] = "Deactivate"; - stateSequence[5] = "Activate"; - stateDirection[5] = false; - stateTimeoutValue[5] = 1; - stateTransitionOnLoaded[5] = "ActivateReady"; - stateTransitionOnTimeout[5] = "Dead"; - - stateName[6] = "Dead"; - stateTransitionOnLoaded[6] = "ActivateReady"; - - stateName[7] = "NoAmmo"; - stateTransitionOnAmmo[7] = "Reload"; - stateSequence[7] = "NoAmmo"; -}; - +// -------------------------------------------------------------- +// Outdoor Deployable Turret barrel +// -------------------------------------------------------------- + +// -------------------------------------------------------------- +// Sound datablocks +// -------------------------------------------------------------- +datablock EffectProfile(OBLSwitchEffect) +{ + effectname = "powered/turret_light_activate"; + minDistance = 2.5; + maxDistance = 5.0; +}; + +datablock EffectProfile(OBLFireEffect) +{ + effectname = "powered/turret_outdoor_fire"; + minDistance = 2.5; + maxDistance = 5.0; +}; + +datablock AudioProfile(OBLSwitchSound) +{ + filename = "fx/powered/turret_light_activate.wav"; + description = AudioClose3d; + preload = true; + effect = OBLSwitchEffect; +}; + +datablock AudioProfile(OBLFireSound) +{ + filename = "fx/powered/turret_outdoor_fire.wav"; + description = AudioDefault3d; + preload = true; + effect = OBLFireEffect; +}; + +// -------------------------------------------------------------- +// Projectile data +// -------------------------------------------------------------- + +datablock TracerProjectileData(FusionBolt) +{ + doDynamicClientHits = true; + + projectileShapeName = ""; + directDamage = 0.0; + directDamageType = $DamageType::OutdoorDepTurret; + hasDamageRadius = true; + indirectDamage = 0.24; + damageRadius = 4.0; + kickBackStrength = 0.0; + radiusDamageType = $DamageType::OutdoorDepTurret; + sound = BlasterProjectileSound; + explosion = PlasmaBoltExplosion; + + dryVelocity = 60.0; + wetVelocity = 40.0; + velInheritFactor = 1.0; + fizzleTimeMS = 4000; + lifetimeMS = 6000; + explodeOnDeath = false; + reflectOnWaterImpactAngle = 0.0; + explodeOnWaterImpact = true; + deflectionOnWaterImpact = 0.0; + fizzleUnderwaterMS = -1; + + activateDelayMS = 100; + + tracerLength = 5; + tracerAlpha = false; + tracerMinPixels = 3; + tracerColor = "1 0 0 1"; + tracerTex[0] = "special/landSpikeBolt"; + tracerTex[1] = "special/landSpikeBoltCross"; + tracerWidth = 0.35; + crossSize = 0.79; + crossViewAng = 0.990; + renderCross = true; + emap = true; +}; + +// -------------------------------------------------------------- + +datablock SensorData(DeployedOutdoorTurretSensor) +{ + detects = true; + detectsUsingLOS = true; + detectsPassiveJammed = false; + detectsActiveJammed = false; + detectsCloaked = false; + detectionPings = true; + detectRadius = 60; +}; + +datablock ShockwaveData(OutdoorTurretMuzzleFlash) +{ + width = 0.5; + numSegments = 13; + numVertSegments = 1; + velocity = 2.0; + acceleration = -1.0; + lifetimeMS = 300; + height = 0.1; + verticalCurve = 0.5; + + mapToTerrain = false; + renderBottom = false; + orientToNormal = true; + renderSquare = true; + + texture[0] = "special/blasterHit"; + texture[1] = "special/gradient"; + texWrap = 3.0; + + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; + + colors[0] = "1.0 0.8 0.5 1.0"; + colors[1] = "1.0 0.8 0.5 1.0"; + colors[2] = "1.0 0.8 0.5 0.0"; +}; + +datablock TurretData(TurretDeployedOutdoor) : TurretDamageProfile +{ + className = DeployedTurret; + shapeFile = "turret_outdoor_deploy.dts"; + + rechargeRate = 0.15; + + mass = 5.0; + maxDamage = 0.80; + destroyedLevel = 0.80; + disabledLevel = 0.35; + explosion = HandGrenadeExplosion; + expDmgRadius = 5.0; + expDamage = 0.3; + expImpulse = 500.0; + repairRate = 0; + + deployedObject = true; + + thetaMin = 0; + thetaMax = 145; + thetaNull = 90; + + yawVariance = 30.0; // these will smooth out the elf tracking code. + pitchVariance = 30.0; // more or less just tolerances + + isShielded = true; + energyPerDamagePoint = 110; + maxEnergy = 60; + renderWhenDestroyed = false; + barrel = DeployableOutdoorBarrel; + heatSignature = 0; + + canControl = true; + cmdCategory = "DTactical"; + cmdIcon = CMDTurretIcon; + cmdMiniIconName = "commander/MiniIcons/com_turret_grey"; + targetNameTag = 'Landspike'; + targetTypeTag = 'Turret'; + sensorData = DeployedOutdoorTurretSensor; + sensorRadius = DeployedOutdoorTurretSensor.detectRadius; + sensorColor = "191 0 226"; + + firstPersonOnly = true; + + debrisShapeName = "debris_generic_small.dts"; + debris = TurretDebrisSmall; +}; + +datablock TurretImageData(DeployableOutdoorBarrel) +{ + shapeFile = "turret_muzzlepoint.dts"; + item = TurretOutdoorDeployable; // z0dd - ZOD, 4/25/02. Was wrong: OutdoorTurretBarrel + + projectileType = TracerProjectile; + projectile = FusionBolt; + usesEnergy = true; + fireEnergy = 11.0; + minEnergy = 11.0; + + lightType = "WeaponFireLight"; + lightColor = "0.25 0.25 0.15 0.2"; + lightTime = "1000"; + lightRadius = "2"; + + muzzleFlash = OutdoorTurretMuzzleFlash; + + // Turret parameters + activationMS = 210; // z0dd - ZOD, 3/27/02. Was 300. Amount of time it takes turret to unfold + deactivateDelayMS = 600; + thinkTimeMS = 140; // z0dd - ZOD, 3/27/02. Was 200. Amount of time before turret starts to unfold (activate) + degPerSecTheta = 580; + degPerSecPhi = 960; + attackRadius = 100; + + // State transitions + stateName[0] = "Activate"; + stateTransitionOnNotLoaded[0] = "Dead"; + stateTransitionOnLoaded[0] = "ActivateReady"; + + stateName[1] = "ActivateReady"; + stateSequence[1] = "Activate"; + stateSound[1] = OBLSwitchSound; + stateTimeoutValue[1] = 1; + stateTransitionOnTimeout[1] = "Ready"; + stateTransitionOnNotLoaded[1] = "Deactivate"; + stateTransitionOnNoAmmo[1] = "NoAmmo"; + + stateName[2] = "Ready"; + stateTransitionOnNotLoaded[2] = "Deactivate"; + stateTransitionOnTriggerDown[2] = "Fire"; + stateTransitionOnNoAmmo[2] = "NoAmmo"; + + stateName[3] = "Fire"; + stateTransitionOnTimeout[3] = "Reload"; + stateTimeoutValue[3] = 0.3; + stateFire[3] = true; + stateShockwave[3] = true; + stateRecoil[3] = LightRecoil; + stateAllowImageChange[3] = false; + stateSequence[3] = "Fire"; + stateSound[3] = OBLFireSound; + stateScript[3] = "onFire"; + + stateName[4] = "Reload"; + stateTimeoutValue[4] = 1.2; + stateAllowImageChange[4] = false; + stateSequence[4] = "Reload"; + stateTransitionOnTimeout[4] = "Ready"; + stateTransitionOnNotLoaded[4] = "Deactivate"; + stateTransitionOnNoAmmo[4] = "NoAmmo"; + + stateName[5] = "Deactivate"; + stateSequence[5] = "Activate"; + stateDirection[5] = false; + stateTimeoutValue[5] = 1; + stateTransitionOnLoaded[5] = "ActivateReady"; + stateTransitionOnTimeout[5] = "Dead"; + + stateName[6] = "Dead"; + stateTransitionOnLoaded[6] = "ActivateReady"; + + stateName[7] = "NoAmmo"; + stateTransitionOnAmmo[7] = "Reload"; + stateSequence[7] = "NoAmmo"; +}; + diff --git a/scripts/turrets/plasmaBarrelLarge.cs b/scripts/turrets/plasmaBarrelLarge.cs index 5d26cab..9812616 100644 --- a/scripts/turrets/plasmaBarrelLarge.cs +++ b/scripts/turrets/plasmaBarrelLarge.cs @@ -1,324 +1,324 @@ -//-------------------------------------------------------------------------- -// Plasma Turret -// -// -//-------------------------------------------------------------------------- - -//-------------------------------------------------------------------------- -// Sounds -//-------------------------------------------------------------------------- -datablock EffectProfile(PBLSwitchEffect) -{ - effectname = "powered/turret_light_activate"; - minDistance = 2.5; - maxDistance = 5.0; -}; - -datablock EffectProfile(PBLFireEffect) -{ - effectname = "powered/turret_plasma_fire"; - minDistance = 2.5; - maxDistance = 5.0; -}; - -datablock AudioProfile(PBLSwitchSound) -{ - filename = "fx/powered/turret_light_activate.wav"; - description = AudioClose3d; - preload = true; - effect = PBLSwitchEffect; -}; - -datablock AudioProfile(PBLFireSound) -{ - filename = "fx/powered/turret_plasma_fire.wav"; - description = AudioDefault3d; - preload = true; - effect = PBLFireEffect; -}; - -//-------------------------------------------------------------------------- -// Explosion -//-------------------------------------------------------------------------- - -datablock AudioProfile(PlasmaBarrelExpSound) -{ - filename = "fx/powered/turret_plasma_explode.wav"; - description = "AudioExplosion3d"; - preload = true; -}; - - -datablock ParticleData( PlasmaBarrelCrescentParticle ) -{ - dragCoefficient = 2; - gravityCoefficient = 0.0; - inheritedVelFactor = 0.2; - constantAcceleration = -0.0; - lifetimeMS = 600; - lifetimeVarianceMS = 000; - textureName = "special/crescent3"; - - colors[0] = "0.3 0.4 1.0 1.0"; - colors[1] = "0.3 0.4 1.0 0.5"; - colors[2] = "0.3 0.4 1.0 0.0"; - sizes[0] = 2.0; - sizes[1] = 4.0; - sizes[2] = 5.0; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData( PlasmaBarrelCrescentEmitter ) -{ - ejectionPeriodMS = 25; - periodVarianceMS = 0; - ejectionVelocity = 20; - velocityVariance = 5.0; - ejectionOffset = 0.0; - thetaMin = 0; - thetaMax = 80; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - orientParticles = true; - lifetimeMS = 200; - particles = "PlasmaBarrelCrescentParticle"; -}; - -datablock ParticleData(PlasmaBarrelExplosionParticle) -{ - dragCoefficient = 2; - gravityCoefficient = 0.2; - inheritedVelFactor = 0.2; - constantAcceleration = 0.0; - lifetimeMS = 750; - lifetimeVarianceMS = 150; - textureName = "particleTest"; - colors[0] = "0.3 0.4 1.0 1.0"; - colors[1] = "0.3 0.4 1.0 0.0"; - sizes[0] = 1; - sizes[1] = 2; -}; - -datablock ParticleEmitterData(PlasmaBarrelExplosionEmitter) -{ - ejectionPeriodMS = 7; - periodVarianceMS = 0; - ejectionVelocity = 12; - velocityVariance = 1.75; - ejectionOffset = 0.0; - thetaMin = 0; - thetaMax = 60; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - particles = "PlasmaBarrelExplosionParticle"; -}; - - -datablock ExplosionData(PlasmaBarrelSubExplosion1) -{ - explosionShape = "disc_explosion.dts"; - faceViewer = true; - - delayMS = 50; - - offset = 3.0; - - playSpeed = 1.5; - - sizes[0] = "0.25 0.25 0.25"; - sizes[1] = "0.25 0.25 0.25"; - times[0] = 0.0; - times[1] = 1.0; - -}; - -datablock ExplosionData(PlasmaBarrelSubExplosion2) -{ - explosionShape = "disc_explosion.dts"; - faceViewer = true; - - delayMS = 100; - - offset = 3.5; - - playSpeed = 1.0; - - sizes[0] = "0.5 0.5 0.5"; - sizes[1] = "0.5 0.5 0.5"; - times[0] = 0.0; - times[1] = 1.0; -}; - -datablock ExplosionData(PlasmaBarrelSubExplosion3) -{ - explosionShape = "disc_explosion.dts"; - faceViewer = true; - - delayMS = 0; - - offset = 0.0; - - playSpeed = 0.7; - - - sizes[0] = "0.5 0.5 0.5"; - sizes[1] = "1.0 1.0 1.0"; - times[0] = 0.0; - times[1] = 1.0; - -}; - -datablock ExplosionData(PlasmaBarrelBoltExplosion) -{ - soundProfile = PlasmaBarrelExpSound; - particleEmitter = PlasmaBarrelExplosionEmitter; - particleDensity = 250; - particleRadius = 1.25; - faceViewer = true; - - emitter[0] = PlasmaBarrelCrescentEmitter; - - subExplosion[0] = PlasmaBarrelSubExplosion1; - subExplosion[1] = PlasmaBarrelSubExplosion2; - subExplosion[2] = PlasmaBarrelSubExplosion3; - - shakeCamera = true; - camShakeFreq = "10.0 9.0 9.0"; - camShakeAmp = "10.0 10.0 10.0"; - camShakeDuration = 0.5; - camShakeRadius = 15.0; -}; - -//-------------------------------------------------------------------------- -// Projectile -//-------------------------------------- - -datablock LinearFlareProjectileData(PlasmaBarrelBolt) -{ - doDynamicClientHits = true; - - directDamage = 0; - directDamageType = $DamageType::PlasmaTurret; - hasDamageRadius = true; - indirectDamage = 1.2; // z0dd - ZOD, 4/25/02. Was 0.5 - damageRadius = 10.0; - kickBackStrength = 500; - radiusDamageType = $DamageType::PlasmaTurret; - explosion = PlasmaBarrelBoltExplosion; - splash = PlasmaSplash; - - dryVelocity = 75.0; // z0dd - ZOD, 4/25/02. Was 50. Velocity of projectile out of water - wetVelocity = -1; - velInheritFactor = 1.0; - fizzleTimeMS = 4000; - lifetimeMS = 4000; // z0dd - ZOD, 4/25/02. Was 6000 - explodeOnDeath = false; - reflectOnWaterImpactAngle = 0.0; - explodeOnWaterImpact = true; - deflectionOnWaterImpact = 0.0; - fizzleUnderwaterMS = -1; - - activateDelayMS = 100; - - scale = "1.5 1.5 1.5"; - numFlares = 30; - flareColor = "0.1 0.3 1.0"; - flareModTexture = "flaremod"; - flareBaseTexture = "flarebase"; -}; - -//-------------------------------------------------------------------------- -// Plasma Turret Image -//-------------------------------------------------------------------------- - -datablock TurretImageData(PlasmaBarrelLarge) -{ - shapeFile = "turret_fusion_large.dts"; - item = PlasmaBarrelPack; // z0dd - ZOD, 4/25/02. Was wrong: PlasmaBarrelLargePack - - projectile = PlasmaBarrelBolt; - projectileType = LinearFlareProjectile; - usesEnergy = true; - fireEnergy = 10; - minEnergy = 10; - emap = true; - - // Turret parameters - activationMS = 700; // z0dd - ZOD, 3/27/02. Was 1000. Amount of time it takes turret to unfold - deactivateDelayMS = 1500; - thinkTimeMS = 140; // z0dd - ZOD, 3/27/02. Was 200. Amount of time before turret starts to unfold (activate) - degPerSecTheta = 300; - degPerSecPhi = 500; - attackRadius = 150; // z0dd - ZOD, 3/27/02. Was 120 - - // State transitions - stateName[0] = "Activate"; - stateTransitionOnNotLoaded[0] = "Dead"; - stateTransitionOnLoaded[0] = "ActivateReady"; - - stateName[1] = "ActivateReady"; - stateSequence[1] = "Activate"; - stateSound[1] = PBLSwitchSound; - stateTimeoutValue[1] = 1; - stateTransitionOnTimeout[1] = "Ready"; - stateTransitionOnNotLoaded[1] = "Deactivate"; - stateTransitionOnNoAmmo[1] = "NoAmmo"; - - stateName[2] = "Ready"; - stateTransitionOnNotLoaded[2] = "Deactivate"; - stateTransitionOnTriggerDown[2] = "Fire"; - stateTransitionOnNoAmmo[2] = "NoAmmo"; - - stateName[3] = "Fire"; - stateTransitionOnTimeout[3] = "Reload"; - stateTimeoutValue[3] = 0.3; - stateFire[3] = true; - stateRecoil[3] = LightRecoil; - stateAllowImageChange[3] = false; - stateSequence[3] = "Fire"; - stateSound[3] = PBLFireSound; - stateScript[3] = "onFire"; - - stateName[4] = "Reload"; - stateTimeoutValue[4] = 0.80; - stateAllowImageChange[4] = false; - stateSequence[4] = "Reload"; - stateTransitionOnTimeout[4] = "Ready"; - stateTransitionOnNotLoaded[4] = "Deactivate"; - stateTransitionOnNoAmmo[4] = "NoAmmo"; - - stateName[5] = "Deactivate"; - stateSequence[5] = "Activate"; - stateDirection[5] = false; - stateTimeoutValue[5] = 1; - stateTransitionOnLoaded[5] = "ActivateReady"; - stateTransitionOnTimeout[5] = "Dead"; - - stateName[6] = "Dead"; - stateTransitionOnLoaded[6] = "ActivateReady"; - - stateName[7] = "NoAmmo"; - stateTransitionOnAmmo[7] = "Reload"; - stateSequence[7] = "NoAmmo"; -}; - - - - - - - - - - - - - - - - - +//-------------------------------------------------------------------------- +// Plasma Turret +// +// +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +// Sounds +//-------------------------------------------------------------------------- +datablock EffectProfile(PBLSwitchEffect) +{ + effectname = "powered/turret_light_activate"; + minDistance = 2.5; + maxDistance = 5.0; +}; + +datablock EffectProfile(PBLFireEffect) +{ + effectname = "powered/turret_plasma_fire"; + minDistance = 2.5; + maxDistance = 5.0; +}; + +datablock AudioProfile(PBLSwitchSound) +{ + filename = "fx/powered/turret_light_activate.wav"; + description = AudioClose3d; + preload = true; + effect = PBLSwitchEffect; +}; + +datablock AudioProfile(PBLFireSound) +{ + filename = "fx/powered/turret_plasma_fire.wav"; + description = AudioDefault3d; + preload = true; + effect = PBLFireEffect; +}; + +//-------------------------------------------------------------------------- +// Explosion +//-------------------------------------------------------------------------- + +datablock AudioProfile(PlasmaBarrelExpSound) +{ + filename = "fx/powered/turret_plasma_explode.wav"; + description = "AudioExplosion3d"; + preload = true; +}; + + +datablock ParticleData( PlasmaBarrelCrescentParticle ) +{ + dragCoefficient = 2; + gravityCoefficient = 0.0; + inheritedVelFactor = 0.2; + constantAcceleration = -0.0; + lifetimeMS = 600; + lifetimeVarianceMS = 000; + textureName = "special/crescent3"; + + colors[0] = "0.3 0.4 1.0 1.0"; + colors[1] = "0.3 0.4 1.0 0.5"; + colors[2] = "0.3 0.4 1.0 0.0"; + sizes[0] = 2.0; + sizes[1] = 4.0; + sizes[2] = 5.0; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; +}; + +datablock ParticleEmitterData( PlasmaBarrelCrescentEmitter ) +{ + ejectionPeriodMS = 25; + periodVarianceMS = 0; + ejectionVelocity = 20; + velocityVariance = 5.0; + ejectionOffset = 0.0; + thetaMin = 0; + thetaMax = 80; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + orientParticles = true; + lifetimeMS = 200; + particles = "PlasmaBarrelCrescentParticle"; +}; + +datablock ParticleData(PlasmaBarrelExplosionParticle) +{ + dragCoefficient = 2; + gravityCoefficient = 0.2; + inheritedVelFactor = 0.2; + constantAcceleration = 0.0; + lifetimeMS = 750; + lifetimeVarianceMS = 150; + textureName = "particleTest"; + colors[0] = "0.3 0.4 1.0 1.0"; + colors[1] = "0.3 0.4 1.0 0.0"; + sizes[0] = 1; + sizes[1] = 2; +}; + +datablock ParticleEmitterData(PlasmaBarrelExplosionEmitter) +{ + ejectionPeriodMS = 7; + periodVarianceMS = 0; + ejectionVelocity = 12; + velocityVariance = 1.75; + ejectionOffset = 0.0; + thetaMin = 0; + thetaMax = 60; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + particles = "PlasmaBarrelExplosionParticle"; +}; + + +datablock ExplosionData(PlasmaBarrelSubExplosion1) +{ + explosionShape = "disc_explosion.dts"; + faceViewer = true; + + delayMS = 50; + + offset = 3.0; + + playSpeed = 1.5; + + sizes[0] = "0.25 0.25 0.25"; + sizes[1] = "0.25 0.25 0.25"; + times[0] = 0.0; + times[1] = 1.0; + +}; + +datablock ExplosionData(PlasmaBarrelSubExplosion2) +{ + explosionShape = "disc_explosion.dts"; + faceViewer = true; + + delayMS = 100; + + offset = 3.5; + + playSpeed = 1.0; + + sizes[0] = "0.5 0.5 0.5"; + sizes[1] = "0.5 0.5 0.5"; + times[0] = 0.0; + times[1] = 1.0; +}; + +datablock ExplosionData(PlasmaBarrelSubExplosion3) +{ + explosionShape = "disc_explosion.dts"; + faceViewer = true; + + delayMS = 0; + + offset = 0.0; + + playSpeed = 0.7; + + + sizes[0] = "0.5 0.5 0.5"; + sizes[1] = "1.0 1.0 1.0"; + times[0] = 0.0; + times[1] = 1.0; + +}; + +datablock ExplosionData(PlasmaBarrelBoltExplosion) +{ + soundProfile = PlasmaBarrelExpSound; + particleEmitter = PlasmaBarrelExplosionEmitter; + particleDensity = 250; + particleRadius = 1.25; + faceViewer = true; + + emitter[0] = PlasmaBarrelCrescentEmitter; + + subExplosion[0] = PlasmaBarrelSubExplosion1; + subExplosion[1] = PlasmaBarrelSubExplosion2; + subExplosion[2] = PlasmaBarrelSubExplosion3; + + shakeCamera = true; + camShakeFreq = "10.0 9.0 9.0"; + camShakeAmp = "10.0 10.0 10.0"; + camShakeDuration = 0.5; + camShakeRadius = 15.0; +}; + +//-------------------------------------------------------------------------- +// Projectile +//-------------------------------------- + +datablock LinearFlareProjectileData(PlasmaBarrelBolt) +{ + doDynamicClientHits = true; + + directDamage = 0; + directDamageType = $DamageType::PlasmaTurret; + hasDamageRadius = true; + indirectDamage = 1.2; // z0dd - ZOD, 4/25/02. Was 0.5 + damageRadius = 10.0; + kickBackStrength = 500; + radiusDamageType = $DamageType::PlasmaTurret; + explosion = PlasmaBarrelBoltExplosion; + splash = PlasmaSplash; + + dryVelocity = 75.0; // z0dd - ZOD, 4/25/02. Was 50. Velocity of projectile out of water + wetVelocity = -1; + velInheritFactor = 1.0; + fizzleTimeMS = 4000; + lifetimeMS = 4000; // z0dd - ZOD, 4/25/02. Was 6000 + explodeOnDeath = false; + reflectOnWaterImpactAngle = 0.0; + explodeOnWaterImpact = true; + deflectionOnWaterImpact = 0.0; + fizzleUnderwaterMS = -1; + + activateDelayMS = 100; + + scale = "1.5 1.5 1.5"; + numFlares = 30; + flareColor = "0.1 0.3 1.0"; + flareModTexture = "flaremod"; + flareBaseTexture = "flarebase"; +}; + +//-------------------------------------------------------------------------- +// Plasma Turret Image +//-------------------------------------------------------------------------- + +datablock TurretImageData(PlasmaBarrelLarge) +{ + shapeFile = "turret_fusion_large.dts"; + item = PlasmaBarrelPack; // z0dd - ZOD, 4/25/02. Was wrong: PlasmaBarrelLargePack + + projectile = PlasmaBarrelBolt; + projectileType = LinearFlareProjectile; + usesEnergy = true; + fireEnergy = 10; + minEnergy = 10; + emap = true; + + // Turret parameters + activationMS = 700; // z0dd - ZOD, 3/27/02. Was 1000. Amount of time it takes turret to unfold + deactivateDelayMS = 1500; + thinkTimeMS = 140; // z0dd - ZOD, 3/27/02. Was 200. Amount of time before turret starts to unfold (activate) + degPerSecTheta = 300; + degPerSecPhi = 500; + attackRadius = 150; // z0dd - ZOD, 3/27/02. Was 120 + + // State transitions + stateName[0] = "Activate"; + stateTransitionOnNotLoaded[0] = "Dead"; + stateTransitionOnLoaded[0] = "ActivateReady"; + + stateName[1] = "ActivateReady"; + stateSequence[1] = "Activate"; + stateSound[1] = PBLSwitchSound; + stateTimeoutValue[1] = 1; + stateTransitionOnTimeout[1] = "Ready"; + stateTransitionOnNotLoaded[1] = "Deactivate"; + stateTransitionOnNoAmmo[1] = "NoAmmo"; + + stateName[2] = "Ready"; + stateTransitionOnNotLoaded[2] = "Deactivate"; + stateTransitionOnTriggerDown[2] = "Fire"; + stateTransitionOnNoAmmo[2] = "NoAmmo"; + + stateName[3] = "Fire"; + stateTransitionOnTimeout[3] = "Reload"; + stateTimeoutValue[3] = 0.3; + stateFire[3] = true; + stateRecoil[3] = LightRecoil; + stateAllowImageChange[3] = false; + stateSequence[3] = "Fire"; + stateSound[3] = PBLFireSound; + stateScript[3] = "onFire"; + + stateName[4] = "Reload"; + stateTimeoutValue[4] = 0.80; + stateAllowImageChange[4] = false; + stateSequence[4] = "Reload"; + stateTransitionOnTimeout[4] = "Ready"; + stateTransitionOnNotLoaded[4] = "Deactivate"; + stateTransitionOnNoAmmo[4] = "NoAmmo"; + + stateName[5] = "Deactivate"; + stateSequence[5] = "Activate"; + stateDirection[5] = false; + stateTimeoutValue[5] = 1; + stateTransitionOnLoaded[5] = "ActivateReady"; + stateTransitionOnTimeout[5] = "Dead"; + + stateName[6] = "Dead"; + stateTransitionOnLoaded[6] = "ActivateReady"; + + stateName[7] = "NoAmmo"; + stateTransitionOnAmmo[7] = "Reload"; + stateSequence[7] = "NoAmmo"; +}; + + + + + + + + + + + + + + + + + diff --git a/scripts/vehicles/serverVehicleHud.cs b/scripts/vehicles/serverVehicleHud.cs index ef8be77..85125ca 100644 --- a/scripts/vehicles/serverVehicleHud.cs +++ b/scripts/vehicles/serverVehicleHud.cs @@ -1,324 +1,324 @@ -//------------------------------------------------------------------------------ -datablock EffectProfile(VehicleAppearEffect) -{ - effectname = "vehicles/inventory_pad_appear"; - minDistance = 5; - maxDistance = 10; -}; - -datablock EffectProfile(ActivateVehiclePadEffect) -{ - effectname = "powered/vehicle_pad_on"; - minDistance = 20; - maxDistance = 30; -}; - -datablock AudioProfile(VehicleAppearSound) -{ - filename = "fx/vehicles/inventory_pad_appear.wav"; - description = AudioClosest3d; - preload = true; - effect = VehicleAppearEffect; -}; - -datablock AudioProfile(ActivateVehiclePadSound) -{ - filename = "fx/powered/vehicle_pad_on.wav"; - description = AudioClose3d; - preload = true; - effect = ActivateVehiclePadEffect; -}; - -datablock StationFXVehicleData( VehicleInvFX ) -{ - lifetime = 6.0; - - glowTopHeight = 1.5; - glowBottomHeight = 0.1; - glowTopRadius = 12.5; - glowBottomRadius = 12.0; - numGlowSegments = 26; - glowFadeTime = 3.25; - - armLightDelay = 2.3; - armLightLifetime = 3.0; - armLightFadeTime = 1.5; - numArcSegments = 10.0; - - sphereColor = "0.1 0.1 0.5"; - spherePhiSegments = 13; - sphereThetaSegments = 8; - sphereRadius = 12.0; - sphereScale = "1.05 1.05 0.85"; - - glowNodeName = "GLOWFX"; - - leftNodeName[0] = "LFX1"; - leftNodeName[1] = "LFX2"; - leftNodeName[2] = "LFX3"; - leftNodeName[3] = "LFX4"; - - rightNodeName[0] = "RFX1"; - rightNodeName[1] = "RFX2"; - rightNodeName[2] = "RFX3"; - rightNodeName[3] = "RFX4"; - - - texture[0] = "special/stationGlow"; - texture[1] = "special/stationLight2"; -}; - -//------------------------------------------------------------------------------ -//------------------------------------------------------------------------------ -function serverCmdBuyVehicle(%client, %blockName) -{ - %team = %client.getSensorGroup(); - if(vehicleCheck(%blockName, %team)) - { - %station = %client.player.station.pad; - if( (%station.ready) && (%station.station.vehicle[%blockName]) ) - { - %trans = %station.getTransform(); - %pos = getWords(%trans, 0, 2); - %matrix = VectorOrthoBasis(getWords(%trans, 3, 6)); - %yrot = getWords(%matrix, 3, 5); - %p = vectorAdd(%pos,vectorScale(%yrot, -3)); - %p = getWords(%p,0, 1) @ " " @ getWord(%p,2) + 4; - -// error(%blockName); -// error(%blockName.spawnOffset); - - %p = vectorAdd(%p, %blockName.spawnOffset); - %rot = getWords(%trans, 3, 5); - %angle = getWord(%trans, 6) + 3.14; - %mask = $TypeMasks::VehicleObjectType | $TypeMasks::PlayerObjectType | - $TypeMasks::StationObjectType | $TypeMasks::TurretObjectType; - InitContainerRadiusSearch(%p, %blockName.checkRadius, %mask); - - %clear = 1; - for (%x = 0; (%obj = containerSearchNext()) != 0; %x++) - { - if((%obj.getType() & $TypeMasks::VehicleObjectType) && (%obj.getDataBlock().checkIfPlayersMounted(%obj))) - { - %clear = 0; - break; - } - else - %removeObjects[%x] = %obj; - } - if(%clear) - { - %fadeTime = 0; - for(%i = 0; %i < %x; %i++) - { - if(%removeObjects[%i].getType() & $TypeMasks::PlayerObjectType) - { - %pData = %removeObjects[%i].getDataBlock(); - %pData.damageObject(%removeObjects[%i], 0, "0 0 0", 1000, $DamageType::VehicleSpawn); - } - else - { - %removeObjects[%i].mountable = 0; - %removeObjects[%i].startFade( 1000, 0, true ); - %removeObjects[%i].schedule(1001, "delete"); - %fadeTime = 1500; - } - } - schedule(%fadeTime, 0, "createVehicle", %client, %station, %blockName, %team , %p, %rot, %angle); - } - else - MessageClient(%client, "", 'Can\'t create vehicle. A player is on the creation pad.'); - } - //-------------------------------------------------------------------------------------- - // z0dd - ZOD, 4/25/02. client tried to quick purchase a vehicle that isn't on this map - else - { - messageClient(%client, "", "~wfx/misc/misc.error.wav"); - } - //-------------------------------------------------------------------------------------- - } - //-------------------------------------------------------------------------------------------------------------- - // z0dd - ZOD, 4/25/02. client tried to quick purchase vehicle when max vehicles of this type are already in use - else - { - messageClient(%client, "", "~wfx/misc/misc.error.wav"); - } - //-------------------------------------------------------------------------------------------------------------- -} - -function createVehicle(%client, %station, %blockName, %team , %pos, %rot, %angle) -{ - %obj = %blockName.create(%team); - if(%obj) - { - //----------------------------------------------- - // z0dd - ZOD, 4/25/02. MPB Teleporter. - if ( %blockName $= "MobileBaseVehicle" ) - { - %station.station.teleporter.MPB = %obj; - %obj.teleporter = %station.station.teleporter; - } - //----------------------------------------------- - %station.ready = false; - %obj.team = %team; - %obj.useCreateHeight(true); - %obj.schedule(5500, "useCreateHeight", false); - %obj.getDataBlock().isMountable(%obj, false); - %obj.getDataBlock().schedule(6500, "isMountable", %obj, true); - - %station.playThread($ActivateThread,"activate2"); - %station.playAudio($ActivateSound, ActivateVehiclePadSound); - - vehicleListAdd(%blockName, %obj); - MissionCleanup.add(%obj); - - %turret = %obj.getMountNodeObject(10); - if(%turret > 0) - { - %turret.setCloaked(true); - %turret.schedule(4800, "setCloaked", false); - } - - %obj.setCloaked(true); - %obj.setTransform(%pos @ " " @ %rot @ " " @ %angle); - - %obj.schedule(3700, "playAudio", 0, VehicleAppearSound); - %obj.schedule(4800, "setCloaked", false); - - if(%client.player.lastVehicle) - { - %client.player.lastVehicle.lastPilot = ""; - vehicleAbandonTimeOut(%client.player.lastVehicle); - %client.player.lastVehicle = ""; - } - %client.player.lastVehicle = %obj; - %obj.lastPilot = %client.player; - - // play the FX - %fx = new StationFXVehicle() - { - dataBlock = VehicleInvFX; - stationObject = %station; - }; - - if ( %client.isVehicleTeleportEnabled() ) - %obj.getDataBlock().schedule(5000, "mountDriver", %obj, %client.player); - } - if(%obj.getTarget() != -1) - setTargetSensorGroup(%obj.getTarget(), %client.getSensorGroup()); - // We are now closing the vehicle hud when you buy a vehicle, making the following call - // unnecessary (and it breaks stuff, too!) - //VehicleHud.updateHud(%client, 'vehicleHud'); -} - -//------------------------------------------------------------------------------ -function VehicleData::mountDriver(%data, %obj, %player) -{ - if(isObject(%obj) && %obj.getDamageState() !$= "Destroyed") - { - %player.startFade(1000, 0, true); - schedule(1000, 0, "testVehicleForMount", %player, %obj); - %player.schedule(1500,"startFade",1000, 0, false); - } -} - -function testVehicleForMount(%player, %obj) -{ - // z0dd - ZOD, 4/25/02. Do not auto mount players who are teleporting, bug fix. - // z0dd - ZOD, 7/10/02. Added check to see if player is in inv. Prevents switching - // to illegal armor for a vehicle by purchasing a vehicle and buying a illegal - // armor durig the tele phase period. - if(isObject(%obj) && %obj.getDamageState() !$= "Destroyed" && !%player.teleporting && !%player.client.inInv) - %player.getDataBlock().onCollision(%player, %obj, 0); -} - - -//------------------------------------------------------------------------------ -function VehicleData::checkIfPlayersMounted(%data, %obj) -{ - for(%i = 0; %i < %obj.getDatablock().numMountPoints; %i++) - if (%obj.getMountNodeObject(%i)) - return true; - return false; -} - -//------------------------------------------------------------------------------ -function VehicleData::isMountable(%data, %obj, %val) -{ - %obj.mountable = %val; -} - -//------------------------------------------------------------------------------ -function vehicleCheck(%blockName, %team) -{ - if(($VehicleMax[%blockName] - $VehicleTotalCount[%team, %blockName]) > 0) - return true; -// else -// { -// for(%i = 0; %i < $VehicleMax[%blockName]; %i++) -// { -// %obj = $VehicleInField[%blockName, %i]; -// if(%obj.abandon) -// { -// vehicleListRemove(%blockName, %obj); -// %obj.delete(); -// return true; -// } -// } -// } - return false; -} - - -//-------------------------------------------------------------------------------------------------------------------------------------- -// z0dd - ZOD, 4/24/02. rewrote this function -function VehicleHud::updateHud( %obj, %client, %tag ) -{ - %station = %client.player.station; - %team = %client.getSensorGroup(); - %count = 0; - %none = "-"; - - %vehmsg = %station.vehicle[ScoutVehicle] ? "( 1 ) GRAV CYCLE " : %none; - %numleft = %station.vehicle[ScoutVehicle] ? ($VehicleMax[ScoutVehicle] - $VehicleTotalCount[%team, ScoutVehicle]) : 0; - messageClient( %client, 'SetLineHud', "", %tag, %count, %vehmsg, "", ScoutVehicle, %numleft ); - %count++; - - %vehmsg = %station.vehicle[AssaultVehicle] ? "( 2 ) ASSAULT TANK " : %none; - %numleft = %station.vehicle[AssaultVehicle] ? ($VehicleMax[AssaultVehicle] - $VehicleTotalCount[%team, AssaultVehicle]) : 0; - messageClient( %client, 'SetLineHud', "", %tag, %count, %vehmsg, "", AssaultVehicle, %numleft ); - %count++; - - %vehmsg = %station.vehicle[mobileBaseVehicle] ? "( 3 ) MOBILE POINT BASE " : %none; - %numleft = %station.vehicle[MobileBaseVehicle] ? ($VehicleMax[MobileBaseVehicle] - $VehicleTotalCount[%team, MobileBaseVehicle]) : 0; - messageClient( %client, 'SetLineHud', "", %tag, %count, %vehmsg, "", MobileBaseVehicle, %numleft ); - %count++; - - %vehmsg = %station.vehicle[scoutFlyer] ? "( 4 ) SCOUT FLIER " : %none; - %numleft = %station.vehicle[ScoutFlyer] ? ($VehicleMax[ScoutFlyer] - $VehicleTotalCount[%team, ScoutFlyer]) : 0; - messageClient( %client, 'SetLineHud', "", %tag, %count, %vehmsg, "", ScoutFlyer, %numleft ); - %count++; - - %vehmsg = %station.vehicle[bomberFlyer] ? "( 5 ) BOMBER " : %none; - %numleft = %station.vehicle[BomberFlyer] ? ($VehicleMax[BomberFlyer] - $VehicleTotalCount[%team, BomberFlyer]) : 0; - messageClient( %client, 'SetLineHud', "", %tag, %count, %vehmsg, "", BomberFlyer, %numleft ); - %count++; - - %vehmsg = %station.vehicle[hapcFlyer] ? "( 6 ) TRANSPORT " : %none; - %numleft = %station.vehicle[HAPCFlyer] ? ($VehicleMax[HAPCFlyer] - $VehicleTotalCount[%team, HAPCFlyer]) : 0; - messageClient( %client, 'SetLineHud', "", %tag, %count, %vehmsg, "", HAPCFlyer, %numleft ); -} -//-------------------------------------------------------------------------------------------------------------------------------------- - -//------------------------------------------------------------------------------ -function VehicleHud::clearHud( %obj, %client, %tag, %count ) -{ - for ( %i = 0; %i < %count; %i++ ) - messageClient( %client, 'RemoveLineHud', "", %tag, %i ); -} - -//------------------------------------------------------------------------------ -function serverCmdEnableVehicleTeleport( %client, %enabled ) -{ - %client.setVehicleTeleportEnabled( %enabled ); -} +//------------------------------------------------------------------------------ +datablock EffectProfile(VehicleAppearEffect) +{ + effectname = "vehicles/inventory_pad_appear"; + minDistance = 5; + maxDistance = 10; +}; + +datablock EffectProfile(ActivateVehiclePadEffect) +{ + effectname = "powered/vehicle_pad_on"; + minDistance = 20; + maxDistance = 30; +}; + +datablock AudioProfile(VehicleAppearSound) +{ + filename = "fx/vehicles/inventory_pad_appear.wav"; + description = AudioClosest3d; + preload = true; + effect = VehicleAppearEffect; +}; + +datablock AudioProfile(ActivateVehiclePadSound) +{ + filename = "fx/powered/vehicle_pad_on.wav"; + description = AudioClose3d; + preload = true; + effect = ActivateVehiclePadEffect; +}; + +datablock StationFXVehicleData( VehicleInvFX ) +{ + lifetime = 6.0; + + glowTopHeight = 1.5; + glowBottomHeight = 0.1; + glowTopRadius = 12.5; + glowBottomRadius = 12.0; + numGlowSegments = 26; + glowFadeTime = 3.25; + + armLightDelay = 2.3; + armLightLifetime = 3.0; + armLightFadeTime = 1.5; + numArcSegments = 10.0; + + sphereColor = "0.1 0.1 0.5"; + spherePhiSegments = 13; + sphereThetaSegments = 8; + sphereRadius = 12.0; + sphereScale = "1.05 1.05 0.85"; + + glowNodeName = "GLOWFX"; + + leftNodeName[0] = "LFX1"; + leftNodeName[1] = "LFX2"; + leftNodeName[2] = "LFX3"; + leftNodeName[3] = "LFX4"; + + rightNodeName[0] = "RFX1"; + rightNodeName[1] = "RFX2"; + rightNodeName[2] = "RFX3"; + rightNodeName[3] = "RFX4"; + + + texture[0] = "special/stationGlow"; + texture[1] = "special/stationLight2"; +}; + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +function serverCmdBuyVehicle(%client, %blockName) +{ + %team = %client.getSensorGroup(); + if(vehicleCheck(%blockName, %team)) + { + %station = %client.player.station.pad; + if( (%station.ready) && (%station.station.vehicle[%blockName]) ) + { + %trans = %station.getTransform(); + %pos = getWords(%trans, 0, 2); + %matrix = VectorOrthoBasis(getWords(%trans, 3, 6)); + %yrot = getWords(%matrix, 3, 5); + %p = vectorAdd(%pos,vectorScale(%yrot, -3)); + %p = getWords(%p,0, 1) @ " " @ getWord(%p,2) + 4; + +// error(%blockName); +// error(%blockName.spawnOffset); + + %p = vectorAdd(%p, %blockName.spawnOffset); + %rot = getWords(%trans, 3, 5); + %angle = getWord(%trans, 6) + 3.14; + %mask = $TypeMasks::VehicleObjectType | $TypeMasks::PlayerObjectType | + $TypeMasks::StationObjectType | $TypeMasks::TurretObjectType; + InitContainerRadiusSearch(%p, %blockName.checkRadius, %mask); + + %clear = 1; + for (%x = 0; (%obj = containerSearchNext()) != 0; %x++) + { + if((%obj.getType() & $TypeMasks::VehicleObjectType) && (%obj.getDataBlock().checkIfPlayersMounted(%obj))) + { + %clear = 0; + break; + } + else + %removeObjects[%x] = %obj; + } + if(%clear) + { + %fadeTime = 0; + for(%i = 0; %i < %x; %i++) + { + if(%removeObjects[%i].getType() & $TypeMasks::PlayerObjectType) + { + %pData = %removeObjects[%i].getDataBlock(); + %pData.damageObject(%removeObjects[%i], 0, "0 0 0", 1000, $DamageType::VehicleSpawn); + } + else + { + %removeObjects[%i].mountable = 0; + %removeObjects[%i].startFade( 1000, 0, true ); + %removeObjects[%i].schedule(1001, "delete"); + %fadeTime = 1500; + } + } + schedule(%fadeTime, 0, "createVehicle", %client, %station, %blockName, %team , %p, %rot, %angle); + } + else + MessageClient(%client, "", 'Can\'t create vehicle. A player is on the creation pad.'); + } + //-------------------------------------------------------------------------------------- + // z0dd - ZOD, 4/25/02. client tried to quick purchase a vehicle that isn't on this map + else + { + messageClient(%client, "", "~wfx/misc/misc.error.wav"); + } + //-------------------------------------------------------------------------------------- + } + //-------------------------------------------------------------------------------------------------------------- + // z0dd - ZOD, 4/25/02. client tried to quick purchase vehicle when max vehicles of this type are already in use + else + { + messageClient(%client, "", "~wfx/misc/misc.error.wav"); + } + //-------------------------------------------------------------------------------------------------------------- +} + +function createVehicle(%client, %station, %blockName, %team , %pos, %rot, %angle) +{ + %obj = %blockName.create(%team); + if(%obj) + { + //----------------------------------------------- + // z0dd - ZOD, 4/25/02. MPB Teleporter. + if ( %blockName $= "MobileBaseVehicle" ) + { + %station.station.teleporter.MPB = %obj; + %obj.teleporter = %station.station.teleporter; + } + //----------------------------------------------- + %station.ready = false; + %obj.team = %team; + %obj.useCreateHeight(true); + %obj.schedule(5500, "useCreateHeight", false); + %obj.getDataBlock().isMountable(%obj, false); + %obj.getDataBlock().schedule(6500, "isMountable", %obj, true); + + %station.playThread($ActivateThread,"activate2"); + %station.playAudio($ActivateSound, ActivateVehiclePadSound); + + vehicleListAdd(%blockName, %obj); + MissionCleanup.add(%obj); + + %turret = %obj.getMountNodeObject(10); + if(%turret > 0) + { + %turret.setCloaked(true); + %turret.schedule(4800, "setCloaked", false); + } + + %obj.setCloaked(true); + %obj.setTransform(%pos @ " " @ %rot @ " " @ %angle); + + %obj.schedule(3700, "playAudio", 0, VehicleAppearSound); + %obj.schedule(4800, "setCloaked", false); + + if(%client.player.lastVehicle) + { + %client.player.lastVehicle.lastPilot = ""; + vehicleAbandonTimeOut(%client.player.lastVehicle); + %client.player.lastVehicle = ""; + } + %client.player.lastVehicle = %obj; + %obj.lastPilot = %client.player; + + // play the FX + %fx = new StationFXVehicle() + { + dataBlock = VehicleInvFX; + stationObject = %station; + }; + + if ( %client.isVehicleTeleportEnabled() ) + %obj.getDataBlock().schedule(5000, "mountDriver", %obj, %client.player); + } + if(%obj.getTarget() != -1) + setTargetSensorGroup(%obj.getTarget(), %client.getSensorGroup()); + // We are now closing the vehicle hud when you buy a vehicle, making the following call + // unnecessary (and it breaks stuff, too!) + //VehicleHud.updateHud(%client, 'vehicleHud'); +} + +//------------------------------------------------------------------------------ +function VehicleData::mountDriver(%data, %obj, %player) +{ + if(isObject(%obj) && %obj.getDamageState() !$= "Destroyed") + { + %player.startFade(1000, 0, true); + schedule(1000, 0, "testVehicleForMount", %player, %obj); + %player.schedule(1500,"startFade",1000, 0, false); + } +} + +function testVehicleForMount(%player, %obj) +{ + // z0dd - ZOD, 4/25/02. Do not auto mount players who are teleporting, bug fix. + // z0dd - ZOD, 7/10/02. Added check to see if player is in inv. Prevents switching + // to illegal armor for a vehicle by purchasing a vehicle and buying a illegal + // armor durig the tele phase period. + if(isObject(%obj) && %obj.getDamageState() !$= "Destroyed" && !%player.teleporting && !%player.client.inInv) + %player.getDataBlock().onCollision(%player, %obj, 0); +} + + +//------------------------------------------------------------------------------ +function VehicleData::checkIfPlayersMounted(%data, %obj) +{ + for(%i = 0; %i < %obj.getDatablock().numMountPoints; %i++) + if (%obj.getMountNodeObject(%i)) + return true; + return false; +} + +//------------------------------------------------------------------------------ +function VehicleData::isMountable(%data, %obj, %val) +{ + %obj.mountable = %val; +} + +//------------------------------------------------------------------------------ +function vehicleCheck(%blockName, %team) +{ + if(($VehicleMax[%blockName] - $VehicleTotalCount[%team, %blockName]) > 0) + return true; +// else +// { +// for(%i = 0; %i < $VehicleMax[%blockName]; %i++) +// { +// %obj = $VehicleInField[%blockName, %i]; +// if(%obj.abandon) +// { +// vehicleListRemove(%blockName, %obj); +// %obj.delete(); +// return true; +// } +// } +// } + return false; +} + + +//-------------------------------------------------------------------------------------------------------------------------------------- +// z0dd - ZOD, 4/24/02. rewrote this function +function VehicleHud::updateHud( %obj, %client, %tag ) +{ + %station = %client.player.station; + %team = %client.getSensorGroup(); + %count = 0; + %none = "-"; + + %vehmsg = %station.vehicle[ScoutVehicle] ? "( 1 ) GRAV CYCLE " : %none; + %numleft = %station.vehicle[ScoutVehicle] ? ($VehicleMax[ScoutVehicle] - $VehicleTotalCount[%team, ScoutVehicle]) : 0; + messageClient( %client, 'SetLineHud', "", %tag, %count, %vehmsg, "", ScoutVehicle, %numleft ); + %count++; + + %vehmsg = %station.vehicle[AssaultVehicle] ? "( 2 ) ASSAULT TANK " : %none; + %numleft = %station.vehicle[AssaultVehicle] ? ($VehicleMax[AssaultVehicle] - $VehicleTotalCount[%team, AssaultVehicle]) : 0; + messageClient( %client, 'SetLineHud', "", %tag, %count, %vehmsg, "", AssaultVehicle, %numleft ); + %count++; + + %vehmsg = %station.vehicle[mobileBaseVehicle] ? "( 3 ) MOBILE POINT BASE " : %none; + %numleft = %station.vehicle[MobileBaseVehicle] ? ($VehicleMax[MobileBaseVehicle] - $VehicleTotalCount[%team, MobileBaseVehicle]) : 0; + messageClient( %client, 'SetLineHud', "", %tag, %count, %vehmsg, "", MobileBaseVehicle, %numleft ); + %count++; + + %vehmsg = %station.vehicle[scoutFlyer] ? "( 4 ) SCOUT FLIER " : %none; + %numleft = %station.vehicle[ScoutFlyer] ? ($VehicleMax[ScoutFlyer] - $VehicleTotalCount[%team, ScoutFlyer]) : 0; + messageClient( %client, 'SetLineHud', "", %tag, %count, %vehmsg, "", ScoutFlyer, %numleft ); + %count++; + + %vehmsg = %station.vehicle[bomberFlyer] ? "( 5 ) BOMBER " : %none; + %numleft = %station.vehicle[BomberFlyer] ? ($VehicleMax[BomberFlyer] - $VehicleTotalCount[%team, BomberFlyer]) : 0; + messageClient( %client, 'SetLineHud', "", %tag, %count, %vehmsg, "", BomberFlyer, %numleft ); + %count++; + + %vehmsg = %station.vehicle[hapcFlyer] ? "( 6 ) TRANSPORT " : %none; + %numleft = %station.vehicle[HAPCFlyer] ? ($VehicleMax[HAPCFlyer] - $VehicleTotalCount[%team, HAPCFlyer]) : 0; + messageClient( %client, 'SetLineHud', "", %tag, %count, %vehmsg, "", HAPCFlyer, %numleft ); +} +//-------------------------------------------------------------------------------------------------------------------------------------- + +//------------------------------------------------------------------------------ +function VehicleHud::clearHud( %obj, %client, %tag, %count ) +{ + for ( %i = 0; %i < %count; %i++ ) + messageClient( %client, 'RemoveLineHud', "", %tag, %i ); +} + +//------------------------------------------------------------------------------ +function serverCmdEnableVehicleTeleport( %client, %enabled ) +{ + %client.setVehicleTeleportEnabled( %enabled ); +} diff --git a/scripts/vehicles/vehicle.cs b/scripts/vehicles/vehicle.cs index 7a36b3b..a290d61 100644 --- a/scripts/vehicles/vehicle.cs +++ b/scripts/vehicles/vehicle.cs @@ -1,1621 +1,1621 @@ -// Notes: -// - respawning vehicles with turrets (bomber/tank) will not setup the turret properly - -//Damage Rate for entering Liquid -$VehicleDamageLava = 0.0325; -$VehicleDamageHotLava = 0.0325; -$VehicleDamageCrustyLava = 0.0325; - -$NumVehiclesDeploy = 0; - -//************************************************************** -//* GENERAL PURPOSE FUNCTIONS -//************************************************************** - -function VehicleData::onAdd(%data, %obj) -{ - Parent::onAdd(%data, %obj); - if((%data.sensorData !$= "") && (%obj.getTarget() != -1)) - setTargetSensorData(%obj.getTarget(), %data.sensorData); - %obj.setRechargeRate(%data.rechargeRate); - // set full energy - %obj.setEnergyLevel(%data.MaxEnergy); - - if(%obj.disableMove) - %obj.immobilized = true; - if(%obj.deployed) - { - if($countDownStarted) - %data.schedule(($Host::WarmupTime * 1000) / 2, "vehicleDeploy", %obj, 0, 1); - else - { - $VehiclesDeploy[$NumVehiclesDeploy] = %obj; - $NumVehiclesDeploy++; - } - } - if(%obj.mountable || %obj.mountable $= "") - %data.isMountable(%obj, true); - else - %data.isMountable(%obj, false); - - %obj.setSelfPowered(); -// %data.canObserve = true; -} - -function VehicleData::onRemove(%this, %obj) -{ - // if there are passengers/driver, kick them out - %this.deleteAllMounted(%obj); - for(%i = 0; %i < %obj.getDatablock().numMountPoints; %i++) - if (%obj.getMountNodeObject(%i)) { - %passenger = %obj.getMountNodeObject(%i); - %passenger.unmount(); - } - vehicleListRemove(%obj.getDataBlock(), %obj); - if(%obj.lastPilot.lastVehicle == %obj) - %obj.lastPilot.lastVehicle = ""; - - Parent::onRemove(%this, %obj); -} - -function VehicleData::onDamage(%this,%obj) -{ - %damage = %obj.getDamageLevel(); - if (%damage >= %this.destroyedLevel) - { - if(%obj.getDamageState() !$= "Destroyed") - { - if(%obj.respawnTime !$= "") - %obj.marker.schedule = %obj.marker.data.schedule(%obj.respawnTime, "respawn", %obj.marker); - %obj.setDamageState(Destroyed); - } - } - else - { - if(%obj.getDamageState() !$= "Enabled") - %obj.setDamageState(Enabled); - } -} - -function VehicleData::playerDismounted(%data, %obj, %player) -{ - if( %player.client.observeCount > 0 ) - resetObserveFollow( %player.client, true ); - - setTargetSensorGroup(%obj.getTarget(), %obj.team); - - // if there is a turret, set its team as well. - if( %obj.turretObject > 0 ) - setTargetSensorGroup(%obj.turretObject.getTarget(), %obj.team); -} - -function HoverVehicle::useCreateHeight() -{ - //this function is declared to prevent console error msg spam... -} - -function WheeledVehicle::useCreateHeight() -{ - //this function is declared to prevent console error msg spam... -} - -function AssaultVehicle::onDamage(%this, %obj) -{ - if(isObject(%obj.getMountNodeObject(10))) - (%obj.getMountNodeObject(10)).setDamagelevel(%obj.getDamageLevel()); - Parent::onDamage(%this, %obj); -} - -function BomberFlyer::onDamage(%this, %obj) -{ - if(isObject(%obj.getMountNodeObject(10))) - (%obj.getMountNodeObject(10)).setDamagelevel(%obj.getDamageLevel()); - Parent::onDamage(%this, %obj); -} - -function MobileBaseVehicle::onDamage(%this, %obj) -{ - if(isObject(%obj.getMountNodeObject(1))) - (%obj.getMountNodeObject(1)).setDamagelevel(%obj.getDamageLevel()); - Parent::onDamage(%this, %obj); -} - -function VehicleData::onEnterLiquid(%data, %obj, %coverage, %type) -{ - switch(%type) - { - case 0: - //Water - %obj.setHeat(0.0); - case 1: - //Ocean Water - %obj.setHeat(0.0); - case 2: - //River Water - %obj.setHeat(0.0); - case 3: - //Stagnant Water - %obj.setHeat(0.0); - case 4: - //Lava - %obj.liquidDamage(%data, $VehicleDamageLava, $DamageType::Lava); - case 5: - //Hot Lava - %obj.liquidDamage(%data, $VehicleDamageHotLava, $DamageType::Lava); - case 6: - //Crusty Lava - %obj.liquidDamage(%data, $VehicleDamageCrustyLava, $DamageType::Lava); - case 7: - //Quick Sand - } -} - -function FlyingVehicle::liquidDamage(%obj, %data, %damageAmount, %damageType) -{ - if(%obj.getDamageState() !$= "Destroyed") - { - %data.damageObject(%obj, 0, "0 0 0", %damageAmount, %damageType); - %obj.lDamageSchedule = %obj.schedule(50, "liquidDamage", %data, %damageAmount, %damageType); - passengerLiquidDamage(%obj, %damageAmount, %damageType); - } - else - %obj.lDamageSchedule = ""; -} - -function WheeledVehicle::liquidDamage(%obj, %data, %damageAmount, %damageType) -{ - if(%obj.getDamageState() !$= "Destroyed") - { - %data.damageObject(%obj, 0, "0 0 0", %damageAmount, %damageType); - %obj.lDamageSchedule = %obj.schedule(50, "liquidDamage", %data, %damageAmount, %damageType); - passengerLiquidDamage(%obj, %damageAmount, %damageType); - } - else - %obj.lDamageSchedule = ""; -} - -function HoverVehicle::liquidDamage(%obj, %data, %damageAmount, %damageType) -{ - if(%obj.getDamageState() !$= "Destroyed") - { - %data.damageObject(%obj, 0, "0 0 0", %damageAmount, %damageType); - %obj.lDamageSchedule = %obj.schedule(50, "liquidDamage", %data, %damageAmount, %damageType); - passengerLiquidDamage(%obj, %damageAmount, %damageType); - } - else - %obj.lDamageSchedule = ""; -} - -function passengerLiquidDamage(%obj, %damageAmount, %damageType) -{ - for(%i = %num; %i < %obj.getDataBlock().numMountPoints; %i++) - if (%p = %obj.getMountNodeObject(%i)) - %p.liquidDamage(%p.getDatablock(), $DamageLava, $DamageType::Lava); -} - -function VehicleData::onLeaveLiquid(%data, %obj, %type) -{ - switch(%type) - { - case 0: - //Water - %obj.setHeat(1.0); - case 1: - //Ocean Water - %obj.setHeat(1.0); - case 2: - //River Water - %obj.setHeat(1.0); - case 3: - //Stagnant Water - %obj.setHeat(1.0); - case 4: - //Lava - case 5: - //Hot Lava - case 6: - //Crusty Lava - case 7: - //Quick Sand - } - - if(%obj.lDamageSchedule !$= "") - { - cancel(%obj.lDamageSchedule); - %obj.lDamageSchedule = ""; - } -} - -function VehicleData::onDestroyed(%data, %obj, %prevState) -{ - if(%obj.lastDamagedBy) - { - %destroyer = %obj.lastDamagedBy; - game.vehicleDestroyed(%obj, %destroyer); - //error("vehicleDestroyed( "@ %obj @", "@ %destroyer @")"); - } - - radiusVehicleExplosion(%data, %obj); - if(%obj.turretObject) - if(%obj.turretObject.getControllingClient()) - %obj.turretObject.getDataBlock().playerDismount(%obj.turretObject); - for(%i = 0; %i < %obj.getDatablock().numMountPoints; %i++) - { - if (%obj.getMountNodeObject(%i)) { - %flingee = %obj.getMountNodeObject(%i); - %flingee.getDataBlock().doDismount(%flingee, true); - %xVel = 250.0 - (getRandom() * 500.0); - %yVel = 250.0 - (getRandom() * 500.0); - %zVel = (getRandom() * 100.0) + 50.0; - %flingVel = %xVel @ " " @ %yVel @ " " @ %zVel; - %flingee.applyImpulse(%flingee.getTransform(), %flingVel); - echo("got player..." @ %flingee.getClassName()); - %flingee.damage(0, %obj.getPosition(), 0.4, $DamageType::Crash); - } - } - - %data.deleteAllMounted(%obj); - // ----------------------------------------------------------------------------------------- - // z0dd - ZOD - Czar, 6/24/02. Move this vehicle out of the way so nothing collides with it. - if(%data.getName() $="BomberFlyer" || %data.getName() $="MobileBaseVehicle" || %data.getName() $="AssaultVehicle") - { - %obj.setFrozenState(true); - %obj.schedule(2000, "delete"); - %data.schedule(500, 'onAvoidCollisions', %obj); - } - else - { - %obj.setFrozenState(true); - %obj.schedule(500, "delete"); - } - // ----------------------------------------------------------------------------------------- -} - -// ---------------------------------------------------------------------------------- -// z0dd - ZOD, 6/13/02. Move this vehicle out of the way so nothing collides with it. -function VehicleData::onAvoidCollisions(%data, %obj) -{ - // Get the current location of the vehicle and send it to the moon! - %transform = posFromTransform(%obj.getTransform()); - %position = getWord(%transform, 0) SPC getWord(%transform, 1) SPC (getWord(%transform, 2)+2000); - %rotation = getWord(%transform, 3) SPC getWord(%transform, 4) SPC getWord(%transform, 5) SPC getWord(%transform, 6); - %obj.setTransform(%position SPC %rotation); -} -// ---------------------------------------------------------------------------------- - -function radiusVehicleExplosion(%data, %vehicle) -{ - // this is a modified version of RadiusExplosion() from projectiles.cs - %position = %vehicle.getPosition(); - InitContainerRadiusSearch(%position, %data.explosionRadius, $TypeMasks::PlayerObjectType | - $TypeMasks::VehicleObjectType | - $TypeMasks::MoveableObjectType | - $TypeMasks::StaticShapeObjectType | - $TypeMasks::ForceFieldObjectType | - $TypeMasks::TurretObjectType | - $TypeMasks::ItemObjectType); - - %numTargets = 0; - while ((%targetObject = containerSearchNext()) != 0) - { - if(%targetObject == %vehicle) - continue; - - %dist = containerSearchCurrRadDamageDist(); - - if (%dist > %data.explosionRadius) - continue; - - if (%targetObject.isMounted()) - { - %mount = %targetObject.getObjectMount(); - if(%mount == %vehicle) - continue; - - %found = -1; - for (%i = 0; %i < %mount.getDataBlock().numMountPoints; %i++) - { - if (%mount.getMountNodeObject(%i) == %targetObject) - { - %found = %i; - break; - } - } - - if (%found != -1) - { - if (%mount.getDataBlock().isProtectedMountPoint[%found] && (%mount != %vehicle)) - continue; - } - } - - %targets[%numTargets] = %targetObject; - %targetDists[%numTargets] = %dist; - %numTargets++; - } - - for (%i = 0; %i < %numTargets; %i++) - { - %targetObject = %targets[%i]; - %dist = %targetDists[%i]; - - %coverage = calcExplosionCoverage(%position, %targetObject, - ($TypeMasks::InteriorObjectType | - $TypeMasks::TerrainObjectType | - $TypeMasks::ForceFieldObjectType)); - if (%coverage == 0) - continue; - - %amount = (1.0 - (%dist / %data.explosionRadius)) * %coverage * %data.explosionDamage; - %targetData = %targetObject.getDataBlock(); - - %momVec = "0 0 1"; - - if(%amount > 0) - %targetData.damageObject(%targetObject, %sourceObject, %position, %amount, $DamageType::Explosion, %momVec); - } -} - -function VehicleData::deleteAllMounted() -{ - -} - -//************************************************************** -//* VEHICLE CREATION -//************************************************************** -// (NOTE: No entry for Wildcat Grav Cycle is here. -- DG) - -//---------------------------- -// SHRIKE SCOUT FLIER -//---------------------------- - -function ScoutFlyer::onAdd(%this, %obj) -{ - Parent::onAdd(%this, %obj); - %obj.mountImage(ScoutChaingunParam, 0); - %obj.mountImage(ScoutChaingunImage, 2); - %obj.mountImage(ScoutChaingunPairImage, 3); - %obj.nextWeaponFire = 2; - %obj.schedule(5500, "playThread", $ActivateThread, "activate"); -} - -//---------------------------- -// THUNDERSWORD BOMBER -//---------------------------- - -function BomberFlyer::onAdd(%this, %obj) -{ - Parent::onAdd(%this, %obj); - - %turret = TurretData::create(BomberTurret); - MissionCleanup.add(%turret); - %turret.team = %obj.teamBought; - %turret.selectedWeapon = 1; - %turret.setSelfPowered(); - %obj.mountObject(%turret, 10); - %turret.mountImage(BomberTurretBarrel,2); - %turret.mountImage(BomberTurretBarrelPair,3); - %turret.mountImage(BomberBombImage, 4); - %turret.mountImage(BomberBombPairImage, 5); - %turret.mountImage(BomberTargetingImage, 6); - %obj.turretObject = %turret; - %turret.setCapacitorRechargeRate( %turret.getDataBlock().capacitorRechargeRate ); - %turret.vehicleMounted = %obj; - - //vehicle turrets should not auto fire at targets - %turret.setAutoFire(false); - - //for this particular weapon - a non-firing datablock used only so the AI can aim the turret - //Also needed so we can set the turret parameters.. - %turret.mountImage(AIAimingTurretBarrel, 0); - - // setup the turret's target info - setTargetSensorGroup(%turret.getTarget(), %turret.team); - setTargetNeverVisMask(%turret.getTarget(), 0xffffffff); -} - -//---------------------------- -// HAVOC TRANSPORT FLIER -//---------------------------- - -function HAPCFlyer::onAdd(%this, %obj) -{ - Parent::onAdd(%this, %obj); - %obj.schedule(6000, "playThread", $ActivateThread, "activate"); -} - -//---------------------------- -// BEOWULF ASSAULT VEHICLE -//---------------------------- - -function AssaultVehicle::onAdd(%this, %obj) -{ - Parent::onAdd(%this, %obj); - - %turret = TurretData::create(AssaultPlasmaTurret); - %turret.selectedWeapon = 1; - MissionCleanup.add(%turret); - %turret.team = %obj.teamBought; - %turret.setSelfPowered(); - %obj.mountObject(%turret, 10); - %turret.mountImage(AssaultPlasmaTurretBarrel, 2); - %turret.mountImage(AssaultMortarTurretBarrel, 4); - %turret.setCapacitorRechargeRate( %turret.getDataBlock().capacitorRechargeRate ); - %obj.turretObject = %turret; - - //vehicle turrets should not auto fire at targets - %turret.setAutoFire(false); - - //Needed so we can set the turret parameters.. - %turret.mountImage(AssaultTurretParam, 0); - %obj.schedule(6000, "playThread", $ActivateThread, "activate"); - - // set the turret's target info - setTargetSensorGroup(%turret.getTarget(), %turret.team); - setTargetNeverVisMask(%turret.getTarget(), 0xffffffff); -} - -//---------------------------- -// JERICHO FORWARD BASE (Mobile Point Base) -//---------------------------- - -function MobileBaseVehicle::onAdd(%this, %obj) -{ - Parent::onAdd(%this, %obj); - %obj.station = ""; - %obj.turret = ""; - %obj.beacon = ""; - - %obj.schedule(5000, "playThread", $AmbientThread, "ambient"); -} - -//************************************************************** -//* MULTI-CREW VEHICLE DELETION -//************************************************************** - -//---------------------------- -//BEOWULF ASSAULT VEHICLE -//---------------------------- - -function AssaultVehicle::deleteAllMounted(%data, %obj) -{ - %turret = %obj.getMountNodeObject(10); - if(!%turret) - return; - - if(%client = %turret.getControllingClient()) - { - %client.player.setControlObject(%client.player); - %client.player.mountImage(%client.player.lastWeapon, $WeaponSlot); - %client.player.mountVehicle = false; - } - %turret.schedule(2000, delete); -} - -//---------------------------- -// THUNDERSWORD BOMBER -//---------------------------- - -function BomberFlyer::deleteAllMounted(%data, %obj) -{ - if(isObject(%obj.beacon)) - %obj.beacon.schedule(50, delete); - - %turret = %obj.getMountNodeObject(10); - if(!%turret) - return; - - %turret.altTrigger = 0; - %turret.fireTrigger = 0; - - if(%client = %turret.getControllingClient()) - { - commandToClient(%client, 'endBomberSight'); - %client.player.setControlObject(%client.player); - %client.player.mountImage(%client.player.lastWeapon, $WeaponSlot); - %client.player.mountVehicle = false; - - %client.player.bomber = false; - %client.player.isBomber = false; - } - %turret.schedule(2000, delete); -} - -//---------------------------- -// JERICHO FORWARD BASE -//---------------------------- - -function MobileBaseVehicle::deleteAllMounted(%data, %obj) -{ - if(isObject(%obj.station)) // z0dd - ZOD, 4/25/02. Console spam fix. - { - %obj.station.getDataBlock().onLosePowerDisabled(%obj.station); - %obj.unmountObject(%obj.station); - %obj.station.trigger.schedule(2000, delete); - %obj.station.schedule(2000, delete); - } - if(isObject(%obj.turret)) // z0dd - ZOD, 4/25/02. Console spam fix. - { - %obj.turret.getDataBlock().onLosePowerDisabled(%obj.turret); - %obj.unmountObject(%obj.turret); - %obj.turret.schedule(2000, delete); - } - //-------------------------------------------------------------------------- - // z0dd - ZOD, 4/25/02. MPB Teleporter. -// if (isObject(%obj.teleporter)) -// { -// %obj.teleporter.setThreadDir($ActivateThread, FALSE); -// %obj.teleporter.playThread($ActivateThread,"activate"); -// %obj.teleporter.playAudio($ActivateSound, StationVehicleDeactivateSound); -// } - //-------------------------------------------------------------------------- - if(isObject(%obj.shield)) - %obj.shield.schedule(2000, delete); - - if(isObject(%obj.beacon)) - { - %obj.beacon.schedule(0, delete); - } -} - -//************************************************************** -//* WEAPON MOUNTING ON VEHICLES -//************************************************************** - -//---------------------------- -// SHRIKE SCOUT FLIER -//---------------------------- - -function ScoutFlyer::playerMounted(%data, %obj, %player, %node) -{ - // scout flyer == SUV (single-user vehicle) - commandToClient(%player.client, 'setHudMode', 'Pilot', "Shrike", %node); - $numVWeapons = 1; - - // update observers who are following this guy... - if( %player.client.observeCount > 0 ) - resetObserveFollow( %player.client, false ); -} - -//---------------------------- -// THUNDERSWORD BOMBER -//---------------------------- - -function BomberFlyer::playerMounted(%data, %obj, %player, %node) -{ - if(%node == 0) - { - // pilot position - %player.setPilot(true); - commandToClient(%player.client, 'setHudMode', 'Pilot', "Bomber", %node); - } - else if(%node == 1) - { - // bombardier position - %turret = %obj.getMountNodeObject(10); - %player.vehicleTurret = %turret; - %player.setTransform("0 0 0 0 0 1 0"); - %player.lastWeapon = %player.getMountedImage($WeaponSlot); - %player.unmountImage($WeaponSlot); - if(!%player.client.isAIControlled()) - { - %player.setControlObject(%turret); - %player.client.setObjectActiveImage(%turret, 2); - } - commandToClient(%player.client, 'startBomberSight'); - %turret.bomber = %player; - $bWeaponActive = 0; - %obj.getMountNodeObject(10).selectedWeapon = 1; - commandToClient(%player.client,'SetWeaponryVehicleKeys', true); - - commandToClient(%player.client, 'setHudMode', 'Pilot', "Bomber", %node); - %player.isBomber = true; - } - else - { - // tail gunner position - commandToClient(%player.client, 'setHudMode', 'Passenger', "Bomber", %node); - } - // build a space-separated string representing passengers - // 0 = no passenger; 1 = passenger (e.g. "1 0 0 ") - %passString = buildPassengerString(%obj); - // send the string of passengers to all mounted players - for(%i = 0; %i < %data.numMountPoints; %i++) - if(%obj.getMountNodeObject(%i) > 0) - commandToClient(%obj.getMountNodeObject(%i).client, 'checkPassengers', %passString); - - // update observers who are following this guy... - if( %player.client.observeCount > 0 ) - resetObserveFollow( %player.client, false ); -} - -//---------------------------- -// HAVOC TRANSPORT FLIER -//---------------------------- - -function HAPCFlyer::playerMounted(%data, %obj, %player, %node) -{ - if(%node == 0) { - // pilot position - commandToClient(%player.client, 'setHudMode', 'Pilot', "HAPC", %node); - } - else { - // all others - commandToClient(%player.client, 'setHudMode', 'Passenger', "HAPC", %node); - } - // build a space-separated string representing passengers - // 0 = no passenger; 1 = passenger (e.g. "1 0 0 1 1 0 ") - %passString = buildPassengerString(%obj); - // send the string of passengers to all mounted players - for(%i = 0; %i < %data.numMountPoints; %i++) - if(%obj.getMountNodeObject(%i) > 0) - commandToClient(%obj.getMountNodeObject(%i).client, 'checkPassengers', %passString); - - // update observers who are following this guy... - if( %player.client.observeCount > 0 ) - resetObserveFollow( %player.client, false ); -} - -//---------------------------- -// WILDCAT GRAV CYCLE -//---------------------------- - -function ScoutVehicle::playerMounted(%data, %obj, %player, %node) -{ - // scout vehicle == SUV (single-user vehicle) - commandToClient(%player.client, 'setHudMode', 'Pilot', "Hoverbike", %node); - - // update observers who are following this guy... - if( %player.client.observeCount > 0 ) - resetObserveFollow( %player.client, false ); -} - -//---------------------------- -// BEOWULF ASSAULT VEHICLE -//---------------------------- - -function AssaultVehicle::playerMounted(%data, %obj, %player, %node) -{ - if(%node == 0) { - // driver position - // is there someone manning the turret? - //%turreteer = %obj.getMountedNodeObject(1); - commandToClient(%player.client, 'setHudMode', 'Pilot', "Assault", %node); - } - else if(%node == 1) - { - // turreteer position - %turret = %obj.getMountNodeObject(10); - %player.vehicleTurret = %turret; - %player.setTransform("0 0 0 0 0 1 0"); - %player.lastWeapon = %player.getMountedImage($WeaponSlot); - %player.unmountImage($WeaponSlot); - if(!%player.client.isAIControlled()) - { - %player.setControlObject(%turret); - %player.client.setObjectActiveImage(%turret, 2); - } - %turret.turreteer = %player; - // if the player is the turreteer, show vehicle's weapon icons - //commandToClient(%player.client, 'showVehicleWeapons', %data.getName()); - //%player.client.setVWeaponsHudActive(1); // plasma turret icon (default) - - $aWeaponActive = 0; - commandToClient(%player.client,'SetWeaponryVehicleKeys', true); - %obj.getMountNodeObject(10).selectedWeapon = 1; - commandToClient(%player.client, 'setHudMode', 'Pilot', "Assault", %node); - } - - // update observers who are following this guy... - if( %player.client.observeCount > 0 ) - resetObserveFollow( %player.client, false ); - - // build a space-separated string representing passengers - // 0 = no passenger; 1 = passenger (e.g. "1 0 ") - %passString = buildPassengerString(%obj); - // send the string of passengers to all mounted players - for(%i = 0; %i < %data.numMountPoints; %i++) - if(%obj.getMountNodeObject(%i) > 0) - commandToClient(%obj.getMountNodeObject(%i).client, 'checkPassengers', %passString); -} - -//---------------------------- -// JERICHO FORWARD BASE -//---------------------------- - -function MobileBaseVehicle::playerMounted(%data, %obj, %player, %node) -{ - // MPB vehicle == SUV (single-user vehicle) - commandToClient(%player.client, 'setHudMode', 'Pilot', "MPB", %node); - if(%obj.deploySchedule) - { - %obj.deploySchedule.clear(); - %obj.deploySchedule = ""; - } - - if(%obj.deployed !$= "" && %obj.deployed == 1) - { - %obj.setThreadDir($DeployThread, false); - %obj.playThread($DeployThread,"deploy"); - %obj.playAudio($DeploySound, MobileBaseUndeploySound); - %obj.station.setThreadDir($DeployThread, false); - %obj.station.getDataBlock().onLosePowerDisabled(%obj.station); - %obj.station.clearSelfPowered(); - %obj.station.goingOut=false; - %obj.station.notDeployed = 1; - %obj.station.playAudio($DeploySound, MobileBaseStationUndeploySound); - - if((%turretClient = %obj.turret.getControllingClient()) !$= "") - { - CommandToServer( 'resetControlObject', %turretClient ); - } - - %obj.turret.setThreadDir($DeployThread, false); - %obj.turret.clearTarget(); - %obj.turret.setTargetObject(-1); - - %obj.turret.playAudio($DeploySound, MobileBaseTurretUndeploySound); - %obj.shield.open(); - %obj.shield.schedule(1000,"delete"); - %obj.deploySchedule = ""; - //----------------------------------------------------------------------- - // z0dd - ZOD, 4/25/02. MPB Teleporter. -// %obj.teleporter.setThreadDir($ActivateThread, FALSE); -// %obj.teleporter.playThread($ActivateThread,"activate"); -// %obj.teleporter.playAudio($ActivateSound, StationVehicleDeactivateSound); - //----------------------------------------------------------------------- - %obj.fullyDeployed = 0; - - %obj.noEnemyControl = 0; - } - %obj.deployed = 0; - - // update observers who are following this guy... - if( %player.client.observeCount > 0 ) - resetObserveFollow( %player.client, false ); -} - -function buildPassengerString(%vehicle) -{ - %passStr = ""; - for(%i = 0; %i < %vehicle.getDatablock().numMountPoints; %i++) - { - if(%vehicle.getMountNodeObject(%i) > 0) - %passStr = %passStr @ "1 "; - else - %passStr = %passStr @ "0 "; - } - - return %passStr; -} - -function MobileBaseVehicle::playerDismounted(%data, %obj, %player) -{ - %obj.schedule(500, "deployVehicle", %data, %player); - Parent::playerDismounted( %data, %obj, %player ); -} - -function WheeledVehicle::deployVehicle(%obj, %data, %player) -{ - if (!%data.vehicleDeploy(%obj, %player)) - %obj.schedule(500, "deployVehicle", %data, %player); -} - -//************************************************************** -//* JERICHO DEPLOYMENT and UNDEPLOYMENT -//************************************************************** - -function MobileBaseVehicle::vehicleDeploy(%data, %obj, %player, %force) -{ - if(VectorLen(%obj.getVelocity()) <= 0.1 || %force) - { - %deployMessage = ""; - if( (%deployMessage = %data.checkTurretDistance(%obj)) $= "" || %force) - { - if(%obj.station $= "") - { - if( (%deployMessage = %data.checkDeploy(%obj)) $= "" || %force) - { - %obj.station = new StaticShape() { - scale = "1 1 1"; - dataBlock = "MobileInvStation"; - lockCount = "0"; - homingCount = "0"; - team = %obj.team; - vehicle = %obj; - }; - %obj.station.startFade(0,0,true); - %obj.mountObject(%obj.station, 2); - %obj.station.getDataBlock().createTrigger(%obj.station); - %obj.station.setSelfPowered(); - %obj.station.playThread($PowerThread,"Power"); - %obj.station.playAudio($HumSound,StationHumSound); - %obj.station.vehicle = %obj; - %obj.turret = new turret() { - scale = "1 1 1"; - dataBlock = "MobileTurretBase"; - lockCount = "0"; - homingCount = "0"; - team = %obj.team; - }; - %obj.turret.setDamageLevel(%obj.getDamageLevel()); - %obj.mountObject(%obj.turret, 1); - %obj.turret.setSelfPowered(); - %obj.turret.playThread($PowerThread,"Power"); - - //%obj.turret.mountImage(MissileBarrelLarge, 0 ,false); - // ----------------------------------------------------- - // z0dd - ZOD, 4/25/02. modular MPB turret - if(%obj.barrel !$= "") - { - %obj.turret.mountImage(%obj.barrel, 0 ,false); - } - else - { - %obj.turret.mountImage(MissileBarrelLarge, 0 ,false); - } - // ----------------------------------------------------- - - %obj.beacon = new BeaconObject() { - dataBlock = "DeployedBeacon"; - position = %obj.position; - rotation = %obj.rotation; - team = %obj.team; - }; - %obj.beacon.setBeaconType(friend); - %obj.beacon.setTarget(%obj.team); - - checkSpawnPos(%obj, 20); - } - } - else - { - %obj.station.setSelfPowered(); - %obj.station.playThread($PowerThread,"Power"); - %obj.turret.setSelfPowered(); - %obj.turret.playThread($PowerThread,"Power"); - } - if(%deployMessage $= "" || %force) - { - if(%obj.turret.getTarget() == -1) - { - %obj.turret.setTarget(%obj.turret.target); - } - %obj.turret.setThreadDir($DeployThread, true); - %obj.turret.playThread($DeployThread,"deploy"); - %obj.turret.playAudio($DeploySound, MobileBaseTurretDeploySound); - - %obj.station.notDeployed = 1; - %obj.setThreadDir($DeployThread, true); - %obj.playThread($DeployThread,"deploy"); - %obj.playAudio($DeploySound, MobileBaseDeploySound); - %obj.deployed = 1; - %obj.deploySchedule = ""; - %obj.disableMove = true; - %obj.setFrozenState(true); - if(isObject(%obj.shield)) - %obj.shield.delete(); - - %obj.shield = new forceFieldBare() - { - scale = "1.22 1.8 1.1"; - dataBlock = "defaultTeamSlowFieldBare"; - team = %obj.team; - }; - %obj.shield.open(); - setTargetSensorData(%obj.getTarget(), MPBDeployedSensor); - } - } - if(%deployMessage !$= "") - messageClient(%player.client, '', %deployMessage); - - return true; - } - else - { - return false; - } -} - -function MobileBaseVehicle::onEndSequence(%data, %obj, %thread) -{ - if(%thread == $DeployThread && !%obj.deployed) - { - %obj.unmountObject(%obj.station); - %obj.station.trigger.delete(); - %obj.station.delete(); - %obj.station = ""; - - %obj.beacon.delete(); - - %obj.unmountObject(%obj.turret); - %obj.turret.delete(); - %obj.turret = ""; - - if(!%obj.immobilized) - { - %obj.disableMove = false; - %obj.setFrozenState(false); - } - setTargetSensorData(%obj.getTarget(), %data.sensorData); - } - else - { - %obj.station.startFade(0,0,false); - %obj.station.setThreadDir($DeployThread, true); - %obj.station.playThread($DeployThread,"deploy"); - %obj.station.playAudio($DeploySound, MobileBaseStationDeploySound); - %obj.station.goingOut = true; - %obj.shield.setTransform(%obj.getSlotTransform(3)); - %obj.shield.close(); - %obj.isDeployed = true; - %obj.noEnemyControl = 1; - } - - Parent::onEndSequence(%data, %obj, %thread); -} - -function MobileInvStation::onEndSequence(%data, %obj, %thread) -{ - if(!%obj.goingOut) - %obj.startFade(0,0,true); - else - { - %obj.notDeployed = 0; - %obj.vehicle.fullyDeployed = 1; - //-------------------------------------------------------------------------------- - // z0dd - ZOD, 4/25/02. MPB Teleporter. -// if(isObject(%obj.vehicle.teleporter)) -// { -// %obj.vehicle.teleporter.setThreadDir($ActivateThread, TRUE); -// %obj.vehicle.teleporter.playThread($ActivateThread,"activate"); -// %obj.vehicle.teleporter.playAudio($ActivateSound, StationVehicleAcitvateSound); -// } - //-------------------------------------------------------------------------------- - } - Parent::onEndSequence(%data, %obj, %thread); -} - -function MobileBaseVehicle::checkDeploy(%data, %obj) -{ - %mask = $TypeMasks::VehicleObjectType | $TypeMasks::MoveableObjectType | - $TypeMasks::StaticShapeObjectType | $TypeMasks::ForceFieldObjectType | - $TypeMasks::ItemObjectType | $TypeMasks::PlayerObjectType | - $TypeMasks::TurretObjectType | //$TypeMasks::StaticTSObjectType | - $TypeMasks::InteriorObjectType; - - //%slot 1 = turret %slot 2 = station - %height[1] = 0; - %height[2] = 0; - %radius[1] = 2.4; - %radius[2] = 2.4; - %stationFailed = false; - %turretFailed = false; - - for(%x = 1; %x < 3; %x++) - { - %posXY = getWords(%obj.getSlotTransform(%x), 0, 1); - %posZ = (getWord(%obj.getSlotTransform(%x), 2) + %height[%x]); - InitContainerRadiusSearch(%posXY @ " " @ %posZ, %radius[%x], %mask); - - while ((%objFound = ContainerSearchNext()) != 0) - { - if(%objFound != %obj) - { - if(%x == 1) - %turretFailed = true; - else - %stationFailed = true; - break; - } - } - } - - //If turret, station or both fail the send back the error message... - if(%turretFailed && %stationFailed) - return "Both Turret and Station are blocked and unable to deploy."; - if(%turretFailed) - return "Turret is blocked and unable to deploy."; - if(%stationFailed) - return "Station is blocked and unable to deploy."; - - //Check the station for collision with the Terrain - %mat = %obj.getTransform(); - for(%x = 1; %x < 7; %x+=2) - { - %startPos = MatrixMulPoint(%mat, %data.stationPoints[%x]); - %endPos = MatrixMulPoint(%mat, %data.stationPoints[%x+1]); - - %rayCastObj = containerRayCast(%startPos, %endPos, $TypeMasks::TerrainObjectType, 0); - if(%rayCastObj) - return "Station is blocked by terrain and unable to deploy."; - } - - return ""; -} -function MobileBaseVehicle::checkTurretDistance(%data, %obj) -{ - %pos = getWords(%obj.getTransform(), 0, 2); - InitContainerRadiusSearch(%pos, 20, $TypeMasks::TurretObjectType | $TypeMasks::InteriorObjectType); // z0dd - ZOD, 6/21/02. Allow closer deploy. Was 100 - while ((%objFound = ContainerSearchNext()) != 0) - { - if(%objFound.getType() & $TypeMasks::TurretObjectType) - { - if(%objFound.getDataBlock().ClassName $= "TurretBase") - return "Turret Base is in the area. Unable to deploy."; - } - else - { - %subStr = getSubStr(%objFound.interiorFile, 1, 4); - if(%subStr !$= "rock" && %subStr !$= "spir" && %subStr !$= "misc") - return "Building is in the area. Unable to deploy."; - } - } - return ""; -} - - -//************************************************************** -//* VEHICLE INVENTORY MANAGEMENT -//************************************************************** - -//-------------------------------------------------------------- -// NUMBER OF PURCHASEABLE VEHICLES PER TEAM -//-------------------------------------------------------------- - -$VehicleRespawnTime = 15000; -$Vehiclemax[ScoutVehicle] = 4; -$VehicleMax[AssaultVehicle] = 3; -$VehicleMax[MobileBaseVehicle] = 1; -$VehicleMax[ScoutFlyer] = 4; -$VehicleMax[BomberFlyer] = 2; -$VehicleMax[HAPCFlyer] = 2; - -function vehicleListRemove(%data, %obj) -{ - %blockName = %data.getName(); - for($i = 0; %i < $VehicleMax[%blockName]; %i++) - if($VehicleInField[%obj.team, %blockName, %i] == %obj) - { - $VehicleInField[%obj.team, %blockName, %i] = 0; - $VehicleTotalCount[%obj.team, %blockName]--; - break; - } -} - -function vehicleListAdd(%blockName, %obj) -{ - for($i = 0; %i < $VehicleMax[%blockName]; %i++) - { - if($VehicleInField[%obj.team, %blockName, %i] $= "" || $VehicleInField[%obj.team, %blockName, %i] == 0) - { - $VehicleInField[%obj.team, %blockName, %i] = %obj; - $VehicleTotalCount[%obj.team, %blockName]++; - break; - } - } -} - -function clearVehicleCount(%team) -{ - $VehicleTotalCount[%team, ScoutVehicle] = 0; - $VehicleTotalCount[%team, AssaultVehicle] = 0; - $VehicleTotalCount[%team, MobileBaseVehicle] = 0; - $VehicleTotalCount[%team, ScoutFlyer] = 0; - $VehicleTotalCount[%team, BomberFlyer] = 0; - $VehicleTotalCount[%team, HAPCFlyer] = 0; -} - -//************************************************************** -//* VEHICLE HUD SEAT INDICATOR LIGHTS -//************************************************************** - -// --------------------------------------------------------- -// z0dd - ZOD, 6/18/02. Get the name of the vehicle node and -// pass to Armor::onMount and Armor::onDismount in player.cs -function findNodeName(%vehicle, %node) -{ - %vName = %vehicle.getDataBlock().getName(); - if(%vName !$= "HAPCFlyer") - { - if(%node == 0) - return 'pilot'; - else if(%node == 1) - return 'gunner'; - else - return 'tailgunner'; - } - else - { - if(%node == 0) - return 'pilot'; - else if(%node == 1) - return 'tailgunner'; - else - return 'passenger'; - } -} - -function findAIEmptySeat(%vehicle, %player) -{ - %dataBlock = %vehicle.getDataBlock(); - if (%dataBlock.getName() $= "BomberFlyer") - %num = 2; - else - %num = 1; - %node = -1; - for(%i = %num; %i < %dataBlock.numMountPoints; %i++) - { - if (!%vehicle.getMountNodeObject(%i)) - { - //cheap hack - for now, AI's will mount the next available node regardless of where they collided - %node = %i; - break; - } - } - - //return the empty seat - return %node; -} - -function findEmptySeat(%vehicle, %player, %forceNode) -{ - %minNode = 1; - %node = -1; - %dataBlock = %vehicle.getDataBlock(); - %dis = %dataBlock.minMountDist; - %playerPos = getWords(%player.getTransform(), 0, 2); - %message = ""; - if(%dataBlock.lightOnly) - { - if(%player.client.armor $= "Light") - %minNode = 0; - else - %message = '\c2Only Scout Armors can pilot this vehicle.~wfx/misc/misc.error.wav'; - } - else if(%player.client.armor $= "Light" || %player.client.armor $= "Medium") - %minNode = 0; - else - %minNode = findFirstHeavyNode(%dataBlock); - - if(%forceNode !$= "") - %node = %forceNode; - else - { - for(%i = 0; %i < %dataBlock.numMountPoints; %i++) - if(!%vehicle.getMountNodeObject(%i)) - { - %seatPos = getWords(%vehicle.getSlotTransform(%i), 0, 2); - %disTemp = VectorLen(VectorSub(%seatPos, %playerPos)); - if(%disTemp <= %dis) - { - %node = %i; - %dis = %disTemp; - } - } - } - if(%node != -1 && %node < %minNode) - { - if(%message $= "") - { - if(%node == 0) - %message = '\c2Only Scout or Assault Armors can pilot this vehicle.~wfx/misc/misc.error.wav'; - else - %message = '\c2Only Scout or Assault Armors can use that position.~wfx/misc/misc.error.wav'; - } - - if(!%player.noSitMessage) - { - %player.noSitMessage = true; - %player.schedule(2000, "resetSitMessage"); - messageClient(%player.client, 'MsgArmorCantMountVehicle', %message); - } - %node = -1; - } - return %node; -} - -function findFirstHeavyNode(%data) -{ - for(%i = 0; %i < %data.numMountPoints; %i++) - if(%data.mountPose[%i] $= "") - return %i; - return %data.numMountPoints; -} - -//************************************************************** -//* DAMAGE FUNCTIONS -//************************************************************** - -function VehicleData::damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType, %momVec, %theClient, %proj) -{ - if(%proj !$= "") - { - if(%amount > 0 && %targetObject.lastDamageProj !$= %proj) - { - %targetObject.lastDamageProj = %proj; - %targetObject.lastDamageAmount = %amount; - } - else if(%targetObject.lastDamageAmount < %amount) - %amount = %amount - %targetObject.lastDamageAmount; - else - return; - } - - // check for team damage - %sourceClient = %sourceObject ? %sourceObject.getOwnerClient() : 0; - %targetTeam = getTargetSensorGroup(%targetObject.getTarget()); - - if(%sourceClient) - %sourceTeam = %sourceClient.getSensorGroup(); - else if(isObject(%sourceObject) && %sourceObject.getClassName() $= "Turret") - { - %sourceTeam = getTargetSensorGroup(%sourceObject.getTarget()); - %sourceClient = %sourceObject.getControllingClient(); // z0dd - ZOD, 6/10/02. Play a sound to client when they hit a vehicle with a controlled turret - } - else - { - %sourceTeam = %sourceObject ? getTargetSensorGroup(%sourceObject.getTarget()) : -1; - // Client is allready defined and this spams console - ZOD - //%sourceClient = %sourceObject.getControllingClient(); // z0dd - ZOD, 6/10/02. Play a sound to client when they hit a vehicle from a vehicle - } - - // vehicles no longer obey team damage -JR -// if(!$teamDamage && (%targetTeam == %sourceTeam) && %targetObject.getDamagePercent() > 0.5) -// return; - //but we do want to track the destroyer - if(%sourceObject) - { - %targetObject.lastDamagedBy = %sourceObject; - %targetObject.lastDamageType = %damageType; - } - else - %targetObject.lastDamagedBy = 0; - - // ---------------------------------------------------------------------------------- - // z0dd - ZOD, 6/10/02. Play a sound to client when they hit a vehicle - if(%sourceClient && %sourceClient.vehicleHitSound) - { - if(%targetTeam != %sourceTeam) - { - if ((%damageType > 0 && %damageType < 11) || - (%damageType == 13) || - (%damageType > 15 && %damageType < 24) || - (%damageType > 25 && %damageType < 32)) - { - messageClient(%sourceClient, 'MsgClientHit', %sourceClient.vehicleHitWav); - } - } - } - // ---------------------------------------------------------------------------------- - - // Scale damage type & include shield calculations... - if (%data.isShielded) - %amount = %data.checkShields(%targetObject, %position, %amount, %damageType); - - - %damageScale = %data.damageScale[%damageType]; - if(%damageScale !$= "") - %amount *= %damageScale; - - if(%amount != 0) - %targetObject.applyDamage(%amount); - - if(%targetObject.getDamageState() $= "Destroyed" ) - { - if( %momVec !$= "") - %targetObject.setMomentumVector(%momVec); - } -} - -function VehicleData::onImpact(%data, %vehicleObject, %collidedObject, %vec, %vecLen) -{ - if(%vecLen > %data.minImpactSpeed) - %data.damageObject(%vehicleObject, 0, VectorAdd(%vec, %vehicleObject.getPosition()), - %vecLen * %data.speedDamageScale, $DamageType::Ground); - - // associated "crash" sounds - if(%vecLen > %vDataBlock.hardImpactSpeed) - %vehicleObject.playAudio(0, %vDataBlock.hardImpactSound); - else if(%vecLen > %vDataBlock.softImpactSpeed) - %vehicleObject.playAudio(0, %vDataBlock.softImpactSound); -} - -//************************************************************** -//* VEHICLE TIMEOUTS -//************************************************************** - -function vehicleAbandonTimeOut(%vehicle) -{ - if(%vehicle.getDatablock().cantAbandon $= "" && %vehicle.lastPilot $= "") - { - for(%i = 0; %i < %vehicle.getDatablock().numMountPoints; %i++) - if (%vehicle.getMountNodeObject(%i)) - { - %passenger = %vehicle.getMountNodeObject(%i); - if(%passenger.lastVehicle !$= "") - schedule(15000, %passenger.lastVehicle,"vehicleAbandonTimeOut", %passenger.lastVehicle); - %passenger.lastVehicle = %vehicle; - %vehicle.lastPilot = %passenger; - return; - } - - if(%vehicle.respawnTime !$= "") - %vehicle.marker.schedule = %vehicle.marker.data.schedule(%vehicle.respawnTime, "respawn", %vehicle.marker); - %vehicle.mountable = 0; - %vehicle.startFade(1000, 0, true); - %vehicle.schedule(1001, "delete"); - } -} - -//------------------------------------------------------------------------------ -function HoverVehicleData::create(%block, %team, %oldObj) -{ - if(%oldObj $= "") - { - %obj = new HoverVehicle() - { - dataBlock = %block; - respawn = "0"; - teamBought = %team; - team = %team; - }; - } - else - { - %obj = new HoverVehicle() - { - dataBlock = %data; - respawn = "0"; - teamBought = %team; - team = %team; - mountable = %oldObj.mountable; - disableMove = %oldObj.disableMove; - resetPos = %oldObj.resetPos; - respawnTime = %oldObj.respawnTime; - marker = %oldObj; - }; - } - return(%obj); -} - -function WheeledVehicleData::create(%data, %team, %oldObj) -{ - if(%oldObj $= "") - { - %obj = new WheeledVehicle() - { - dataBlock = %data; - respawn = "0"; - teamBought = %team; - team = %team; - }; - } - else - { - %obj = new WheeledVehicle() - { - dataBlock = %data; - respawn = "0"; - teamBought = %team; - team = %team; - mountable = %oldObj.mountable; - disableMove = %oldObj.disableMove; - resetPos = %oldObj.resetPos; - deployed = %oldObj.deployed; - respawnTime = %oldObj.respawnTime; - marker = %oldObj; - }; - } - - return(%obj); -} - -function FlyingVehicleData::create(%data, %team, %oldObj) -{ - if(%oldObj $= "") - { - %obj = new FlyingVehicle() - { - dataBlock = %data; - respawn = "0"; - teamBought = %team; - team = %team; - }; - } - else - { - %obj = new FlyingVehicle() - { - dataBlock = %data; - teamBought = %team; - team = %team; - mountable = %oldObj.mountable; - disableMove = %oldObj.disableMove; - resetPos = %oldObj.resetPos; - respawnTime = %oldObj.respawnTime; - marker = %oldObj; - }; - } - - return(%obj); -} - -function FlyingVehicleData::switchSidesSetPos(%data, %oldObj) -{ - %team = %oldObj.curTeam == 1 ? 2 : 1; - %oldObj.curTeam = %team; - %obj = new FlyingVehicle() - { - dataBlock = %data; - teamBought = %team; - team = %team; - mountable = %oldObj.mountable; - disableMove = %oldObj.disableMove; - resetPos = %oldObj.resetPos; - respawnTime = %oldObj.respawnTime; - marker = %oldObj; - }; - %obj.setTransform(%oldObj.getTransform()); - - return(%obj); -} - -function WheeledVehicleData::switchSidesSetPos(%data, %oldObj) -{ - %team = %oldObj.curTeam == 1 ? 2 : 1; - %oldObj.curTeam = %team; - %obj = new WheeledVehicle() - { - dataBlock = %data; - respawn = "0"; - teamBought = %team; - team = %team; - mountable = %oldObj.mountable; - disableMove = %oldObj.disableMove; - resetPos = %oldObj.resetPos; - deployed = %oldObj.deployed; - respawnTime = %oldObj.respawnTime; - marker = %oldObj; - }; - %obj.setTransform(%oldObj.getTransform()); - return(%obj); -} - -function HoverVehicleData::switchSides(%data, %oldObj) -{ - %team = %oldObj.curTeam == 1 ? 2 : 1; - %oldObj.curTeam = %team; - %obj = new HoverVehicle() - { - dataBlock = %data; - respawn = "0"; - teamBought = %team; - team = %team; - mountable = %oldObj.mountable; - disableMove = %oldObj.disableMove; - resetPos = %oldObj.resetPos; - respawnTime = %oldObj.respawnTime; - marker = %oldObj; - }; - %obj.setTransform(%oldObj.getTransform()); - return(%obj); -} - -function resetNonStaticObjPositions() -{ - MissionGroup.setupPositionMarkers(false); - MissionCleanup.positionReset(); -} - -function next(%team) -{ - ResetObjsPositions(%team); -} - -function SimGroup::positionReset(%group) -{ - for(%i = %group.getCount() - 1; %i >=0 ; %i--) - { - %obj = %group.getObject(%i); - if(%obj.resetPos && %obj.getName() !$= PosMarker) - %obj.delete(); - else - %obj.positionReset(); - } - - for(%i = 0; %i < %group.getCount(); %i++) - { - %obj = %group.getObject(%i); - if(%obj.getName() $= PosMarker) - { - cancel(%obj.schedule); - %newObj = %obj.data.switchSidesSetPos(%obj); - MissionCleanup.add(%newObj); - setTargetSensorGroup(%newObj.target, %newObj.team); - } - else - %obj.positionReset(); - } -} - -function VehicleData::respawn(%data, %marker) -{ - %mask = $TypeMasks::PlayerObjectType | $TypeMasks::VehicleObjectType | $TypeMasks::TurretObjectType; - InitContainerRadiusSearch(%marker.getWorldBoxCenter(), %data.checkRadius, %mask); - if(containerSearchNext() == 0) - { - %newObj = %data.create(%marker.curTeam, %marker); - %newObj.startFade(1000, 0, false); - %newObj.setTransform(%marker.getTransform()); - - setTargetSensorGroup(%newObj.target, %newObj.team); - MissionCleanup.add(%newObj); - } - else - { - %marker.schedule = %data.schedule(3000, "respawn", %marker); - } -} - -function SimObject::positionReset(%group, %team) -{ - //Used to avoid warnings -} - -function Terraformer::positionReset(%group, %team) -{ - //Used to avoid warnings -} - -function SimGroup::setupPositionMarkers(%group, %create) -{ - for(%i = %group.getCount() - 1; %i >= 0; %i--) - { - %obj = %group.getObject(%i); - if(%obj.resetPos || %obj.respawnTime !$= "") - { - if(%create) - { - %marker = %obj.getDataBlock().createPositionMarker(%obj); - MissionCleanup.add(%marker); - %obj.marker = %marker; - } - else - { - %obj.delete(); - } - } - else - %obj.setupPositionMarkers(%create); - } -} - -function SimObject::setupPositionMarkers(%group, %create) -{ - //Used to avoid warnings -} - -function VehicleData::createPositionMarker(%data, %obj) -{ - %marker = new Trigger(PosMarker) - { - dataBlock = markerTrigger; - mountable = %obj.mountable; - disableMove = %obj.disableMove; - resetPos = %obj.resetPos; - data = %obj.getDataBlock().getName(); - deployed = %obj.deployed; - curTeam = %obj.team; - respawnTime = %obj.respawnTime; - }; - %marker.setTransform(%obj.getTransform()); - return %marker; -} - -function VehicleData::hasDismountOverrides(%data, %obj) -{ - return false; -} - +// Notes: +// - respawning vehicles with turrets (bomber/tank) will not setup the turret properly + +//Damage Rate for entering Liquid +$VehicleDamageLava = 0.0325; +$VehicleDamageHotLava = 0.0325; +$VehicleDamageCrustyLava = 0.0325; + +$NumVehiclesDeploy = 0; + +//************************************************************** +//* GENERAL PURPOSE FUNCTIONS +//************************************************************** + +function VehicleData::onAdd(%data, %obj) +{ + Parent::onAdd(%data, %obj); + if((%data.sensorData !$= "") && (%obj.getTarget() != -1)) + setTargetSensorData(%obj.getTarget(), %data.sensorData); + %obj.setRechargeRate(%data.rechargeRate); + // set full energy + %obj.setEnergyLevel(%data.MaxEnergy); + + if(%obj.disableMove) + %obj.immobilized = true; + if(%obj.deployed) + { + if($countDownStarted) + %data.schedule(($Host::WarmupTime * 1000) / 2, "vehicleDeploy", %obj, 0, 1); + else + { + $VehiclesDeploy[$NumVehiclesDeploy] = %obj; + $NumVehiclesDeploy++; + } + } + if(%obj.mountable || %obj.mountable $= "") + %data.isMountable(%obj, true); + else + %data.isMountable(%obj, false); + + %obj.setSelfPowered(); +// %data.canObserve = true; +} + +function VehicleData::onRemove(%this, %obj) +{ + // if there are passengers/driver, kick them out + %this.deleteAllMounted(%obj); + for(%i = 0; %i < %obj.getDatablock().numMountPoints; %i++) + if (%obj.getMountNodeObject(%i)) { + %passenger = %obj.getMountNodeObject(%i); + %passenger.unmount(); + } + vehicleListRemove(%obj.getDataBlock(), %obj); + if(%obj.lastPilot.lastVehicle == %obj) + %obj.lastPilot.lastVehicle = ""; + + Parent::onRemove(%this, %obj); +} + +function VehicleData::onDamage(%this,%obj) +{ + %damage = %obj.getDamageLevel(); + if (%damage >= %this.destroyedLevel) + { + if(%obj.getDamageState() !$= "Destroyed") + { + if(%obj.respawnTime !$= "") + %obj.marker.schedule = %obj.marker.data.schedule(%obj.respawnTime, "respawn", %obj.marker); + %obj.setDamageState(Destroyed); + } + } + else + { + if(%obj.getDamageState() !$= "Enabled") + %obj.setDamageState(Enabled); + } +} + +function VehicleData::playerDismounted(%data, %obj, %player) +{ + if( %player.client.observeCount > 0 ) + resetObserveFollow( %player.client, true ); + + setTargetSensorGroup(%obj.getTarget(), %obj.team); + + // if there is a turret, set its team as well. + if( %obj.turretObject > 0 ) + setTargetSensorGroup(%obj.turretObject.getTarget(), %obj.team); +} + +function HoverVehicle::useCreateHeight() +{ + //this function is declared to prevent console error msg spam... +} + +function WheeledVehicle::useCreateHeight() +{ + //this function is declared to prevent console error msg spam... +} + +function AssaultVehicle::onDamage(%this, %obj) +{ + if(isObject(%obj.getMountNodeObject(10))) + (%obj.getMountNodeObject(10)).setDamagelevel(%obj.getDamageLevel()); + Parent::onDamage(%this, %obj); +} + +function BomberFlyer::onDamage(%this, %obj) +{ + if(isObject(%obj.getMountNodeObject(10))) + (%obj.getMountNodeObject(10)).setDamagelevel(%obj.getDamageLevel()); + Parent::onDamage(%this, %obj); +} + +function MobileBaseVehicle::onDamage(%this, %obj) +{ + if(isObject(%obj.getMountNodeObject(1))) + (%obj.getMountNodeObject(1)).setDamagelevel(%obj.getDamageLevel()); + Parent::onDamage(%this, %obj); +} + +function VehicleData::onEnterLiquid(%data, %obj, %coverage, %type) +{ + switch(%type) + { + case 0: + //Water + %obj.setHeat(0.0); + case 1: + //Ocean Water + %obj.setHeat(0.0); + case 2: + //River Water + %obj.setHeat(0.0); + case 3: + //Stagnant Water + %obj.setHeat(0.0); + case 4: + //Lava + %obj.liquidDamage(%data, $VehicleDamageLava, $DamageType::Lava); + case 5: + //Hot Lava + %obj.liquidDamage(%data, $VehicleDamageHotLava, $DamageType::Lava); + case 6: + //Crusty Lava + %obj.liquidDamage(%data, $VehicleDamageCrustyLava, $DamageType::Lava); + case 7: + //Quick Sand + } +} + +function FlyingVehicle::liquidDamage(%obj, %data, %damageAmount, %damageType) +{ + if(%obj.getDamageState() !$= "Destroyed") + { + %data.damageObject(%obj, 0, "0 0 0", %damageAmount, %damageType); + %obj.lDamageSchedule = %obj.schedule(50, "liquidDamage", %data, %damageAmount, %damageType); + passengerLiquidDamage(%obj, %damageAmount, %damageType); + } + else + %obj.lDamageSchedule = ""; +} + +function WheeledVehicle::liquidDamage(%obj, %data, %damageAmount, %damageType) +{ + if(%obj.getDamageState() !$= "Destroyed") + { + %data.damageObject(%obj, 0, "0 0 0", %damageAmount, %damageType); + %obj.lDamageSchedule = %obj.schedule(50, "liquidDamage", %data, %damageAmount, %damageType); + passengerLiquidDamage(%obj, %damageAmount, %damageType); + } + else + %obj.lDamageSchedule = ""; +} + +function HoverVehicle::liquidDamage(%obj, %data, %damageAmount, %damageType) +{ + if(%obj.getDamageState() !$= "Destroyed") + { + %data.damageObject(%obj, 0, "0 0 0", %damageAmount, %damageType); + %obj.lDamageSchedule = %obj.schedule(50, "liquidDamage", %data, %damageAmount, %damageType); + passengerLiquidDamage(%obj, %damageAmount, %damageType); + } + else + %obj.lDamageSchedule = ""; +} + +function passengerLiquidDamage(%obj, %damageAmount, %damageType) +{ + for(%i = %num; %i < %obj.getDataBlock().numMountPoints; %i++) + if (%p = %obj.getMountNodeObject(%i)) + %p.liquidDamage(%p.getDatablock(), $DamageLava, $DamageType::Lava); +} + +function VehicleData::onLeaveLiquid(%data, %obj, %type) +{ + switch(%type) + { + case 0: + //Water + %obj.setHeat(1.0); + case 1: + //Ocean Water + %obj.setHeat(1.0); + case 2: + //River Water + %obj.setHeat(1.0); + case 3: + //Stagnant Water + %obj.setHeat(1.0); + case 4: + //Lava + case 5: + //Hot Lava + case 6: + //Crusty Lava + case 7: + //Quick Sand + } + + if(%obj.lDamageSchedule !$= "") + { + cancel(%obj.lDamageSchedule); + %obj.lDamageSchedule = ""; + } +} + +function VehicleData::onDestroyed(%data, %obj, %prevState) +{ + if(%obj.lastDamagedBy) + { + %destroyer = %obj.lastDamagedBy; + game.vehicleDestroyed(%obj, %destroyer); + //error("vehicleDestroyed( "@ %obj @", "@ %destroyer @")"); + } + + radiusVehicleExplosion(%data, %obj); + if(%obj.turretObject) + if(%obj.turretObject.getControllingClient()) + %obj.turretObject.getDataBlock().playerDismount(%obj.turretObject); + for(%i = 0; %i < %obj.getDatablock().numMountPoints; %i++) + { + if (%obj.getMountNodeObject(%i)) { + %flingee = %obj.getMountNodeObject(%i); + %flingee.getDataBlock().doDismount(%flingee, true); + %xVel = 250.0 - (getRandom() * 500.0); + %yVel = 250.0 - (getRandom() * 500.0); + %zVel = (getRandom() * 100.0) + 50.0; + %flingVel = %xVel @ " " @ %yVel @ " " @ %zVel; + %flingee.applyImpulse(%flingee.getTransform(), %flingVel); + echo("got player..." @ %flingee.getClassName()); + %flingee.damage(0, %obj.getPosition(), 0.4, $DamageType::Crash); + } + } + + %data.deleteAllMounted(%obj); + // ----------------------------------------------------------------------------------------- + // z0dd - ZOD - Czar, 6/24/02. Move this vehicle out of the way so nothing collides with it. + if(%data.getName() $="BomberFlyer" || %data.getName() $="MobileBaseVehicle" || %data.getName() $="AssaultVehicle") + { + %obj.setFrozenState(true); + %obj.schedule(2000, "delete"); + %data.schedule(500, 'onAvoidCollisions', %obj); + } + else + { + %obj.setFrozenState(true); + %obj.schedule(500, "delete"); + } + // ----------------------------------------------------------------------------------------- +} + +// ---------------------------------------------------------------------------------- +// z0dd - ZOD, 6/13/02. Move this vehicle out of the way so nothing collides with it. +function VehicleData::onAvoidCollisions(%data, %obj) +{ + // Get the current location of the vehicle and send it to the moon! + %transform = posFromTransform(%obj.getTransform()); + %position = getWord(%transform, 0) SPC getWord(%transform, 1) SPC (getWord(%transform, 2)+2000); + %rotation = getWord(%transform, 3) SPC getWord(%transform, 4) SPC getWord(%transform, 5) SPC getWord(%transform, 6); + %obj.setTransform(%position SPC %rotation); +} +// ---------------------------------------------------------------------------------- + +function radiusVehicleExplosion(%data, %vehicle) +{ + // this is a modified version of RadiusExplosion() from projectiles.cs + %position = %vehicle.getPosition(); + InitContainerRadiusSearch(%position, %data.explosionRadius, $TypeMasks::PlayerObjectType | + $TypeMasks::VehicleObjectType | + $TypeMasks::MoveableObjectType | + $TypeMasks::StaticShapeObjectType | + $TypeMasks::ForceFieldObjectType | + $TypeMasks::TurretObjectType | + $TypeMasks::ItemObjectType); + + %numTargets = 0; + while ((%targetObject = containerSearchNext()) != 0) + { + if(%targetObject == %vehicle) + continue; + + %dist = containerSearchCurrRadDamageDist(); + + if (%dist > %data.explosionRadius) + continue; + + if (%targetObject.isMounted()) + { + %mount = %targetObject.getObjectMount(); + if(%mount == %vehicle) + continue; + + %found = -1; + for (%i = 0; %i < %mount.getDataBlock().numMountPoints; %i++) + { + if (%mount.getMountNodeObject(%i) == %targetObject) + { + %found = %i; + break; + } + } + + if (%found != -1) + { + if (%mount.getDataBlock().isProtectedMountPoint[%found] && (%mount != %vehicle)) + continue; + } + } + + %targets[%numTargets] = %targetObject; + %targetDists[%numTargets] = %dist; + %numTargets++; + } + + for (%i = 0; %i < %numTargets; %i++) + { + %targetObject = %targets[%i]; + %dist = %targetDists[%i]; + + %coverage = calcExplosionCoverage(%position, %targetObject, + ($TypeMasks::InteriorObjectType | + $TypeMasks::TerrainObjectType | + $TypeMasks::ForceFieldObjectType)); + if (%coverage == 0) + continue; + + %amount = (1.0 - (%dist / %data.explosionRadius)) * %coverage * %data.explosionDamage; + %targetData = %targetObject.getDataBlock(); + + %momVec = "0 0 1"; + + if(%amount > 0) + %targetData.damageObject(%targetObject, %sourceObject, %position, %amount, $DamageType::Explosion, %momVec); + } +} + +function VehicleData::deleteAllMounted() +{ + +} + +//************************************************************** +//* VEHICLE CREATION +//************************************************************** +// (NOTE: No entry for Wildcat Grav Cycle is here. -- DG) + +//---------------------------- +// SHRIKE SCOUT FLIER +//---------------------------- + +function ScoutFlyer::onAdd(%this, %obj) +{ + Parent::onAdd(%this, %obj); + %obj.mountImage(ScoutChaingunParam, 0); + %obj.mountImage(ScoutChaingunImage, 2); + %obj.mountImage(ScoutChaingunPairImage, 3); + %obj.nextWeaponFire = 2; + %obj.schedule(5500, "playThread", $ActivateThread, "activate"); +} + +//---------------------------- +// THUNDERSWORD BOMBER +//---------------------------- + +function BomberFlyer::onAdd(%this, %obj) +{ + Parent::onAdd(%this, %obj); + + %turret = TurretData::create(BomberTurret); + MissionCleanup.add(%turret); + %turret.team = %obj.teamBought; + %turret.selectedWeapon = 1; + %turret.setSelfPowered(); + %obj.mountObject(%turret, 10); + %turret.mountImage(BomberTurretBarrel,2); + %turret.mountImage(BomberTurretBarrelPair,3); + %turret.mountImage(BomberBombImage, 4); + %turret.mountImage(BomberBombPairImage, 5); + %turret.mountImage(BomberTargetingImage, 6); + %obj.turretObject = %turret; + %turret.setCapacitorRechargeRate( %turret.getDataBlock().capacitorRechargeRate ); + %turret.vehicleMounted = %obj; + + //vehicle turrets should not auto fire at targets + %turret.setAutoFire(false); + + //for this particular weapon - a non-firing datablock used only so the AI can aim the turret + //Also needed so we can set the turret parameters.. + %turret.mountImage(AIAimingTurretBarrel, 0); + + // setup the turret's target info + setTargetSensorGroup(%turret.getTarget(), %turret.team); + setTargetNeverVisMask(%turret.getTarget(), 0xffffffff); +} + +//---------------------------- +// HAVOC TRANSPORT FLIER +//---------------------------- + +function HAPCFlyer::onAdd(%this, %obj) +{ + Parent::onAdd(%this, %obj); + %obj.schedule(6000, "playThread", $ActivateThread, "activate"); +} + +//---------------------------- +// BEOWULF ASSAULT VEHICLE +//---------------------------- + +function AssaultVehicle::onAdd(%this, %obj) +{ + Parent::onAdd(%this, %obj); + + %turret = TurretData::create(AssaultPlasmaTurret); + %turret.selectedWeapon = 1; + MissionCleanup.add(%turret); + %turret.team = %obj.teamBought; + %turret.setSelfPowered(); + %obj.mountObject(%turret, 10); + %turret.mountImage(AssaultPlasmaTurretBarrel, 2); + %turret.mountImage(AssaultMortarTurretBarrel, 4); + %turret.setCapacitorRechargeRate( %turret.getDataBlock().capacitorRechargeRate ); + %obj.turretObject = %turret; + + //vehicle turrets should not auto fire at targets + %turret.setAutoFire(false); + + //Needed so we can set the turret parameters.. + %turret.mountImage(AssaultTurretParam, 0); + %obj.schedule(6000, "playThread", $ActivateThread, "activate"); + + // set the turret's target info + setTargetSensorGroup(%turret.getTarget(), %turret.team); + setTargetNeverVisMask(%turret.getTarget(), 0xffffffff); +} + +//---------------------------- +// JERICHO FORWARD BASE (Mobile Point Base) +//---------------------------- + +function MobileBaseVehicle::onAdd(%this, %obj) +{ + Parent::onAdd(%this, %obj); + %obj.station = ""; + %obj.turret = ""; + %obj.beacon = ""; + + %obj.schedule(5000, "playThread", $AmbientThread, "ambient"); +} + +//************************************************************** +//* MULTI-CREW VEHICLE DELETION +//************************************************************** + +//---------------------------- +//BEOWULF ASSAULT VEHICLE +//---------------------------- + +function AssaultVehicle::deleteAllMounted(%data, %obj) +{ + %turret = %obj.getMountNodeObject(10); + if(!%turret) + return; + + if(%client = %turret.getControllingClient()) + { + %client.player.setControlObject(%client.player); + %client.player.mountImage(%client.player.lastWeapon, $WeaponSlot); + %client.player.mountVehicle = false; + } + %turret.schedule(2000, delete); +} + +//---------------------------- +// THUNDERSWORD BOMBER +//---------------------------- + +function BomberFlyer::deleteAllMounted(%data, %obj) +{ + if(isObject(%obj.beacon)) + %obj.beacon.schedule(50, delete); + + %turret = %obj.getMountNodeObject(10); + if(!%turret) + return; + + %turret.altTrigger = 0; + %turret.fireTrigger = 0; + + if(%client = %turret.getControllingClient()) + { + commandToClient(%client, 'endBomberSight'); + %client.player.setControlObject(%client.player); + %client.player.mountImage(%client.player.lastWeapon, $WeaponSlot); + %client.player.mountVehicle = false; + + %client.player.bomber = false; + %client.player.isBomber = false; + } + %turret.schedule(2000, delete); +} + +//---------------------------- +// JERICHO FORWARD BASE +//---------------------------- + +function MobileBaseVehicle::deleteAllMounted(%data, %obj) +{ + if(isObject(%obj.station)) // z0dd - ZOD, 4/25/02. Console spam fix. + { + %obj.station.getDataBlock().onLosePowerDisabled(%obj.station); + %obj.unmountObject(%obj.station); + %obj.station.trigger.schedule(2000, delete); + %obj.station.schedule(2000, delete); + } + if(isObject(%obj.turret)) // z0dd - ZOD, 4/25/02. Console spam fix. + { + %obj.turret.getDataBlock().onLosePowerDisabled(%obj.turret); + %obj.unmountObject(%obj.turret); + %obj.turret.schedule(2000, delete); + } + //-------------------------------------------------------------------------- + // z0dd - ZOD, 4/25/02. MPB Teleporter. +// if (isObject(%obj.teleporter)) +// { +// %obj.teleporter.setThreadDir($ActivateThread, FALSE); +// %obj.teleporter.playThread($ActivateThread,"activate"); +// %obj.teleporter.playAudio($ActivateSound, StationVehicleDeactivateSound); +// } + //-------------------------------------------------------------------------- + if(isObject(%obj.shield)) + %obj.shield.schedule(2000, delete); + + if(isObject(%obj.beacon)) + { + %obj.beacon.schedule(0, delete); + } +} + +//************************************************************** +//* WEAPON MOUNTING ON VEHICLES +//************************************************************** + +//---------------------------- +// SHRIKE SCOUT FLIER +//---------------------------- + +function ScoutFlyer::playerMounted(%data, %obj, %player, %node) +{ + // scout flyer == SUV (single-user vehicle) + commandToClient(%player.client, 'setHudMode', 'Pilot', "Shrike", %node); + $numVWeapons = 1; + + // update observers who are following this guy... + if( %player.client.observeCount > 0 ) + resetObserveFollow( %player.client, false ); +} + +//---------------------------- +// THUNDERSWORD BOMBER +//---------------------------- + +function BomberFlyer::playerMounted(%data, %obj, %player, %node) +{ + if(%node == 0) + { + // pilot position + %player.setPilot(true); + commandToClient(%player.client, 'setHudMode', 'Pilot', "Bomber", %node); + } + else if(%node == 1) + { + // bombardier position + %turret = %obj.getMountNodeObject(10); + %player.vehicleTurret = %turret; + %player.setTransform("0 0 0 0 0 1 0"); + %player.lastWeapon = %player.getMountedImage($WeaponSlot); + %player.unmountImage($WeaponSlot); + if(!%player.client.isAIControlled()) + { + %player.setControlObject(%turret); + %player.client.setObjectActiveImage(%turret, 2); + } + commandToClient(%player.client, 'startBomberSight'); + %turret.bomber = %player; + $bWeaponActive = 0; + %obj.getMountNodeObject(10).selectedWeapon = 1; + commandToClient(%player.client,'SetWeaponryVehicleKeys', true); + + commandToClient(%player.client, 'setHudMode', 'Pilot', "Bomber", %node); + %player.isBomber = true; + } + else + { + // tail gunner position + commandToClient(%player.client, 'setHudMode', 'Passenger', "Bomber", %node); + } + // build a space-separated string representing passengers + // 0 = no passenger; 1 = passenger (e.g. "1 0 0 ") + %passString = buildPassengerString(%obj); + // send the string of passengers to all mounted players + for(%i = 0; %i < %data.numMountPoints; %i++) + if(%obj.getMountNodeObject(%i) > 0) + commandToClient(%obj.getMountNodeObject(%i).client, 'checkPassengers', %passString); + + // update observers who are following this guy... + if( %player.client.observeCount > 0 ) + resetObserveFollow( %player.client, false ); +} + +//---------------------------- +// HAVOC TRANSPORT FLIER +//---------------------------- + +function HAPCFlyer::playerMounted(%data, %obj, %player, %node) +{ + if(%node == 0) { + // pilot position + commandToClient(%player.client, 'setHudMode', 'Pilot', "HAPC", %node); + } + else { + // all others + commandToClient(%player.client, 'setHudMode', 'Passenger', "HAPC", %node); + } + // build a space-separated string representing passengers + // 0 = no passenger; 1 = passenger (e.g. "1 0 0 1 1 0 ") + %passString = buildPassengerString(%obj); + // send the string of passengers to all mounted players + for(%i = 0; %i < %data.numMountPoints; %i++) + if(%obj.getMountNodeObject(%i) > 0) + commandToClient(%obj.getMountNodeObject(%i).client, 'checkPassengers', %passString); + + // update observers who are following this guy... + if( %player.client.observeCount > 0 ) + resetObserveFollow( %player.client, false ); +} + +//---------------------------- +// WILDCAT GRAV CYCLE +//---------------------------- + +function ScoutVehicle::playerMounted(%data, %obj, %player, %node) +{ + // scout vehicle == SUV (single-user vehicle) + commandToClient(%player.client, 'setHudMode', 'Pilot', "Hoverbike", %node); + + // update observers who are following this guy... + if( %player.client.observeCount > 0 ) + resetObserveFollow( %player.client, false ); +} + +//---------------------------- +// BEOWULF ASSAULT VEHICLE +//---------------------------- + +function AssaultVehicle::playerMounted(%data, %obj, %player, %node) +{ + if(%node == 0) { + // driver position + // is there someone manning the turret? + //%turreteer = %obj.getMountedNodeObject(1); + commandToClient(%player.client, 'setHudMode', 'Pilot', "Assault", %node); + } + else if(%node == 1) + { + // turreteer position + %turret = %obj.getMountNodeObject(10); + %player.vehicleTurret = %turret; + %player.setTransform("0 0 0 0 0 1 0"); + %player.lastWeapon = %player.getMountedImage($WeaponSlot); + %player.unmountImage($WeaponSlot); + if(!%player.client.isAIControlled()) + { + %player.setControlObject(%turret); + %player.client.setObjectActiveImage(%turret, 2); + } + %turret.turreteer = %player; + // if the player is the turreteer, show vehicle's weapon icons + //commandToClient(%player.client, 'showVehicleWeapons', %data.getName()); + //%player.client.setVWeaponsHudActive(1); // plasma turret icon (default) + + $aWeaponActive = 0; + commandToClient(%player.client,'SetWeaponryVehicleKeys', true); + %obj.getMountNodeObject(10).selectedWeapon = 1; + commandToClient(%player.client, 'setHudMode', 'Pilot', "Assault", %node); + } + + // update observers who are following this guy... + if( %player.client.observeCount > 0 ) + resetObserveFollow( %player.client, false ); + + // build a space-separated string representing passengers + // 0 = no passenger; 1 = passenger (e.g. "1 0 ") + %passString = buildPassengerString(%obj); + // send the string of passengers to all mounted players + for(%i = 0; %i < %data.numMountPoints; %i++) + if(%obj.getMountNodeObject(%i) > 0) + commandToClient(%obj.getMountNodeObject(%i).client, 'checkPassengers', %passString); +} + +//---------------------------- +// JERICHO FORWARD BASE +//---------------------------- + +function MobileBaseVehicle::playerMounted(%data, %obj, %player, %node) +{ + // MPB vehicle == SUV (single-user vehicle) + commandToClient(%player.client, 'setHudMode', 'Pilot', "MPB", %node); + if(%obj.deploySchedule) + { + %obj.deploySchedule.clear(); + %obj.deploySchedule = ""; + } + + if(%obj.deployed !$= "" && %obj.deployed == 1) + { + %obj.setThreadDir($DeployThread, false); + %obj.playThread($DeployThread,"deploy"); + %obj.playAudio($DeploySound, MobileBaseUndeploySound); + %obj.station.setThreadDir($DeployThread, false); + %obj.station.getDataBlock().onLosePowerDisabled(%obj.station); + %obj.station.clearSelfPowered(); + %obj.station.goingOut=false; + %obj.station.notDeployed = 1; + %obj.station.playAudio($DeploySound, MobileBaseStationUndeploySound); + + if((%turretClient = %obj.turret.getControllingClient()) !$= "") + { + CommandToServer( 'resetControlObject', %turretClient ); + } + + %obj.turret.setThreadDir($DeployThread, false); + %obj.turret.clearTarget(); + %obj.turret.setTargetObject(-1); + + %obj.turret.playAudio($DeploySound, MobileBaseTurretUndeploySound); + %obj.shield.open(); + %obj.shield.schedule(1000,"delete"); + %obj.deploySchedule = ""; + //----------------------------------------------------------------------- + // z0dd - ZOD, 4/25/02. MPB Teleporter. +// %obj.teleporter.setThreadDir($ActivateThread, FALSE); +// %obj.teleporter.playThread($ActivateThread,"activate"); +// %obj.teleporter.playAudio($ActivateSound, StationVehicleDeactivateSound); + //----------------------------------------------------------------------- + %obj.fullyDeployed = 0; + + %obj.noEnemyControl = 0; + } + %obj.deployed = 0; + + // update observers who are following this guy... + if( %player.client.observeCount > 0 ) + resetObserveFollow( %player.client, false ); +} + +function buildPassengerString(%vehicle) +{ + %passStr = ""; + for(%i = 0; %i < %vehicle.getDatablock().numMountPoints; %i++) + { + if(%vehicle.getMountNodeObject(%i) > 0) + %passStr = %passStr @ "1 "; + else + %passStr = %passStr @ "0 "; + } + + return %passStr; +} + +function MobileBaseVehicle::playerDismounted(%data, %obj, %player) +{ + %obj.schedule(500, "deployVehicle", %data, %player); + Parent::playerDismounted( %data, %obj, %player ); +} + +function WheeledVehicle::deployVehicle(%obj, %data, %player) +{ + if (!%data.vehicleDeploy(%obj, %player)) + %obj.schedule(500, "deployVehicle", %data, %player); +} + +//************************************************************** +//* JERICHO DEPLOYMENT and UNDEPLOYMENT +//************************************************************** + +function MobileBaseVehicle::vehicleDeploy(%data, %obj, %player, %force) +{ + if(VectorLen(%obj.getVelocity()) <= 0.1 || %force) + { + %deployMessage = ""; + if( (%deployMessage = %data.checkTurretDistance(%obj)) $= "" || %force) + { + if(%obj.station $= "") + { + if( (%deployMessage = %data.checkDeploy(%obj)) $= "" || %force) + { + %obj.station = new StaticShape() { + scale = "1 1 1"; + dataBlock = "MobileInvStation"; + lockCount = "0"; + homingCount = "0"; + team = %obj.team; + vehicle = %obj; + }; + %obj.station.startFade(0,0,true); + %obj.mountObject(%obj.station, 2); + %obj.station.getDataBlock().createTrigger(%obj.station); + %obj.station.setSelfPowered(); + %obj.station.playThread($PowerThread,"Power"); + %obj.station.playAudio($HumSound,StationHumSound); + %obj.station.vehicle = %obj; + %obj.turret = new turret() { + scale = "1 1 1"; + dataBlock = "MobileTurretBase"; + lockCount = "0"; + homingCount = "0"; + team = %obj.team; + }; + %obj.turret.setDamageLevel(%obj.getDamageLevel()); + %obj.mountObject(%obj.turret, 1); + %obj.turret.setSelfPowered(); + %obj.turret.playThread($PowerThread,"Power"); + + //%obj.turret.mountImage(MissileBarrelLarge, 0 ,false); + // ----------------------------------------------------- + // z0dd - ZOD, 4/25/02. modular MPB turret + if(%obj.barrel !$= "") + { + %obj.turret.mountImage(%obj.barrel, 0 ,false); + } + else + { + %obj.turret.mountImage(MissileBarrelLarge, 0 ,false); + } + // ----------------------------------------------------- + + %obj.beacon = new BeaconObject() { + dataBlock = "DeployedBeacon"; + position = %obj.position; + rotation = %obj.rotation; + team = %obj.team; + }; + %obj.beacon.setBeaconType(friend); + %obj.beacon.setTarget(%obj.team); + + checkSpawnPos(%obj, 20); + } + } + else + { + %obj.station.setSelfPowered(); + %obj.station.playThread($PowerThread,"Power"); + %obj.turret.setSelfPowered(); + %obj.turret.playThread($PowerThread,"Power"); + } + if(%deployMessage $= "" || %force) + { + if(%obj.turret.getTarget() == -1) + { + %obj.turret.setTarget(%obj.turret.target); + } + %obj.turret.setThreadDir($DeployThread, true); + %obj.turret.playThread($DeployThread,"deploy"); + %obj.turret.playAudio($DeploySound, MobileBaseTurretDeploySound); + + %obj.station.notDeployed = 1; + %obj.setThreadDir($DeployThread, true); + %obj.playThread($DeployThread,"deploy"); + %obj.playAudio($DeploySound, MobileBaseDeploySound); + %obj.deployed = 1; + %obj.deploySchedule = ""; + %obj.disableMove = true; + %obj.setFrozenState(true); + if(isObject(%obj.shield)) + %obj.shield.delete(); + + %obj.shield = new forceFieldBare() + { + scale = "1.22 1.8 1.1"; + dataBlock = "defaultTeamSlowFieldBare"; + team = %obj.team; + }; + %obj.shield.open(); + setTargetSensorData(%obj.getTarget(), MPBDeployedSensor); + } + } + if(%deployMessage !$= "") + messageClient(%player.client, '', %deployMessage); + + return true; + } + else + { + return false; + } +} + +function MobileBaseVehicle::onEndSequence(%data, %obj, %thread) +{ + if(%thread == $DeployThread && !%obj.deployed) + { + %obj.unmountObject(%obj.station); + %obj.station.trigger.delete(); + %obj.station.delete(); + %obj.station = ""; + + %obj.beacon.delete(); + + %obj.unmountObject(%obj.turret); + %obj.turret.delete(); + %obj.turret = ""; + + if(!%obj.immobilized) + { + %obj.disableMove = false; + %obj.setFrozenState(false); + } + setTargetSensorData(%obj.getTarget(), %data.sensorData); + } + else + { + %obj.station.startFade(0,0,false); + %obj.station.setThreadDir($DeployThread, true); + %obj.station.playThread($DeployThread,"deploy"); + %obj.station.playAudio($DeploySound, MobileBaseStationDeploySound); + %obj.station.goingOut = true; + %obj.shield.setTransform(%obj.getSlotTransform(3)); + %obj.shield.close(); + %obj.isDeployed = true; + %obj.noEnemyControl = 1; + } + + Parent::onEndSequence(%data, %obj, %thread); +} + +function MobileInvStation::onEndSequence(%data, %obj, %thread) +{ + if(!%obj.goingOut) + %obj.startFade(0,0,true); + else + { + %obj.notDeployed = 0; + %obj.vehicle.fullyDeployed = 1; + //-------------------------------------------------------------------------------- + // z0dd - ZOD, 4/25/02. MPB Teleporter. +// if(isObject(%obj.vehicle.teleporter)) +// { +// %obj.vehicle.teleporter.setThreadDir($ActivateThread, TRUE); +// %obj.vehicle.teleporter.playThread($ActivateThread,"activate"); +// %obj.vehicle.teleporter.playAudio($ActivateSound, StationVehicleAcitvateSound); +// } + //-------------------------------------------------------------------------------- + } + Parent::onEndSequence(%data, %obj, %thread); +} + +function MobileBaseVehicle::checkDeploy(%data, %obj) +{ + %mask = $TypeMasks::VehicleObjectType | $TypeMasks::MoveableObjectType | + $TypeMasks::StaticShapeObjectType | $TypeMasks::ForceFieldObjectType | + $TypeMasks::ItemObjectType | $TypeMasks::PlayerObjectType | + $TypeMasks::TurretObjectType | //$TypeMasks::StaticTSObjectType | + $TypeMasks::InteriorObjectType; + + //%slot 1 = turret %slot 2 = station + %height[1] = 0; + %height[2] = 0; + %radius[1] = 2.4; + %radius[2] = 2.4; + %stationFailed = false; + %turretFailed = false; + + for(%x = 1; %x < 3; %x++) + { + %posXY = getWords(%obj.getSlotTransform(%x), 0, 1); + %posZ = (getWord(%obj.getSlotTransform(%x), 2) + %height[%x]); + InitContainerRadiusSearch(%posXY @ " " @ %posZ, %radius[%x], %mask); + + while ((%objFound = ContainerSearchNext()) != 0) + { + if(%objFound != %obj) + { + if(%x == 1) + %turretFailed = true; + else + %stationFailed = true; + break; + } + } + } + + //If turret, station or both fail the send back the error message... + if(%turretFailed && %stationFailed) + return "Both Turret and Station are blocked and unable to deploy."; + if(%turretFailed) + return "Turret is blocked and unable to deploy."; + if(%stationFailed) + return "Station is blocked and unable to deploy."; + + //Check the station for collision with the Terrain + %mat = %obj.getTransform(); + for(%x = 1; %x < 7; %x+=2) + { + %startPos = MatrixMulPoint(%mat, %data.stationPoints[%x]); + %endPos = MatrixMulPoint(%mat, %data.stationPoints[%x+1]); + + %rayCastObj = containerRayCast(%startPos, %endPos, $TypeMasks::TerrainObjectType, 0); + if(%rayCastObj) + return "Station is blocked by terrain and unable to deploy."; + } + + return ""; +} +function MobileBaseVehicle::checkTurretDistance(%data, %obj) +{ + %pos = getWords(%obj.getTransform(), 0, 2); + InitContainerRadiusSearch(%pos, 20, $TypeMasks::TurretObjectType | $TypeMasks::InteriorObjectType); // z0dd - ZOD, 6/21/02. Allow closer deploy. Was 100 + while ((%objFound = ContainerSearchNext()) != 0) + { + if(%objFound.getType() & $TypeMasks::TurretObjectType) + { + if(%objFound.getDataBlock().ClassName $= "TurretBase") + return "Turret Base is in the area. Unable to deploy."; + } + else + { + %subStr = getSubStr(%objFound.interiorFile, 1, 4); + if(%subStr !$= "rock" && %subStr !$= "spir" && %subStr !$= "misc") + return "Building is in the area. Unable to deploy."; + } + } + return ""; +} + + +//************************************************************** +//* VEHICLE INVENTORY MANAGEMENT +//************************************************************** + +//-------------------------------------------------------------- +// NUMBER OF PURCHASEABLE VEHICLES PER TEAM +//-------------------------------------------------------------- + +$VehicleRespawnTime = 15000; +$Vehiclemax[ScoutVehicle] = 4; +$VehicleMax[AssaultVehicle] = 3; +$VehicleMax[MobileBaseVehicle] = 1; +$VehicleMax[ScoutFlyer] = 4; +$VehicleMax[BomberFlyer] = 2; +$VehicleMax[HAPCFlyer] = 2; + +function vehicleListRemove(%data, %obj) +{ + %blockName = %data.getName(); + for($i = 0; %i < $VehicleMax[%blockName]; %i++) + if($VehicleInField[%obj.team, %blockName, %i] == %obj) + { + $VehicleInField[%obj.team, %blockName, %i] = 0; + $VehicleTotalCount[%obj.team, %blockName]--; + break; + } +} + +function vehicleListAdd(%blockName, %obj) +{ + for($i = 0; %i < $VehicleMax[%blockName]; %i++) + { + if($VehicleInField[%obj.team, %blockName, %i] $= "" || $VehicleInField[%obj.team, %blockName, %i] == 0) + { + $VehicleInField[%obj.team, %blockName, %i] = %obj; + $VehicleTotalCount[%obj.team, %blockName]++; + break; + } + } +} + +function clearVehicleCount(%team) +{ + $VehicleTotalCount[%team, ScoutVehicle] = 0; + $VehicleTotalCount[%team, AssaultVehicle] = 0; + $VehicleTotalCount[%team, MobileBaseVehicle] = 0; + $VehicleTotalCount[%team, ScoutFlyer] = 0; + $VehicleTotalCount[%team, BomberFlyer] = 0; + $VehicleTotalCount[%team, HAPCFlyer] = 0; +} + +//************************************************************** +//* VEHICLE HUD SEAT INDICATOR LIGHTS +//************************************************************** + +// --------------------------------------------------------- +// z0dd - ZOD, 6/18/02. Get the name of the vehicle node and +// pass to Armor::onMount and Armor::onDismount in player.cs +function findNodeName(%vehicle, %node) +{ + %vName = %vehicle.getDataBlock().getName(); + if(%vName !$= "HAPCFlyer") + { + if(%node == 0) + return 'pilot'; + else if(%node == 1) + return 'gunner'; + else + return 'tailgunner'; + } + else + { + if(%node == 0) + return 'pilot'; + else if(%node == 1) + return 'tailgunner'; + else + return 'passenger'; + } +} + +function findAIEmptySeat(%vehicle, %player) +{ + %dataBlock = %vehicle.getDataBlock(); + if (%dataBlock.getName() $= "BomberFlyer") + %num = 2; + else + %num = 1; + %node = -1; + for(%i = %num; %i < %dataBlock.numMountPoints; %i++) + { + if (!%vehicle.getMountNodeObject(%i)) + { + //cheap hack - for now, AI's will mount the next available node regardless of where they collided + %node = %i; + break; + } + } + + //return the empty seat + return %node; +} + +function findEmptySeat(%vehicle, %player, %forceNode) +{ + %minNode = 1; + %node = -1; + %dataBlock = %vehicle.getDataBlock(); + %dis = %dataBlock.minMountDist; + %playerPos = getWords(%player.getTransform(), 0, 2); + %message = ""; + if(%dataBlock.lightOnly) + { + if(%player.client.armor $= "Light") + %minNode = 0; + else + %message = '\c2Only Scout Armors can pilot this vehicle.~wfx/misc/misc.error.wav'; + } + else if(%player.client.armor $= "Light" || %player.client.armor $= "Medium") + %minNode = 0; + else + %minNode = findFirstHeavyNode(%dataBlock); + + if(%forceNode !$= "") + %node = %forceNode; + else + { + for(%i = 0; %i < %dataBlock.numMountPoints; %i++) + if(!%vehicle.getMountNodeObject(%i)) + { + %seatPos = getWords(%vehicle.getSlotTransform(%i), 0, 2); + %disTemp = VectorLen(VectorSub(%seatPos, %playerPos)); + if(%disTemp <= %dis) + { + %node = %i; + %dis = %disTemp; + } + } + } + if(%node != -1 && %node < %minNode) + { + if(%message $= "") + { + if(%node == 0) + %message = '\c2Only Scout or Assault Armors can pilot this vehicle.~wfx/misc/misc.error.wav'; + else + %message = '\c2Only Scout or Assault Armors can use that position.~wfx/misc/misc.error.wav'; + } + + if(!%player.noSitMessage) + { + %player.noSitMessage = true; + %player.schedule(2000, "resetSitMessage"); + messageClient(%player.client, 'MsgArmorCantMountVehicle', %message); + } + %node = -1; + } + return %node; +} + +function findFirstHeavyNode(%data) +{ + for(%i = 0; %i < %data.numMountPoints; %i++) + if(%data.mountPose[%i] $= "") + return %i; + return %data.numMountPoints; +} + +//************************************************************** +//* DAMAGE FUNCTIONS +//************************************************************** + +function VehicleData::damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType, %momVec, %theClient, %proj) +{ + if(%proj !$= "") + { + if(%amount > 0 && %targetObject.lastDamageProj !$= %proj) + { + %targetObject.lastDamageProj = %proj; + %targetObject.lastDamageAmount = %amount; + } + else if(%targetObject.lastDamageAmount < %amount) + %amount = %amount - %targetObject.lastDamageAmount; + else + return; + } + + // check for team damage + %sourceClient = %sourceObject ? %sourceObject.getOwnerClient() : 0; + %targetTeam = getTargetSensorGroup(%targetObject.getTarget()); + + if(%sourceClient) + %sourceTeam = %sourceClient.getSensorGroup(); + else if(isObject(%sourceObject) && %sourceObject.getClassName() $= "Turret") + { + %sourceTeam = getTargetSensorGroup(%sourceObject.getTarget()); + %sourceClient = %sourceObject.getControllingClient(); // z0dd - ZOD, 6/10/02. Play a sound to client when they hit a vehicle with a controlled turret + } + else + { + %sourceTeam = %sourceObject ? getTargetSensorGroup(%sourceObject.getTarget()) : -1; + // Client is allready defined and this spams console - ZOD + //%sourceClient = %sourceObject.getControllingClient(); // z0dd - ZOD, 6/10/02. Play a sound to client when they hit a vehicle from a vehicle + } + + // vehicles no longer obey team damage -JR +// if(!$teamDamage && (%targetTeam == %sourceTeam) && %targetObject.getDamagePercent() > 0.5) +// return; + //but we do want to track the destroyer + if(%sourceObject) + { + %targetObject.lastDamagedBy = %sourceObject; + %targetObject.lastDamageType = %damageType; + } + else + %targetObject.lastDamagedBy = 0; + + // ---------------------------------------------------------------------------------- + // z0dd - ZOD, 6/10/02. Play a sound to client when they hit a vehicle + if(%sourceClient && %sourceClient.vehicleHitSound) + { + if(%targetTeam != %sourceTeam) + { + if ((%damageType > 0 && %damageType < 11) || + (%damageType == 13) || + (%damageType > 15 && %damageType < 24) || + (%damageType > 25 && %damageType < 32)) + { + messageClient(%sourceClient, 'MsgClientHit', %sourceClient.vehicleHitWav); + } + } + } + // ---------------------------------------------------------------------------------- + + // Scale damage type & include shield calculations... + if (%data.isShielded) + %amount = %data.checkShields(%targetObject, %position, %amount, %damageType); + + + %damageScale = %data.damageScale[%damageType]; + if(%damageScale !$= "") + %amount *= %damageScale; + + if(%amount != 0) + %targetObject.applyDamage(%amount); + + if(%targetObject.getDamageState() $= "Destroyed" ) + { + if( %momVec !$= "") + %targetObject.setMomentumVector(%momVec); + } +} + +function VehicleData::onImpact(%data, %vehicleObject, %collidedObject, %vec, %vecLen) +{ + if(%vecLen > %data.minImpactSpeed) + %data.damageObject(%vehicleObject, 0, VectorAdd(%vec, %vehicleObject.getPosition()), + %vecLen * %data.speedDamageScale, $DamageType::Ground); + + // associated "crash" sounds + if(%vecLen > %vDataBlock.hardImpactSpeed) + %vehicleObject.playAudio(0, %vDataBlock.hardImpactSound); + else if(%vecLen > %vDataBlock.softImpactSpeed) + %vehicleObject.playAudio(0, %vDataBlock.softImpactSound); +} + +//************************************************************** +//* VEHICLE TIMEOUTS +//************************************************************** + +function vehicleAbandonTimeOut(%vehicle) +{ + if(%vehicle.getDatablock().cantAbandon $= "" && %vehicle.lastPilot $= "") + { + for(%i = 0; %i < %vehicle.getDatablock().numMountPoints; %i++) + if (%vehicle.getMountNodeObject(%i)) + { + %passenger = %vehicle.getMountNodeObject(%i); + if(%passenger.lastVehicle !$= "") + schedule(15000, %passenger.lastVehicle,"vehicleAbandonTimeOut", %passenger.lastVehicle); + %passenger.lastVehicle = %vehicle; + %vehicle.lastPilot = %passenger; + return; + } + + if(%vehicle.respawnTime !$= "") + %vehicle.marker.schedule = %vehicle.marker.data.schedule(%vehicle.respawnTime, "respawn", %vehicle.marker); + %vehicle.mountable = 0; + %vehicle.startFade(1000, 0, true); + %vehicle.schedule(1001, "delete"); + } +} + +//------------------------------------------------------------------------------ +function HoverVehicleData::create(%block, %team, %oldObj) +{ + if(%oldObj $= "") + { + %obj = new HoverVehicle() + { + dataBlock = %block; + respawn = "0"; + teamBought = %team; + team = %team; + }; + } + else + { + %obj = new HoverVehicle() + { + dataBlock = %data; + respawn = "0"; + teamBought = %team; + team = %team; + mountable = %oldObj.mountable; + disableMove = %oldObj.disableMove; + resetPos = %oldObj.resetPos; + respawnTime = %oldObj.respawnTime; + marker = %oldObj; + }; + } + return(%obj); +} + +function WheeledVehicleData::create(%data, %team, %oldObj) +{ + if(%oldObj $= "") + { + %obj = new WheeledVehicle() + { + dataBlock = %data; + respawn = "0"; + teamBought = %team; + team = %team; + }; + } + else + { + %obj = new WheeledVehicle() + { + dataBlock = %data; + respawn = "0"; + teamBought = %team; + team = %team; + mountable = %oldObj.mountable; + disableMove = %oldObj.disableMove; + resetPos = %oldObj.resetPos; + deployed = %oldObj.deployed; + respawnTime = %oldObj.respawnTime; + marker = %oldObj; + }; + } + + return(%obj); +} + +function FlyingVehicleData::create(%data, %team, %oldObj) +{ + if(%oldObj $= "") + { + %obj = new FlyingVehicle() + { + dataBlock = %data; + respawn = "0"; + teamBought = %team; + team = %team; + }; + } + else + { + %obj = new FlyingVehicle() + { + dataBlock = %data; + teamBought = %team; + team = %team; + mountable = %oldObj.mountable; + disableMove = %oldObj.disableMove; + resetPos = %oldObj.resetPos; + respawnTime = %oldObj.respawnTime; + marker = %oldObj; + }; + } + + return(%obj); +} + +function FlyingVehicleData::switchSidesSetPos(%data, %oldObj) +{ + %team = %oldObj.curTeam == 1 ? 2 : 1; + %oldObj.curTeam = %team; + %obj = new FlyingVehicle() + { + dataBlock = %data; + teamBought = %team; + team = %team; + mountable = %oldObj.mountable; + disableMove = %oldObj.disableMove; + resetPos = %oldObj.resetPos; + respawnTime = %oldObj.respawnTime; + marker = %oldObj; + }; + %obj.setTransform(%oldObj.getTransform()); + + return(%obj); +} + +function WheeledVehicleData::switchSidesSetPos(%data, %oldObj) +{ + %team = %oldObj.curTeam == 1 ? 2 : 1; + %oldObj.curTeam = %team; + %obj = new WheeledVehicle() + { + dataBlock = %data; + respawn = "0"; + teamBought = %team; + team = %team; + mountable = %oldObj.mountable; + disableMove = %oldObj.disableMove; + resetPos = %oldObj.resetPos; + deployed = %oldObj.deployed; + respawnTime = %oldObj.respawnTime; + marker = %oldObj; + }; + %obj.setTransform(%oldObj.getTransform()); + return(%obj); +} + +function HoverVehicleData::switchSides(%data, %oldObj) +{ + %team = %oldObj.curTeam == 1 ? 2 : 1; + %oldObj.curTeam = %team; + %obj = new HoverVehicle() + { + dataBlock = %data; + respawn = "0"; + teamBought = %team; + team = %team; + mountable = %oldObj.mountable; + disableMove = %oldObj.disableMove; + resetPos = %oldObj.resetPos; + respawnTime = %oldObj.respawnTime; + marker = %oldObj; + }; + %obj.setTransform(%oldObj.getTransform()); + return(%obj); +} + +function resetNonStaticObjPositions() +{ + MissionGroup.setupPositionMarkers(false); + MissionCleanup.positionReset(); +} + +function next(%team) +{ + ResetObjsPositions(%team); +} + +function SimGroup::positionReset(%group) +{ + for(%i = %group.getCount() - 1; %i >=0 ; %i--) + { + %obj = %group.getObject(%i); + if(%obj.resetPos && %obj.getName() !$= PosMarker) + %obj.delete(); + else + %obj.positionReset(); + } + + for(%i = 0; %i < %group.getCount(); %i++) + { + %obj = %group.getObject(%i); + if(%obj.getName() $= PosMarker) + { + cancel(%obj.schedule); + %newObj = %obj.data.switchSidesSetPos(%obj); + MissionCleanup.add(%newObj); + setTargetSensorGroup(%newObj.target, %newObj.team); + } + else + %obj.positionReset(); + } +} + +function VehicleData::respawn(%data, %marker) +{ + %mask = $TypeMasks::PlayerObjectType | $TypeMasks::VehicleObjectType | $TypeMasks::TurretObjectType; + InitContainerRadiusSearch(%marker.getWorldBoxCenter(), %data.checkRadius, %mask); + if(containerSearchNext() == 0) + { + %newObj = %data.create(%marker.curTeam, %marker); + %newObj.startFade(1000, 0, false); + %newObj.setTransform(%marker.getTransform()); + + setTargetSensorGroup(%newObj.target, %newObj.team); + MissionCleanup.add(%newObj); + } + else + { + %marker.schedule = %data.schedule(3000, "respawn", %marker); + } +} + +function SimObject::positionReset(%group, %team) +{ + //Used to avoid warnings +} + +function Terraformer::positionReset(%group, %team) +{ + //Used to avoid warnings +} + +function SimGroup::setupPositionMarkers(%group, %create) +{ + for(%i = %group.getCount() - 1; %i >= 0; %i--) + { + %obj = %group.getObject(%i); + if(%obj.resetPos || %obj.respawnTime !$= "") + { + if(%create) + { + %marker = %obj.getDataBlock().createPositionMarker(%obj); + MissionCleanup.add(%marker); + %obj.marker = %marker; + } + else + { + %obj.delete(); + } + } + else + %obj.setupPositionMarkers(%create); + } +} + +function SimObject::setupPositionMarkers(%group, %create) +{ + //Used to avoid warnings +} + +function VehicleData::createPositionMarker(%data, %obj) +{ + %marker = new Trigger(PosMarker) + { + dataBlock = markerTrigger; + mountable = %obj.mountable; + disableMove = %obj.disableMove; + resetPos = %obj.resetPos; + data = %obj.getDataBlock().getName(); + deployed = %obj.deployed; + curTeam = %obj.team; + respawnTime = %obj.respawnTime; + }; + %marker.setTransform(%obj.getTransform()); + return %marker; +} + +function VehicleData::hasDismountOverrides(%data, %obj) +{ + return false; +} + diff --git a/scripts/vehicles/vehicle_bomber.cs b/scripts/vehicles/vehicle_bomber.cs index 1c1c3bd..493c51e 100644 --- a/scripts/vehicles/vehicle_bomber.cs +++ b/scripts/vehicles/vehicle_bomber.cs @@ -1,972 +1,972 @@ -//************************************************************** -// THUNDERSWORD BOMBER -//************************************************************** -//************************************************************** -// SOUNDS -//************************************************************** -datablock EffectProfile(BomberFlyerEngineEffect) -{ - effectname = "vehicles/bomber_engine"; - minDistance = 5.0; - maxDistance = 10.0; -}; - -datablock EffectProfile(BomberFlyerThrustEffect) -{ - effectname = "vehicles/bomber_boost"; - minDistance = 5.0; - maxDistance = 10.0; -}; - -datablock EffectProfile(BomberTurretFireEffect) -{ - effectname = "vehicles/bomber_turret_fire"; - minDistance = 5.0; - maxDistance = 10.0; -}; - -datablock EffectProfile(BomberTurretActivateEffect) -{ - effectname = "vehicles/bomber_turret_activate"; - minDistance = 5.0; - maxDistance = 10.0; -}; - -datablock EffectProfile(BomberTurretReloadEffect) -{ - effectname = "vehicles/bomber_turret_reload"; - minDistance = 5.0; - maxDistance = 10.0; -}; - -datablock EffectProfile(BomberTurretDryFireEffect) -{ - effectname = "vehicles/bomber_turret_dryfire"; - minDistance = 5.0; - maxDistance = 10.0; -}; - -datablock EffectProfile(BomberBombReloadEffect) -{ - effectname = "vehicles/bomber_bomb_reload"; - minDistance = 5.0; - maxDistance = 10.0; -}; - -datablock EffectProfile(BomberBombDryFireEffect) -{ - effectname = "vehicles/bomber_bomb_dryfire"; - minDistance = 5.0; - maxDistance = 10.0; -}; - -datablock EffectProfile(BomberBombFireEffect) -{ - effectname = "weapons/generic_throw"; - minDistance = 10.0; - maxDistance = 20.0; -}; - -datablock AudioProfile(BomberFlyerEngineSound) -{ - filename = "fx/vehicles/bomber_engine.wav"; - description = AudioDefaultLooping3d; - preload = true; - effect = BomberFlyerEngineEffect; -}; - -datablock AudioProfile(BomberFlyerThrustSound) -{ - filename = "fx/vehicles/bomber_boost.wav"; - description = AudioDefaultLooping3d; - preload = true; - effect = BomberFlyerThrustEffect; -}; - -datablock AudioProfile(FusionExpSound) -// Sound played when mortar impacts on target -{ - filename = "fx/powered/turret_mortar_explode.wav"; - description = "AudioBIGExplosion3d"; - preload = true; -}; - -datablock AudioProfile(BomberTurretFireSound) -{ - filename = "fx/vehicles/bomber_turret_fire.wav"; - description = AudioClose3d; - preload = true; - effect = BomberTurretFireEffect; -}; - -datablock AudioProfile(BomberTurretActivateSound) -{ - filename = "fx/vehicles/bomber_turret_activate.wav"; - description = AudioClose3d; - preload = true; - effect = BomberTurretActivateEffect; -}; - -datablock AudioProfile(BomberTurretReloadSound) -{ - filename = "fx/vehicles/bomber_turret_reload.wav"; - description = AudioClose3d; - preload = true; - effect = BomberTurretReloadEffect; -}; - -datablock AudioProfile(BomberTurretIdleSound) -{ - filename = "fx/misc/diagnostic_on.wav"; - description = ClosestLooping3d; - preload = true; -}; - -datablock AudioProfile(BomberTurretDryFireSound) -{ - filename = "fx/vehicles/bomber_turret_dryfire.wav"; - description = AudioClose3d; - preload = true; - effect = BomberTurretDryFireEffect; -}; - -datablock AudioProfile(BomberBombReloadSound) -{ - filename = "fx/vehicles/bomber_bomb_reload.wav"; - description = AudioClose3d; - preload = true; - effect = BomberBombReloadEffect; -}; - -datablock AudioProfile(BomberBombProjectileSound) -{ - filename = "fx/vehicles/bomber_bomb_projectile.wav"; - description = AudioDefaultLooping3d; - preload = true; - effect = BomberBombFireEffect; -}; - -datablock AudioProfile(BomberBombDryFireSound) -{ - filename = "fx/vehicles/bomber_bomb_dryfire.wav"; - description = AudioClose3d; - preload = true; - effect = BomberBombDryFireEffect; -}; - -datablock AudioProfile(BomberBombFireSound) -{ - filename = "fx/vehicles/bomber_bomb_reload.wav"; - description = AudioClose3d; - preload = true; - effect = BomberBombFireEffect; -}; - -datablock AudioProfile(BomberBombIdleSound) -{ - filename = "fx/misc/diagnostic_on.wav"; - description = ClosestLooping3d; - preload = true; -}; - -//************************************************************** -// VEHICLE CHARACTERISTICS -//************************************************************** - -datablock FlyingVehicleData(BomberFlyer) : BomberDamageProfile -{ - spawnOffset = "0 0 2"; - - catagory = "Vehicles"; - shapeFile = "vehicle_air_bomber.dts"; - multipassenger = true; - computeCRC = true; - - weaponNode = 1; - - debrisShapeName = "vehicle_air_bomber_debris.dts"; - debris = ShapeDebris; - renderWhenDestroyed = false; - - drag = 0.2; - density = 1.0; - - mountPose[0] = sitting; - mountPose[1] = sitting; - numMountPoints = 3; - isProtectedMountPoint[0] = true; - isProtectedMountPoint[1] = true; - isProtectedMountPoint[2] = true; - - cameraDefaultFov = 90.0; - cameraMinFov = 5.0; - cameraMaxFov = 120.0; - - cameraMaxDist = 22; - cameraOffset = 5; - cameraLag = 1.0; - explosion = LargeAirVehicleExplosion; - explosionDamage = 0.5; - explosionRadius = 5.0; - - maxDamage = 2.80; - destroyedLevel = 2.80; - - isShielded = true; - energyPerDamagePoint = 150; - maxEnergy = 400; // Afterburner and any energy weapon pool - minDrag = 60; // Linear Drag (eventually slows you down when not thrusting...constant drag) - rotationalDrag = 1800; // Angular Drag (dampens the drift after you stop moving the mouse...also tumble drag) - rechargeRate = 0.8; - - // Auto stabilize speed - maxAutoSpeed = 15; // Autostabilizer kicks in when less than this speed. (meters/second) - autoAngularForce = 1500; // Angular stabilizer force (this force levels you out when autostabilizer kicks in) - autoLinearForce = 300; // Linear stabilzer force (this slows you down when autostabilizer kicks in) - autoInputDamping = 0.95; // Dampen control input so you don't whack out at very slow speeds - - // Maneuvering - maxSteeringAngle = 5; // Max radiens you can rotate the wheel. Smaller number is more maneuverable. - horizontalSurfaceForce = 5; // Horizontal center "wing" (provides "bite" into the wind for climbing/diving and turning) - verticalSurfaceForce = 8; // Vertical center "wing" (controls side slip. lower numbers make MORE slide.) - maneuveringForce = 4725; // Horizontal jets (W,S,D,A key thrust) // z0dd - ZOD, 9/8/02. Was 4700 - steeringForce = 1100; // Steering jets (force applied when you move the mouse) - steeringRollForce = 300; // Steering jets (how much you heel over when you turn) - rollForce = 8; // Auto-roll (self-correction to right you after you roll/invert) - hoverHeight = 5; // Height off the ground at rest - createHoverHeight = 3; // Height off the ground when created - maxForwardSpeed = 87; // speed in which forward thrust force is no longer applied (meters/second) // z0dd - ZOD, 9/8/02. Was 85 - - // Turbo Jet - jetForce = 3100; // Afterburner thrust (this is in addition to normal thrust) // z0dd - ZOD, 9/8/02. Was 3000 - minJetEnergy = 40.0; // Afterburner can't be used if below this threshhold. - jetEnergyDrain = 3.0; // Energy use of the afterburners (low number is less drain...can be fractional) - vertThrustMultiple = 3.5; // z0dd - ZOD, 9/8/02. Was 3.0 - - dustEmitter = LargeVehicleLiftoffDustEmitter; - triggerDustHeight = 4.0; - dustHeight = 2.0; - - damageEmitter[0] = LightDamageSmoke; - damageEmitter[1] = HeavyDamageSmoke; - damageEmitter[2] = DamageBubbles; - damageEmitterOffset[0] = "3.0 -3.0 0.0 "; - damageEmitterOffset[1] = "-3.0 -3.0 0.0 "; - damageLevelTolerance[0] = 0.3; - damageLevelTolerance[1] = 0.7; - numDmgEmitterAreas = 2; - - // Rigid body - mass = 350; // Mass of the vehicle - bodyFriction = 0; // Don't mess with this. - bodyRestitution = 0.5; // When you hit the ground, how much you rebound. (between 0 and 1) - minRollSpeed = 0; // Don't mess with this. - softImpactSpeed = 20; // Sound hooks. This is the soft hit. - hardImpactSpeed = 25; // Sound hooks. This is the hard hit. - - // Ground Impact Damage (uses DamageType::Ground) - minImpactSpeed = 20; // If hit ground at speed above this then it's an impact. Meters/second - speedDamageScale = 0.060; - - // Object Impact Damage (uses DamageType::Impact) - collDamageThresholdVel = 25; - collDamageMultiplier = 0.020; - - // - minTrailSpeed = 15; // The speed your contrail shows up at. - trailEmitter = ContrailEmitter; - forwardJetEmitter = FlyerJetEmitter; - downJetEmitter = FlyerJetEmitter; - - // - jetSound = BomberFlyerThrustSound; - engineSound = BomberFlyerEngineSound; - softImpactSound = SoftImpactSound; - hardImpactSound = HardImpactSound; - //wheelImpactSound = WheelImpactSound; - - // - softSplashSoundVelocity = 15.0; - mediumSplashSoundVelocity = 20.0; - hardSplashSoundVelocity = 30.0; - exitSplashSoundVelocity = 10.0; - - exitingWater = VehicleExitWaterHardSound; - impactWaterEasy = VehicleImpactWaterSoftSound; - impactWaterMedium = VehicleImpactWaterMediumSound; - impactWaterHard = VehicleImpactWaterHardSound; - waterWakeSound = VehicleWakeHardSplashSound; - - minMountDist = 4; - - splashEmitter[0] = VehicleFoamDropletsEmitter; - splashEmitter[1] = VehicleFoamEmitter; - - shieldImpact = VehicleShieldImpact; - - cmdCategory = "Tactical"; - cmdIcon = CMDFlyingBomberIcon; - cmdMiniIconName = "commander/MiniIcons/com_bomber_grey"; - targetNameTag = 'Thundersword'; - targetTypeTag = 'Bomber'; - sensorData = VehiclePulseSensor; - sensorRadius = VehiclePulseSensor.detectRadius; // z0dd - ZOD, 4/25/02. Allows sensor to be shown on CC - - checkRadius = 7.1895; - observeParameters = "1 10 10"; - shieldEffectScale = "0.75 0.975 0.375"; - showPilotInfo = 1; -}; - -//************************************************************** -// WEAPONS -//************************************************************** - -//------------------------------------- -// BOMBER BELLY TURRET GUN (projectile) -//------------------------------------- - -datablock ShockwaveData(BomberFusionShockwave) -{ - width = 0.5; - numSegments = 13; - numVertSegments = 1; - velocity = 0.5; - acceleration = 2.0; - lifetimeMS = 900; - height = 0.1; - verticalCurve = 0.5; - - mapToTerrain = false; - renderBottom = false; - orientToNormal = true; - - texture[0] = "special/shockwave5"; - texture[1] = "special/gradient"; - texWrap = 3.0; - - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - - colors[0] = "0.6 0.6 1.0 1.0"; - colors[1] = "0.6 0.3 1.0 0.5"; - colors[2] = "0.0 0.0 1.0 0.0"; -}; - -datablock ParticleData(BomberFusionExplosionParticle1) -{ - dragCoefficient = 2; - gravityCoefficient = 0.0; - inheritedVelFactor = 0.2; - constantAcceleration = -0.0; - lifetimeMS = 600; - lifetimeVarianceMS = 000; - textureName = "special/crescent4"; - colors[0] = "0.6 0.6 1.0 1.0"; - colors[1] = "0.6 0.3 1.0 1.0"; - colors[2] = "0.0 0.0 1.0 0.0"; - sizes[0] = 0.25; - sizes[1] = 0.5; - sizes[2] = 1.0; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData(BomberFusionExplosionEmitter) -{ - ejectionPeriodMS = 7; - periodVarianceMS = 0; - ejectionVelocity = 2; - velocityVariance = 1.5; - ejectionOffset = 0.0; - thetaMin = 80; - thetaMax = 90; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - orientParticles = true; - lifetimeMS = 200; - particles = "BomberFusionExplosionParticle1"; -}; - -datablock ExplosionData(BomberFusionBoltExplosion) -{ - soundProfile = blasterExpSound; - shockwave = BomberFusionShockwave; - emitter[0] = BomberFusionExplosionEmitter; -}; - - -datablock LinearFlareProjectileData(BomberFusionBolt) -{ - projectileShapeName = ""; - directDamage = 0.35; - directDamageType = $DamageType::BellyTurret; - hasDamageRadius = false; - explosion = BomberFusionBoltExplosion; - sound = BlasterProjectileSound; - - dryVelocity = 200.0; - wetVelocity = 200.0; - velInheritFactor = 1.0; - fizzleTimeMS = 2000; - lifetimeMS = 3000; - explodeOnDeath = false; - reflectOnWaterImpactAngle = 0.0; - explodeOnWaterImpact = true; - deflectionOnWaterImpact = 0.0; - fizzleUnderwaterMS = -1; - - activateDelayMS = 100; - - numFlares = 0; - size = 0.15; - flareColor = "0.7 0.3 1.0"; - flareModTexture = "flaremod"; - flareBaseTexture = "flarebase"; -}; - -//------------------------------------- -// BOMBER BELLY TURRET CHARACTERISTICS -//------------------------------------- - -datablock TurretData(BomberTurret) : TurretDamageProfile -{ - className = VehicleTurret; - catagory = "Turrets"; - shapeFile = "turret_belly_base.dts"; - preload = true; - - mass = 1.0; // Not really relevant - repairRate = 0; - maxDamage = BomberFlyer.maxDamage; - destroyedLevel = BomberFlyer.destroyedLevel; - - thetaMin = 90; - thetaMax = 180; - - // capacitor - maxCapacitorEnergy = 250; - capacitorRechargeRate = 0.8; - - inheritEnergyFromMount = true; - firstPersonOnly = true; - useEyePoint = true; - numWeapons = 3; - - targetNameTag = 'Thundersword Belly'; - targetTypeTag = 'Turret'; -}; - -datablock TurretImageData(BomberTurretBarrel) -{ - shapeFile = "turret_belly_barrell.dts"; - mountPoint = 0; - - projectile = BomberFusionBolt; - projectileType = LinearFlareProjectile; - - usesEnergy = true; - useCapacitor = true; - useMountEnergy = true; - fireEnergy = 16.0; - minEnergy = 16.0; - - // Turret parameters - activationMS = 1000; - deactivateDelayMS = 1500; - thinkTimeMS = 200; - degPerSecTheta = 360; - degPerSecPhi = 360; - - attackRadius = 75; - - // State transitions - stateName[0] = "Activate"; - stateTransitionOnTimeout[0] = "WaitFire1"; - stateTimeoutValue[0] = 0.5; - stateSequence[0] = "Activate"; - stateSound[0] = BomberTurretActivateSound; - - stateName[1] = "WaitFire1"; - stateTransitionOnTriggerDown[1] = "Fire1"; - stateTransitionOnNoAmmo[1] = "NoAmmo1"; - - stateName[2] = "Fire1"; - stateTransitionOnTimeout[2] = "Reload1"; - stateTimeoutValue[2] = 0.13; - stateFire[2] = true; - stateRecoil[2] = LightRecoil; - stateAllowImageChange[2] = false; - stateSequence[2] = "Fire"; - stateScript[2] = "onFire"; - stateSound[2] = BomberTurretFireSound; - - stateName[3] = "Reload1"; - stateSequence[3] = "Reload"; - stateTimeoutValue[3] = 0.1; - stateAllowImageChange[3] = false; - stateTransitionOnTimeout[3] = "WaitFire2"; - stateTransitionOnNoAmmo[3] = "NoAmmo1"; - - stateName[4] = "NoAmmo1"; - stateTransitionOnAmmo[4] = "Reload1"; - stateSequence[4] = "NoAmmo1"; // z0dd - ZOD, 5/12/02. Was wrong: NoAmmo - stateTransitionOnTriggerDown[4] = "DryFire1"; - - stateName[5] = "DryFire1"; - stateSound[5] = BomberTurretDryFireSound; - stateTimeoutValue[5] = 0.5; - stateTransitionOnTimeout[5] = "NoAmmo1"; - - stateName[6] = "WaitFire2"; - stateTransitionOnTriggerDown[6] = "Fire2"; - stateTransitionOnNoAmmo[6] = "NoAmmo2"; // z0dd - ZOD, 5/12/02. Was wrong: NoAmmo - - stateName[7] = "Fire2"; - stateTransitionOnTimeout[7] = "Reload2"; - stateTimeoutValue[7] = 0.13; - stateScript[7] = "FirePair"; - - stateName[8] = "Reload2"; - stateSequence[8] = "Reload"; - stateTimeoutValue[8] = 0.1; - stateAllowImageChange[8] = false; - stateTransitionOnTimeout[8] = "WaitFire1"; - stateTransitionOnNoAmmo[8] = "NoAmmo2"; - - stateName[9] = "NoAmmo2"; - stateTransitionOnAmmo[9] = "Reload2"; - stateSequence[9] = "NoAmmo2"; // z0dd - ZOD, 5/12/02. Was wrong: NoAmmo - stateTransitionOnTriggerDown[9] = "DryFire2"; - - stateName[10] = "DryFire2"; - stateSound[10] = BomberTurretDryFireSound; - stateTimeoutValue[10] = 0.5; - stateTransitionOnTimeout[10] = "NoAmmo2"; - -}; - -datablock TurretImageData(BomberTurretBarrelPair) -{ - shapeFile = "turret_belly_barrelr.dts"; - mountPoint = 1; - - projectile = BomberFusionBolt; - projectileType = LinearFlareProjectile; - - usesEnergy = true; - useCapacitor = true; - useMountEnergy = true; - fireEnergy = 16.0; - minEnergy = 16.0; - - // Turret parameters - activationMS = 1000; - deactivateDelayMS = 1500; - thinkTimeMS = 200; - degPerSecTheta = 360; - degPerSecPhi = 360; - - attackRadius = 75; - - stateName[0] = "WaitFire"; - stateTransitionOnTriggerDown[0] = "Fire"; - - stateName[1] = "Fire"; - stateTransitionOnTimeout[1] = "StopFire"; - stateTimeoutValue[1] = 0.13; - stateFire[1] = true; - stateRecoil[1] = LightRecoil; - stateAllowImageChange[1] = false; - stateSequence[1] = "Fire"; - stateScript[1] = "onFire"; - stateSound[1] = BomberTurretFireSound; - - stateName[2] = "StopFire"; - stateTimeoutValue[2] = 0.1; - stateTransitionOnTimeout[2] = "WaitFire"; - stateScript[2] = "stopFire"; -}; - -datablock TurretImageData(AIAimingTurretBarrel) -{ - shapeFile = "turret_muzzlepoint.dts"; - mountPoint = 3; - - projectile = BomberFusionBolt; - - // Turret parameters - activationMS = 1000; - deactivateDelayMS = 1500; - thinkTimeMS = 200; - degPerSecTheta = 500; - degPerSecPhi = 800; - - attackRadius = 75; -}; - -//------------------------------------- -// BOMBER BOMB PROJECTILE -//------------------------------------- - -datablock BombProjectileData(BomberBomb) -{ - projectileShapeName = "bomb.dts"; - emitterDelay = -1; - directDamage = 0.0; - hasDamageRadius = true; - indirectDamage = 1.1; - damageRadius = 30; - radiusDamageType = $DamageType::BomberBombs; - kickBackStrength = 4500; // z0dd - ZOD, 4/25/02. Was 2500 - - explosion = "VehicleBombExplosion"; - velInheritFactor = 1.0; - - grenadeElasticity = 0.25; - grenadeFriction = 0.4; - armingDelayMS = 2000; - muzzleVelocity = 0.1; - drag = 0.3; - gravityMod = 20.0 / mabs($Classic::gravSetting); // z0dd - ZOD, 8/28/02. Compensate for our grav change. Math: base grav / our grav - - minRotSpeed = "60.0 0.0 0.0"; - maxRotSpeed = "80.0 0.0 0.0"; - scale = "1.0 1.0 1.0"; - - sound = BomberBombProjectileSound; -}; - -//------------------------------------- -// BOMBER BOMB CHARACTERISTICS -//------------------------------------- - -datablock ItemData(BombAmmo) -{ - className = Ammo; - catagory = "Ammo"; - shapeFile = "repair_kit.dts"; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 1; - computeCRC = true; -}; - -datablock StaticShapeData(DropBombs) -{ - catagory = "Turrets"; - shapeFile = "bombers_eye.dts"; - maxDamage = 1.0; - disabledLevel = 0.6; - destroyedLevel = 0.8; -}; - -datablock TurretImageData(BomberBombImage) -{ - shapeFile = "turret_muzzlepoint.dts"; - offset = "2 -4 -0.5"; - mountPoint = 10; - - projectile = BomberBomb; - projectileType = BombProjectile; - usesEnergy = true; - useMountEnergy = true; - useCapacitor = true; - - fireEnergy = 53.0; - minEnergy = 53.0; - - - stateName[0] = "Activate"; - stateTransitionOnTimeout[0] = "WaitFire1"; - stateTimeoutValue[0] = 0.5; - stateSequence[0] = "Activate"; - - stateName[1] = "WaitFire1"; - stateTransitionOnTriggerDown[1] = "Fire1"; - stateTransitionOnNoAmmo[1] = "NoAmmo1"; - - stateName[2] = "Fire1"; - stateTransitionOnTimeout[2] = "Reload1"; - stateTimeoutValue[2] = 0.32; - stateFire[2] = true; - stateAllowImageChange[2] = false; - stateSequence[2] = "Fire"; - stateScript[2] = "onFire"; - stateSound[2] = BomberBombFireSound; - - stateName[3] = "Reload1"; - stateSequence[3] = "Reload"; - stateTimeoutValue[3] = 0.1; - stateAllowImageChange[3] = false; - stateTransitionOnTimeout[3] = "WaitFire2"; - stateTransitionOnNoAmmo[3] = "NoAmmo1"; - - stateName[4] = "NoAmmo1"; - stateTransitionOnAmmo[4] = "Reload1"; - stateSequence[4] = "NoAmmo1"; // z0dd - ZOD, 5/12/02. Was wrong: NoAmmo - stateTransitionOnTriggerDown[4] = "DryFire1"; - - stateName[5] = "DryFire1"; - stateSound[5] = BomberBombDryFireSound; - stateTimeoutValue[5] = 0.5; - stateTransitionOnTimeout[5] = "NoAmmo1"; - - stateName[6] = "WaitFire2"; - stateTransitionOnTriggerDown[6] = "Fire2"; - stateTransitionOnNoAmmo[6] = "NoAmmo2"; // z0dd - ZOD, 5/12/02. Was wrong: NoAmmo - - stateName[7] = "Fire2"; - stateTransitionOnTimeout[7] = "Reload2"; - stateTimeoutValue[7] = 0.32; - stateScript[7] = "FirePair"; - - stateName[8] = "Reload2"; - stateSequence[8] = "Reload"; - stateTimeoutValue[8] = 0.1; - stateAllowImageChange[8] = false; - stateTransitionOnTimeout[8] = "WaitFire1"; - stateTransitionOnNoAmmo[8] = "NoAmmo2"; - - stateName[9] = "NoAmmo2"; - stateTransitionOnAmmo[9] = "Reload2"; - stateSequence[9] = "NoAmmo2"; // z0dd - ZOD, 5/12/02. Was wrong: NoAmmo - stateTransitionOnTriggerDown[9] = "DryFire2"; - - stateName[10] = "DryFire2"; - stateSound[10] = BomberBombDryFireSound; - stateTimeoutValue[10] = 0.5; - stateTransitionOnTimeout[10] = "NoAmmo2"; -}; - -datablock TurretImageData(BomberBombPairImage) -{ - shapeFile = "turret_muzzlepoint.dts"; - offset = "-2 -4 -0.5"; - mountPoint = 10; - - projectile = BomberBomb; - projectileType = BombProjectile; - usesEnergy = true; - useMountEnergy = true; - useCapacitor = true; - fireEnergy = 53.0; - minEnergy = 53.0; - - stateName[0] = "WaitFire"; - stateTransitionOnTriggerDown[0] = "Fire"; - - stateName[1] = "Fire"; - stateTransitionOnTimeout[1] = "StopFire"; - stateTimeoutValue[1] = 0.13; - stateFire[1] = true; - stateAllowImageChange[1] = false; - stateSequence[1] = "Fire"; - stateScript[1] = "onFire"; - stateSound[1] = BomberBombFireSound; - - stateName[2] = "StopFire"; - stateTimeoutValue[2] = 0.1; - stateTransitionOnTimeout[2] = "WaitFire"; - stateScript[2] = "stopFire"; - -}; - -//************************************************************** -// WEAPONS SPECIAL EFFECTS -//************************************************************** - -//------------------------------------- -// BOMBER BELLY TURRET GUN (explosion) -//------------------------------------- - -datablock ParticleData(FusionExplosionParticle) -{ - dragCoefficient = 2; - gravityCoefficient = 0.2; - inheritedVelFactor = 0.2; - constantAcceleration = 0.0; - lifetimeMS = 750; - lifetimeVarianceMS = 150; - textureName = "particleTest"; - colors[0] = "0.56 0.36 0.26 1.0"; - colors[1] = "0.56 0.36 0.26 0.0"; - sizes[0] = 1; - sizes[1] = 2; -}; - -datablock ParticleEmitterData(FusionExplosionEmitter) -{ - ejectionPeriodMS = 7; - periodVarianceMS = 0; - ejectionVelocity = 12; - velocityVariance = 1.75; - ejectionOffset = 0.0; - thetaMin = 0; - thetaMax = 60; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - particles = "FusionExplosionParticle"; -}; - -datablock ExplosionData(FusionBoltExplosion) -{ - explosionShape = "effect_plasma_explosion.dts"; - soundProfile = FusionExpSound; - particleEmitter = FusionExplosionEmitter; - particleDensity = 250; - particleRadius = 1.25; - faceViewer = true; -}; - -//-------------------------------------------------------------------------- -// BOMBER TARGETING LASER -//-------------------------------------------------------------------------- - -datablock AudioProfile(BomberTargetingSwitchSound) -{ - filename = "fx/weapons/generic_switch.wav"; - description = AudioClosest3d; - preload = true; -}; - -datablock AudioProfile(BomberTargetingPaintSound) -{ - filename = "fx/weapons/targetinglaser_paint.wav"; - description = CloseLooping3d; - preload = true; -}; - -//-------------------------------------- -// BOMBER TARGETING PROJECTILE -//-------------------------------------- -datablock TargetProjectileData(BomberTargeter) -{ - directDamage = 0.0; - hasDamageRadius = false; - indirectDamage = 0.0; - damageRadius = 0.0; - velInheritFactor = 1.0; - - maxRifleRange = 1000; - beamColor = "0.1 1.0 0.1"; - - startBeamWidth = 0.20; - pulseBeamWidth = 0.15; - beamFlareAngle = 3.0; - minFlareSize = 0.0; - maxFlareSize = 400.0; - pulseSpeed = 6.0; - pulseLength = 0.150; - - textureName[0] = "special/nonlingradient"; - textureName[1] = "special/flare"; - textureName[2] = "special/pulse"; - textureName[3] = "special/expFlare"; -}; - -//------------------------------------- -// BOMBER TARGETING CHARACTERISTICS -//------------------------------------- -datablock ShapeBaseImageData(BomberTargetingImage) -{ - className = WeaponImage; - - shapeFile = "turret_muzzlepoint.dts"; - offset = "0 -0.04 -0.01"; - mountPoint = 2; - - projectile = BomberTargeter; - projectileType = TargetProjectile; - deleteLastProjectile = true; - - usesEnergy = true; - minEnergy = 3; - - stateName[0] = "Activate"; - stateSequence[0] = "Activate"; - stateSound[0] = BomberTargetingSwitchSound; - stateTimeoutValue[0] = 0.5; - stateTransitionOnTimeout[0] = "ActivateReady"; - - stateName[1] = "ActivateReady"; - stateTransitionOnAmmo[1] = "Ready"; - stateTransitionOnNoAmmo[1] = "NoAmmo"; - - stateName[2] = "Ready"; - stateTransitionOnNoAmmo[2] = "NoAmmo"; - stateTransitionOnTriggerDown[2] = "Fire"; - - stateName[3] = "Fire"; - stateEnergyDrain[3] = 3; - stateFire[3] = true; - stateAllowImageChange[3] = false; - stateScript[3] = "onFire"; - stateTransitionOnTriggerUp[3] = "Deconstruction"; - stateTransitionOnNoAmmo[3] = "Deconstruction"; - stateSound[3] = BomberTargetingPaintSound; - - stateName[4] = "NoAmmo"; - stateTransitionOnAmmo[4] = "Ready"; - - stateName[5] = "Deconstruction"; - stateTransitionOnTimeout[5] = "ActivateReady"; - stateTimeoutValue[5] = 0.05; -}; - -function BomberTargetingImage::onFire(%data,%obj,%slot) -{ - %bomber = %obj.getObjectMount(); - if(%bomber.beacon) - { - %bomber.beacon.delete(); - %bomber.beacon = ""; - } - %p = Parent::onFire(%data, %obj, %slot); - %p.setTarget(%obj.team); -} - -function BomberTargetingImage::deconstruct(%data, %obj, %slot) -{ - %pos = %obj.lastProjectile.getTargetPoint(); - %bomber = %obj.getObjectMount(); - - if(%bomber.beacon) - { - %bomber.beacon.delete(); - %bomber.beacon = ""; - } - %bomber.beacon = new BeaconObject() { - dataBlock = "BomberBeacon"; - beaconType = "vehicle"; - position = %pos; - }; - - %bomber.beacon.playThread($AmbientThread, "ambient"); - %bomber.beacon.team = %bomber.team; - %bomber.beacon.sourceObject = %bomber; - - // give it a team target - %bomber.beacon.setTarget(%bomber.team); - MissionCleanup.add(%bomber.beacon); - - Parent::deconstruct(%data, %obj, %slot); -} - -//------------------------------------- -// BOMBER BEACON -//------------------------------------- -datablock StaticShapeData(BomberBeacon) -{ - shapeFile = "turret_muzzlepoint.dts"; - targetNameTag = 'beacon'; - isInvincible = true; - - dynamicType = $TypeMasks::SensorObjectType; -}; - +//************************************************************** +// THUNDERSWORD BOMBER +//************************************************************** +//************************************************************** +// SOUNDS +//************************************************************** +datablock EffectProfile(BomberFlyerEngineEffect) +{ + effectname = "vehicles/bomber_engine"; + minDistance = 5.0; + maxDistance = 10.0; +}; + +datablock EffectProfile(BomberFlyerThrustEffect) +{ + effectname = "vehicles/bomber_boost"; + minDistance = 5.0; + maxDistance = 10.0; +}; + +datablock EffectProfile(BomberTurretFireEffect) +{ + effectname = "vehicles/bomber_turret_fire"; + minDistance = 5.0; + maxDistance = 10.0; +}; + +datablock EffectProfile(BomberTurretActivateEffect) +{ + effectname = "vehicles/bomber_turret_activate"; + minDistance = 5.0; + maxDistance = 10.0; +}; + +datablock EffectProfile(BomberTurretReloadEffect) +{ + effectname = "vehicles/bomber_turret_reload"; + minDistance = 5.0; + maxDistance = 10.0; +}; + +datablock EffectProfile(BomberTurretDryFireEffect) +{ + effectname = "vehicles/bomber_turret_dryfire"; + minDistance = 5.0; + maxDistance = 10.0; +}; + +datablock EffectProfile(BomberBombReloadEffect) +{ + effectname = "vehicles/bomber_bomb_reload"; + minDistance = 5.0; + maxDistance = 10.0; +}; + +datablock EffectProfile(BomberBombDryFireEffect) +{ + effectname = "vehicles/bomber_bomb_dryfire"; + minDistance = 5.0; + maxDistance = 10.0; +}; + +datablock EffectProfile(BomberBombFireEffect) +{ + effectname = "weapons/generic_throw"; + minDistance = 10.0; + maxDistance = 20.0; +}; + +datablock AudioProfile(BomberFlyerEngineSound) +{ + filename = "fx/vehicles/bomber_engine.wav"; + description = AudioDefaultLooping3d; + preload = true; + effect = BomberFlyerEngineEffect; +}; + +datablock AudioProfile(BomberFlyerThrustSound) +{ + filename = "fx/vehicles/bomber_boost.wav"; + description = AudioDefaultLooping3d; + preload = true; + effect = BomberFlyerThrustEffect; +}; + +datablock AudioProfile(FusionExpSound) +// Sound played when mortar impacts on target +{ + filename = "fx/powered/turret_mortar_explode.wav"; + description = "AudioBIGExplosion3d"; + preload = true; +}; + +datablock AudioProfile(BomberTurretFireSound) +{ + filename = "fx/vehicles/bomber_turret_fire.wav"; + description = AudioClose3d; + preload = true; + effect = BomberTurretFireEffect; +}; + +datablock AudioProfile(BomberTurretActivateSound) +{ + filename = "fx/vehicles/bomber_turret_activate.wav"; + description = AudioClose3d; + preload = true; + effect = BomberTurretActivateEffect; +}; + +datablock AudioProfile(BomberTurretReloadSound) +{ + filename = "fx/vehicles/bomber_turret_reload.wav"; + description = AudioClose3d; + preload = true; + effect = BomberTurretReloadEffect; +}; + +datablock AudioProfile(BomberTurretIdleSound) +{ + filename = "fx/misc/diagnostic_on.wav"; + description = ClosestLooping3d; + preload = true; +}; + +datablock AudioProfile(BomberTurretDryFireSound) +{ + filename = "fx/vehicles/bomber_turret_dryfire.wav"; + description = AudioClose3d; + preload = true; + effect = BomberTurretDryFireEffect; +}; + +datablock AudioProfile(BomberBombReloadSound) +{ + filename = "fx/vehicles/bomber_bomb_reload.wav"; + description = AudioClose3d; + preload = true; + effect = BomberBombReloadEffect; +}; + +datablock AudioProfile(BomberBombProjectileSound) +{ + filename = "fx/vehicles/bomber_bomb_projectile.wav"; + description = AudioDefaultLooping3d; + preload = true; + effect = BomberBombFireEffect; +}; + +datablock AudioProfile(BomberBombDryFireSound) +{ + filename = "fx/vehicles/bomber_bomb_dryfire.wav"; + description = AudioClose3d; + preload = true; + effect = BomberBombDryFireEffect; +}; + +datablock AudioProfile(BomberBombFireSound) +{ + filename = "fx/vehicles/bomber_bomb_reload.wav"; + description = AudioClose3d; + preload = true; + effect = BomberBombFireEffect; +}; + +datablock AudioProfile(BomberBombIdleSound) +{ + filename = "fx/misc/diagnostic_on.wav"; + description = ClosestLooping3d; + preload = true; +}; + +//************************************************************** +// VEHICLE CHARACTERISTICS +//************************************************************** + +datablock FlyingVehicleData(BomberFlyer) : BomberDamageProfile +{ + spawnOffset = "0 0 2"; + + catagory = "Vehicles"; + shapeFile = "vehicle_air_bomber.dts"; + multipassenger = true; + computeCRC = true; + + weaponNode = 1; + + debrisShapeName = "vehicle_air_bomber_debris.dts"; + debris = ShapeDebris; + renderWhenDestroyed = false; + + drag = 0.2; + density = 1.0; + + mountPose[0] = sitting; + mountPose[1] = sitting; + numMountPoints = 3; + isProtectedMountPoint[0] = true; + isProtectedMountPoint[1] = true; + isProtectedMountPoint[2] = true; + + cameraDefaultFov = 90.0; + cameraMinFov = 5.0; + cameraMaxFov = 120.0; + + cameraMaxDist = 22; + cameraOffset = 5; + cameraLag = 1.0; + explosion = LargeAirVehicleExplosion; + explosionDamage = 0.5; + explosionRadius = 5.0; + + maxDamage = 2.80; + destroyedLevel = 2.80; + + isShielded = true; + energyPerDamagePoint = 150; + maxEnergy = 400; // Afterburner and any energy weapon pool + minDrag = 60; // Linear Drag (eventually slows you down when not thrusting...constant drag) + rotationalDrag = 1800; // Angular Drag (dampens the drift after you stop moving the mouse...also tumble drag) + rechargeRate = 0.8; + + // Auto stabilize speed + maxAutoSpeed = 15; // Autostabilizer kicks in when less than this speed. (meters/second) + autoAngularForce = 1500; // Angular stabilizer force (this force levels you out when autostabilizer kicks in) + autoLinearForce = 300; // Linear stabilzer force (this slows you down when autostabilizer kicks in) + autoInputDamping = 0.95; // Dampen control input so you don't whack out at very slow speeds + + // Maneuvering + maxSteeringAngle = 5; // Max radiens you can rotate the wheel. Smaller number is more maneuverable. + horizontalSurfaceForce = 5; // Horizontal center "wing" (provides "bite" into the wind for climbing/diving and turning) + verticalSurfaceForce = 8; // Vertical center "wing" (controls side slip. lower numbers make MORE slide.) + maneuveringForce = 4725; // Horizontal jets (W,S,D,A key thrust) // z0dd - ZOD, 9/8/02. Was 4700 + steeringForce = 1100; // Steering jets (force applied when you move the mouse) + steeringRollForce = 300; // Steering jets (how much you heel over when you turn) + rollForce = 8; // Auto-roll (self-correction to right you after you roll/invert) + hoverHeight = 5; // Height off the ground at rest + createHoverHeight = 3; // Height off the ground when created + maxForwardSpeed = 87; // speed in which forward thrust force is no longer applied (meters/second) // z0dd - ZOD, 9/8/02. Was 85 + + // Turbo Jet + jetForce = 3100; // Afterburner thrust (this is in addition to normal thrust) // z0dd - ZOD, 9/8/02. Was 3000 + minJetEnergy = 40.0; // Afterburner can't be used if below this threshhold. + jetEnergyDrain = 3.0; // Energy use of the afterburners (low number is less drain...can be fractional) + vertThrustMultiple = 3.5; // z0dd - ZOD, 9/8/02. Was 3.0 + + dustEmitter = LargeVehicleLiftoffDustEmitter; + triggerDustHeight = 4.0; + dustHeight = 2.0; + + damageEmitter[0] = LightDamageSmoke; + damageEmitter[1] = HeavyDamageSmoke; + damageEmitter[2] = DamageBubbles; + damageEmitterOffset[0] = "3.0 -3.0 0.0 "; + damageEmitterOffset[1] = "-3.0 -3.0 0.0 "; + damageLevelTolerance[0] = 0.3; + damageLevelTolerance[1] = 0.7; + numDmgEmitterAreas = 2; + + // Rigid body + mass = 350; // Mass of the vehicle + bodyFriction = 0; // Don't mess with this. + bodyRestitution = 0.5; // When you hit the ground, how much you rebound. (between 0 and 1) + minRollSpeed = 0; // Don't mess with this. + softImpactSpeed = 20; // Sound hooks. This is the soft hit. + hardImpactSpeed = 25; // Sound hooks. This is the hard hit. + + // Ground Impact Damage (uses DamageType::Ground) + minImpactSpeed = 20; // If hit ground at speed above this then it's an impact. Meters/second + speedDamageScale = 0.060; + + // Object Impact Damage (uses DamageType::Impact) + collDamageThresholdVel = 25; + collDamageMultiplier = 0.020; + + // + minTrailSpeed = 15; // The speed your contrail shows up at. + trailEmitter = ContrailEmitter; + forwardJetEmitter = FlyerJetEmitter; + downJetEmitter = FlyerJetEmitter; + + // + jetSound = BomberFlyerThrustSound; + engineSound = BomberFlyerEngineSound; + softImpactSound = SoftImpactSound; + hardImpactSound = HardImpactSound; + //wheelImpactSound = WheelImpactSound; + + // + softSplashSoundVelocity = 15.0; + mediumSplashSoundVelocity = 20.0; + hardSplashSoundVelocity = 30.0; + exitSplashSoundVelocity = 10.0; + + exitingWater = VehicleExitWaterHardSound; + impactWaterEasy = VehicleImpactWaterSoftSound; + impactWaterMedium = VehicleImpactWaterMediumSound; + impactWaterHard = VehicleImpactWaterHardSound; + waterWakeSound = VehicleWakeHardSplashSound; + + minMountDist = 4; + + splashEmitter[0] = VehicleFoamDropletsEmitter; + splashEmitter[1] = VehicleFoamEmitter; + + shieldImpact = VehicleShieldImpact; + + cmdCategory = "Tactical"; + cmdIcon = CMDFlyingBomberIcon; + cmdMiniIconName = "commander/MiniIcons/com_bomber_grey"; + targetNameTag = 'Thundersword'; + targetTypeTag = 'Bomber'; + sensorData = VehiclePulseSensor; + sensorRadius = VehiclePulseSensor.detectRadius; // z0dd - ZOD, 4/25/02. Allows sensor to be shown on CC + + checkRadius = 7.1895; + observeParameters = "1 10 10"; + shieldEffectScale = "0.75 0.975 0.375"; + showPilotInfo = 1; +}; + +//************************************************************** +// WEAPONS +//************************************************************** + +//------------------------------------- +// BOMBER BELLY TURRET GUN (projectile) +//------------------------------------- + +datablock ShockwaveData(BomberFusionShockwave) +{ + width = 0.5; + numSegments = 13; + numVertSegments = 1; + velocity = 0.5; + acceleration = 2.0; + lifetimeMS = 900; + height = 0.1; + verticalCurve = 0.5; + + mapToTerrain = false; + renderBottom = false; + orientToNormal = true; + + texture[0] = "special/shockwave5"; + texture[1] = "special/gradient"; + texWrap = 3.0; + + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; + + colors[0] = "0.6 0.6 1.0 1.0"; + colors[1] = "0.6 0.3 1.0 0.5"; + colors[2] = "0.0 0.0 1.0 0.0"; +}; + +datablock ParticleData(BomberFusionExplosionParticle1) +{ + dragCoefficient = 2; + gravityCoefficient = 0.0; + inheritedVelFactor = 0.2; + constantAcceleration = -0.0; + lifetimeMS = 600; + lifetimeVarianceMS = 000; + textureName = "special/crescent4"; + colors[0] = "0.6 0.6 1.0 1.0"; + colors[1] = "0.6 0.3 1.0 1.0"; + colors[2] = "0.0 0.0 1.0 0.0"; + sizes[0] = 0.25; + sizes[1] = 0.5; + sizes[2] = 1.0; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; +}; + +datablock ParticleEmitterData(BomberFusionExplosionEmitter) +{ + ejectionPeriodMS = 7; + periodVarianceMS = 0; + ejectionVelocity = 2; + velocityVariance = 1.5; + ejectionOffset = 0.0; + thetaMin = 80; + thetaMax = 90; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + orientParticles = true; + lifetimeMS = 200; + particles = "BomberFusionExplosionParticle1"; +}; + +datablock ExplosionData(BomberFusionBoltExplosion) +{ + soundProfile = blasterExpSound; + shockwave = BomberFusionShockwave; + emitter[0] = BomberFusionExplosionEmitter; +}; + + +datablock LinearFlareProjectileData(BomberFusionBolt) +{ + projectileShapeName = ""; + directDamage = 0.35; + directDamageType = $DamageType::BellyTurret; + hasDamageRadius = false; + explosion = BomberFusionBoltExplosion; + sound = BlasterProjectileSound; + + dryVelocity = 200.0; + wetVelocity = 200.0; + velInheritFactor = 1.0; + fizzleTimeMS = 2000; + lifetimeMS = 3000; + explodeOnDeath = false; + reflectOnWaterImpactAngle = 0.0; + explodeOnWaterImpact = true; + deflectionOnWaterImpact = 0.0; + fizzleUnderwaterMS = -1; + + activateDelayMS = 100; + + numFlares = 0; + size = 0.15; + flareColor = "0.7 0.3 1.0"; + flareModTexture = "flaremod"; + flareBaseTexture = "flarebase"; +}; + +//------------------------------------- +// BOMBER BELLY TURRET CHARACTERISTICS +//------------------------------------- + +datablock TurretData(BomberTurret) : TurretDamageProfile +{ + className = VehicleTurret; + catagory = "Turrets"; + shapeFile = "turret_belly_base.dts"; + preload = true; + + mass = 1.0; // Not really relevant + repairRate = 0; + maxDamage = BomberFlyer.maxDamage; + destroyedLevel = BomberFlyer.destroyedLevel; + + thetaMin = 90; + thetaMax = 180; + + // capacitor + maxCapacitorEnergy = 250; + capacitorRechargeRate = 0.8; + + inheritEnergyFromMount = true; + firstPersonOnly = true; + useEyePoint = true; + numWeapons = 3; + + targetNameTag = 'Thundersword Belly'; + targetTypeTag = 'Turret'; +}; + +datablock TurretImageData(BomberTurretBarrel) +{ + shapeFile = "turret_belly_barrell.dts"; + mountPoint = 0; + + projectile = BomberFusionBolt; + projectileType = LinearFlareProjectile; + + usesEnergy = true; + useCapacitor = true; + useMountEnergy = true; + fireEnergy = 16.0; + minEnergy = 16.0; + + // Turret parameters + activationMS = 1000; + deactivateDelayMS = 1500; + thinkTimeMS = 200; + degPerSecTheta = 360; + degPerSecPhi = 360; + + attackRadius = 75; + + // State transitions + stateName[0] = "Activate"; + stateTransitionOnTimeout[0] = "WaitFire1"; + stateTimeoutValue[0] = 0.5; + stateSequence[0] = "Activate"; + stateSound[0] = BomberTurretActivateSound; + + stateName[1] = "WaitFire1"; + stateTransitionOnTriggerDown[1] = "Fire1"; + stateTransitionOnNoAmmo[1] = "NoAmmo1"; + + stateName[2] = "Fire1"; + stateTransitionOnTimeout[2] = "Reload1"; + stateTimeoutValue[2] = 0.13; + stateFire[2] = true; + stateRecoil[2] = LightRecoil; + stateAllowImageChange[2] = false; + stateSequence[2] = "Fire"; + stateScript[2] = "onFire"; + stateSound[2] = BomberTurretFireSound; + + stateName[3] = "Reload1"; + stateSequence[3] = "Reload"; + stateTimeoutValue[3] = 0.1; + stateAllowImageChange[3] = false; + stateTransitionOnTimeout[3] = "WaitFire2"; + stateTransitionOnNoAmmo[3] = "NoAmmo1"; + + stateName[4] = "NoAmmo1"; + stateTransitionOnAmmo[4] = "Reload1"; + stateSequence[4] = "NoAmmo1"; // z0dd - ZOD, 5/12/02. Was wrong: NoAmmo + stateTransitionOnTriggerDown[4] = "DryFire1"; + + stateName[5] = "DryFire1"; + stateSound[5] = BomberTurretDryFireSound; + stateTimeoutValue[5] = 0.5; + stateTransitionOnTimeout[5] = "NoAmmo1"; + + stateName[6] = "WaitFire2"; + stateTransitionOnTriggerDown[6] = "Fire2"; + stateTransitionOnNoAmmo[6] = "NoAmmo2"; // z0dd - ZOD, 5/12/02. Was wrong: NoAmmo + + stateName[7] = "Fire2"; + stateTransitionOnTimeout[7] = "Reload2"; + stateTimeoutValue[7] = 0.13; + stateScript[7] = "FirePair"; + + stateName[8] = "Reload2"; + stateSequence[8] = "Reload"; + stateTimeoutValue[8] = 0.1; + stateAllowImageChange[8] = false; + stateTransitionOnTimeout[8] = "WaitFire1"; + stateTransitionOnNoAmmo[8] = "NoAmmo2"; + + stateName[9] = "NoAmmo2"; + stateTransitionOnAmmo[9] = "Reload2"; + stateSequence[9] = "NoAmmo2"; // z0dd - ZOD, 5/12/02. Was wrong: NoAmmo + stateTransitionOnTriggerDown[9] = "DryFire2"; + + stateName[10] = "DryFire2"; + stateSound[10] = BomberTurretDryFireSound; + stateTimeoutValue[10] = 0.5; + stateTransitionOnTimeout[10] = "NoAmmo2"; + +}; + +datablock TurretImageData(BomberTurretBarrelPair) +{ + shapeFile = "turret_belly_barrelr.dts"; + mountPoint = 1; + + projectile = BomberFusionBolt; + projectileType = LinearFlareProjectile; + + usesEnergy = true; + useCapacitor = true; + useMountEnergy = true; + fireEnergy = 16.0; + minEnergy = 16.0; + + // Turret parameters + activationMS = 1000; + deactivateDelayMS = 1500; + thinkTimeMS = 200; + degPerSecTheta = 360; + degPerSecPhi = 360; + + attackRadius = 75; + + stateName[0] = "WaitFire"; + stateTransitionOnTriggerDown[0] = "Fire"; + + stateName[1] = "Fire"; + stateTransitionOnTimeout[1] = "StopFire"; + stateTimeoutValue[1] = 0.13; + stateFire[1] = true; + stateRecoil[1] = LightRecoil; + stateAllowImageChange[1] = false; + stateSequence[1] = "Fire"; + stateScript[1] = "onFire"; + stateSound[1] = BomberTurretFireSound; + + stateName[2] = "StopFire"; + stateTimeoutValue[2] = 0.1; + stateTransitionOnTimeout[2] = "WaitFire"; + stateScript[2] = "stopFire"; +}; + +datablock TurretImageData(AIAimingTurretBarrel) +{ + shapeFile = "turret_muzzlepoint.dts"; + mountPoint = 3; + + projectile = BomberFusionBolt; + + // Turret parameters + activationMS = 1000; + deactivateDelayMS = 1500; + thinkTimeMS = 200; + degPerSecTheta = 500; + degPerSecPhi = 800; + + attackRadius = 75; +}; + +//------------------------------------- +// BOMBER BOMB PROJECTILE +//------------------------------------- + +datablock BombProjectileData(BomberBomb) +{ + projectileShapeName = "bomb.dts"; + emitterDelay = -1; + directDamage = 0.0; + hasDamageRadius = true; + indirectDamage = 1.1; + damageRadius = 30; + radiusDamageType = $DamageType::BomberBombs; + kickBackStrength = 4500; // z0dd - ZOD, 4/25/02. Was 2500 + + explosion = "VehicleBombExplosion"; + velInheritFactor = 1.0; + + grenadeElasticity = 0.25; + grenadeFriction = 0.4; + armingDelayMS = 2000; + muzzleVelocity = 0.1; + drag = 0.3; + gravityMod = 20.0 / mabs($Classic::gravSetting); // z0dd - ZOD, 8/28/02. Compensate for our grav change. Math: base grav / our grav + + minRotSpeed = "60.0 0.0 0.0"; + maxRotSpeed = "80.0 0.0 0.0"; + scale = "1.0 1.0 1.0"; + + sound = BomberBombProjectileSound; +}; + +//------------------------------------- +// BOMBER BOMB CHARACTERISTICS +//------------------------------------- + +datablock ItemData(BombAmmo) +{ + className = Ammo; + catagory = "Ammo"; + shapeFile = "repair_kit.dts"; + mass = 1; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 1; + computeCRC = true; +}; + +datablock StaticShapeData(DropBombs) +{ + catagory = "Turrets"; + shapeFile = "bombers_eye.dts"; + maxDamage = 1.0; + disabledLevel = 0.6; + destroyedLevel = 0.8; +}; + +datablock TurretImageData(BomberBombImage) +{ + shapeFile = "turret_muzzlepoint.dts"; + offset = "2 -4 -0.5"; + mountPoint = 10; + + projectile = BomberBomb; + projectileType = BombProjectile; + usesEnergy = true; + useMountEnergy = true; + useCapacitor = true; + + fireEnergy = 53.0; + minEnergy = 53.0; + + + stateName[0] = "Activate"; + stateTransitionOnTimeout[0] = "WaitFire1"; + stateTimeoutValue[0] = 0.5; + stateSequence[0] = "Activate"; + + stateName[1] = "WaitFire1"; + stateTransitionOnTriggerDown[1] = "Fire1"; + stateTransitionOnNoAmmo[1] = "NoAmmo1"; + + stateName[2] = "Fire1"; + stateTransitionOnTimeout[2] = "Reload1"; + stateTimeoutValue[2] = 0.32; + stateFire[2] = true; + stateAllowImageChange[2] = false; + stateSequence[2] = "Fire"; + stateScript[2] = "onFire"; + stateSound[2] = BomberBombFireSound; + + stateName[3] = "Reload1"; + stateSequence[3] = "Reload"; + stateTimeoutValue[3] = 0.1; + stateAllowImageChange[3] = false; + stateTransitionOnTimeout[3] = "WaitFire2"; + stateTransitionOnNoAmmo[3] = "NoAmmo1"; + + stateName[4] = "NoAmmo1"; + stateTransitionOnAmmo[4] = "Reload1"; + stateSequence[4] = "NoAmmo1"; // z0dd - ZOD, 5/12/02. Was wrong: NoAmmo + stateTransitionOnTriggerDown[4] = "DryFire1"; + + stateName[5] = "DryFire1"; + stateSound[5] = BomberBombDryFireSound; + stateTimeoutValue[5] = 0.5; + stateTransitionOnTimeout[5] = "NoAmmo1"; + + stateName[6] = "WaitFire2"; + stateTransitionOnTriggerDown[6] = "Fire2"; + stateTransitionOnNoAmmo[6] = "NoAmmo2"; // z0dd - ZOD, 5/12/02. Was wrong: NoAmmo + + stateName[7] = "Fire2"; + stateTransitionOnTimeout[7] = "Reload2"; + stateTimeoutValue[7] = 0.32; + stateScript[7] = "FirePair"; + + stateName[8] = "Reload2"; + stateSequence[8] = "Reload"; + stateTimeoutValue[8] = 0.1; + stateAllowImageChange[8] = false; + stateTransitionOnTimeout[8] = "WaitFire1"; + stateTransitionOnNoAmmo[8] = "NoAmmo2"; + + stateName[9] = "NoAmmo2"; + stateTransitionOnAmmo[9] = "Reload2"; + stateSequence[9] = "NoAmmo2"; // z0dd - ZOD, 5/12/02. Was wrong: NoAmmo + stateTransitionOnTriggerDown[9] = "DryFire2"; + + stateName[10] = "DryFire2"; + stateSound[10] = BomberBombDryFireSound; + stateTimeoutValue[10] = 0.5; + stateTransitionOnTimeout[10] = "NoAmmo2"; +}; + +datablock TurretImageData(BomberBombPairImage) +{ + shapeFile = "turret_muzzlepoint.dts"; + offset = "-2 -4 -0.5"; + mountPoint = 10; + + projectile = BomberBomb; + projectileType = BombProjectile; + usesEnergy = true; + useMountEnergy = true; + useCapacitor = true; + fireEnergy = 53.0; + minEnergy = 53.0; + + stateName[0] = "WaitFire"; + stateTransitionOnTriggerDown[0] = "Fire"; + + stateName[1] = "Fire"; + stateTransitionOnTimeout[1] = "StopFire"; + stateTimeoutValue[1] = 0.13; + stateFire[1] = true; + stateAllowImageChange[1] = false; + stateSequence[1] = "Fire"; + stateScript[1] = "onFire"; + stateSound[1] = BomberBombFireSound; + + stateName[2] = "StopFire"; + stateTimeoutValue[2] = 0.1; + stateTransitionOnTimeout[2] = "WaitFire"; + stateScript[2] = "stopFire"; + +}; + +//************************************************************** +// WEAPONS SPECIAL EFFECTS +//************************************************************** + +//------------------------------------- +// BOMBER BELLY TURRET GUN (explosion) +//------------------------------------- + +datablock ParticleData(FusionExplosionParticle) +{ + dragCoefficient = 2; + gravityCoefficient = 0.2; + inheritedVelFactor = 0.2; + constantAcceleration = 0.0; + lifetimeMS = 750; + lifetimeVarianceMS = 150; + textureName = "particleTest"; + colors[0] = "0.56 0.36 0.26 1.0"; + colors[1] = "0.56 0.36 0.26 0.0"; + sizes[0] = 1; + sizes[1] = 2; +}; + +datablock ParticleEmitterData(FusionExplosionEmitter) +{ + ejectionPeriodMS = 7; + periodVarianceMS = 0; + ejectionVelocity = 12; + velocityVariance = 1.75; + ejectionOffset = 0.0; + thetaMin = 0; + thetaMax = 60; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + particles = "FusionExplosionParticle"; +}; + +datablock ExplosionData(FusionBoltExplosion) +{ + explosionShape = "effect_plasma_explosion.dts"; + soundProfile = FusionExpSound; + particleEmitter = FusionExplosionEmitter; + particleDensity = 250; + particleRadius = 1.25; + faceViewer = true; +}; + +//-------------------------------------------------------------------------- +// BOMBER TARGETING LASER +//-------------------------------------------------------------------------- + +datablock AudioProfile(BomberTargetingSwitchSound) +{ + filename = "fx/weapons/generic_switch.wav"; + description = AudioClosest3d; + preload = true; +}; + +datablock AudioProfile(BomberTargetingPaintSound) +{ + filename = "fx/weapons/targetinglaser_paint.wav"; + description = CloseLooping3d; + preload = true; +}; + +//-------------------------------------- +// BOMBER TARGETING PROJECTILE +//-------------------------------------- +datablock TargetProjectileData(BomberTargeter) +{ + directDamage = 0.0; + hasDamageRadius = false; + indirectDamage = 0.0; + damageRadius = 0.0; + velInheritFactor = 1.0; + + maxRifleRange = 1000; + beamColor = "0.1 1.0 0.1"; + + startBeamWidth = 0.20; + pulseBeamWidth = 0.15; + beamFlareAngle = 3.0; + minFlareSize = 0.0; + maxFlareSize = 400.0; + pulseSpeed = 6.0; + pulseLength = 0.150; + + textureName[0] = "special/nonlingradient"; + textureName[1] = "special/flare"; + textureName[2] = "special/pulse"; + textureName[3] = "special/expFlare"; +}; + +//------------------------------------- +// BOMBER TARGETING CHARACTERISTICS +//------------------------------------- +datablock ShapeBaseImageData(BomberTargetingImage) +{ + className = WeaponImage; + + shapeFile = "turret_muzzlepoint.dts"; + offset = "0 -0.04 -0.01"; + mountPoint = 2; + + projectile = BomberTargeter; + projectileType = TargetProjectile; + deleteLastProjectile = true; + + usesEnergy = true; + minEnergy = 3; + + stateName[0] = "Activate"; + stateSequence[0] = "Activate"; + stateSound[0] = BomberTargetingSwitchSound; + stateTimeoutValue[0] = 0.5; + stateTransitionOnTimeout[0] = "ActivateReady"; + + stateName[1] = "ActivateReady"; + stateTransitionOnAmmo[1] = "Ready"; + stateTransitionOnNoAmmo[1] = "NoAmmo"; + + stateName[2] = "Ready"; + stateTransitionOnNoAmmo[2] = "NoAmmo"; + stateTransitionOnTriggerDown[2] = "Fire"; + + stateName[3] = "Fire"; + stateEnergyDrain[3] = 3; + stateFire[3] = true; + stateAllowImageChange[3] = false; + stateScript[3] = "onFire"; + stateTransitionOnTriggerUp[3] = "Deconstruction"; + stateTransitionOnNoAmmo[3] = "Deconstruction"; + stateSound[3] = BomberTargetingPaintSound; + + stateName[4] = "NoAmmo"; + stateTransitionOnAmmo[4] = "Ready"; + + stateName[5] = "Deconstruction"; + stateTransitionOnTimeout[5] = "ActivateReady"; + stateTimeoutValue[5] = 0.05; +}; + +function BomberTargetingImage::onFire(%data,%obj,%slot) +{ + %bomber = %obj.getObjectMount(); + if(%bomber.beacon) + { + %bomber.beacon.delete(); + %bomber.beacon = ""; + } + %p = Parent::onFire(%data, %obj, %slot); + %p.setTarget(%obj.team); +} + +function BomberTargetingImage::deconstruct(%data, %obj, %slot) +{ + %pos = %obj.lastProjectile.getTargetPoint(); + %bomber = %obj.getObjectMount(); + + if(%bomber.beacon) + { + %bomber.beacon.delete(); + %bomber.beacon = ""; + } + %bomber.beacon = new BeaconObject() { + dataBlock = "BomberBeacon"; + beaconType = "vehicle"; + position = %pos; + }; + + %bomber.beacon.playThread($AmbientThread, "ambient"); + %bomber.beacon.team = %bomber.team; + %bomber.beacon.sourceObject = %bomber; + + // give it a team target + %bomber.beacon.setTarget(%bomber.team); + MissionCleanup.add(%bomber.beacon); + + Parent::deconstruct(%data, %obj, %slot); +} + +//------------------------------------- +// BOMBER BEACON +//------------------------------------- +datablock StaticShapeData(BomberBeacon) +{ + shapeFile = "turret_muzzlepoint.dts"; + targetNameTag = 'beacon'; + isInvincible = true; + + dynamicType = $TypeMasks::SensorObjectType; +}; + diff --git a/scripts/vehicles/vehicle_havoc.cs b/scripts/vehicles/vehicle_havoc.cs index 7eb9e2a..60b8da6 100644 --- a/scripts/vehicles/vehicle_havoc.cs +++ b/scripts/vehicles/vehicle_havoc.cs @@ -1,227 +1,227 @@ -//************************************************************** -// HAVOC HEAVY TRANSPORT FLIER -//************************************************************** -//************************************************************** -// SOUNDS -//************************************************************** -datablock EffectProfile(HAPCFlyerEngineEffect) -{ - effectname = "vehicles/htransport_thrust"; - minDistance = 5.0; - maxDistance = 10.0; -}; - -datablock EffectProfile(HAPCFlyerThrustEffect) -{ - effectname = "vehicles/htransport_boost"; - minDistance = 5.0; - maxDistance = 10.0; -}; - -datablock AudioProfile(HAPCFlyerEngineSound) -{ - filename = "fx/vehicles/htransport_thrust.wav"; - description = AudioDefaultLooping3d; - effect = HAPCFlyerEngineEffect; -}; - -datablock AudioProfile(HAPCFlyerThrustSound) -{ - filename = "fx/vehicles/htransport_boost.wav"; - description = AudioDefaultLooping3d; - effect = HAPCFlyerThrustEffect; -}; - -//************************************************************** -// VEHICLE CHARACTERISTICS -//************************************************************** - -datablock FlyingVehicleData(HAPCFlyer) : HavocDamageProfile -{ - spawnOffset = "0 0 6"; - renderWhenDestroyed = false; - - catagory = "Vehicles"; - shapeFile = "vehicle_air_hapc.dts"; - multipassenger = true; - computeCRC = true; - - - debrisShapeName = "vehicle_air_hapc_debris.dts"; - debris = ShapeDebris; - - drag = 0.2; - density = 1.0; - - mountPose[0] = sitting; -// mountPose[1] = sitting; - numMountPoints = 6; - isProtectedMountPoint[0] = true; - isProtectedMountPoint[1] = true; - isProtectedMountPoint[2] = true; - isProtectedMountPoint[3] = true; - isProtectedMountPoint[4] = true; - isProtectedMountPoint[5] = true; - - cameraMaxDist = 17; - cameraOffset = 2; - cameraLag = 8.5; - explosion = LargeAirVehicleExplosion; - explosionDamage = 0.5; - explosionRadius = 5.0; - - maxDamage = 3.50; - destroyedLevel = 3.50; - - isShielded = true; - rechargeRate = 1.45; // z0dd - ZOD, 4/16/02. Was 0.8 - energyPerDamagePoint = 150; // z0dd - ZOD, 4/16/02. Was 200 - maxEnergy = 800; // z0dd - ZOD, 4/16/02. Was 550 - minDrag = 100; // Linear Drag - rotationalDrag = 2700; // Anguler Drag - - // Auto stabilize speed - maxAutoSpeed = 10; - autoAngularForce = 3000; // Angular stabilizer force - autoLinearForce = 450; // Linear stabilzer force - autoInputDamping = 0.95; // - - // Maneuvering - maxSteeringAngle = 8; - horizontalSurfaceForce = 10; // Horizontal center "wing" - verticalSurfaceForce = 10; // Vertical center "wing" - maneuveringForce = 6250; // Horizontal jets // z0dd - ZOD, 4/25/02. Was 6000 - steeringForce = 1000; // Steering jets - steeringRollForce = 400; // Steering jets - rollForce = 12; // Auto-roll - hoverHeight = 8; // Height off the ground at rest - createHoverHeight = 6; // Height off the ground when created - maxForwardSpeed = 75; // speed in which forward thrust force is no longer applied (meters/second) z0dd - ZOD, 4/25/02. Was 71 - - // Turbo Jet - jetForce = 5750; // z0dd - ZOD, 4/25/02. Was 5000 - minJetEnergy = 55; - jetEnergyDrain = 4.5; // z0dd - ZOD, 4/16/02. Was 3.6 - vertThrustMultiple = 3.0; - - - dustEmitter = LargeVehicleLiftoffDustEmitter; - triggerDustHeight = 4.0; - dustHeight = 2.0; - - damageEmitter[0] = LightDamageSmoke; - damageEmitter[1] = HeavyDamageSmoke; - damageEmitter[2] = DamageBubbles; - damageEmitterOffset[0] = "3.0 -3.0 0.0 "; - damageEmitterOffset[1] = "-3.0 -3.0 0.0 "; - damageLevelTolerance[0] = 0.3; - damageLevelTolerance[1] = 0.7; - numDmgEmitterAreas = 2; - - // Rigid body - mass = 550; - bodyFriction = 0; - bodyRestitution = 0.3; - minRollSpeed = 0; - softImpactSpeed = 12; // Sound hooks. This is the soft hit. - hardImpactSpeed = 15; // Sound hooks. This is the hard hit. - - // Ground Impact Damage (uses DamageType::Ground) - minImpactSpeed = 25; // If hit ground at speed above this then it's an impact. Meters/second - speedDamageScale = 0.060; - - // Object Impact Damage (uses DamageType::Impact) - collDamageThresholdVel = 28; - collDamageMultiplier = 0.020; - - // - minTrailSpeed = 15; - trailEmitter = ContrailEmitter; - forwardJetEmitter = FlyerJetEmitter; - downJetEmitter = FlyerJetEmitter; - - // - jetSound = HAPCFlyerThrustSound; - engineSound = HAPCFlyerEngineSound; - softImpactSound = SoftImpactSound; - hardImpactSound = HardImpactSound; - //wheelImpactSound = WheelImpactSound; - - // - softSplashSoundVelocity = 5.0; - mediumSplashSoundVelocity = 8.0; - hardSplashSoundVelocity = 12.0; - exitSplashSoundVelocity = 8.0; - - exitingWater = VehicleExitWaterHardSound; - impactWaterEasy = VehicleImpactWaterSoftSound; - impactWaterMedium = VehicleImpactWaterMediumSound; - impactWaterHard = VehicleImpactWaterHardSound; - waterWakeSound = VehicleWakeHardSplashSound; - - minMountDist = 4; - - splashEmitter[0] = VehicleFoamDropletsEmitter; - splashEmitter[1] = VehicleFoamEmitter; - - shieldImpact = VehicleShieldImpact; - - cmdCategory = "Tactical"; - cmdIcon = CMDFlyingHAPCIcon; - cmdMiniIconName = "commander/MiniIcons/com_hapc_grey"; - targetNameTag = 'Havoc'; - targetTypeTag = 'Heavy Transport'; - sensorData = VehiclePulseSensor; - sensorRadius = VehiclePulseSensor.detectRadius; // z0dd - ZOD, 4/25/02. Allows sensor to be shown on CC - - checkRadius = 7.8115; - observeParameters = "1 15 15"; - - stuckTimerTicks = 32; // If the hapc spends more than 1 sec in contact with something - stuckTimerAngle = 80; // with a > 80 deg. pitch, BOOM! - - shieldEffectScale = "1.0 0.9375 0.45"; -}; - -function HAPCFlyer::hasDismountOverrides(%data, %obj) -{ - return true; -} - -function HAPCFlyer::getDismountOverride(%data, %obj, %mounted) -{ - %node = -1; - for (%i = 0; %i < %data.numMountPoints; %i++) - { - if (%obj.getMountNodeObject(%i) == %mounted) - { - %node = %i; - break; - } - } - if (%node == -1) - { - warning("Couldn't find object mount point"); - return "0 0 1"; - } - - if (%node == 3 || %node == 2) - { - return "-1 0 1"; - } - else if (%node == 5 || %node == 4) - { - return "1 0 1"; - } - else - { - return "0 0 1"; - } -} - -//************************************************************** -// WEAPONS -//************************************************************** - - - +//************************************************************** +// HAVOC HEAVY TRANSPORT FLIER +//************************************************************** +//************************************************************** +// SOUNDS +//************************************************************** +datablock EffectProfile(HAPCFlyerEngineEffect) +{ + effectname = "vehicles/htransport_thrust"; + minDistance = 5.0; + maxDistance = 10.0; +}; + +datablock EffectProfile(HAPCFlyerThrustEffect) +{ + effectname = "vehicles/htransport_boost"; + minDistance = 5.0; + maxDistance = 10.0; +}; + +datablock AudioProfile(HAPCFlyerEngineSound) +{ + filename = "fx/vehicles/htransport_thrust.wav"; + description = AudioDefaultLooping3d; + effect = HAPCFlyerEngineEffect; +}; + +datablock AudioProfile(HAPCFlyerThrustSound) +{ + filename = "fx/vehicles/htransport_boost.wav"; + description = AudioDefaultLooping3d; + effect = HAPCFlyerThrustEffect; +}; + +//************************************************************** +// VEHICLE CHARACTERISTICS +//************************************************************** + +datablock FlyingVehicleData(HAPCFlyer) : HavocDamageProfile +{ + spawnOffset = "0 0 6"; + renderWhenDestroyed = false; + + catagory = "Vehicles"; + shapeFile = "vehicle_air_hapc.dts"; + multipassenger = true; + computeCRC = true; + + + debrisShapeName = "vehicle_air_hapc_debris.dts"; + debris = ShapeDebris; + + drag = 0.2; + density = 1.0; + + mountPose[0] = sitting; +// mountPose[1] = sitting; + numMountPoints = 6; + isProtectedMountPoint[0] = true; + isProtectedMountPoint[1] = true; + isProtectedMountPoint[2] = true; + isProtectedMountPoint[3] = true; + isProtectedMountPoint[4] = true; + isProtectedMountPoint[5] = true; + + cameraMaxDist = 17; + cameraOffset = 2; + cameraLag = 8.5; + explosion = LargeAirVehicleExplosion; + explosionDamage = 0.5; + explosionRadius = 5.0; + + maxDamage = 3.50; + destroyedLevel = 3.50; + + isShielded = true; + rechargeRate = 1.45; // z0dd - ZOD, 4/16/02. Was 0.8 + energyPerDamagePoint = 150; // z0dd - ZOD, 4/16/02. Was 200 + maxEnergy = 800; // z0dd - ZOD, 4/16/02. Was 550 + minDrag = 100; // Linear Drag + rotationalDrag = 2700; // Anguler Drag + + // Auto stabilize speed + maxAutoSpeed = 10; + autoAngularForce = 3000; // Angular stabilizer force + autoLinearForce = 450; // Linear stabilzer force + autoInputDamping = 0.95; // + + // Maneuvering + maxSteeringAngle = 8; + horizontalSurfaceForce = 10; // Horizontal center "wing" + verticalSurfaceForce = 10; // Vertical center "wing" + maneuveringForce = 6250; // Horizontal jets // z0dd - ZOD, 4/25/02. Was 6000 + steeringForce = 1000; // Steering jets + steeringRollForce = 400; // Steering jets + rollForce = 12; // Auto-roll + hoverHeight = 8; // Height off the ground at rest + createHoverHeight = 6; // Height off the ground when created + maxForwardSpeed = 75; // speed in which forward thrust force is no longer applied (meters/second) z0dd - ZOD, 4/25/02. Was 71 + + // Turbo Jet + jetForce = 5750; // z0dd - ZOD, 4/25/02. Was 5000 + minJetEnergy = 55; + jetEnergyDrain = 4.5; // z0dd - ZOD, 4/16/02. Was 3.6 + vertThrustMultiple = 3.0; + + + dustEmitter = LargeVehicleLiftoffDustEmitter; + triggerDustHeight = 4.0; + dustHeight = 2.0; + + damageEmitter[0] = LightDamageSmoke; + damageEmitter[1] = HeavyDamageSmoke; + damageEmitter[2] = DamageBubbles; + damageEmitterOffset[0] = "3.0 -3.0 0.0 "; + damageEmitterOffset[1] = "-3.0 -3.0 0.0 "; + damageLevelTolerance[0] = 0.3; + damageLevelTolerance[1] = 0.7; + numDmgEmitterAreas = 2; + + // Rigid body + mass = 550; + bodyFriction = 0; + bodyRestitution = 0.3; + minRollSpeed = 0; + softImpactSpeed = 12; // Sound hooks. This is the soft hit. + hardImpactSpeed = 15; // Sound hooks. This is the hard hit. + + // Ground Impact Damage (uses DamageType::Ground) + minImpactSpeed = 25; // If hit ground at speed above this then it's an impact. Meters/second + speedDamageScale = 0.060; + + // Object Impact Damage (uses DamageType::Impact) + collDamageThresholdVel = 28; + collDamageMultiplier = 0.020; + + // + minTrailSpeed = 15; + trailEmitter = ContrailEmitter; + forwardJetEmitter = FlyerJetEmitter; + downJetEmitter = FlyerJetEmitter; + + // + jetSound = HAPCFlyerThrustSound; + engineSound = HAPCFlyerEngineSound; + softImpactSound = SoftImpactSound; + hardImpactSound = HardImpactSound; + //wheelImpactSound = WheelImpactSound; + + // + softSplashSoundVelocity = 5.0; + mediumSplashSoundVelocity = 8.0; + hardSplashSoundVelocity = 12.0; + exitSplashSoundVelocity = 8.0; + + exitingWater = VehicleExitWaterHardSound; + impactWaterEasy = VehicleImpactWaterSoftSound; + impactWaterMedium = VehicleImpactWaterMediumSound; + impactWaterHard = VehicleImpactWaterHardSound; + waterWakeSound = VehicleWakeHardSplashSound; + + minMountDist = 4; + + splashEmitter[0] = VehicleFoamDropletsEmitter; + splashEmitter[1] = VehicleFoamEmitter; + + shieldImpact = VehicleShieldImpact; + + cmdCategory = "Tactical"; + cmdIcon = CMDFlyingHAPCIcon; + cmdMiniIconName = "commander/MiniIcons/com_hapc_grey"; + targetNameTag = 'Havoc'; + targetTypeTag = 'Heavy Transport'; + sensorData = VehiclePulseSensor; + sensorRadius = VehiclePulseSensor.detectRadius; // z0dd - ZOD, 4/25/02. Allows sensor to be shown on CC + + checkRadius = 7.8115; + observeParameters = "1 15 15"; + + stuckTimerTicks = 32; // If the hapc spends more than 1 sec in contact with something + stuckTimerAngle = 80; // with a > 80 deg. pitch, BOOM! + + shieldEffectScale = "1.0 0.9375 0.45"; +}; + +function HAPCFlyer::hasDismountOverrides(%data, %obj) +{ + return true; +} + +function HAPCFlyer::getDismountOverride(%data, %obj, %mounted) +{ + %node = -1; + for (%i = 0; %i < %data.numMountPoints; %i++) + { + if (%obj.getMountNodeObject(%i) == %mounted) + { + %node = %i; + break; + } + } + if (%node == -1) + { + warning("Couldn't find object mount point"); + return "0 0 1"; + } + + if (%node == 3 || %node == 2) + { + return "-1 0 1"; + } + else if (%node == 5 || %node == 4) + { + return "1 0 1"; + } + else + { + return "0 0 1"; + } +} + +//************************************************************** +// WEAPONS +//************************************************************** + + + diff --git a/scripts/vehicles/vehicle_mpb.cs b/scripts/vehicles/vehicle_mpb.cs index 50248d6..e1ae795 100644 --- a/scripts/vehicles/vehicle_mpb.cs +++ b/scripts/vehicles/vehicle_mpb.cs @@ -1,305 +1,305 @@ -//************************************************************** -// JERICHO FORWARD BASE (Mobile Point Base) -//************************************************************** -//************************************************************** -// SOUNDS -//************************************************************** -datablock EffectProfile(MPBEngineEffect) -{ - effectname = "vehicles/mpb_thrust"; - minDistance = 5.0; - maxDistance = 10.0; -}; - -datablock EffectProfile(MPBThrustEffect) -{ - effectname = "vehicles/mpb_boost"; - minDistance = 5.0; - maxDistance = 10.0; -}; - -datablock AudioProfile(MPBEngineSound) -{ - filename = "fx/vehicles/mpb_thrust.wav"; - description = AudioDefaultLooping3d; - preload = true; - effect = MPBEngineEffect; -}; - -datablock AudioProfile(MPBThrustSound) -{ - filename = "fx/vehicles/mpb_boost.wav"; - description = AudioDefaultLooping3d; - preload = true; - effect = MPBThrustEffect; -}; - -datablock AudioProfile(MobileBaseDeploySound) -{ - filename = "fx/vehicles/MPB_deploy.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(MobileBaseUndeploySound) -{ - filename = "fx/vehicles/MPB_undeploy_turret.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(MobileBaseTurretDeploySound) -{ - filename = "fx/vehicles/MPB_deploy_turret.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(MobileBaseTurretUndeploySound) -{ - filename = "fx/vehicles/MPB_undeploy_turret.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(MobileBaseStationDeploySound) -{ - filename = "fx/vehicles/MPB_deploy_station.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(MobileBaseStationUndeploySound) -{ - filename = "fx/vehicles/MPB_close_lid.wav"; - description = AudioClose3d; - preload = true; -}; - - -//************************************************************** -// LIGHTS -//************************************************************** -datablock RunningLightData(MPBLight1) -{ - pointSize = 3.0; - pointColor = "1.0 1.0 1.0 0.3"; - pointNodeName = "Headlight_node01"; - texture = "special/expFlare"; -}; - -datablock RunningLightData(MPBLight2) -{ - pointSize = 3.0; - pointColor = "1.0 1.0 1.0 0.3"; - pointNodeName = "Headlight_node02"; - texture = "special/expFlare"; -}; - - -//************************************************************** -// VEHICLE CHARACTERISTICS -//************************************************************** -datablock SensorData(MPBDeployedSensor) : VehiclePulseSensor -{ - jams = true; - jamsOnlyGroup = true; - jamsUsingLOS = false; - jamRadius = 50; -}; - -datablock WheeledVehicleData(MobileBaseVehicle) : MPBDamageProfile -{ - spawnOffset = "0 0 1.5"; // z0dd - ZOD, 7/10/02. Change height, 3rd value, from 1.0 to 1.5 to prevent it from being dry docked - renderWhenDestroyed = false; - - catagory = "Vehicles"; - shapeFile = "vehicle_land_mpbase.dts"; - multipassenger = false; - computeCRC = true; - - debrisShapeName = "vehicle_land_mpbase_debris.dts"; - debris = ShapeDebris; - - drag = 0.0; - density = 20.0; - - mountPose[0] = sitting; - numMountPoints = 1; - isProtectedMountPoint[0] = true; - - cantAbandon = 1; - cantTeamSwitch = 1; - - cameraMaxDist = 20; - cameraOffset = 6; - cameraLag = 1.5; - explosion = LargeGroundVehicleExplosion; - explosionDamage = 0.5; - explosionRadius = 5.0; - - maxSteeringAngle = 0.3; // 20 deg. - - // Used to test if the station can deploy - stationPoints[1] = "-2.3 -7.38703 -0.65"; - stationPoints[2] = "-2.3 -11.8 -0.65"; - stationPoints[3] = "0 -7.38703 -0.65"; - stationPoints[4] = "0 -11.8 -0.65"; - stationPoints[5] = "2.3 -7.38703 -0.65"; - stationPoints[6] = "2.3 -11.8 -0.65"; - - // Rigid Body - mass = 2000; - bodyFriction = 0.8; - bodyRestitution = 0.5; - minRollSpeed = 3; - gyroForce = 400; - gyroDamping = 0.3; - stabilizerForce = 10; - minDrag = 10; - softImpactSpeed = 15; // Play SoftImpact Sound - hardImpactSpeed = 25; // Play HardImpact Sound - - // Ground Impact Damage (uses DamageType::Ground) - minImpactSpeed = 12; - speedDamageScale = 0.060; - - // Object Impact Damage (uses DamageType::Impact) - collDamageThresholdVel = 18; - collDamageMultiplier = 0.070; - - // Engine - engineTorque = 7.0 * 745; - breakTorque = 7.0 * 745; - maxWheelSpeed = 20; - - // Springs - springForce = 8000; - springDamping = 1300; - antiSwayForce = 6000; - staticLoadScale = 2; - - // Tires - tireRadius = 1.6; - tireFriction = 10.0; - tireRestitution = 0.5; - tireLateralForce = 3000; - tireLateralDamping = 400; - tireLateralRelaxation = 1; - tireLongitudinalForce = 12000; - tireLongitudinalDamping = 600; - tireLongitudinalRelaxation = 1; - tireEmitter = TireEmitter; - - // - maxDamage = 3.85; - destroyedLevel = 3.85; - - isShielded = true; - energyPerDamagePoint = 125; - maxEnergy = 600; - jetForce = 4000; // z0dd - ZOD, 4/25/02. Was 2800 - minJetEnergy = 60; - jetEnergyDrain = 2.75; - rechargeRate = 1.0; - - jetSound = MPBThrustSound; - engineSound = MPBEngineSound; - squeelSound = AssaultVehicleSkid; - softImpactSound = GravSoftImpactSound; - hardImpactSound = HardImpactSound; - //wheelImpactSound = WheelImpactSound; - - // - softSplashSoundVelocity = 5.0; - mediumSplashSoundVelocity = 8.0; - hardSplashSoundVelocity = 12.0; - exitSplashSoundVelocity = 8.0; - - exitingWater = VehicleExitWaterSoftSound; - impactWaterEasy = VehicleImpactWaterSoftSound; - impactWaterMedium = VehicleImpactWaterMediumSound; - impactWaterHard = VehicleImpactWaterHardSound; - waterWakeSound = VehicleWakeMediumSplashSound; - - minMountDist = 3; - - damageEmitter[0] = LightDamageSmoke; - damageEmitter[1] = HeavyDamageSmoke; - damageEmitter[2] = DamageBubbles; - damageEmitterOffset[0] = "3.0 0.5 0.0 "; - damageEmitterOffset[1] = "-3.0 0.5 0.0 "; - damageLevelTolerance[0] = 0.3; - damageLevelTolerance[1] = 0.7; - numDmgEmitterAreas = 2; - - splashEmitter[0] = VehicleFoamDropletsEmitter; - splashEmitter[1] = VehicleFoamEmitter; - - shieldImpact = VehicleShieldImpact; - - cmdCategory = "Tactical"; - cmdIcon = CMDGroundMPBIcon; - cmdMiniIconName = "commander/MiniIcons/com_mpb_grey"; - targetNameTag = 'Jericho'; - targetTypeTag = 'MPB'; - sensorData = VehiclePulseSensor; - sensorRadius = VehiclePulseSensor.detectRadius; // z0dd - ZOD, 4/25/02. Allows sensor to be shown on CC - - checkRadius = 7.5225; - - observeParameters = "1 12 12"; - - runningLight[0] = MPBLight1; - runningLight[1] = MPBLight2; - - shieldEffectScale = "0.85 1.2 0.7"; -}; - -//************************************************************** -// WEAPONS -//************************************************************** - -datablock SensorData(MPBTurretMissileSensor) -{ - detects = true; - detectsUsingLOS = true; - detectsPassiveJammed = false; - detectsActiveJammed = false; - detectsCloaked = false; - detectionPings = true; - detectRadius = 200; -}; - -datablock TurretData(MobileTurretBase) -{ - className = VehicleTurret; - catagory = "Turrets"; - shapeFile = "turret_base_mpb.dts"; - preload = true; - - mass = 1.0; // Not really relevant - - maxDamage = MobileBaseVehicle.maxDamage; - destroyedLevel = MobileBaseVehicle.destroyedLevel; - - thetaMin = 15; - thetaMax = 140; - - energyPerDamagePoint = 33; - inheritEnergyFromMount = true; - firstPersonOnly = true; - - sensorColor = "0 212 45"; - sensorData = MPBTurretMissileSensor; - sensorRadius = MPBTurretMissileSensor.detectRadius; - cmdCategory = "Tactical"; - cmdMiniIconName = "commander/MiniIcons/com_turret_grey"; - targetNameTag = 'Jericho'; - targetTypeTag = 'Turret'; - - canControl = true; -}; - - - +//************************************************************** +// JERICHO FORWARD BASE (Mobile Point Base) +//************************************************************** +//************************************************************** +// SOUNDS +//************************************************************** +datablock EffectProfile(MPBEngineEffect) +{ + effectname = "vehicles/mpb_thrust"; + minDistance = 5.0; + maxDistance = 10.0; +}; + +datablock EffectProfile(MPBThrustEffect) +{ + effectname = "vehicles/mpb_boost"; + minDistance = 5.0; + maxDistance = 10.0; +}; + +datablock AudioProfile(MPBEngineSound) +{ + filename = "fx/vehicles/mpb_thrust.wav"; + description = AudioDefaultLooping3d; + preload = true; + effect = MPBEngineEffect; +}; + +datablock AudioProfile(MPBThrustSound) +{ + filename = "fx/vehicles/mpb_boost.wav"; + description = AudioDefaultLooping3d; + preload = true; + effect = MPBThrustEffect; +}; + +datablock AudioProfile(MobileBaseDeploySound) +{ + filename = "fx/vehicles/MPB_deploy.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(MobileBaseUndeploySound) +{ + filename = "fx/vehicles/MPB_undeploy_turret.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(MobileBaseTurretDeploySound) +{ + filename = "fx/vehicles/MPB_deploy_turret.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(MobileBaseTurretUndeploySound) +{ + filename = "fx/vehicles/MPB_undeploy_turret.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(MobileBaseStationDeploySound) +{ + filename = "fx/vehicles/MPB_deploy_station.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(MobileBaseStationUndeploySound) +{ + filename = "fx/vehicles/MPB_close_lid.wav"; + description = AudioClose3d; + preload = true; +}; + + +//************************************************************** +// LIGHTS +//************************************************************** +datablock RunningLightData(MPBLight1) +{ + pointSize = 3.0; + pointColor = "1.0 1.0 1.0 0.3"; + pointNodeName = "Headlight_node01"; + texture = "special/expFlare"; +}; + +datablock RunningLightData(MPBLight2) +{ + pointSize = 3.0; + pointColor = "1.0 1.0 1.0 0.3"; + pointNodeName = "Headlight_node02"; + texture = "special/expFlare"; +}; + + +//************************************************************** +// VEHICLE CHARACTERISTICS +//************************************************************** +datablock SensorData(MPBDeployedSensor) : VehiclePulseSensor +{ + jams = true; + jamsOnlyGroup = true; + jamsUsingLOS = false; + jamRadius = 50; +}; + +datablock WheeledVehicleData(MobileBaseVehicle) : MPBDamageProfile +{ + spawnOffset = "0 0 1.5"; // z0dd - ZOD, 7/10/02. Change height, 3rd value, from 1.0 to 1.5 to prevent it from being dry docked + renderWhenDestroyed = false; + + catagory = "Vehicles"; + shapeFile = "vehicle_land_mpbase.dts"; + multipassenger = false; + computeCRC = true; + + debrisShapeName = "vehicle_land_mpbase_debris.dts"; + debris = ShapeDebris; + + drag = 0.0; + density = 20.0; + + mountPose[0] = sitting; + numMountPoints = 1; + isProtectedMountPoint[0] = true; + + cantAbandon = 1; + cantTeamSwitch = 1; + + cameraMaxDist = 20; + cameraOffset = 6; + cameraLag = 1.5; + explosion = LargeGroundVehicleExplosion; + explosionDamage = 0.5; + explosionRadius = 5.0; + + maxSteeringAngle = 0.3; // 20 deg. + + // Used to test if the station can deploy + stationPoints[1] = "-2.3 -7.38703 -0.65"; + stationPoints[2] = "-2.3 -11.8 -0.65"; + stationPoints[3] = "0 -7.38703 -0.65"; + stationPoints[4] = "0 -11.8 -0.65"; + stationPoints[5] = "2.3 -7.38703 -0.65"; + stationPoints[6] = "2.3 -11.8 -0.65"; + + // Rigid Body + mass = 2000; + bodyFriction = 0.8; + bodyRestitution = 0.5; + minRollSpeed = 3; + gyroForce = 400; + gyroDamping = 0.3; + stabilizerForce = 10; + minDrag = 10; + softImpactSpeed = 15; // Play SoftImpact Sound + hardImpactSpeed = 25; // Play HardImpact Sound + + // Ground Impact Damage (uses DamageType::Ground) + minImpactSpeed = 12; + speedDamageScale = 0.060; + + // Object Impact Damage (uses DamageType::Impact) + collDamageThresholdVel = 18; + collDamageMultiplier = 0.070; + + // Engine + engineTorque = 7.0 * 745; + breakTorque = 7.0 * 745; + maxWheelSpeed = 20; + + // Springs + springForce = 8000; + springDamping = 1300; + antiSwayForce = 6000; + staticLoadScale = 2; + + // Tires + tireRadius = 1.6; + tireFriction = 10.0; + tireRestitution = 0.5; + tireLateralForce = 3000; + tireLateralDamping = 400; + tireLateralRelaxation = 1; + tireLongitudinalForce = 12000; + tireLongitudinalDamping = 600; + tireLongitudinalRelaxation = 1; + tireEmitter = TireEmitter; + + // + maxDamage = 3.85; + destroyedLevel = 3.85; + + isShielded = true; + energyPerDamagePoint = 125; + maxEnergy = 600; + jetForce = 4000; // z0dd - ZOD, 4/25/02. Was 2800 + minJetEnergy = 60; + jetEnergyDrain = 2.75; + rechargeRate = 1.0; + + jetSound = MPBThrustSound; + engineSound = MPBEngineSound; + squeelSound = AssaultVehicleSkid; + softImpactSound = GravSoftImpactSound; + hardImpactSound = HardImpactSound; + //wheelImpactSound = WheelImpactSound; + + // + softSplashSoundVelocity = 5.0; + mediumSplashSoundVelocity = 8.0; + hardSplashSoundVelocity = 12.0; + exitSplashSoundVelocity = 8.0; + + exitingWater = VehicleExitWaterSoftSound; + impactWaterEasy = VehicleImpactWaterSoftSound; + impactWaterMedium = VehicleImpactWaterMediumSound; + impactWaterHard = VehicleImpactWaterHardSound; + waterWakeSound = VehicleWakeMediumSplashSound; + + minMountDist = 3; + + damageEmitter[0] = LightDamageSmoke; + damageEmitter[1] = HeavyDamageSmoke; + damageEmitter[2] = DamageBubbles; + damageEmitterOffset[0] = "3.0 0.5 0.0 "; + damageEmitterOffset[1] = "-3.0 0.5 0.0 "; + damageLevelTolerance[0] = 0.3; + damageLevelTolerance[1] = 0.7; + numDmgEmitterAreas = 2; + + splashEmitter[0] = VehicleFoamDropletsEmitter; + splashEmitter[1] = VehicleFoamEmitter; + + shieldImpact = VehicleShieldImpact; + + cmdCategory = "Tactical"; + cmdIcon = CMDGroundMPBIcon; + cmdMiniIconName = "commander/MiniIcons/com_mpb_grey"; + targetNameTag = 'Jericho'; + targetTypeTag = 'MPB'; + sensorData = VehiclePulseSensor; + sensorRadius = VehiclePulseSensor.detectRadius; // z0dd - ZOD, 4/25/02. Allows sensor to be shown on CC + + checkRadius = 7.5225; + + observeParameters = "1 12 12"; + + runningLight[0] = MPBLight1; + runningLight[1] = MPBLight2; + + shieldEffectScale = "0.85 1.2 0.7"; +}; + +//************************************************************** +// WEAPONS +//************************************************************** + +datablock SensorData(MPBTurretMissileSensor) +{ + detects = true; + detectsUsingLOS = true; + detectsPassiveJammed = false; + detectsActiveJammed = false; + detectsCloaked = false; + detectionPings = true; + detectRadius = 200; +}; + +datablock TurretData(MobileTurretBase) +{ + className = VehicleTurret; + catagory = "Turrets"; + shapeFile = "turret_base_mpb.dts"; + preload = true; + + mass = 1.0; // Not really relevant + + maxDamage = MobileBaseVehicle.maxDamage; + destroyedLevel = MobileBaseVehicle.destroyedLevel; + + thetaMin = 15; + thetaMax = 140; + + energyPerDamagePoint = 33; + inheritEnergyFromMount = true; + firstPersonOnly = true; + + sensorColor = "0 212 45"; + sensorData = MPBTurretMissileSensor; + sensorRadius = MPBTurretMissileSensor.detectRadius; + cmdCategory = "Tactical"; + cmdMiniIconName = "commander/MiniIcons/com_turret_grey"; + targetNameTag = 'Jericho'; + targetTypeTag = 'Turret'; + + canControl = true; +}; + + + diff --git a/scripts/vehicles/vehicle_shrike.cs b/scripts/vehicles/vehicle_shrike.cs index d73a9cf..618a191 100644 --- a/scripts/vehicles/vehicle_shrike.cs +++ b/scripts/vehicles/vehicle_shrike.cs @@ -1,341 +1,341 @@ -//************************************************************** -// SHRIKE SCOUT FLIER -//************************************************************** -//************************************************************** -// SOUNDS -//************************************************************** -datablock EffectProfile(ScoutFlyerThrustEffect) -{ - effectname = "vehicles/shrike_boost"; - minDistance = 5.0; - maxDistance = 10.0; -}; - -datablock EffectProfile(ScoutFlyerEngineEffect) -{ - effectname = "vehicles/shrike_engine"; - minDistance = 5.0; - maxDistance = 10.0; -}; - -datablock EffectProfile(ShrikeBlasterFireEffect) -{ - effectname = "vehicles/shrike_blaster"; - minDistance = 5.0; - maxDistance = 10.0; -}; - -datablock AudioProfile(ScoutFlyerThrustSound) -{ - filename = "fx/vehicles/shrike_boost.wav"; - description = AudioDefaultLooping3d; - preload = true; - effect = ScoutFlyerThrustEffect; -}; - -datablock AudioProfile(ScoutFlyerEngineSound) -{ - filename = "fx/vehicles/shrike_engine.wav"; - description = AudioDefaultLooping3d; - preload = true; -}; - -datablock AudioProfile(ShrikeBlasterFire) -{ - filename = "fx/vehicles/shrike_blaster.wav"; - description = AudioDefault3d; - preload = true; - effect = ScoutFlyerEngineEffect; -}; - -datablock AudioProfile(ShrikeBlasterProjectile) -{ - filename = "fx/weapons/shrike_blaster_projectile.wav"; - description = ProjectileLooping3d; - preload = true; - effect = ShrikeBlasterFireEffect; -}; - -datablock AudioProfile(ShrikeBlasterDryFireSound) -{ - filename = "fx/weapons/chaingun_dryfire.wav"; - description = AudioClose3d; - preload = true; -}; - -//************************************************************** -// LIGHTS -//************************************************************** -datablock RunningLightData(ShrikeLight1) -{ - type = 1; - radius = 2.0; - length = 3.0; - color = "1.0 1.0 1.0 1.0"; - direction = "0.0 1.0 -1.0 "; - offset = "0.0 0.0 -0.5"; - texture = "special/lightcone04"; -}; - -datablock RunningLightData(ShrikeLight2) -{ - radius = 1.5; - color = "1.0 1.0 1.0 0.3"; - direction = "0.0 0.0 -1.0"; - offset = "0.0 0.8 -1.2"; - texture = "special/headlight4"; -}; - -//************************************************************** -// VEHICLE CHARACTERISTICS -//************************************************************** - -datablock FlyingVehicleData(ScoutFlyer) : ShrikeDamageProfile -{ - spawnOffset = "0 0 2"; - - catagory = "Vehicles"; - shapeFile = "vehicle_air_scout.dts"; - multipassenger = false; - computeCRC = true; - - debrisShapeName = "vehicle_air_scout_debris.dts"; - debris = ShapeDebris; - renderWhenDestroyed = false; - - drag = 0.15; - density = 1.0; - - mountPose[0] = sitting; - numMountPoints = 1; - isProtectedMountPoint[0] = true; - cameraMaxDist = 15; - cameraOffset = 2.5; - cameraLag = 0.9; - explosion = VehicleExplosion; - explosionDamage = 0.5; - explosionRadius = 5.0; - - maxDamage = 1.40; - destroyedLevel = 1.40; - - isShielded = true; - energyPerDamagePoint = 160; - maxEnergy = 280; // Afterburner and any energy weapon pool - rechargeRate = 0.8; - - minDrag = 30; // Linear Drag (eventually slows you down when not thrusting...constant drag) - rotationalDrag = 900; // Anguler Drag (dampens the drift after you stop moving the mouse...also tumble drag) - - maxAutoSpeed = 15; // Autostabilizer kicks in when less than this speed. (meters/second) - autoAngularForce = 400; // Angular stabilizer force (this force levels you out when autostabilizer kicks in) - autoLinearForce = 300; // Linear stabilzer force (this slows you down when autostabilizer kicks in) - autoInputDamping = 0.95; // Dampen control input so you don't` whack out at very slow speeds - - // Maneuvering - maxSteeringAngle = 5; // Max radiens you can rotate the wheel. Smaller number is more maneuverable. - horizontalSurfaceForce = 6; // Horizontal center "wing" (provides "bite" into the wind for climbing/diving and turning) - verticalSurfaceForce = 4; // Vertical center "wing" (controls side slip. lower numbers make MORE slide.) - maneuveringForce = 3000; // Horizontal jets (W,S,D,A key thrust) - steeringForce = 1200; // Steering jets (force applied when you move the mouse) - steeringRollForce = 400; // Steering jets (how much you heel over when you turn) - rollForce = 4; // Auto-roll (self-correction to right you after you roll/invert) - hoverHeight = 5; // Height off the ground at rest - createHoverHeight = 3; // Height off the ground when created - maxForwardSpeed = 100; // speed in which forward thrust force is no longer applied (meters/second) - - // Turbo Jet - jetForce = 2000; // Afterburner thrust (this is in addition to normal thrust) - minJetEnergy = 28; // Afterburner can't be used if below this threshhold. - jetEnergyDrain = 2.8; // Energy use of the afterburners (low number is less drain...can be fractional) // Auto stabilize speed - vertThrustMultiple = 4.0; // z0dd - ZOD, 9/8/02. Was 3.0 - - // Rigid body - mass = 150; // Mass of the vehicle - bodyFriction = 0; // Don't mess with this. - bodyRestitution = 0.5; // When you hit the ground, how much you rebound. (between 0 and 1) - minRollSpeed = 0; // Don't mess with this. - softImpactSpeed = 14; // Sound hooks. This is the soft hit. - hardImpactSpeed = 25; // Sound hooks. This is the hard hit. - - // Ground Impact Damage (uses DamageType::Ground) - minImpactSpeed = 10; // If hit ground at speed above this then it's an impact. Meters/second - speedDamageScale = 0.06; - - // Object Impact Damage (uses DamageType::Impact) - collDamageThresholdVel = 23.0; - collDamageMultiplier = 0.02; - - // - minTrailSpeed = 15; // The speed your contrail shows up at. - trailEmitter = ContrailEmitter; - forwardJetEmitter = FlyerJetEmitter; - downJetEmitter = FlyerJetEmitter; - - // - jetSound = ScoutFlyerThrustSound; - engineSound = ScoutFlyerEngineSound; - softImpactSound = SoftImpactSound; - hardImpactSound = HardImpactSound; - //wheelImpactSound = WheelImpactSound; - - // - softSplashSoundVelocity = 10.0; - mediumSplashSoundVelocity = 15.0; - hardSplashSoundVelocity = 20.0; - exitSplashSoundVelocity = 10.0; - - exitingWater = VehicleExitWaterMediumSound; - impactWaterEasy = VehicleImpactWaterSoftSound; - impactWaterMedium = VehicleImpactWaterMediumSound; - impactWaterHard = VehicleImpactWaterMediumSound; - waterWakeSound = VehicleWakeMediumSplashSound; - - dustEmitter = VehicleLiftoffDustEmitter; - triggerDustHeight = 4.0; - dustHeight = 1.0; - - damageEmitter[0] = LightDamageSmoke; - damageEmitter[1] = HeavyDamageSmoke; - damageEmitter[2] = DamageBubbles; - damageEmitterOffset[0] = "0.0 -3.0 0.0 "; - damageLevelTolerance[0] = 0.3; - damageLevelTolerance[1] = 0.7; - numDmgEmitterAreas = 1; - - // - max[chaingunAmmo] = 1000; - - minMountDist = 4; - - splashEmitter[0] = VehicleFoamDropletsEmitter; - splashEmitter[1] = VehicleFoamEmitter; - - shieldImpact = VehicleShieldImpact; - - cmdCategory = "Tactical"; - cmdIcon = CMDFlyingScoutIcon; - cmdMiniIconName = "commander/MiniIcons/com_scout_grey"; - targetNameTag = 'Shrike'; - targetTypeTag = 'Turbograv'; - sensorData = AWACPulseSensor; - sensorRadius = AWACPulseSensor.detectRadius; - sensorColor = "255 194 9"; - - checkRadius = 5.5; - observeParameters = "1 10 10"; - - runningLight[0] = ShrikeLight1; -// runningLight[1] = ShrikeLight2; - - shieldEffectScale = "0.937 1.125 0.60"; - -}; - -//************************************************************** -// WEAPONS -//************************************************************** - -datablock ShapeBaseImageData(ScoutChaingunPairImage) -{ - className = WeaponImage; - shapeFile = "weapon_energy_vehicle.dts"; - item = Chaingun; - ammo = ChaingunAmmo; - projectile = ScoutChaingunBullet; - projectileType = TracerProjectile; - mountPoint = 10; -//**original** offset = ".73 0 0"; - offset = "1.93 -0.52 0.044"; - - projectileSpread = 1.0 / 1000.0; - - usesEnergy = true; - useMountEnergy = true; - // DAVEG -- balancing numbers below! - minEnergy = 5; - fireEnergy = 5; - fireTimeout = 125; - - - //-------------------------------------- - stateName[0] = "Activate"; - stateSequence[0] = "Activate"; - stateAllowImageChange[0] = false; - stateTimeoutValue[0] = 0.05; - stateTransitionOnTimeout[0] = "Ready"; - stateTransitionOnNoAmmo[0] = "NoAmmo"; - //-------------------------------------- - stateName[1] = "Ready"; - stateSpinThread[1] = Stop; - stateTransitionOnTriggerDown[1] = "Spinup"; - stateTransitionOnNoAmmo[1] = "NoAmmo"; - //-------------------------------------- - stateName[2] = "NoAmmo"; - stateTransitionOnAmmo[2] = "Ready"; - stateSpinThread[2] = Stop; - stateTransitionOnTriggerDown[2] = "DryFire"; - //-------------------------------------- - stateName[3] = "Spinup"; - stateSpinThread[3] = SpinUp; - stateTimeoutValue[3] = 0.01; - stateWaitForTimeout[3] = false; - stateTransitionOnTimeout[3] = "Fire"; - stateTransitionOnTriggerUp[3] = "Spindown"; - //-------------------------------------- - stateName[4] = "Fire"; - stateSpinThread[4] = FullSpeed; - stateRecoil[4] = LightRecoil; - stateAllowImageChange[4] = false; - stateScript[4] = "onFire"; - stateFire[4] = true; - stateSound[4] = ShrikeBlasterFire; - // IMPORTANT! The stateTimeoutValue below has been replaced by fireTimeOut - // above. - stateTimeoutValue[4] = 0.25; - stateTransitionOnTimeout[4] = "checkState"; - //-------------------------------------- - stateName[5] = "Spindown"; - stateSpinThread[5] = SpinDown; - stateTimeoutValue[5] = 0.01; - stateWaitForTimeout[5] = false; - stateTransitionOnTimeout[5] = "Ready"; - stateTransitionOnTriggerDown[5] = "Spinup"; - //-------------------------------------- - stateName[6] = "EmptySpindown"; -// stateSound[6] = ChaingunSpindownSound; - stateSpinThread[6] = SpinDown; - stateTransitionOnAmmo[6] = "Ready"; - stateTimeoutValue[6] = 0.01; - stateTransitionOnTimeout[6] = "NoAmmo"; - //-------------------------------------- - stateName[7] = "DryFire"; - stateSound[7] = ShrikeBlasterDryFireSound; - stateTransitionOnTriggerUp[7] = "NoAmmo"; - stateTimeoutValue[7] = 0.25; - stateTransitionOnTimeout[7] = "NoAmmo"; - - stateName[8] = "checkState"; - stateTransitionOnTriggerUp[8] = "Spindown"; - stateTransitionOnNoAmmo[8] = "EmptySpindown"; - stateTimeoutValue[8] = 0.01; - stateTransitionOnTimeout[8] = "ready"; -}; - -datablock ShapeBaseImageData(ScoutChaingunImage) : ScoutChaingunPairImage -{ -//**original** offset = "-.73 0 0"; - offset = "-1.93 -0.52 0.044"; - stateScript[3] = "onTriggerDown"; - stateScript[5] = "onTriggerUp"; - stateScript[6] = "onTriggerUp"; -}; - -datablock ShapeBaseImageData(ScoutChaingunParam) -{ - mountPoint = 2; - shapeFile = "turret_muzzlepoint.dts"; - - projectile = ScoutChaingunBullet; - projectileType = TracerProjectile; +//************************************************************** +// SHRIKE SCOUT FLIER +//************************************************************** +//************************************************************** +// SOUNDS +//************************************************************** +datablock EffectProfile(ScoutFlyerThrustEffect) +{ + effectname = "vehicles/shrike_boost"; + minDistance = 5.0; + maxDistance = 10.0; +}; + +datablock EffectProfile(ScoutFlyerEngineEffect) +{ + effectname = "vehicles/shrike_engine"; + minDistance = 5.0; + maxDistance = 10.0; +}; + +datablock EffectProfile(ShrikeBlasterFireEffect) +{ + effectname = "vehicles/shrike_blaster"; + minDistance = 5.0; + maxDistance = 10.0; +}; + +datablock AudioProfile(ScoutFlyerThrustSound) +{ + filename = "fx/vehicles/shrike_boost.wav"; + description = AudioDefaultLooping3d; + preload = true; + effect = ScoutFlyerThrustEffect; +}; + +datablock AudioProfile(ScoutFlyerEngineSound) +{ + filename = "fx/vehicles/shrike_engine.wav"; + description = AudioDefaultLooping3d; + preload = true; +}; + +datablock AudioProfile(ShrikeBlasterFire) +{ + filename = "fx/vehicles/shrike_blaster.wav"; + description = AudioDefault3d; + preload = true; + effect = ScoutFlyerEngineEffect; +}; + +datablock AudioProfile(ShrikeBlasterProjectile) +{ + filename = "fx/weapons/shrike_blaster_projectile.wav"; + description = ProjectileLooping3d; + preload = true; + effect = ShrikeBlasterFireEffect; +}; + +datablock AudioProfile(ShrikeBlasterDryFireSound) +{ + filename = "fx/weapons/chaingun_dryfire.wav"; + description = AudioClose3d; + preload = true; +}; + +//************************************************************** +// LIGHTS +//************************************************************** +datablock RunningLightData(ShrikeLight1) +{ + type = 1; + radius = 2.0; + length = 3.0; + color = "1.0 1.0 1.0 1.0"; + direction = "0.0 1.0 -1.0 "; + offset = "0.0 0.0 -0.5"; + texture = "special/lightcone04"; +}; + +datablock RunningLightData(ShrikeLight2) +{ + radius = 1.5; + color = "1.0 1.0 1.0 0.3"; + direction = "0.0 0.0 -1.0"; + offset = "0.0 0.8 -1.2"; + texture = "special/headlight4"; +}; + +//************************************************************** +// VEHICLE CHARACTERISTICS +//************************************************************** + +datablock FlyingVehicleData(ScoutFlyer) : ShrikeDamageProfile +{ + spawnOffset = "0 0 2"; + + catagory = "Vehicles"; + shapeFile = "vehicle_air_scout.dts"; + multipassenger = false; + computeCRC = true; + + debrisShapeName = "vehicle_air_scout_debris.dts"; + debris = ShapeDebris; + renderWhenDestroyed = false; + + drag = 0.15; + density = 1.0; + + mountPose[0] = sitting; + numMountPoints = 1; + isProtectedMountPoint[0] = true; + cameraMaxDist = 15; + cameraOffset = 2.5; + cameraLag = 0.9; + explosion = VehicleExplosion; + explosionDamage = 0.5; + explosionRadius = 5.0; + + maxDamage = 1.40; + destroyedLevel = 1.40; + + isShielded = true; + energyPerDamagePoint = 160; + maxEnergy = 280; // Afterburner and any energy weapon pool + rechargeRate = 0.8; + + minDrag = 30; // Linear Drag (eventually slows you down when not thrusting...constant drag) + rotationalDrag = 900; // Anguler Drag (dampens the drift after you stop moving the mouse...also tumble drag) + + maxAutoSpeed = 15; // Autostabilizer kicks in when less than this speed. (meters/second) + autoAngularForce = 400; // Angular stabilizer force (this force levels you out when autostabilizer kicks in) + autoLinearForce = 300; // Linear stabilzer force (this slows you down when autostabilizer kicks in) + autoInputDamping = 0.95; // Dampen control input so you don't` whack out at very slow speeds + + // Maneuvering + maxSteeringAngle = 5; // Max radiens you can rotate the wheel. Smaller number is more maneuverable. + horizontalSurfaceForce = 6; // Horizontal center "wing" (provides "bite" into the wind for climbing/diving and turning) + verticalSurfaceForce = 4; // Vertical center "wing" (controls side slip. lower numbers make MORE slide.) + maneuveringForce = 3000; // Horizontal jets (W,S,D,A key thrust) + steeringForce = 1200; // Steering jets (force applied when you move the mouse) + steeringRollForce = 400; // Steering jets (how much you heel over when you turn) + rollForce = 4; // Auto-roll (self-correction to right you after you roll/invert) + hoverHeight = 5; // Height off the ground at rest + createHoverHeight = 3; // Height off the ground when created + maxForwardSpeed = 100; // speed in which forward thrust force is no longer applied (meters/second) + + // Turbo Jet + jetForce = 2000; // Afterburner thrust (this is in addition to normal thrust) + minJetEnergy = 28; // Afterburner can't be used if below this threshhold. + jetEnergyDrain = 2.8; // Energy use of the afterburners (low number is less drain...can be fractional) // Auto stabilize speed + vertThrustMultiple = 4.0; // z0dd - ZOD, 9/8/02. Was 3.0 + + // Rigid body + mass = 150; // Mass of the vehicle + bodyFriction = 0; // Don't mess with this. + bodyRestitution = 0.5; // When you hit the ground, how much you rebound. (between 0 and 1) + minRollSpeed = 0; // Don't mess with this. + softImpactSpeed = 14; // Sound hooks. This is the soft hit. + hardImpactSpeed = 25; // Sound hooks. This is the hard hit. + + // Ground Impact Damage (uses DamageType::Ground) + minImpactSpeed = 10; // If hit ground at speed above this then it's an impact. Meters/second + speedDamageScale = 0.06; + + // Object Impact Damage (uses DamageType::Impact) + collDamageThresholdVel = 23.0; + collDamageMultiplier = 0.02; + + // + minTrailSpeed = 15; // The speed your contrail shows up at. + trailEmitter = ContrailEmitter; + forwardJetEmitter = FlyerJetEmitter; + downJetEmitter = FlyerJetEmitter; + + // + jetSound = ScoutFlyerThrustSound; + engineSound = ScoutFlyerEngineSound; + softImpactSound = SoftImpactSound; + hardImpactSound = HardImpactSound; + //wheelImpactSound = WheelImpactSound; + + // + softSplashSoundVelocity = 10.0; + mediumSplashSoundVelocity = 15.0; + hardSplashSoundVelocity = 20.0; + exitSplashSoundVelocity = 10.0; + + exitingWater = VehicleExitWaterMediumSound; + impactWaterEasy = VehicleImpactWaterSoftSound; + impactWaterMedium = VehicleImpactWaterMediumSound; + impactWaterHard = VehicleImpactWaterMediumSound; + waterWakeSound = VehicleWakeMediumSplashSound; + + dustEmitter = VehicleLiftoffDustEmitter; + triggerDustHeight = 4.0; + dustHeight = 1.0; + + damageEmitter[0] = LightDamageSmoke; + damageEmitter[1] = HeavyDamageSmoke; + damageEmitter[2] = DamageBubbles; + damageEmitterOffset[0] = "0.0 -3.0 0.0 "; + damageLevelTolerance[0] = 0.3; + damageLevelTolerance[1] = 0.7; + numDmgEmitterAreas = 1; + + // + max[chaingunAmmo] = 1000; + + minMountDist = 4; + + splashEmitter[0] = VehicleFoamDropletsEmitter; + splashEmitter[1] = VehicleFoamEmitter; + + shieldImpact = VehicleShieldImpact; + + cmdCategory = "Tactical"; + cmdIcon = CMDFlyingScoutIcon; + cmdMiniIconName = "commander/MiniIcons/com_scout_grey"; + targetNameTag = 'Shrike'; + targetTypeTag = 'Turbograv'; + sensorData = AWACPulseSensor; + sensorRadius = AWACPulseSensor.detectRadius; + sensorColor = "255 194 9"; + + checkRadius = 5.5; + observeParameters = "1 10 10"; + + runningLight[0] = ShrikeLight1; +// runningLight[1] = ShrikeLight2; + + shieldEffectScale = "0.937 1.125 0.60"; + +}; + +//************************************************************** +// WEAPONS +//************************************************************** + +datablock ShapeBaseImageData(ScoutChaingunPairImage) +{ + className = WeaponImage; + shapeFile = "weapon_energy_vehicle.dts"; + item = Chaingun; + ammo = ChaingunAmmo; + projectile = ScoutChaingunBullet; + projectileType = TracerProjectile; + mountPoint = 10; +//**original** offset = ".73 0 0"; + offset = "1.93 -0.52 0.044"; + + projectileSpread = 1.0 / 1000.0; + + usesEnergy = true; + useMountEnergy = true; + // DAVEG -- balancing numbers below! + minEnergy = 5; + fireEnergy = 5; + fireTimeout = 125; + + + //-------------------------------------- + stateName[0] = "Activate"; + stateSequence[0] = "Activate"; + stateAllowImageChange[0] = false; + stateTimeoutValue[0] = 0.05; + stateTransitionOnTimeout[0] = "Ready"; + stateTransitionOnNoAmmo[0] = "NoAmmo"; + //-------------------------------------- + stateName[1] = "Ready"; + stateSpinThread[1] = Stop; + stateTransitionOnTriggerDown[1] = "Spinup"; + stateTransitionOnNoAmmo[1] = "NoAmmo"; + //-------------------------------------- + stateName[2] = "NoAmmo"; + stateTransitionOnAmmo[2] = "Ready"; + stateSpinThread[2] = Stop; + stateTransitionOnTriggerDown[2] = "DryFire"; + //-------------------------------------- + stateName[3] = "Spinup"; + stateSpinThread[3] = SpinUp; + stateTimeoutValue[3] = 0.01; + stateWaitForTimeout[3] = false; + stateTransitionOnTimeout[3] = "Fire"; + stateTransitionOnTriggerUp[3] = "Spindown"; + //-------------------------------------- + stateName[4] = "Fire"; + stateSpinThread[4] = FullSpeed; + stateRecoil[4] = LightRecoil; + stateAllowImageChange[4] = false; + stateScript[4] = "onFire"; + stateFire[4] = true; + stateSound[4] = ShrikeBlasterFire; + // IMPORTANT! The stateTimeoutValue below has been replaced by fireTimeOut + // above. + stateTimeoutValue[4] = 0.25; + stateTransitionOnTimeout[4] = "checkState"; + //-------------------------------------- + stateName[5] = "Spindown"; + stateSpinThread[5] = SpinDown; + stateTimeoutValue[5] = 0.01; + stateWaitForTimeout[5] = false; + stateTransitionOnTimeout[5] = "Ready"; + stateTransitionOnTriggerDown[5] = "Spinup"; + //-------------------------------------- + stateName[6] = "EmptySpindown"; +// stateSound[6] = ChaingunSpindownSound; + stateSpinThread[6] = SpinDown; + stateTransitionOnAmmo[6] = "Ready"; + stateTimeoutValue[6] = 0.01; + stateTransitionOnTimeout[6] = "NoAmmo"; + //-------------------------------------- + stateName[7] = "DryFire"; + stateSound[7] = ShrikeBlasterDryFireSound; + stateTransitionOnTriggerUp[7] = "NoAmmo"; + stateTimeoutValue[7] = 0.25; + stateTransitionOnTimeout[7] = "NoAmmo"; + + stateName[8] = "checkState"; + stateTransitionOnTriggerUp[8] = "Spindown"; + stateTransitionOnNoAmmo[8] = "EmptySpindown"; + stateTimeoutValue[8] = 0.01; + stateTransitionOnTimeout[8] = "ready"; +}; + +datablock ShapeBaseImageData(ScoutChaingunImage) : ScoutChaingunPairImage +{ +//**original** offset = "-.73 0 0"; + offset = "-1.93 -0.52 0.044"; + stateScript[3] = "onTriggerDown"; + stateScript[5] = "onTriggerUp"; + stateScript[6] = "onTriggerUp"; +}; + +datablock ShapeBaseImageData(ScoutChaingunParam) +{ + mountPoint = 2; + shapeFile = "turret_muzzlepoint.dts"; + + projectile = ScoutChaingunBullet; + projectileType = TracerProjectile; }; \ No newline at end of file diff --git a/scripts/vehicles/vehicle_tank.cs b/scripts/vehicles/vehicle_tank.cs index 9044b8d..bfde21d 100644 --- a/scripts/vehicles/vehicle_tank.cs +++ b/scripts/vehicles/vehicle_tank.cs @@ -1,682 +1,682 @@ -//************************************************************** -// BEOWULF ASSAULT VEHICLE -//************************************************************** -//************************************************************** -// SOUNDS -//************************************************************** -datablock EffectProfile(AssaultVehicleEngineEffect) -{ - effectname = "vehicles/tank_engine"; - minDistance = 5.0; - maxDistance = 10.0; -}; - -datablock EffectProfile(AssaultVehicleThrustEffect) -{ - effectname = "vehicles/tank_boost"; - minDistance = 5.0; - maxDistance = 10.0; -}; - -datablock EffectProfile(AssaultTurretActivateEffect) -{ - effectname = "vehicles/tank_activate"; - minDistance = 5.0; - maxDistance = 10.0; -}; - -datablock EffectProfile(AssaultMortarDryFireEffect) -{ - effectname = "weapons/mortar_dryfire"; - minDistance = 5.0; - maxDistance = 10.0; -}; - -datablock EffectProfile(AssaultMortarFireEffect) -{ - effectname = "vehicles/tank_mortar_fire"; - minDistance = 5.0; - maxDistance = 10.0; -}; - -datablock EffectProfile(AssaultMortarReloadEffect) -{ - effectname = "weapons/mortar_reload"; - minDistance = 5.0; - maxDistance = 10.0; -}; - -datablock EffectProfile(AssaultChaingunFireEffect) -{ - effectname = "weapons/chaingun_fire"; - minDistance = 5.0; - maxDistance = 10.0; -}; - -datablock AudioProfile(AssaultVehicleSkid) -{ - filename = "fx/vehicles/tank_skid.wav"; - description = ClosestLooping3d; - preload = true; -}; - -datablock AudioProfile(AssaultVehicleEngineSound) -{ - filename = "fx/vehicles/tank_engine.wav"; - description = AudioDefaultLooping3d; - preload = true; - effect = AssaultVehicleEngineEffect; -}; - -datablock AudioProfile(AssaultVehicleThrustSound) -{ - filename = "fx/vehicles/tank_boost.wav"; - description = AudioDefaultLooping3d; - preload = true; - effect = AssaultVehicleThrustEffect; -}; - -datablock AudioProfile(AssaultChaingunFireSound) -{ - filename = "fx/vehicles/tank_chaingun.wav"; - description = AudioDefaultLooping3d; - preload = true; - effect = AssaultChaingunFireEffect; -}; - -datablock AudioProfile(AssaultChaingunReloadSound) -{ - filename = "fx/weapons/chaingun_dryfire.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(TankChaingunProjectile) -{ - filename = "fx/weapons/chaingun_projectile.wav"; - description = ProjectileLooping3d; - preload = true; -}; - -datablock AudioProfile(AssaultTurretActivateSound) -{ - filename = "fx/vehicles/tank_activate.wav"; - description = AudioClose3d; - preload = true; - effect = AssaultTurretActivateEffect; -}; - -datablock AudioProfile(AssaultChaingunDryFireSound) -{ - filename = "fx/weapons/chaingun_dryfire.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(AssaultChaingunIdleSound) -{ - filename = "fx/misc/diagnostic_on.wav"; - description = ClosestLooping3d; - preload = true; -}; - -datablock AudioProfile(AssaultMortarDryFireSound) -{ - filename = "fx/weapons/mortar_dryfire.wav"; - description = AudioClose3d; - preload = true; - effect = AssaultMortarDryFireEffect; -}; - -datablock AudioProfile(AssaultMortarFireSound) -{ - filename = "fx/vehicles/tank_mortar_fire.wav"; - description = AudioClose3d; - preload = true; - effect = AssaultMortarFireEffect; -}; - -datablock AudioProfile(AssaultMortarReloadSound) -{ - filename = "fx/weapons/mortar_reload.wav"; - description = AudioClose3d; - preload = true; - effect = AssaultMortarReloadEffect; -}; - -datablock AudioProfile(AssaultMortarIdleSound) -{ - filename = "fx/misc/diagnostic_on.wav"; - description = ClosestLooping3d; - preload = true; -}; - -//************************************************************** -// LIGHTS -//************************************************************** -datablock RunningLightData(TankLight1) -{ - radius = 1.5; - color = "1.0 1.0 1.0 0.2"; - nodeName = "Headlight_node01"; - direction = "0.0 1.0 0.0"; - texture = "special/headlight4"; -}; - -datablock RunningLightData(TankLight2) -{ - radius = 1.5; - color = "1.0 1.0 1.0 0.2"; - nodeName = "Headlight_node02"; - direction = "0.0 1.0 0.0"; - texture = "special/headlight4"; -}; - -datablock RunningLightData(TankLight3) -{ - radius = 1.5; - color = "1.0 1.0 1.0 0.2"; - nodeName = "Headlight_node03"; - direction = "0.0 1.0 0.0"; - texture = "special/headlight4"; -}; - -datablock RunningLightData(TankLight4) -{ - radius = 1.5; - color = "1.0 1.0 1.0 0.2"; - nodeName = "Headlight_node04"; - direction = "0.0 1.0 0.0"; - texture = "special/headlight4"; -}; - -//************************************************************** -// VEHICLE CHARACTERISTICS -//************************************************************** - -datablock HoverVehicleData(AssaultVehicle) : TankDamageProfile -{ - spawnOffset = "0 0 4"; - - floatingGravMag = 4.5; - - catagory = "Vehicles"; - shapeFile = "vehicle_grav_tank.dts"; - multipassenger = true; - computeCRC = true; - renderWhenDestroyed = false; - - weaponNode = 1; - - debrisShapeName = "vehicle_land_assault_debris.dts"; - debris = ShapeDebris; - - drag = 0.0; - density = 0.9; - - mountPose[0] = sitting; - mountPose[1] = sitting; - numMountPoints = 2; - isProtectedMountPoint[0] = true; - isProtectedMountPoint[1] = true; - - cameraMaxDist = 20; - cameraOffset = 3; - cameraLag = 1.5; - explosion = LargeGroundVehicleExplosion; - explosionDamage = 0.5; - explosionRadius = 5.0; - - maxSteeringAngle = 0.5; // 20 deg. - - maxDamage = 3.15; - destroyedLevel = 3.15; - - isShielded = true; - rechargeRate = 1.0; - energyPerDamagePoint = 135; - maxEnergy = 400; - minJetEnergy = 15; - jetEnergyDrain = 2.0; - - // Rigid Body - mass = 1500; - bodyFriction = 0.8; - bodyRestitution = 0.5; - minRollSpeed = 3; - gyroForce = 400; - gyroDamping = 0.3; - stabilizerForce = 20; - minDrag = 10; - softImpactSpeed = 18; // Play SoftImpact Sound. z0dd - ZOD, 3/30/02. Higher speed before tank takes ground collision dmg. Was 15 - hardImpactSpeed = 21; // Play HardImpact Sound. z0dd - ZOD, 3/30/02. Higher speed before tank takes ground collision dmg. Was 18 - - // Ground Impact Damage (uses DamageType::Ground) - minImpactSpeed = 20; // z0dd - ZOD, 3/30/02. Higher speed before tank takes ground collision dmg. Was 17 - speedDamageScale = 0.060; - - // Object Impact Damage (uses DamageType::Impact) - collDamageThresholdVel = 18; - collDamageMultiplier = 0.045; - - dragForce = 40 / 20; - vertFactor = 0.0; - floatingThrustFactor = 0.15; // z0dd - ZOD, 3/30/02. Stronger air cushion. Was 0.15 - - mainThrustForce = 55; // z0dd - ZOD, 3/30/02. Was 50 - reverseThrustForce = 40; - strafeThrustForce = 40; - turboFactor = 1.85; // z0dd - ZOD, 3/30/02. Was 1.7 - - brakingForce = 25; - brakingActivationSpeed = 4; - - stabLenMin = 3.25; - stabLenMax = 4; - stabSpringConstant = 50; - stabDampingConstant = 20; - - gyroDrag = 20; - normalForce = 20; - restorativeForce = 10; - steeringForce = 15; - rollForce = 5; - pitchForce = 3; - - dustEmitter = TankDustEmitter; - triggerDustHeight = 3.5; - dustHeight = 1.0; - dustTrailEmitter = TireEmitter; - dustTrailOffset = "0.0 -1.0 0.5"; - triggerTrailHeight = 3.6; - dustTrailFreqMod = 15.0; - - jetSound = AssaultVehicleThrustSound; - engineSound = AssaultVehicleEngineSound; - floatSound = AssaultVehicleSkid; - softImpactSound = GravSoftImpactSound; - hardImpactSound = HardImpactSound; - wheelImpactSound = WheelImpactSound; - - forwardJetEmitter = TankJetEmitter; - - // - softSplashSoundVelocity = 5.0; - mediumSplashSoundVelocity = 10.0; - hardSplashSoundVelocity = 15.0; - exitSplashSoundVelocity = 10.0; - - exitingWater = VehicleExitWaterMediumSound; - impactWaterEasy = VehicleImpactWaterSoftSound; - impactWaterMedium = VehicleImpactWaterMediumSound; - impactWaterHard = VehicleImpactWaterMediumSound; - waterWakeSound = VehicleWakeMediumSplashSound; - - minMountDist = 4; - - damageEmitter[0] = SmallLightDamageSmoke; - damageEmitter[1] = SmallHeavyDamageSmoke; - damageEmitter[2] = DamageBubbles; - damageEmitterOffset[0] = "0.0 -1.5 3.5 "; - damageLevelTolerance[0] = 0.3; - damageLevelTolerance[1] = 0.7; - numDmgEmitterAreas = 1; - - splashEmitter[0] = VehicleFoamDropletsEmitter; - splashEmitter[1] = VehicleFoamEmitter; - - shieldImpact = VehicleShieldImpact; - - cmdCategory = "Tactical"; - cmdIcon = CMDGroundTankIcon; - cmdMiniIconName = "commander/MiniIcons/com_tank_grey"; - targetNameTag = 'Beowulf'; - targetTypeTag = 'Assault Tank'; - sensorData = VehiclePulseSensor; - sensorRadius = VehiclePulseSensor.detectRadius; // z0dd - ZOD, 3/30/02. Allows sensor to be shown on CC - - checkRadius = 5.5535; - observeParameters = "1 10 10"; - runningLight[0] = TankLight1; - runningLight[1] = TankLight2; - runningLight[2] = TankLight3; - runningLight[3] = TankLight4; - shieldEffectScale = "0.9 1.0 0.6"; - showPilotInfo = 1; -}; - -//************************************************************** -// WEAPONS -//************************************************************** - -//------------------------------------- -// ASSAULT CHAINGUN (projectile) -//------------------------------------- - -datablock TracerProjectileData(AssaultChaingunBullet) -{ - doDynamicClientHits = true; - - projectileShapeName = ""; - directDamage = 0.16; - directDamageType = $DamageType::TankChaingun; - hasDamageRadius = false; - splash = ChaingunSplash; - - kickbackstrength = 0.0; - sound = TankChaingunProjectile; - - dryVelocity = 425.0; - wetVelocity = 100.0; - velInheritFactor = 1.0; - fizzleTimeMS = 3000; - lifetimeMS = 3000; - explodeOnDeath = false; - reflectOnWaterImpactAngle = 0.0; - explodeOnWaterImpact = false; - deflectionOnWaterImpact = 0.0; - fizzleUnderwaterMS = 3000; - - tracerLength = 15.0; - tracerAlpha = false; - tracerMinPixels = 6; - tracerColor = 211.0/255.0 @ " " @ 215.0/255.0 @ " " @ 120.0/255.0 @ " 0.75"; - tracerTex[0] = "special/tracer00"; - tracerTex[1] = "special/tracercross"; - tracerWidth = 0.10; - crossSize = 0.20; - crossViewAng = 0.990; - renderCross = true; - - decalData[0] = ChaingunDecal1; - decalData[1] = ChaingunDecal2; - decalData[2] = ChaingunDecal3; - decalData[3] = ChaingunDecal4; - decalData[4] = ChaingunDecal5; - decalData[5] = ChaingunDecal6; - - activateDelayMS = 100; - - explosion = ChaingunExplosion; -}; - -//------------------------------------- -// ASSAULT CHAINGUN CHARACTERISTICS -//------------------------------------- - -datablock TurretData(AssaultPlasmaTurret) : TurretDamageProfile -{ - className = VehicleTurret; - catagory = "Turrets"; - shapeFile = "Turret_tank_base.dts"; - preload = true; - - mass = 1.0; // Not really relevant - - maxEnergy = 1; - maxDamage = AssaultVehicle.maxDamage; - destroyedLevel = AssaultVehicle.destroyedLevel; - repairRate = 0; - - // capacitor - maxCapacitorEnergy = 250; - capacitorRechargeRate = 1.0; - - thetaMin = 0; - thetaMax = 100; - - inheritEnergyFromMount = true; - firstPersonOnly = true; - useEyePoint = true; - numWeapons = 2; - - cameraDefaultFov = 90.0; - cameraMinFov = 5.0; - cameraMaxFov = 120.0; - - targetNameTag = 'Beowulf Chaingun'; - targetTypeTag = 'Turret'; -}; - -datablock TurretImageData(AssaultPlasmaTurretBarrel) -{ - shapeFile = "turret_tank_barrelchain.dts"; - mountPoint = 1; - - projectile = AssaultChaingunBullet; - projectileType = TracerProjectile; - - casing = ShellDebris; - shellExitDir = "1.0 0.3 1.0"; - shellExitOffset = "0.15 -0.56 -0.1"; - shellExitVariance = 15.0; - shellVelocity = 3.0; - - projectileSpread = 12.0 / 1000.0; - - useCapacitor = true; - usesEnergy = true; - useMountEnergy = true; - fireEnergy = 7.5; - minEnergy = 15.0; - - // Turret parameters - activationMS = 4000; - deactivateDelayMS = 500; - thinkTimeMS = 200; - degPerSecTheta = 360; - degPerSecPhi = 360; - attackRadius = 75; - - // State transitions - stateName[0] = "Activate"; - stateTransitionOnNotLoaded[0] = "Dead"; - stateTransitionOnLoaded[0] = "ActivateReady"; - stateSound[0] = AssaultTurretActivateSound; - - stateName[1] = "ActivateReady"; - stateSequence[1] = "Activate"; - stateSound[1] = AssaultTurretActivateSound; - stateTimeoutValue[1] = 1; - stateTransitionOnTimeout[1] = "Ready"; - stateTransitionOnNotLoaded[1] = "Deactivate"; - - stateName[2] = "Ready"; - stateTransitionOnNotLoaded[2] = "Deactivate"; - stateTransitionOnTriggerDown[2] = "Fire"; - stateTransitionOnNoAmmo[2] = "NoAmmo"; - - stateName[3] = "Fire"; - stateSequence[3] = "Fire"; - stateSequenceRandomFlash[3] = true; - stateFire[3] = true; - stateAllowImageChange[3] = false; - stateSound[3] = AssaultChaingunFireSound; - stateScript[3] = "onFire"; - stateTimeoutValue[3] = 0.1; - stateTransitionOnTimeout[3] = "Fire"; - stateTransitionOnTriggerUp[3] = "Reload"; - stateTransitionOnNoAmmo[3] = "noAmmo"; - - stateName[4] = "Reload"; - stateSequence[4] = "Reload"; - stateTimeoutValue[4] = 0.1; - stateAllowImageChange[4] = false; - stateTransitionOnTimeout[4] = "Ready"; - stateTransitionOnNoAmmo[4] = "NoAmmo"; - stateWaitForTimeout[4] = true; - - stateName[5] = "Deactivate"; - stateSequence[5] = "Activate"; - stateDirection[5] = false; - stateTimeoutValue[5] = 30; - stateTransitionOnTimeout[5] = "ActivateReady"; - - stateName[6] = "Dead"; - stateTransitionOnLoaded[6] = "ActivateReady"; - stateTransitionOnTriggerDown[6] = "DryFire"; - - stateName[7] = "DryFire"; - stateSound[7] = AssaultChaingunDryFireSound; - stateTimeoutValue[7] = 0.5; - stateTransitionOnTimeout[7] = "NoAmmo"; - - stateName[8] = "NoAmmo"; - stateTransitionOnAmmo[8] = "Reload"; - stateSequence[8] = "NoAmmo"; - stateTransitionOnTriggerDown[8] = "DryFire"; - -}; - -//------------------------------------- -// ASSAULT MORTAR (projectile) -//------------------------------------- - -datablock ItemData(AssaultMortarAmmo) -{ - className = Ammo; - catagory = "Ammo"; - shapeFile = "repair_kit.dts"; - mass = 1; - elasticity = 0.5; - friction = 0.6; - pickupRadius = 1; - - computeCRC = true; -}; - -datablock GrenadeProjectileData(AssaultMortar) -{ - projectileShapeName = "mortar_projectile.dts"; - emitterDelay = -1; - directDamage = 0.0; - hasDamageRadius = true; - indirectDamage = 1.0; - damageRadius = 25.0; - radiusDamageType = $DamageType::TankMortar; - kickBackStrength = 2500; - - sound = MortarProjectileSound; - explosion = "MortarExplosion"; - velInheritFactor = 1.0; - - baseEmitter = MortarSmokeEmitter; - - grenadeElasticity = 0.0; - grenadeFriction = 0.4; - armingDelayMS = 250; - muzzleVelocity = 77.15; // z0dd - ZOD, 9/27/02. More velocity to compensate for higher gravity. Was 65 - drag = 0.1; - - hasLight = true; - lightRadius = 4; - lightColor = "0.1 0.4 0.1"; -}; - -//------------------------------------- -// ASSAULT MORTAR CHARACTERISTICS -//------------------------------------- - -datablock TurretImageData(AssaultMortarTurretBarrel) -{ - shapeFile = "turret_tank_barrelmortar.dts"; - mountPoint = 0; - -// ammo = AssaultMortarAmmo; - projectile = AssaultMortar; - projectileType = GrenadeProjectile; - - usesEnergy = true; - useMountEnergy = true; - fireEnergy = 77.00; - minEnergy = 77.00; - useCapacitor = true; - - // Turret parameters - activationMS = 4000; - deactivateDelayMS = 1500; - thinkTimeMS = 200; - degPerSecTheta = 360; - degPerSecPhi = 360; - attackRadius = 75; - - // State transitions - stateName[0] = "Activate"; - stateTransitionOnNotLoaded[0] = "Dead"; - stateTransitionOnLoaded[0] = "ActivateReady"; - - stateName[1] = "ActivateReady"; - stateSequence[1] = "Activate"; - stateSound[1] = AssaultTurretActivateSound; - stateTimeoutValue[1] = 1.0; - stateTransitionOnTimeout[1] = "Ready"; - stateTransitionOnNotLoaded[1] = "Deactivate"; - - stateName[2] = "Ready"; - stateTransitionOnNotLoaded[2] = "Deactivate"; - stateTransitionOnNoAmmo[2] = "NoAmmo"; - stateTransitionOnTriggerDown[2] = "Fire"; - - stateName[3] = "Fire"; - stateSequence[3] = "Fire"; - stateTransitionOnTimeout[3] = "Reload"; - stateTimeoutValue[3] = 1.0; - stateFire[3] = true; - stateRecoil[3] = LightRecoil; - stateAllowImageChange[3] = false; - stateSound[3] = AssaultMortarFireSound; - stateScript[3] = "onFire"; - - stateName[4] = "Reload"; - stateSequence[4] = "Reload"; - stateTimeoutValue[4] = 1.0; - stateAllowImageChange[4] = false; - stateTransitionOnTimeout[4] = "Ready"; - //stateTransitionOnNoAmmo[4] = "NoAmmo"; - stateWaitForTimeout[4] = true; - - stateName[5] = "Deactivate"; - stateDirection[5] = false; - stateSequence[5] = "Activate"; - stateTimeoutValue[5] = 1.0; - stateTransitionOnLoaded[5] = "ActivateReady"; - stateTransitionOnTimeout[5] = "Dead"; - - stateName[6] = "Dead"; - stateTransitionOnLoaded[6] = "ActivateReady"; - stateTransitionOnTriggerDown[6] = "DryFire"; - - stateName[7] = "DryFire"; - stateSound[7] = AssaultMortarDryFireSound; - stateTimeoutValue[7] = 1.0; - stateTransitionOnTimeout[7] = "NoAmmo"; - - stateName[8] = "NoAmmo"; - stateSequence[8] = "NoAmmo"; - stateTransitionOnAmmo[8] = "Reload"; - stateTransitionOnTriggerDown[8] = "DryFire"; -}; - -datablock TurretImageData(AssaultTurretParam) -{ - mountPoint = 2; - shapeFile = "turret_muzzlepoint.dts"; - - projectile = AssaultChaingunBullet; - projectileType = TracerProjectile; - - useCapacitor = true; - usesEnergy = true; - - // Turret parameters - activationMS = 1000; - deactivateDelayMS = 1500; - thinkTimeMS = 200; - degPerSecTheta = 500; - degPerSecPhi = 500; - - attackRadius = 75; -}; - - - +//************************************************************** +// BEOWULF ASSAULT VEHICLE +//************************************************************** +//************************************************************** +// SOUNDS +//************************************************************** +datablock EffectProfile(AssaultVehicleEngineEffect) +{ + effectname = "vehicles/tank_engine"; + minDistance = 5.0; + maxDistance = 10.0; +}; + +datablock EffectProfile(AssaultVehicleThrustEffect) +{ + effectname = "vehicles/tank_boost"; + minDistance = 5.0; + maxDistance = 10.0; +}; + +datablock EffectProfile(AssaultTurretActivateEffect) +{ + effectname = "vehicles/tank_activate"; + minDistance = 5.0; + maxDistance = 10.0; +}; + +datablock EffectProfile(AssaultMortarDryFireEffect) +{ + effectname = "weapons/mortar_dryfire"; + minDistance = 5.0; + maxDistance = 10.0; +}; + +datablock EffectProfile(AssaultMortarFireEffect) +{ + effectname = "vehicles/tank_mortar_fire"; + minDistance = 5.0; + maxDistance = 10.0; +}; + +datablock EffectProfile(AssaultMortarReloadEffect) +{ + effectname = "weapons/mortar_reload"; + minDistance = 5.0; + maxDistance = 10.0; +}; + +datablock EffectProfile(AssaultChaingunFireEffect) +{ + effectname = "weapons/chaingun_fire"; + minDistance = 5.0; + maxDistance = 10.0; +}; + +datablock AudioProfile(AssaultVehicleSkid) +{ + filename = "fx/vehicles/tank_skid.wav"; + description = ClosestLooping3d; + preload = true; +}; + +datablock AudioProfile(AssaultVehicleEngineSound) +{ + filename = "fx/vehicles/tank_engine.wav"; + description = AudioDefaultLooping3d; + preload = true; + effect = AssaultVehicleEngineEffect; +}; + +datablock AudioProfile(AssaultVehicleThrustSound) +{ + filename = "fx/vehicles/tank_boost.wav"; + description = AudioDefaultLooping3d; + preload = true; + effect = AssaultVehicleThrustEffect; +}; + +datablock AudioProfile(AssaultChaingunFireSound) +{ + filename = "fx/vehicles/tank_chaingun.wav"; + description = AudioDefaultLooping3d; + preload = true; + effect = AssaultChaingunFireEffect; +}; + +datablock AudioProfile(AssaultChaingunReloadSound) +{ + filename = "fx/weapons/chaingun_dryfire.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(TankChaingunProjectile) +{ + filename = "fx/weapons/chaingun_projectile.wav"; + description = ProjectileLooping3d; + preload = true; +}; + +datablock AudioProfile(AssaultTurretActivateSound) +{ + filename = "fx/vehicles/tank_activate.wav"; + description = AudioClose3d; + preload = true; + effect = AssaultTurretActivateEffect; +}; + +datablock AudioProfile(AssaultChaingunDryFireSound) +{ + filename = "fx/weapons/chaingun_dryfire.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(AssaultChaingunIdleSound) +{ + filename = "fx/misc/diagnostic_on.wav"; + description = ClosestLooping3d; + preload = true; +}; + +datablock AudioProfile(AssaultMortarDryFireSound) +{ + filename = "fx/weapons/mortar_dryfire.wav"; + description = AudioClose3d; + preload = true; + effect = AssaultMortarDryFireEffect; +}; + +datablock AudioProfile(AssaultMortarFireSound) +{ + filename = "fx/vehicles/tank_mortar_fire.wav"; + description = AudioClose3d; + preload = true; + effect = AssaultMortarFireEffect; +}; + +datablock AudioProfile(AssaultMortarReloadSound) +{ + filename = "fx/weapons/mortar_reload.wav"; + description = AudioClose3d; + preload = true; + effect = AssaultMortarReloadEffect; +}; + +datablock AudioProfile(AssaultMortarIdleSound) +{ + filename = "fx/misc/diagnostic_on.wav"; + description = ClosestLooping3d; + preload = true; +}; + +//************************************************************** +// LIGHTS +//************************************************************** +datablock RunningLightData(TankLight1) +{ + radius = 1.5; + color = "1.0 1.0 1.0 0.2"; + nodeName = "Headlight_node01"; + direction = "0.0 1.0 0.0"; + texture = "special/headlight4"; +}; + +datablock RunningLightData(TankLight2) +{ + radius = 1.5; + color = "1.0 1.0 1.0 0.2"; + nodeName = "Headlight_node02"; + direction = "0.0 1.0 0.0"; + texture = "special/headlight4"; +}; + +datablock RunningLightData(TankLight3) +{ + radius = 1.5; + color = "1.0 1.0 1.0 0.2"; + nodeName = "Headlight_node03"; + direction = "0.0 1.0 0.0"; + texture = "special/headlight4"; +}; + +datablock RunningLightData(TankLight4) +{ + radius = 1.5; + color = "1.0 1.0 1.0 0.2"; + nodeName = "Headlight_node04"; + direction = "0.0 1.0 0.0"; + texture = "special/headlight4"; +}; + +//************************************************************** +// VEHICLE CHARACTERISTICS +//************************************************************** + +datablock HoverVehicleData(AssaultVehicle) : TankDamageProfile +{ + spawnOffset = "0 0 4"; + + floatingGravMag = 4.5; + + catagory = "Vehicles"; + shapeFile = "vehicle_grav_tank.dts"; + multipassenger = true; + computeCRC = true; + renderWhenDestroyed = false; + + weaponNode = 1; + + debrisShapeName = "vehicle_land_assault_debris.dts"; + debris = ShapeDebris; + + drag = 0.0; + density = 0.9; + + mountPose[0] = sitting; + mountPose[1] = sitting; + numMountPoints = 2; + isProtectedMountPoint[0] = true; + isProtectedMountPoint[1] = true; + + cameraMaxDist = 20; + cameraOffset = 3; + cameraLag = 1.5; + explosion = LargeGroundVehicleExplosion; + explosionDamage = 0.5; + explosionRadius = 5.0; + + maxSteeringAngle = 0.5; // 20 deg. + + maxDamage = 3.15; + destroyedLevel = 3.15; + + isShielded = true; + rechargeRate = 1.0; + energyPerDamagePoint = 135; + maxEnergy = 400; + minJetEnergy = 15; + jetEnergyDrain = 2.0; + + // Rigid Body + mass = 1500; + bodyFriction = 0.8; + bodyRestitution = 0.5; + minRollSpeed = 3; + gyroForce = 400; + gyroDamping = 0.3; + stabilizerForce = 20; + minDrag = 10; + softImpactSpeed = 18; // Play SoftImpact Sound. z0dd - ZOD, 3/30/02. Higher speed before tank takes ground collision dmg. Was 15 + hardImpactSpeed = 21; // Play HardImpact Sound. z0dd - ZOD, 3/30/02. Higher speed before tank takes ground collision dmg. Was 18 + + // Ground Impact Damage (uses DamageType::Ground) + minImpactSpeed = 20; // z0dd - ZOD, 3/30/02. Higher speed before tank takes ground collision dmg. Was 17 + speedDamageScale = 0.060; + + // Object Impact Damage (uses DamageType::Impact) + collDamageThresholdVel = 18; + collDamageMultiplier = 0.045; + + dragForce = 40 / 20; + vertFactor = 0.0; + floatingThrustFactor = 0.15; // z0dd - ZOD, 3/30/02. Stronger air cushion. Was 0.15 + + mainThrustForce = 55; // z0dd - ZOD, 3/30/02. Was 50 + reverseThrustForce = 40; + strafeThrustForce = 40; + turboFactor = 1.85; // z0dd - ZOD, 3/30/02. Was 1.7 + + brakingForce = 25; + brakingActivationSpeed = 4; + + stabLenMin = 3.25; + stabLenMax = 4; + stabSpringConstant = 50; + stabDampingConstant = 20; + + gyroDrag = 20; + normalForce = 20; + restorativeForce = 10; + steeringForce = 15; + rollForce = 5; + pitchForce = 3; + + dustEmitter = TankDustEmitter; + triggerDustHeight = 3.5; + dustHeight = 1.0; + dustTrailEmitter = TireEmitter; + dustTrailOffset = "0.0 -1.0 0.5"; + triggerTrailHeight = 3.6; + dustTrailFreqMod = 15.0; + + jetSound = AssaultVehicleThrustSound; + engineSound = AssaultVehicleEngineSound; + floatSound = AssaultVehicleSkid; + softImpactSound = GravSoftImpactSound; + hardImpactSound = HardImpactSound; + wheelImpactSound = WheelImpactSound; + + forwardJetEmitter = TankJetEmitter; + + // + softSplashSoundVelocity = 5.0; + mediumSplashSoundVelocity = 10.0; + hardSplashSoundVelocity = 15.0; + exitSplashSoundVelocity = 10.0; + + exitingWater = VehicleExitWaterMediumSound; + impactWaterEasy = VehicleImpactWaterSoftSound; + impactWaterMedium = VehicleImpactWaterMediumSound; + impactWaterHard = VehicleImpactWaterMediumSound; + waterWakeSound = VehicleWakeMediumSplashSound; + + minMountDist = 4; + + damageEmitter[0] = SmallLightDamageSmoke; + damageEmitter[1] = SmallHeavyDamageSmoke; + damageEmitter[2] = DamageBubbles; + damageEmitterOffset[0] = "0.0 -1.5 3.5 "; + damageLevelTolerance[0] = 0.3; + damageLevelTolerance[1] = 0.7; + numDmgEmitterAreas = 1; + + splashEmitter[0] = VehicleFoamDropletsEmitter; + splashEmitter[1] = VehicleFoamEmitter; + + shieldImpact = VehicleShieldImpact; + + cmdCategory = "Tactical"; + cmdIcon = CMDGroundTankIcon; + cmdMiniIconName = "commander/MiniIcons/com_tank_grey"; + targetNameTag = 'Beowulf'; + targetTypeTag = 'Assault Tank'; + sensorData = VehiclePulseSensor; + sensorRadius = VehiclePulseSensor.detectRadius; // z0dd - ZOD, 3/30/02. Allows sensor to be shown on CC + + checkRadius = 5.5535; + observeParameters = "1 10 10"; + runningLight[0] = TankLight1; + runningLight[1] = TankLight2; + runningLight[2] = TankLight3; + runningLight[3] = TankLight4; + shieldEffectScale = "0.9 1.0 0.6"; + showPilotInfo = 1; +}; + +//************************************************************** +// WEAPONS +//************************************************************** + +//------------------------------------- +// ASSAULT CHAINGUN (projectile) +//------------------------------------- + +datablock TracerProjectileData(AssaultChaingunBullet) +{ + doDynamicClientHits = true; + + projectileShapeName = ""; + directDamage = 0.16; + directDamageType = $DamageType::TankChaingun; + hasDamageRadius = false; + splash = ChaingunSplash; + + kickbackstrength = 0.0; + sound = TankChaingunProjectile; + + dryVelocity = 425.0; + wetVelocity = 100.0; + velInheritFactor = 1.0; + fizzleTimeMS = 3000; + lifetimeMS = 3000; + explodeOnDeath = false; + reflectOnWaterImpactAngle = 0.0; + explodeOnWaterImpact = false; + deflectionOnWaterImpact = 0.0; + fizzleUnderwaterMS = 3000; + + tracerLength = 15.0; + tracerAlpha = false; + tracerMinPixels = 6; + tracerColor = 211.0/255.0 @ " " @ 215.0/255.0 @ " " @ 120.0/255.0 @ " 0.75"; + tracerTex[0] = "special/tracer00"; + tracerTex[1] = "special/tracercross"; + tracerWidth = 0.10; + crossSize = 0.20; + crossViewAng = 0.990; + renderCross = true; + + decalData[0] = ChaingunDecal1; + decalData[1] = ChaingunDecal2; + decalData[2] = ChaingunDecal3; + decalData[3] = ChaingunDecal4; + decalData[4] = ChaingunDecal5; + decalData[5] = ChaingunDecal6; + + activateDelayMS = 100; + + explosion = ChaingunExplosion; +}; + +//------------------------------------- +// ASSAULT CHAINGUN CHARACTERISTICS +//------------------------------------- + +datablock TurretData(AssaultPlasmaTurret) : TurretDamageProfile +{ + className = VehicleTurret; + catagory = "Turrets"; + shapeFile = "Turret_tank_base.dts"; + preload = true; + + mass = 1.0; // Not really relevant + + maxEnergy = 1; + maxDamage = AssaultVehicle.maxDamage; + destroyedLevel = AssaultVehicle.destroyedLevel; + repairRate = 0; + + // capacitor + maxCapacitorEnergy = 250; + capacitorRechargeRate = 1.0; + + thetaMin = 0; + thetaMax = 100; + + inheritEnergyFromMount = true; + firstPersonOnly = true; + useEyePoint = true; + numWeapons = 2; + + cameraDefaultFov = 90.0; + cameraMinFov = 5.0; + cameraMaxFov = 120.0; + + targetNameTag = 'Beowulf Chaingun'; + targetTypeTag = 'Turret'; +}; + +datablock TurretImageData(AssaultPlasmaTurretBarrel) +{ + shapeFile = "turret_tank_barrelchain.dts"; + mountPoint = 1; + + projectile = AssaultChaingunBullet; + projectileType = TracerProjectile; + + casing = ShellDebris; + shellExitDir = "1.0 0.3 1.0"; + shellExitOffset = "0.15 -0.56 -0.1"; + shellExitVariance = 15.0; + shellVelocity = 3.0; + + projectileSpread = 12.0 / 1000.0; + + useCapacitor = true; + usesEnergy = true; + useMountEnergy = true; + fireEnergy = 7.5; + minEnergy = 15.0; + + // Turret parameters + activationMS = 4000; + deactivateDelayMS = 500; + thinkTimeMS = 200; + degPerSecTheta = 360; + degPerSecPhi = 360; + attackRadius = 75; + + // State transitions + stateName[0] = "Activate"; + stateTransitionOnNotLoaded[0] = "Dead"; + stateTransitionOnLoaded[0] = "ActivateReady"; + stateSound[0] = AssaultTurretActivateSound; + + stateName[1] = "ActivateReady"; + stateSequence[1] = "Activate"; + stateSound[1] = AssaultTurretActivateSound; + stateTimeoutValue[1] = 1; + stateTransitionOnTimeout[1] = "Ready"; + stateTransitionOnNotLoaded[1] = "Deactivate"; + + stateName[2] = "Ready"; + stateTransitionOnNotLoaded[2] = "Deactivate"; + stateTransitionOnTriggerDown[2] = "Fire"; + stateTransitionOnNoAmmo[2] = "NoAmmo"; + + stateName[3] = "Fire"; + stateSequence[3] = "Fire"; + stateSequenceRandomFlash[3] = true; + stateFire[3] = true; + stateAllowImageChange[3] = false; + stateSound[3] = AssaultChaingunFireSound; + stateScript[3] = "onFire"; + stateTimeoutValue[3] = 0.1; + stateTransitionOnTimeout[3] = "Fire"; + stateTransitionOnTriggerUp[3] = "Reload"; + stateTransitionOnNoAmmo[3] = "noAmmo"; + + stateName[4] = "Reload"; + stateSequence[4] = "Reload"; + stateTimeoutValue[4] = 0.1; + stateAllowImageChange[4] = false; + stateTransitionOnTimeout[4] = "Ready"; + stateTransitionOnNoAmmo[4] = "NoAmmo"; + stateWaitForTimeout[4] = true; + + stateName[5] = "Deactivate"; + stateSequence[5] = "Activate"; + stateDirection[5] = false; + stateTimeoutValue[5] = 30; + stateTransitionOnTimeout[5] = "ActivateReady"; + + stateName[6] = "Dead"; + stateTransitionOnLoaded[6] = "ActivateReady"; + stateTransitionOnTriggerDown[6] = "DryFire"; + + stateName[7] = "DryFire"; + stateSound[7] = AssaultChaingunDryFireSound; + stateTimeoutValue[7] = 0.5; + stateTransitionOnTimeout[7] = "NoAmmo"; + + stateName[8] = "NoAmmo"; + stateTransitionOnAmmo[8] = "Reload"; + stateSequence[8] = "NoAmmo"; + stateTransitionOnTriggerDown[8] = "DryFire"; + +}; + +//------------------------------------- +// ASSAULT MORTAR (projectile) +//------------------------------------- + +datablock ItemData(AssaultMortarAmmo) +{ + className = Ammo; + catagory = "Ammo"; + shapeFile = "repair_kit.dts"; + mass = 1; + elasticity = 0.5; + friction = 0.6; + pickupRadius = 1; + + computeCRC = true; +}; + +datablock GrenadeProjectileData(AssaultMortar) +{ + projectileShapeName = "mortar_projectile.dts"; + emitterDelay = -1; + directDamage = 0.0; + hasDamageRadius = true; + indirectDamage = 1.0; + damageRadius = 25.0; + radiusDamageType = $DamageType::TankMortar; + kickBackStrength = 2500; + + sound = MortarProjectileSound; + explosion = "MortarExplosion"; + velInheritFactor = 1.0; + + baseEmitter = MortarSmokeEmitter; + + grenadeElasticity = 0.0; + grenadeFriction = 0.4; + armingDelayMS = 250; + muzzleVelocity = 77.15; // z0dd - ZOD, 9/27/02. More velocity to compensate for higher gravity. Was 65 + drag = 0.1; + + hasLight = true; + lightRadius = 4; + lightColor = "0.1 0.4 0.1"; +}; + +//------------------------------------- +// ASSAULT MORTAR CHARACTERISTICS +//------------------------------------- + +datablock TurretImageData(AssaultMortarTurretBarrel) +{ + shapeFile = "turret_tank_barrelmortar.dts"; + mountPoint = 0; + +// ammo = AssaultMortarAmmo; + projectile = AssaultMortar; + projectileType = GrenadeProjectile; + + usesEnergy = true; + useMountEnergy = true; + fireEnergy = 77.00; + minEnergy = 77.00; + useCapacitor = true; + + // Turret parameters + activationMS = 4000; + deactivateDelayMS = 1500; + thinkTimeMS = 200; + degPerSecTheta = 360; + degPerSecPhi = 360; + attackRadius = 75; + + // State transitions + stateName[0] = "Activate"; + stateTransitionOnNotLoaded[0] = "Dead"; + stateTransitionOnLoaded[0] = "ActivateReady"; + + stateName[1] = "ActivateReady"; + stateSequence[1] = "Activate"; + stateSound[1] = AssaultTurretActivateSound; + stateTimeoutValue[1] = 1.0; + stateTransitionOnTimeout[1] = "Ready"; + stateTransitionOnNotLoaded[1] = "Deactivate"; + + stateName[2] = "Ready"; + stateTransitionOnNotLoaded[2] = "Deactivate"; + stateTransitionOnNoAmmo[2] = "NoAmmo"; + stateTransitionOnTriggerDown[2] = "Fire"; + + stateName[3] = "Fire"; + stateSequence[3] = "Fire"; + stateTransitionOnTimeout[3] = "Reload"; + stateTimeoutValue[3] = 1.0; + stateFire[3] = true; + stateRecoil[3] = LightRecoil; + stateAllowImageChange[3] = false; + stateSound[3] = AssaultMortarFireSound; + stateScript[3] = "onFire"; + + stateName[4] = "Reload"; + stateSequence[4] = "Reload"; + stateTimeoutValue[4] = 1.0; + stateAllowImageChange[4] = false; + stateTransitionOnTimeout[4] = "Ready"; + //stateTransitionOnNoAmmo[4] = "NoAmmo"; + stateWaitForTimeout[4] = true; + + stateName[5] = "Deactivate"; + stateDirection[5] = false; + stateSequence[5] = "Activate"; + stateTimeoutValue[5] = 1.0; + stateTransitionOnLoaded[5] = "ActivateReady"; + stateTransitionOnTimeout[5] = "Dead"; + + stateName[6] = "Dead"; + stateTransitionOnLoaded[6] = "ActivateReady"; + stateTransitionOnTriggerDown[6] = "DryFire"; + + stateName[7] = "DryFire"; + stateSound[7] = AssaultMortarDryFireSound; + stateTimeoutValue[7] = 1.0; + stateTransitionOnTimeout[7] = "NoAmmo"; + + stateName[8] = "NoAmmo"; + stateSequence[8] = "NoAmmo"; + stateTransitionOnAmmo[8] = "Reload"; + stateTransitionOnTriggerDown[8] = "DryFire"; +}; + +datablock TurretImageData(AssaultTurretParam) +{ + mountPoint = 2; + shapeFile = "turret_muzzlepoint.dts"; + + projectile = AssaultChaingunBullet; + projectileType = TracerProjectile; + + useCapacitor = true; + usesEnergy = true; + + // Turret parameters + activationMS = 1000; + deactivateDelayMS = 1500; + thinkTimeMS = 200; + degPerSecTheta = 500; + degPerSecPhi = 500; + + attackRadius = 75; +}; + + + diff --git a/scripts/vehicles/vehicle_wildcat.cs b/scripts/vehicles/vehicle_wildcat.cs index bc16987..e1770b6 100644 --- a/scripts/vehicles/vehicle_wildcat.cs +++ b/scripts/vehicles/vehicle_wildcat.cs @@ -1,377 +1,377 @@ -//************************************************************** -// WILDCAT GRAV CYCLE -//************************************************************** -//************************************************************** -// SOUNDS -//************************************************************** -datablock EffectProfile(ScoutEngineEffect) -{ - effectname = "vehicles/outrider_engine"; - minDistance = 5.0; - maxDistance = 10.0; -}; - -datablock EffectProfile(ScoutThrustEffect) -{ - effectname = "vehicles/outrider_boost"; - minDistance = 5.0; - maxDistance = 10.0; -}; - -datablock AudioProfile(ScoutSqueelSound) -{ - filename = "fx/vehicles/outrider_skid.wav"; - description = ClosestLooping3d; - preload = true; -}; - -// Scout -datablock AudioProfile(ScoutEngineSound) -{ - filename = "fx/vehicles/outrider_engine.wav"; - description = AudioDefaultLooping3d; - preload = true; - effect = ScoutEngineEffect; -}; - -datablock AudioProfile(ScoutThrustSound) -{ - filename = "fx/vehicles/outrider_boost.wav"; - description = AudioDefaultLooping3d; - preload = true; - effect = ScoutThrustEffect; -}; - -//************************************************************** -// LIGHTS -//************************************************************** -datablock RunningLightData(WildcatLight1) -{ - radius = 1.0; - color = "1.0 1.0 1.0 0.3"; - nodeName = "Headlight_node01"; - direction = "-1.0 1.0 0.0"; - texture = "special/headlight4"; -}; - -datablock RunningLightData(WildcatLight2) -{ - radius = 1.0; - color = "1.0 1.0 1.0 0.3"; - nodeName = "Headlight_node02"; - direction = "1.0 1.0 0.0"; - texture = "special/headlight4"; -}; - -datablock RunningLightData(WildcatLight3) -{ - type = 2; - radius = 100.0; - color = "1.0 1.0 1.0 1.0"; - offset = "0.0 0.0 0.0"; - direction = "0.0 1.0 0.0"; - texture = "special/projheadlight"; -}; - -//************************************************************** -// VEHICLE CHARACTERISTICS -//************************************************************** - -datablock HoverVehicleData(ScoutVehicle) : WildcatDamageProfile -{ - spawnOffset = "0 0 1"; - - floatingGravMag = 3.5; - - catagory = "Vehicles"; - shapeFile = "vehicle_grav_scout.dts"; - computeCRC = true; - - debrisShapeName = "vehicle_grav_scout_debris.dts"; - debris = ShapeDebris; - renderWhenDestroyed = false; - - drag = 0.0; - density = 0.9; - - mountPose[0] = scoutRoot; - cameraMaxDist = 5.0; - cameraOffset = 0.7; - cameraLag = 0.5; - numMountPoints = 1; - isProtectedMountPoint[0] = true; - explosion = VehicleExplosion; - explosionDamage = 0.5; - explosionRadius = 5.0; - - lightOnly = 1; - - maxDamage = 0.60; - destroyedLevel = 0.60; - - isShielded = true; - rechargeRate = 0.7; - energyPerDamagePoint = 95; // z0dd - ZOD, 3/30/02. Bike shield is less protective. was 75 - maxEnergy = 150; - minJetEnergy = 15; - jetEnergyDrain = 1.3; - - // Rigid Body - mass = 400; - bodyFriction = 0.1; - bodyRestitution = 0.5; - softImpactSpeed = 20; // Play SoftImpact Sound - hardImpactSpeed = 28; // Play HardImpact Sound - - // Ground Impact Damage (uses DamageType::Ground) - minImpactSpeed = 29; - speedDamageScale = 0.010; - - // Object Impact Damage (uses DamageType::Impact) - collDamageThresholdVel = 23; - collDamageMultiplier = 0.030; - - dragForce = 25 / 45.0; - vertFactor = 0.0; - floatingThrustFactor = 0.35; - - mainThrustForce = 35; // z0dd - ZOD, 3/30/02. Bike main thruster more powerful. was 30 - reverseThrustForce = 10; - strafeThrustForce = 8; - turboFactor = 1.80; // z0dd - ZOD, 3/30/02. Bike turbo thruster more powerful. was 1.5 - - brakingForce = 25; - brakingActivationSpeed = 4; - - stabLenMin = 2.25; - stabLenMax = 3.75; - stabSpringConstant = 30; - stabDampingConstant = 16; - - gyroDrag = 16; - normalForce = 30; - restorativeForce = 20; - steeringForce = 30; - rollForce = 15; - pitchForce = 7; - - dustEmitter = VehicleLiftoffDustEmitter; - triggerDustHeight = 2.5; - dustHeight = 1.0; - dustTrailEmitter = TireEmitter; - dustTrailOffset = "0.0 -1.0 0.5"; - triggerTrailHeight = 3.6; - dustTrailFreqMod = 15.0; - - jetSound = ScoutSqueelSound; - engineSound = ScoutEngineSound; - floatSound = ScoutThrustSound; - softImpactSound = GravSoftImpactSound; - hardImpactSound = HardImpactSound; - //wheelImpactSound = WheelImpactSound; - - // - softSplashSoundVelocity = 10.0; - mediumSplashSoundVelocity = 20.0; - hardSplashSoundVelocity = 30.0; - exitSplashSoundVelocity = 10.0; - - exitingWater = VehicleExitWaterSoftSound; - impactWaterEasy = VehicleImpactWaterSoftSound; - impactWaterMedium = VehicleImpactWaterSoftSound; - impactWaterHard = VehicleImpactWaterMediumSound; - waterWakeSound = VehicleWakeSoftSplashSound; - - minMountDist = 4; - - damageEmitter[0] = SmallLightDamageSmoke; - damageEmitter[1] = SmallHeavyDamageSmoke; - damageEmitter[2] = DamageBubbles; - damageEmitterOffset[0] = "0.0 -1.5 0.5 "; - damageLevelTolerance[0] = 0.3; - damageLevelTolerance[1] = 0.7; - numDmgEmitterAreas = 1; - - splashEmitter[0] = VehicleFoamDropletsEmitter; - splashEmitter[1] = VehicleFoamEmitter; - - shieldImpact = VehicleShieldImpact; - - forwardJetEmitter = WildcatJetEmitter; - - cmdCategory = Tactical; - cmdIcon = CMDHoverScoutIcon; - cmdMiniIconName = "commander/MiniIcons/com_landscout_grey"; - targetNameTag = 'WildCat'; - targetTypeTag = 'Grav Cycle'; - sensorData = VehiclePulseSensor; - sensorRadius = VehiclePulseSensor.detectRadius; // z0dd - ZOD, 3/30/02. Allows sensor to be shown on CC - - checkRadius = 1.7785; - observeParameters = "1 10 10"; - - runningLight[0] = WildcatLight1; - runningLight[1] = WildcatLight2; - runningLight[2] = WildcatLight3; - - shieldEffectScale = "0.9375 1.125 0.6"; -}; - -//************************************************************** -// WEAPONS: z0dd - ZOD, 5/14/02 -//************************************************************** - -$DeathMessageCTurretTeamKill[$DamageType::Bullet, 0] = '\c0%4 TEAMKILLED %1 by strafing from a Wildcat.'; - -$DeathMessageCTurretKill[$DamageType::Bullet, 0] = '\c0%4 turns %1 into swiss cheese with %6 Wildcat.'; -$DeathMessageCTurretKill[$DamageType::Bullet, 1] = '\c0The lead from %4\'s Wildcat turns %1 into finely shredded meat.'; -$DeathMessageCTurretKill[$DamageType::Bullet, 2] = '\c0%4 drills %1 full of holes with %6 Wildcat.'; - -datablock EffectProfile(GravChaingunFireEffect) -{ - effectname = "weapons/chaingun_fire"; - minDistance = 5.0; - maxDistance = 10.0; -}; - -datablock AudioProfile(GravChaingunFireSound) -{ - filename = "fx/vehicles/tank_chaingun.wav"; - description = AudioDefaultLooping3d; - preload = true; - effect = GravChaingunFireEffect; -}; - -datablock AudioProfile(GravChaingunDryFireSound) -{ - filename = "fx/weapons/chaingun_off.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(GravChaingunIdleSound) -{ - filename = "fx/misc/diagnostic_on.wav"; - description = ClosestLooping3d; - preload = true; -}; - -datablock TracerProjectileData(GravBullet) : ChaingunBullet -{ - projectileShapeName = "chaingun_shot.dts"; - directDamage = 0.135; -}; - -datablock ShapeBaseImageData(GravChaingunImage) -{ - className = WeaponImage; - shapeFile = "weapon_chaingun.dts"; - item = Chaingun; - offset = "-0.1 0.68 +0.26"; - //rotation = "0 0 0 90"; - projectile = GravBullet; //ChaingunBullet; - projectileType = TracerProjectile; - projectileSpread = 18.0 / 1000.0; // 10 - emap = true; - mountPoint = 10; - usesEnergy = true; - useMountEnergy = true; - // DAVEG -- balancing numbers below! - minEnergy = 8; - fireEnergy = 1.55; - - stateName[0] = "Activate"; - stateSequence[0] = "Activate"; - stateSound[0] = GravChaingunIdleSound; - stateAllowImageChange[0] = false; - stateTimeoutValue[0] = 0.1; - stateTransitionOnTimeout[0] = "Ready"; - stateTransitionOnNoAmmo[0] = "NoAmmo"; - - stateName[1] = "Ready"; - stateSpinThread[1] = Stop; - stateTransitionOnTriggerDown[1] = "Spinup"; - stateTransitionOnNoAmmo[1] = "NoAmmo"; - - stateName[2] = "NoAmmo"; - stateTransitionOnAmmo[2] = "Ready"; - stateSpinThread[2] = Stop; - stateTransitionOnTriggerDown[2] = "DryFire"; - - stateName[3] = "Spinup"; - stateSpinThread[3] = SpinUp; - //stateSound[3] = ChaingunSpinupSound; - stateTimeoutValue[3] = 0.05; - stateWaitForTimeout[3] = false; - stateTransitionOnTimeout[3] = "Fire"; - stateTransitionOnTriggerUp[3] = "Spindown"; - - stateName[4] = "Fire"; - stateSequence[4] = "Fire"; - stateSequenceRandomFlash[4] = true; - stateSpinThread[4] = FullSpeed; - stateSound[4] = GravChaingunFireSound; - //stateRecoil[4] = LightRecoil; - stateAllowImageChange[4] = false; - stateScript[4] = "onFire"; - stateFire[4] = true; - stateEjectShell[4] = true; - stateTimeoutValue[4] = 0.1; - stateTransitionOnTimeout[4] = "Fire"; - stateTransitionOnTriggerUp[4] = "Spindown"; - stateTransitionOnNoAmmo[4] = "EmptySpindown"; - - stateName[5] = "Spindown"; - //stateSound[5] = ChaingunSpinDownSound; - stateSpinThread[5] = SpinDown; - stateTimeoutValue[5] = 0.05; - stateWaitForTimeout[5] = true; - stateTransitionOnTimeout[5] = "Ready"; - stateTransitionOnTriggerDown[5] = "Spinup"; - - stateName[6] = "EmptySpindown"; - //stateSound[6] = ChaingunSpinDownSound; - stateSpinThread[6] = SpinDown; - stateTimeoutValue[6] = 0.5; - stateTransitionOnTimeout[6] = "NoAmmo"; - - stateName[7] = "DryFire"; - stateSound[7] = GravChaingunDryFireSound; - stateTimeoutValue[7] = 1.0; - stateTransitionOnTimeout[7] = "NoAmmo"; -}; - -package wildcat -{ -function ScoutVehicle::onAdd(%this, %obj) -{ - Parent::onAdd(%this, %obj); - %obj.mountImage(GravChaingunImage, 0); - %obj.setImageTrigger(0, false); - %obj.schedule(5500, "playThread", $ActivateThread, "activate"); -} - -function ScoutVehicle::playerMounted(%data, %obj, %player, %node) -{ - // scout vehicle == SUV (single-user vehicle) - commandToClient(%player.client, 'setHudMode', 'Pilot', "Hoverbike", %node); - - // z0dd - ZOD, 5/14/02. Create a weapon hud and reticle - commandToClient(%player.client, 'ShowVehicleWeapons', "Hoverbike"); - - // update observers who are following this guy... - if( %player.client.observeCount > 0 ) - resetObserveFollow( %player.client, false ); -} - -function ScoutVehicle::playerDismounted(%data, %obj, %player) -{ - %obj.setImageTrigger(0, false); - setTargetSensorGroup(%obj.getTarget(), %obj.team); - if( %player.client.observeCount > 0 ) - resetObserveFollow( %player.client, true ); -} -}; - -activatePackage(wildcat); - +//************************************************************** +// WILDCAT GRAV CYCLE +//************************************************************** +//************************************************************** +// SOUNDS +//************************************************************** +datablock EffectProfile(ScoutEngineEffect) +{ + effectname = "vehicles/outrider_engine"; + minDistance = 5.0; + maxDistance = 10.0; +}; + +datablock EffectProfile(ScoutThrustEffect) +{ + effectname = "vehicles/outrider_boost"; + minDistance = 5.0; + maxDistance = 10.0; +}; + +datablock AudioProfile(ScoutSqueelSound) +{ + filename = "fx/vehicles/outrider_skid.wav"; + description = ClosestLooping3d; + preload = true; +}; + +// Scout +datablock AudioProfile(ScoutEngineSound) +{ + filename = "fx/vehicles/outrider_engine.wav"; + description = AudioDefaultLooping3d; + preload = true; + effect = ScoutEngineEffect; +}; + +datablock AudioProfile(ScoutThrustSound) +{ + filename = "fx/vehicles/outrider_boost.wav"; + description = AudioDefaultLooping3d; + preload = true; + effect = ScoutThrustEffect; +}; + +//************************************************************** +// LIGHTS +//************************************************************** +datablock RunningLightData(WildcatLight1) +{ + radius = 1.0; + color = "1.0 1.0 1.0 0.3"; + nodeName = "Headlight_node01"; + direction = "-1.0 1.0 0.0"; + texture = "special/headlight4"; +}; + +datablock RunningLightData(WildcatLight2) +{ + radius = 1.0; + color = "1.0 1.0 1.0 0.3"; + nodeName = "Headlight_node02"; + direction = "1.0 1.0 0.0"; + texture = "special/headlight4"; +}; + +datablock RunningLightData(WildcatLight3) +{ + type = 2; + radius = 100.0; + color = "1.0 1.0 1.0 1.0"; + offset = "0.0 0.0 0.0"; + direction = "0.0 1.0 0.0"; + texture = "special/projheadlight"; +}; + +//************************************************************** +// VEHICLE CHARACTERISTICS +//************************************************************** + +datablock HoverVehicleData(ScoutVehicle) : WildcatDamageProfile +{ + spawnOffset = "0 0 1"; + + floatingGravMag = 3.5; + + catagory = "Vehicles"; + shapeFile = "vehicle_grav_scout.dts"; + computeCRC = true; + + debrisShapeName = "vehicle_grav_scout_debris.dts"; + debris = ShapeDebris; + renderWhenDestroyed = false; + + drag = 0.0; + density = 0.9; + + mountPose[0] = scoutRoot; + cameraMaxDist = 5.0; + cameraOffset = 0.7; + cameraLag = 0.5; + numMountPoints = 1; + isProtectedMountPoint[0] = true; + explosion = VehicleExplosion; + explosionDamage = 0.5; + explosionRadius = 5.0; + + lightOnly = 1; + + maxDamage = 0.60; + destroyedLevel = 0.60; + + isShielded = true; + rechargeRate = 0.7; + energyPerDamagePoint = 95; // z0dd - ZOD, 3/30/02. Bike shield is less protective. was 75 + maxEnergy = 150; + minJetEnergy = 15; + jetEnergyDrain = 1.3; + + // Rigid Body + mass = 400; + bodyFriction = 0.1; + bodyRestitution = 0.5; + softImpactSpeed = 20; // Play SoftImpact Sound + hardImpactSpeed = 28; // Play HardImpact Sound + + // Ground Impact Damage (uses DamageType::Ground) + minImpactSpeed = 29; + speedDamageScale = 0.010; + + // Object Impact Damage (uses DamageType::Impact) + collDamageThresholdVel = 23; + collDamageMultiplier = 0.030; + + dragForce = 25 / 45.0; + vertFactor = 0.0; + floatingThrustFactor = 0.35; + + mainThrustForce = 35; // z0dd - ZOD, 3/30/02. Bike main thruster more powerful. was 30 + reverseThrustForce = 10; + strafeThrustForce = 8; + turboFactor = 1.80; // z0dd - ZOD, 3/30/02. Bike turbo thruster more powerful. was 1.5 + + brakingForce = 25; + brakingActivationSpeed = 4; + + stabLenMin = 2.25; + stabLenMax = 3.75; + stabSpringConstant = 30; + stabDampingConstant = 16; + + gyroDrag = 16; + normalForce = 30; + restorativeForce = 20; + steeringForce = 30; + rollForce = 15; + pitchForce = 7; + + dustEmitter = VehicleLiftoffDustEmitter; + triggerDustHeight = 2.5; + dustHeight = 1.0; + dustTrailEmitter = TireEmitter; + dustTrailOffset = "0.0 -1.0 0.5"; + triggerTrailHeight = 3.6; + dustTrailFreqMod = 15.0; + + jetSound = ScoutSqueelSound; + engineSound = ScoutEngineSound; + floatSound = ScoutThrustSound; + softImpactSound = GravSoftImpactSound; + hardImpactSound = HardImpactSound; + //wheelImpactSound = WheelImpactSound; + + // + softSplashSoundVelocity = 10.0; + mediumSplashSoundVelocity = 20.0; + hardSplashSoundVelocity = 30.0; + exitSplashSoundVelocity = 10.0; + + exitingWater = VehicleExitWaterSoftSound; + impactWaterEasy = VehicleImpactWaterSoftSound; + impactWaterMedium = VehicleImpactWaterSoftSound; + impactWaterHard = VehicleImpactWaterMediumSound; + waterWakeSound = VehicleWakeSoftSplashSound; + + minMountDist = 4; + + damageEmitter[0] = SmallLightDamageSmoke; + damageEmitter[1] = SmallHeavyDamageSmoke; + damageEmitter[2] = DamageBubbles; + damageEmitterOffset[0] = "0.0 -1.5 0.5 "; + damageLevelTolerance[0] = 0.3; + damageLevelTolerance[1] = 0.7; + numDmgEmitterAreas = 1; + + splashEmitter[0] = VehicleFoamDropletsEmitter; + splashEmitter[1] = VehicleFoamEmitter; + + shieldImpact = VehicleShieldImpact; + + forwardJetEmitter = WildcatJetEmitter; + + cmdCategory = Tactical; + cmdIcon = CMDHoverScoutIcon; + cmdMiniIconName = "commander/MiniIcons/com_landscout_grey"; + targetNameTag = 'WildCat'; + targetTypeTag = 'Grav Cycle'; + sensorData = VehiclePulseSensor; + sensorRadius = VehiclePulseSensor.detectRadius; // z0dd - ZOD, 3/30/02. Allows sensor to be shown on CC + + checkRadius = 1.7785; + observeParameters = "1 10 10"; + + runningLight[0] = WildcatLight1; + runningLight[1] = WildcatLight2; + runningLight[2] = WildcatLight3; + + shieldEffectScale = "0.9375 1.125 0.6"; +}; + +//************************************************************** +// WEAPONS: z0dd - ZOD, 5/14/02 +//************************************************************** + +$DeathMessageCTurretTeamKill[$DamageType::Bullet, 0] = '\c0%4 TEAMKILLED %1 by strafing from a Wildcat.'; + +$DeathMessageCTurretKill[$DamageType::Bullet, 0] = '\c0%4 turns %1 into swiss cheese with %6 Wildcat.'; +$DeathMessageCTurretKill[$DamageType::Bullet, 1] = '\c0The lead from %4\'s Wildcat turns %1 into finely shredded meat.'; +$DeathMessageCTurretKill[$DamageType::Bullet, 2] = '\c0%4 drills %1 full of holes with %6 Wildcat.'; + +datablock EffectProfile(GravChaingunFireEffect) +{ + effectname = "weapons/chaingun_fire"; + minDistance = 5.0; + maxDistance = 10.0; +}; + +datablock AudioProfile(GravChaingunFireSound) +{ + filename = "fx/vehicles/tank_chaingun.wav"; + description = AudioDefaultLooping3d; + preload = true; + effect = GravChaingunFireEffect; +}; + +datablock AudioProfile(GravChaingunDryFireSound) +{ + filename = "fx/weapons/chaingun_off.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(GravChaingunIdleSound) +{ + filename = "fx/misc/diagnostic_on.wav"; + description = ClosestLooping3d; + preload = true; +}; + +datablock TracerProjectileData(GravBullet) : ChaingunBullet +{ + projectileShapeName = "chaingun_shot.dts"; + directDamage = 0.135; +}; + +datablock ShapeBaseImageData(GravChaingunImage) +{ + className = WeaponImage; + shapeFile = "weapon_chaingun.dts"; + item = Chaingun; + offset = "-0.1 0.68 +0.26"; + //rotation = "0 0 0 90"; + projectile = GravBullet; //ChaingunBullet; + projectileType = TracerProjectile; + projectileSpread = 18.0 / 1000.0; // 10 + emap = true; + mountPoint = 10; + usesEnergy = true; + useMountEnergy = true; + // DAVEG -- balancing numbers below! + minEnergy = 8; + fireEnergy = 1.55; + + stateName[0] = "Activate"; + stateSequence[0] = "Activate"; + stateSound[0] = GravChaingunIdleSound; + stateAllowImageChange[0] = false; + stateTimeoutValue[0] = 0.1; + stateTransitionOnTimeout[0] = "Ready"; + stateTransitionOnNoAmmo[0] = "NoAmmo"; + + stateName[1] = "Ready"; + stateSpinThread[1] = Stop; + stateTransitionOnTriggerDown[1] = "Spinup"; + stateTransitionOnNoAmmo[1] = "NoAmmo"; + + stateName[2] = "NoAmmo"; + stateTransitionOnAmmo[2] = "Ready"; + stateSpinThread[2] = Stop; + stateTransitionOnTriggerDown[2] = "DryFire"; + + stateName[3] = "Spinup"; + stateSpinThread[3] = SpinUp; + //stateSound[3] = ChaingunSpinupSound; + stateTimeoutValue[3] = 0.05; + stateWaitForTimeout[3] = false; + stateTransitionOnTimeout[3] = "Fire"; + stateTransitionOnTriggerUp[3] = "Spindown"; + + stateName[4] = "Fire"; + stateSequence[4] = "Fire"; + stateSequenceRandomFlash[4] = true; + stateSpinThread[4] = FullSpeed; + stateSound[4] = GravChaingunFireSound; + //stateRecoil[4] = LightRecoil; + stateAllowImageChange[4] = false; + stateScript[4] = "onFire"; + stateFire[4] = true; + stateEjectShell[4] = true; + stateTimeoutValue[4] = 0.1; + stateTransitionOnTimeout[4] = "Fire"; + stateTransitionOnTriggerUp[4] = "Spindown"; + stateTransitionOnNoAmmo[4] = "EmptySpindown"; + + stateName[5] = "Spindown"; + //stateSound[5] = ChaingunSpinDownSound; + stateSpinThread[5] = SpinDown; + stateTimeoutValue[5] = 0.05; + stateWaitForTimeout[5] = true; + stateTransitionOnTimeout[5] = "Ready"; + stateTransitionOnTriggerDown[5] = "Spinup"; + + stateName[6] = "EmptySpindown"; + //stateSound[6] = ChaingunSpinDownSound; + stateSpinThread[6] = SpinDown; + stateTimeoutValue[6] = 0.5; + stateTransitionOnTimeout[6] = "NoAmmo"; + + stateName[7] = "DryFire"; + stateSound[7] = GravChaingunDryFireSound; + stateTimeoutValue[7] = 1.0; + stateTransitionOnTimeout[7] = "NoAmmo"; +}; + +package wildcat +{ +function ScoutVehicle::onAdd(%this, %obj) +{ + Parent::onAdd(%this, %obj); + %obj.mountImage(GravChaingunImage, 0); + %obj.setImageTrigger(0, false); + %obj.schedule(5500, "playThread", $ActivateThread, "activate"); +} + +function ScoutVehicle::playerMounted(%data, %obj, %player, %node) +{ + // scout vehicle == SUV (single-user vehicle) + commandToClient(%player.client, 'setHudMode', 'Pilot', "Hoverbike", %node); + + // z0dd - ZOD, 5/14/02. Create a weapon hud and reticle + commandToClient(%player.client, 'ShowVehicleWeapons', "Hoverbike"); + + // update observers who are following this guy... + if( %player.client.observeCount > 0 ) + resetObserveFollow( %player.client, false ); +} + +function ScoutVehicle::playerDismounted(%data, %obj, %player) +{ + %obj.setImageTrigger(0, false); + setTargetSensorGroup(%obj.getTarget(), %obj.team); + if( %player.client.observeCount > 0 ) + resetObserveFollow( %player.client, true ); +} +}; + +activatePackage(wildcat); + diff --git a/scripts/weapTurretCode.cs b/scripts/weapTurretCode.cs index 830d9d4..925dde4 100644 --- a/scripts/weapTurretCode.cs +++ b/scripts/weapTurretCode.cs @@ -1,927 +1,927 @@ -//-------------------------------------- Ammo functions -function Ammo::onCollision(%data, %obj, %col) -{ - // %data = datablock of object; %obj = object number - // %col = thing that collided with object (hopefully a player) - - if (%col.getDataBlock().className $= Armor) - { - %ammoName = %data.getName(); - %ammoStore = %col.inv[%ammoName]; - - // if player has ammo pack, increase max amount of ammo - if(%col.getMountedImage($BackpackSlot) != 0) - { - if(%col.getMountedImage($BackpackSlot).getName() $= "AmmoPackImage") - %aMax = (%col.getDataBlock().max[%ammoName]) + AmmoPack.max[%ammoName]; - else - %aMax = %col.getDataBlock().max[%ammoName]; - } - else - %aMax = %col.getDataBlock().max[%ammoName]; - - if(%col.inv[%ammoName] < %aMax) - { - if( %obj.ammoStore $= "" ) - %obj.ammoStore = $AmmoIncrement[ %ammoName ]; - - %col.incInventory(%ammoName, %obj.ammoStore); - serverPlay3D(ItemPickupSound, %col.getTransform()); - %obj.respawn(); - if (%col.client > 0) - messageClient(%col.client, 'MsgItemPickup', '\c0You picked up %1.', %data.pickUpName); - } - } -} - -function GrenadeThrown::onCollision(%data, %obj, %col) -{ - // nothing you can do now... -} - -function HandInventory::onCollision(%data, %obj, %col) -{ - // %data = datablock of object; %obj = object number - // %col = thing that collided with object (hopefully a player) - if (%col.getDataBlock().className $= Armor) - { - %ammoName = %data.getName(); - %ammoStore = %col.inv[%ammoName]; - - // if player has ammo pack, increase max amount of ammo - if(%col.getMountedImage($BackpackSlot) != 0) - { - if(%col.getMountedImage($BackpackSlot).getName() $= "AmmoPackImage") - %aMax = (%col.getDataBlock().max[%ammoName]) + AmmoPack.max[%ammoName]; - else - %aMax = %col.getDataBlock().max[%ammoName]; - } - else - %aMax = %col.getDataBlock().max[%ammoName]; - - if(%data.isGrenade) - { - // it's a grenade -- see if it matches the type the player is carrying - %pgType = "None"; - for(%x = 0; $InvGrenade[%x] !$= ""; %x++) - { - %gren = $NameToInv[$InvGrenade[%x]]; - if(%col.inv[%gren] > 0) - { - %pgType = %gren; - break; - } - } - if((%pgType $= "None") || (%pgType $= %ammoName)) - { - // player either has no grenades or this type of grenades -- OK to pick up more - %canPickup = true; - } - else - { - // player has a different kind of grenade -- don't pick this kind up - %canPickup = false; - } - } - else - %canPickup = true; - - if(%canPickup) - { - if(%col.inv[%ammoName] < %aMax) - { - //------------------------------------------------------------------------------------------- - // z0dd - ZOD, 4/17/02. Don't allow player to pickup full ammo if they tossed less than full. - if( %obj.ammoStore $= "" ) - %obj.ammoStore = $AmmoIncrement[ %ammoName ]; - %col.incInventory(%ammoName, %obj.ammoStore); - //------------------------------------------------------------------------------------------- - serverPlay3D(ItemPickupSound, %col.getTransform()); - %obj.respawn(); - if (%col.client > 0) - messageClient(%col.client, 'MsgItemPickup', '\c0You picked up %1.', %data.pickUpName); - } - } - } -} - -//-------------------------------------- Specific turret functions - -function SentryTurret::onAdd(%data, %obj) -{ - Parent::onAdd(%data, %obj); - - //error("error"); - %obj.mountImage(%data.barrel, 0, true); -} - -function TurretDeployedCamera::onAdd(%this, %obj) -{ - Parent::onAdd(%this, %obj); - %obj.mountImage(DeployableCameraBarrel, 0, true); - %obj.setRechargeRate(%this.rechargeRate); - - %obj.setAutoFire(false); // z0dd - ZOD, 4/17/02. Server crash fix related to controlable cameras -} - -function TurretDeployedCamera::onDestroyed(%this, %obj, %prevState) -{ - Parent::onDestroyed(%this, %obj, %prevState); - $TeamDeployedCount[%obj.team, DeployedCamera]--; - // doesn't seem to delete itself, so... - %obj.schedule(500, "delete"); -} - -function ScoutFlyer::onTrigger(%data, %obj, %trigger, %state) -{ - // data = ScoutFlyer datablock - // obj = ScoutFlyer object number - // trigger = 0 for "fire", 1 for "jump", 3 for "thrust" - // state = 1 for firing, 0 for not firing - if(%trigger == 0) - { - switch (%state) { - case 0: - %obj.fireWeapon = false; - %obj.setImageTrigger(2, false); - %obj.setImageTrigger(3, false); - case 1: - %obj.fireWeapon = true; - if(%obj.nextWeaponFire == 2) { - %obj.setImageTrigger(2, true); - %obj.setImageTrigger(3, false); - } - else { - %obj.setImageTrigger(2, false); - %obj.setImageTrigger(3, true); - } - } - } -} - -function ScoutFlyer::playerDismounted(%data, %obj, %player) -{ - %obj.fireWeapon = false; - %obj.setImageTrigger(2, false); - %obj.setImageTrigger(3, false); - setTargetSensorGroup(%obj.getTarget(), %obj.team); - - if( %player.client.observeCount > 0 ) - resetObserveFollow( %player.client, true ); -} - -function ScoutChaingunImage::onFire(%data,%obj,%slot) -{ - // obj = ScoutFlyer object number - // slot = 2 - - Parent::onFire(%data,%obj,%slot); - %obj.nextWeaponFire = 3; - schedule(%data.fireTimeout, 0, "fireNextGun", %obj); -} - -function ScoutChaingunPairImage::onFire(%data,%obj,%slot) -{ - // obj = ScoutFlyer object number - // slot = 3 - - Parent::onFire(%data,%obj,%slot); - %obj.nextWeaponFire = 2; - schedule(%data.fireTimeout, 0, "fireNextGun", %obj); -} - -function fireNextGun(%obj) -{ - if(%obj.fireWeapon) - { - if(%obj.nextWeaponFire == 2) - { - %obj.setImageTrigger(2, true); - %obj.setImageTrigger(3, false); - } - else - { - %obj.setImageTrigger(2, false); - %obj.setImageTrigger(3, true); - } - } - else - { - %obj.setImageTrigger(2, false); - %obj.setImageTrigger(3, false); - } -} - -function ScoutChaingunImage::onTriggerDown(%this, %obj, %slot) -{ -} - -function ScoutChaingunImage::onTriggerUp(%this, %obj, %slot) -{ -} - -function ScoutChaingunImage::onMount(%this, %obj, %slot) -{ -// %obj.setImageAmmo(%slot,true); -} - -function ScoutChaingunPairImage::onMount(%this, %obj, %slot) -{ -// %obj.setImageAmmo(%slot,true); -} - -function ScoutChaingunImage::onUnmount(%this,%obj,%slot) -{ -} - -function ScoutChaingunPairImage::onUnmount(%this,%obj,%slot) -{ -} - - -function BomberTurret::onDamage(%data, %obj) -{ - %newDamageVal = %obj.getDamageLevel(); - if(%obj.lastDamageVal !$= "") - if(isObject(%obj.getObjectMount()) && %obj.lastDamageVal > %newDamageVal) - %obj.getObjectMount().setDamageLevel(%newDamageVal); - %obj.lastDamageVal = %newDamageVal; -} - -function BomberTurret::damageObject(%this, %targetObject, %sourceObject, %position, %amount, %damageType ,%vec, %client, %projectile) -{ - //If vehicle turret is hit then apply damage to the vehicle - %vehicle = %targetObject.getObjectMount(); - if(%vehicle) - %vehicle.getDataBlock().damageObject(%vehicle, %sourceObject, %position, %amount, %damageType, %vec, %client, %projectile); -} - -function VehicleTurret::onEndSequence(%data, %obj, %thread) -{ - if($DeployThread == %thread) - %obj.stopThread($DeployThread); -} - -function BomberTurret::onTrigger(%data, %obj, %trigger, %state) -{ - //error("onTrigger: trigger = " @ %trigger @ ", state = " @ %state); - //error("obj = " @ %obj @ ", class " @ %obj.getClassName()); - switch (%trigger) - { - case 0: - %obj.fireTrigger = %state; - if(%obj.selectedWeapon == 1) - { - %obj.setImageTrigger(4, false); - if(%obj.getImageTrigger(6)) - { - %obj.setImageTrigger(6, false); - ShapeBaseImageData::deconstruct(%obj.getMountedImage(6), %obj); - } - if(%state) - %obj.setImageTrigger(2, true); - else - %obj.setImageTrigger(2, false); - } - else if(%obj.selectedWeapon == 2) - { - %obj.setImageTrigger(2, false); - if(%obj.getImageTrigger(6)) - { - %obj.setImageTrigger(6, false); - ShapeBaseImageData::deconstruct(%obj.getMountedImage(6), %obj); - } - if(%state) - %obj.setImageTrigger(4, true); - else - %obj.setImageTrigger(4, false); - } - else - { - %obj.setImageTrigger(2, false); - %obj.setImageTrigger(4, false); - if(%state) - %obj.setImageTrigger(6, true); - else - { - %obj.setImageTrigger(6, false); - BomberTargetingImage::deconstruct(%obj.getMountedImage(6), %obj); - } - } - - case 2: - if(%state) - { - %obj.getDataBlock().playerDismount(%obj); - } - } -} - -function BomberTurret::playerDismount(%data, %obj) -{ - //Passenger Exiting - %obj.fireTrigger = 0; - %obj.setImageTrigger(2, false); - %obj.setImageTrigger(4, false); - if(%obj.getImageTrigger(6)) - { - %obj.setImageTrigger(6, false); - ShapeBaseImageData::deconstruct(%obj.getMountedImage(6), %obj); - } - %client = %obj.getControllingClient(); - %client.player.isBomber = false; - commandToClient(%client, 'endBomberSight'); -// %client.player.setControlObject(%client.player); - %client.player.mountVehicle = false; -// %client.player.getDataBlock().doDismount(%client.player); - if(%client.player.getState() !$= "Dead") - %client.player.mountImage(%client.player.lastWeapon, $WeaponSlot); - setTargetSensorGroup(%obj.getTarget(), 0); - setTargetNeverVisMask(%obj.getTarget(), 0xffffffff); -} - -//function BomberTurret::getHudNum(%data, %num) -//{ -// if(%num == 1) -// return 0; -// else -// return 4; -//} - -function AIAimingTurretBarrel::onFire(%this,%obj,%slot) -{ -} - -function BomberBombImage::onUnmount(%this,%obj,%slot) -{ -} - -function BomberBombPairImage::onUnmount(%this,%obj,%slot) -{ -} - -function BomberTurretBarrel::firePair(%this, %obj, %slot) -{ - %obj.setImageTrigger( 3, true); -} - -function BomberTurretBarrelPair::stopFire(%this, %obj, %slot) -{ - %obj.setImageTrigger( 3, false); -} - -function BomberTurretBarrelPair::onMount(%this, %obj, %slot) -{ -// %obj.setImageAmmo(%slot,true); -} - -function BomberTurretBarrel::onMount(%this, %obj, %slot) -{ -// %obj.setImageAmmo(%slot,true); -} - -function BomberBombImage::firePair(%this, %obj, %slot) -{ - %obj.setImageTrigger( 5, true); -} - -function BomberBombPairImage::stopFire(%this, %obj, %slot) -{ - %obj.setImageTrigger( 5, false); -} - -function BomberBombPairImage::onMount(%this, %obj, %slot) -{ -// %obj.setImageAmmo(%slot,true); -} - -function BomberBombImage::onMount(%this, %obj, %slot) -{ -} - -function BomberBombImage::onUnmount(%this,%obj,%slot) -{ -} - -function BomberBombPairImage::onUnmount(%this,%obj,%slot) -{ -} - -function MobileTurretBase::onAdd(%this, %obj) -{ - Parent::onAdd(%this, %obj); - setTargetSensorGroup(%obj.target, %obj.team); -// setTargetNeverVisMask(%obj.target, 0xffffffff); // z0dd - ZOD, 4/17/02. Causes mpb sensor to be shown in middle of map on cmd screen instead of MPB as origin. no idea why -} - -function MobileTurretBase::onDamage(%data, %obj) -{ - %newDamageVal = %obj.getDamageLevel(); - if(%obj.lastDamageVal !$= "") - if(isObject(%obj.getObjectMount()) && %obj.lastDamageVal > %newDamageVal) - %obj.getObjectMount().setDamageLevel(%newDamageVal); - %obj.lastDamageVal = %newDamageVal; -} - -function MobileTurretBase::damageObject(%this, %targetObject, %sourceObject, %position, %amount, %damageType ,%vec, %client, %projectile) -{ - //If vehicle turret is hit then apply damage to the vehicle - %vehicle = %targetObject.getObjectMount(); - if(%vehicle) - %vehicle.getDataBlock().damageObject(%vehicle, %sourceObject, %position, %amount, %damageType, %vec, %client, %projectile); -} - -function MobileTurretBase::onEndSequence(%data, %obj, %thread) -{ - //Used so that the parent wont be called.. -} - -function AssaultPlasmaTurret::onDamage(%data, %obj) -{ - %newDamageVal = %obj.getDamageLevel(); - if(%obj.lastDamageVal !$= "") - if(isObject(%obj.getObjectMount()) && %obj.lastDamageVal > %newDamageVal) - %obj.getObjectMount().setDamageLevel(%newDamageVal); - %obj.lastDamageVal = %newDamageVal; -} - -function AssaultPlasmaTurret::damageObject(%this, %targetObject, %sourceObject, %position, %amount, %damageType ,%vec, %client, %projectile) -{ - //If vehicle turret is hit then apply damage to the vehicle - %vehicle = %targetObject.getObjectMount(); - if(%vehicle) - %vehicle.getDataBlock().damageObject(%vehicle, %sourceObject, %position, %amount, %damageType, %vec, %client, %projectile); -} - -function AssaultPlasmaTurret::onTrigger(%data, %obj, %trigger, %state) -{ - switch (%trigger) { - case 0: - %obj.fireTrigger = %state; - if(%obj.selectedWeapon == 1) - { - %obj.setImageTrigger(4, false); - if(%state) - %obj.setImageTrigger(2, true); - else - %obj.setImageTrigger(2, false); - } - else - { - %obj.setImageTrigger(2, false); - if(%state) - %obj.setImageTrigger(4, true); - else - %obj.setImageTrigger(4, false); - } - case 2: - if(%state) - { - %obj.getDataBlock().playerDismount(%obj); - } - } -} - -function AssaultPlasmaTurret::playerDismount(%data, %obj) -{ - //Passenger Exiting - %obj.fireTrigger = 0; - %obj.setImageTrigger(2, false); - %obj.setImageTrigger(4, false); - %client = %obj.getControllingClient(); -// %client.setControlObject(%client.player); - %client.player.mountImage(%client.player.lastWeapon, $WeaponSlot); - %client.player.mountVehicle = false; - setTargetSensorGroup(%obj.getTarget(), 0); - setTargetNeverVisMask(%obj.getTarget(), 0xffffffff); -// %client.player.getDataBlock().doDismount(%client.player); -} - -//function AssaultPlasmaTurret::getHudNum(%data, %num) -//{ -// if(%num == 1) -// return 1; -// else -// return 3; -//} - - -// ------------------------------------------ -// camera functions -// ------------------------------------------ - -$CameraDeployTime = 1000; -$CameraDeployCheckMax = 6; -$CameraMinVelocity = 0.1; - -function CameraGrenadeThrown::onThrow(%this, %gren) -{ - // schedule a check to see if the camera is at rest but not deployed - %gren.checkCount = 0; - %gren.velocCheck = %this.schedule($CameraDeployTime, "checkCameraDeploy", %gren); -} - -function CameraGrenadeThrown::onStickyCollision(%data, %obj) -{ - cancel(%obj.velocCheck); - %pos = %obj.getLastStickyPos(); - %norm = %obj.getLastStickyNormal(); - - %intAngle = getTerrainAngle(%norm); // staticShape.cs - %rotAxis = vectorNormalize(vectorCross(%norm, "0 0 1")); - if (getWord(%norm, 2) == 1 || getWord(%norm, 2) == -1) - %rotAxis = vectorNormalize(vectorCross(%norm, "0 1 0")); - - %rotation = %rotAxis @ " " @ %intAngle; - %dcSucc = activateCamera(%pos, %rotation, %obj.sourceObject, %obj.sourceObject.team); - if(%dcSucc == 0) - messageClient(%obj.sourceObject.client, 'MsgDeployFailed', '\c2Your team\'s control network has reached its capacity for this item.~wfx/misc/misc.error.wav'); - %obj.schedule(50,"delete"); -} - -function CameraGrenadeThrown::checkCameraDeploy(%this, %gren) -{ - %gren.checkCount++; - if(VectorLen(%gren.getVelocity()) < $CameraMinVelocity) - { - // camera has come to rest but not deployed -- probably on a staticshape (station, gen, etc) - // no resolution, so get rid of it - %gren.schedule(50, "delete"); - } - else if(%gren.checkCount >= $CameraDeployCheckMax) - { - // camera's still moving but it's been check several times -- it was thrown from too great - // a height or off the edge of the world -- delete it - %gren.schedule(50, "delete"); - } - else - { - // check back in a little while - %gren.velocCheck = %this.schedule($CameraDeployTime, "checkCameraDeploy", %gren); - } -} - -function activateCamera(%position, %rotation, %sourceObj, %team) -{ - if($TeamDeployedCount[%team, DeployedCamera] >= $TeamDeployableMax[DeployedCamera]) - { - // team has too many cameras deployed already, don't deploy this one - return 0; - } - %dCam = new Turret() - { - dataBlock = "TurretDeployedCamera"; - team = %team; - needsNoPower = true; - owner = %sourceObj.client; - ownerHandle = %sourceObj.client.handle; - position = %position; - rotation = %rotation; - }; - addToDeployGroup(%dCam); - - if(%dCam.getTarget() != -1) - setTargetSensorGroup(%dCam.getTarget(), %team); - - %dCam.playAudio($DeploySound, CameraGrenadeAttachSound); - %dCam.deploy(); - %dCam.playThread($AmbientThread, "ambient"); - - // increment team's deployed count for cameras - $TeamDeployedCount[%team, DeployedCamera]++; - return 1; -} - -function FlareGrenade::onUse(%this, %obj) -{ - // a stripped-down version of HandInventory::onUse from weapons.cs - if(Game.handInvOnUse(%data, %obj)) { - %obj.decInventory(%this, 1); - %p = new FlareProjectile() { - dataBlock = FlareGrenadeProj; - initialDirection = %obj.getEyeVector(); - initialPosition = getBoxCenter(%obj.getWorldBox()); - sourceObject = %obj; - sourceSlot = 0; - }; - FlareSet.add(%p); - MissionCleanup.add(%p); - serverPlay3D(GrenadeThrowSound, getBoxCenter(%obj.getWorldBox())); - %p.schedule(6000, "delete"); - // miscellaneous grenade-throwing cleanup stuff - %obj.lastThrowTime[%data] = getSimTime(); - %obj.throwStrength = 0; - } -} - -// uncomment when explosion type can be set from script (dont want underwater explosion here) -//function grenadeOnEnterLiquid(%data, %obj, %coverage, %type, %flash) -//{ -// // 4: Lava -// // 5: Hot Lava -// // 6: Crusty Lava -// if(%type >=4 && %type <= 6) -// { -// if(%obj.getDamageState() !$= "Destroyed") -// { -// cancel(%obj.detThread); -// if(%flash) -// detonateFlashGrenade(%obj); -// else -// detonateGrenade(%obj); -// return(true); -// } -// } -// -// // flash grenades do not ignore quicksand -// if((%type == 7) && !%flash) -// return(true); -// -// return(false); -//} - -function GrenadeThrown::onThrow(%this, %gren) -{ - AIGrenadeThrown(%gren); - %gren.detThread = schedule(1500, %gren, "detonateGrenade", %gren); -} - -//function GrenadeThrown::onEnterLiquid(%data, %obj, %coverage, %type) -//{ -// if(!grenadeOnEnterLiquid(%data, %obj, %coverage, %type, false)) -// Parent::onEnterLiquid(%data, %obj, %coverage, %type); -//} - -function ConcussionGrenadeThrown::onThrow(%this, %gren) -{ - AIGrenadeThrown(%gren); - %gren.detThread = schedule(2000, %gren, "detonateGrenade", %gren); -} - -//function ConcussionGrenadeThrown::onEnterLiquid(%data, %obj, %coverage, %type) -//{ -// if(!grenadeOnEnterLiquid(%data, %obj, %coverage, %type, false)) -// Parent::onEnterLiquid(%data, %obj, %coverage, %type); -//} - -function detonateGrenade(%obj) -{ - %obj.setDamageState(Destroyed); - %data = %obj.getDataBlock(); - RadiusExplosion( %obj, %obj.getPosition(), %data.damageRadius, %data.indirectDamage, - %data.kickBackStrength, %obj.sourceObject, %data.radiusDamageType); - %obj.schedule(500,"delete"); -} - -function FlashGrenadeThrown::onThrow(%this, %gren) -{ - %gren.detThread = schedule(2000, %gren, "detonateFlashGrenade", %gren); -} - -//function FlashGrenadeThrown::onEnterLiquid(%data, %obj, %coverage, %type) -//{ -// if(!grenadeOnEnterLiquid(%data, %obj, %coverage, %type, true)) -// Parent::onEnterLiquid(%data, %obj, %coverage, %type); -//} - -function detonateFlashGrenade(%hg) -{ - %maxWhiteout = %hg.getDataBlock().maxWhiteout; - %thrower = %hg.sourceObject.client; - %hg.setDamageState(Destroyed); - %hgt = %hg.getTransform(); - %plX = firstword(%hgt); - %plY = getWord(%hgt, 1); - %plZ = getWord(%hgt, 2); - %pos = %plX @ " " @ %plY @ " " @ %plZ; - //all this stuff below ripped from projectiles.cs - - InitContainerRadiusSearch(%pos, 100.0, $TypeMasks::PlayerObjectType | - $TypeMasks::TurretObjectType); - - while ((%damage = containerSearchNext()) != 0) - { - %dist = containerSearchCurrDist(); - - %eyeXF = %damage.getEyeTransform(); - %epX = firstword(%eyeXF); - %epY = getWord(%eyeXF, 1); - %epZ = getWord(%eyeXF, 2); - %eyePos = %epX @ " " @ %epY @ " " @ %epZ; - %eyeVec = %damage.getEyeVector(); - - // Make sure we can see the thing... - if (ContainerRayCast(%eyePos, %pos, $TypeMasks::TerrainObjectType | - $TypeMasks::InteriorObjectType | - $TypeMasks::StaticObjectType, %damage) !$= "0") - { - continue; - } - - %distFactor = 1.0; - if (%dist >= 100) - %distFactor = 0.0; - else if (%dist >= 20) { - %distFactor = 1.0 - ((%dist - 20.0) / 80.0); - } - - %dif = VectorNormalize(VectorSub(%pos, %eyePos)); - %dot = VectorDot(%eyeVec, %dif); - - %difAcos = mRadToDeg(mAcos(%dot)); - %dotFactor = 1.0; - if (%difAcos > 60) - %dotFactor = ((1.0 - ((%difAcos - 60.0) / 120.0)) * 0.2) + 0.3; - else if (%difAcos > 45) - %dotFactor = ((1.0 - ((%difAcos - 45.0) / 15.0)) * 0.5) + 0.5; - - %totalFactor = %dotFactor * %distFactor; - - %prevWhiteOut = %damage.getWhiteOut(); - - if(!%prevWhiteOut) - if(!$teamDamage) - { - if(%damage.client != %thrower && %damage.client.team == %thrower.team) - messageClient(%damage.client, 'teamWhiteOut', '\c1You were hit by %1\'s whiteout grenade.', getTaggedString(%thrower.name)); - } - - %whiteoutVal = %prevWhiteOut + %totalFactor; - if(%whiteoutVal > %maxWhiteout) - { - //error("whitout at max"); - %whiteoutVal = %maxWhiteout; - } - - %damage.setWhiteOut( %whiteoutVal ); - } - %hg.schedule( 500, "delete" ); -} - -// ---------------------------------------------- -// mine functions -// ---------------------------------------------- - - -function MineDeployed::onThrow(%this, %mine, %thrower) -{ - %mine.armed = false; - %mine.damaged = 0; - %mine.detonated = false; - %mine.depCount = 0; - %mine.theClient = %thrower.client; - $TeamDeployedCount[%mine.sourceObject.team, MineDeployed]++; // z0dd - ZOD, 8/13/02, Moved this from deployMineCheck to here. Fixes mine count bug - - schedule(1500, %mine, "deployMineCheck", %mine, %thrower); -} - -function deployMineCheck(%mineObj, %player) -{ - if(%mineObj.depCount > %mineObj.getDatablock().maxDepCount) - explodeMine(%mineObj, true); - - // wait until the mine comes to rest - if(%mineObj.getVelocity() $= "0 0 0") - { - // 2-second delay before mine is armed -- let deploy thread play out etc. - schedule(%mineObj.getDatablock().armTime, %mineObj, "armDeployedMine", %mineObj); - - // check for other deployed mines in the vicinity - InitContainerRadiusSearch(%mineObj.getWorldBoxCenter(), %mineObj.getDatablock().spacing, $TypeMasks::ItemObjectType); - while((%itemObj = containerSearchNext()) != 0) - { - if(%itemObj == %mineObj) - continue; - %ioType = %itemObj.getDatablock().getName(); - if(%ioType $= "MineDeployed") - schedule(100, %mineObj, "explodeMine", %mineObj, true); - else - continue; - } - // play "deploy" thread - %mineObj.playThread(0, "deploy"); - serverPlay3D(MineDeploySound, %mineObj.getTransform()); - %mineTeam = %mineObj.sourceObject.team; - //$TeamDeployedCount[%mineTeam, MineDeployed]++; // z0dd - ZOD, 8/13/02, Moved the increment to MineDeployed::onThrow. Fixes mine count bug - if($TeamDeployedCount[%mineTeam, MineDeployed] > $TeamDeployableMax[MineDeployed]) - { - messageClient( %player.client, '', 'Maximum allowable mines deployed.' ); - schedule(100, %mineObj, "explodeMine", %mineObj, true); - } - else - { - //start the thread that keeps checking for objects near the mine... - mineCheckVicinity(%mineObj); - - //let the AI know *after* it's come to rest... - AIDeployMine(%mineObj); - - //let the game know there's a deployed mine - Game.notifyMineDeployed(%mineObj); - } - } - else - { - //schedule this deploy check again a little later - %mineObj.depCount++; - schedule(500, %mineObj, "deployMineCheck", %mineObj, %player); - } -} - -function armDeployedMine(%mine) -{ - %mine.armed = true; -} - -function mineCheckVicinity(%mine) -{ - // this function is called after the mine has been deployed. It will check the - // immediate area around the mine (2.5 meters at present) for players or vehicles - // passing by, and detonate if any are found. This is to extend the range of the - // mine so players don't have to collide with them to set them off. - - // don't bother to check if mine isn't armed yet - if(%mine.armed) - // don't keep checking if mine is already detonating - if(!%mine.boom) - { - // the actual check for objects in the area - %mineLoc = %mine.getWorldBoxCenter(); - %masks = $TypeMasks::PlayerObjectType | $TypeMasks::VehicleObjectType; - %detonateRange = %mine.getDatablock().proximity; - - InitContainerRadiusSearch(%mineLoc, %detonateRange, %masks); - while((%tgt = containerSearchNext()) != 0) - { - %mine.detonated = true; - schedule(50, %mine, "explodeMine", %mine, false); - break; - } - } - // if nothing set off the mine, schedule another check - if(!%mine.detonated) - schedule(300, %mine, "mineCheckVicinity", %mine); -} - -function MineDeployed::onCollision(%data, %obj, %col) -{ - // don't detonate if mine isn't armed yet - if(!%obj.armed) - return; - - // don't detonate if mine is already detonating - if(%obj.boom) - return; - - //check to see what it is that collided with the mine - %struck = %col.getClassName(); - if(%struck $= "Player" || %struck $= "WheeledVehicle" || %struck $= "FlyingVehicle") - { - //error("Mine detonated due to collision with #"@%col@" ("@%struck@"); armed = "@%obj.armed); - explodeMine(%obj, false); - } -} - -function explodeMine(%mo, %noDamage) -{ - %mo.noDamage = %noDamage; - %mo.setDamageState(Destroyed); -} - -function MineDeployed::damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType) -{ - // ----------------------------- - // z0dd - ZOD, 4/17/02. added minedisk - //if(!%targetObject.armed) - // return; - // ----------------------------- - - if(%targetObject.boom) - return; - - %targetObject.damaged += %amount; - - if(%targetObject.damaged >= %data.maxDamage) - { - %targetObject.setDamageState(Destroyed); - } -} - -function MineDeployed::onDestroyed(%data, %obj, %lastState) -{ - %obj.boom = true; - %mineTeam = %obj.team; - $TeamDeployedCount[%mineTeam, MineDeployed]--; - // %noDamage is a boolean flag -- don't want to set off all other mines in - // vicinity if there's a "mine overload", so apply no damage/impulse if true - if(!%obj.noDamage) - RadiusExplosion(%obj, - %obj.getPosition(), - %data.damageRadius, - %data.indirectDamage, - %data.kickBackStrength, - %obj.sourceObject, - %data.radiusDamageType); - - %obj.schedule(600, "delete"); -} +//-------------------------------------- Ammo functions +function Ammo::onCollision(%data, %obj, %col) +{ + // %data = datablock of object; %obj = object number + // %col = thing that collided with object (hopefully a player) + + if (%col.getDataBlock().className $= Armor) + { + %ammoName = %data.getName(); + %ammoStore = %col.inv[%ammoName]; + + // if player has ammo pack, increase max amount of ammo + if(%col.getMountedImage($BackpackSlot) != 0) + { + if(%col.getMountedImage($BackpackSlot).getName() $= "AmmoPackImage") + %aMax = (%col.getDataBlock().max[%ammoName]) + AmmoPack.max[%ammoName]; + else + %aMax = %col.getDataBlock().max[%ammoName]; + } + else + %aMax = %col.getDataBlock().max[%ammoName]; + + if(%col.inv[%ammoName] < %aMax) + { + if( %obj.ammoStore $= "" ) + %obj.ammoStore = $AmmoIncrement[ %ammoName ]; + + %col.incInventory(%ammoName, %obj.ammoStore); + serverPlay3D(ItemPickupSound, %col.getTransform()); + %obj.respawn(); + if (%col.client > 0) + messageClient(%col.client, 'MsgItemPickup', '\c0You picked up %1.', %data.pickUpName); + } + } +} + +function GrenadeThrown::onCollision(%data, %obj, %col) +{ + // nothing you can do now... +} + +function HandInventory::onCollision(%data, %obj, %col) +{ + // %data = datablock of object; %obj = object number + // %col = thing that collided with object (hopefully a player) + if (%col.getDataBlock().className $= Armor) + { + %ammoName = %data.getName(); + %ammoStore = %col.inv[%ammoName]; + + // if player has ammo pack, increase max amount of ammo + if(%col.getMountedImage($BackpackSlot) != 0) + { + if(%col.getMountedImage($BackpackSlot).getName() $= "AmmoPackImage") + %aMax = (%col.getDataBlock().max[%ammoName]) + AmmoPack.max[%ammoName]; + else + %aMax = %col.getDataBlock().max[%ammoName]; + } + else + %aMax = %col.getDataBlock().max[%ammoName]; + + if(%data.isGrenade) + { + // it's a grenade -- see if it matches the type the player is carrying + %pgType = "None"; + for(%x = 0; $InvGrenade[%x] !$= ""; %x++) + { + %gren = $NameToInv[$InvGrenade[%x]]; + if(%col.inv[%gren] > 0) + { + %pgType = %gren; + break; + } + } + if((%pgType $= "None") || (%pgType $= %ammoName)) + { + // player either has no grenades or this type of grenades -- OK to pick up more + %canPickup = true; + } + else + { + // player has a different kind of grenade -- don't pick this kind up + %canPickup = false; + } + } + else + %canPickup = true; + + if(%canPickup) + { + if(%col.inv[%ammoName] < %aMax) + { + //------------------------------------------------------------------------------------------- + // z0dd - ZOD, 4/17/02. Don't allow player to pickup full ammo if they tossed less than full. + if( %obj.ammoStore $= "" ) + %obj.ammoStore = $AmmoIncrement[ %ammoName ]; + %col.incInventory(%ammoName, %obj.ammoStore); + //------------------------------------------------------------------------------------------- + serverPlay3D(ItemPickupSound, %col.getTransform()); + %obj.respawn(); + if (%col.client > 0) + messageClient(%col.client, 'MsgItemPickup', '\c0You picked up %1.', %data.pickUpName); + } + } + } +} + +//-------------------------------------- Specific turret functions + +function SentryTurret::onAdd(%data, %obj) +{ + Parent::onAdd(%data, %obj); + + //error("error"); + %obj.mountImage(%data.barrel, 0, true); +} + +function TurretDeployedCamera::onAdd(%this, %obj) +{ + Parent::onAdd(%this, %obj); + %obj.mountImage(DeployableCameraBarrel, 0, true); + %obj.setRechargeRate(%this.rechargeRate); + + %obj.setAutoFire(false); // z0dd - ZOD, 4/17/02. Server crash fix related to controlable cameras +} + +function TurretDeployedCamera::onDestroyed(%this, %obj, %prevState) +{ + Parent::onDestroyed(%this, %obj, %prevState); + $TeamDeployedCount[%obj.team, DeployedCamera]--; + // doesn't seem to delete itself, so... + %obj.schedule(500, "delete"); +} + +function ScoutFlyer::onTrigger(%data, %obj, %trigger, %state) +{ + // data = ScoutFlyer datablock + // obj = ScoutFlyer object number + // trigger = 0 for "fire", 1 for "jump", 3 for "thrust" + // state = 1 for firing, 0 for not firing + if(%trigger == 0) + { + switch (%state) { + case 0: + %obj.fireWeapon = false; + %obj.setImageTrigger(2, false); + %obj.setImageTrigger(3, false); + case 1: + %obj.fireWeapon = true; + if(%obj.nextWeaponFire == 2) { + %obj.setImageTrigger(2, true); + %obj.setImageTrigger(3, false); + } + else { + %obj.setImageTrigger(2, false); + %obj.setImageTrigger(3, true); + } + } + } +} + +function ScoutFlyer::playerDismounted(%data, %obj, %player) +{ + %obj.fireWeapon = false; + %obj.setImageTrigger(2, false); + %obj.setImageTrigger(3, false); + setTargetSensorGroup(%obj.getTarget(), %obj.team); + + if( %player.client.observeCount > 0 ) + resetObserveFollow( %player.client, true ); +} + +function ScoutChaingunImage::onFire(%data,%obj,%slot) +{ + // obj = ScoutFlyer object number + // slot = 2 + + Parent::onFire(%data,%obj,%slot); + %obj.nextWeaponFire = 3; + schedule(%data.fireTimeout, 0, "fireNextGun", %obj); +} + +function ScoutChaingunPairImage::onFire(%data,%obj,%slot) +{ + // obj = ScoutFlyer object number + // slot = 3 + + Parent::onFire(%data,%obj,%slot); + %obj.nextWeaponFire = 2; + schedule(%data.fireTimeout, 0, "fireNextGun", %obj); +} + +function fireNextGun(%obj) +{ + if(%obj.fireWeapon) + { + if(%obj.nextWeaponFire == 2) + { + %obj.setImageTrigger(2, true); + %obj.setImageTrigger(3, false); + } + else + { + %obj.setImageTrigger(2, false); + %obj.setImageTrigger(3, true); + } + } + else + { + %obj.setImageTrigger(2, false); + %obj.setImageTrigger(3, false); + } +} + +function ScoutChaingunImage::onTriggerDown(%this, %obj, %slot) +{ +} + +function ScoutChaingunImage::onTriggerUp(%this, %obj, %slot) +{ +} + +function ScoutChaingunImage::onMount(%this, %obj, %slot) +{ +// %obj.setImageAmmo(%slot,true); +} + +function ScoutChaingunPairImage::onMount(%this, %obj, %slot) +{ +// %obj.setImageAmmo(%slot,true); +} + +function ScoutChaingunImage::onUnmount(%this,%obj,%slot) +{ +} + +function ScoutChaingunPairImage::onUnmount(%this,%obj,%slot) +{ +} + + +function BomberTurret::onDamage(%data, %obj) +{ + %newDamageVal = %obj.getDamageLevel(); + if(%obj.lastDamageVal !$= "") + if(isObject(%obj.getObjectMount()) && %obj.lastDamageVal > %newDamageVal) + %obj.getObjectMount().setDamageLevel(%newDamageVal); + %obj.lastDamageVal = %newDamageVal; +} + +function BomberTurret::damageObject(%this, %targetObject, %sourceObject, %position, %amount, %damageType ,%vec, %client, %projectile) +{ + //If vehicle turret is hit then apply damage to the vehicle + %vehicle = %targetObject.getObjectMount(); + if(%vehicle) + %vehicle.getDataBlock().damageObject(%vehicle, %sourceObject, %position, %amount, %damageType, %vec, %client, %projectile); +} + +function VehicleTurret::onEndSequence(%data, %obj, %thread) +{ + if($DeployThread == %thread) + %obj.stopThread($DeployThread); +} + +function BomberTurret::onTrigger(%data, %obj, %trigger, %state) +{ + //error("onTrigger: trigger = " @ %trigger @ ", state = " @ %state); + //error("obj = " @ %obj @ ", class " @ %obj.getClassName()); + switch (%trigger) + { + case 0: + %obj.fireTrigger = %state; + if(%obj.selectedWeapon == 1) + { + %obj.setImageTrigger(4, false); + if(%obj.getImageTrigger(6)) + { + %obj.setImageTrigger(6, false); + ShapeBaseImageData::deconstruct(%obj.getMountedImage(6), %obj); + } + if(%state) + %obj.setImageTrigger(2, true); + else + %obj.setImageTrigger(2, false); + } + else if(%obj.selectedWeapon == 2) + { + %obj.setImageTrigger(2, false); + if(%obj.getImageTrigger(6)) + { + %obj.setImageTrigger(6, false); + ShapeBaseImageData::deconstruct(%obj.getMountedImage(6), %obj); + } + if(%state) + %obj.setImageTrigger(4, true); + else + %obj.setImageTrigger(4, false); + } + else + { + %obj.setImageTrigger(2, false); + %obj.setImageTrigger(4, false); + if(%state) + %obj.setImageTrigger(6, true); + else + { + %obj.setImageTrigger(6, false); + BomberTargetingImage::deconstruct(%obj.getMountedImage(6), %obj); + } + } + + case 2: + if(%state) + { + %obj.getDataBlock().playerDismount(%obj); + } + } +} + +function BomberTurret::playerDismount(%data, %obj) +{ + //Passenger Exiting + %obj.fireTrigger = 0; + %obj.setImageTrigger(2, false); + %obj.setImageTrigger(4, false); + if(%obj.getImageTrigger(6)) + { + %obj.setImageTrigger(6, false); + ShapeBaseImageData::deconstruct(%obj.getMountedImage(6), %obj); + } + %client = %obj.getControllingClient(); + %client.player.isBomber = false; + commandToClient(%client, 'endBomberSight'); +// %client.player.setControlObject(%client.player); + %client.player.mountVehicle = false; +// %client.player.getDataBlock().doDismount(%client.player); + if(%client.player.getState() !$= "Dead") + %client.player.mountImage(%client.player.lastWeapon, $WeaponSlot); + setTargetSensorGroup(%obj.getTarget(), 0); + setTargetNeverVisMask(%obj.getTarget(), 0xffffffff); +} + +//function BomberTurret::getHudNum(%data, %num) +//{ +// if(%num == 1) +// return 0; +// else +// return 4; +//} + +function AIAimingTurretBarrel::onFire(%this,%obj,%slot) +{ +} + +function BomberBombImage::onUnmount(%this,%obj,%slot) +{ +} + +function BomberBombPairImage::onUnmount(%this,%obj,%slot) +{ +} + +function BomberTurretBarrel::firePair(%this, %obj, %slot) +{ + %obj.setImageTrigger( 3, true); +} + +function BomberTurretBarrelPair::stopFire(%this, %obj, %slot) +{ + %obj.setImageTrigger( 3, false); +} + +function BomberTurretBarrelPair::onMount(%this, %obj, %slot) +{ +// %obj.setImageAmmo(%slot,true); +} + +function BomberTurretBarrel::onMount(%this, %obj, %slot) +{ +// %obj.setImageAmmo(%slot,true); +} + +function BomberBombImage::firePair(%this, %obj, %slot) +{ + %obj.setImageTrigger( 5, true); +} + +function BomberBombPairImage::stopFire(%this, %obj, %slot) +{ + %obj.setImageTrigger( 5, false); +} + +function BomberBombPairImage::onMount(%this, %obj, %slot) +{ +// %obj.setImageAmmo(%slot,true); +} + +function BomberBombImage::onMount(%this, %obj, %slot) +{ +} + +function BomberBombImage::onUnmount(%this,%obj,%slot) +{ +} + +function BomberBombPairImage::onUnmount(%this,%obj,%slot) +{ +} + +function MobileTurretBase::onAdd(%this, %obj) +{ + Parent::onAdd(%this, %obj); + setTargetSensorGroup(%obj.target, %obj.team); +// setTargetNeverVisMask(%obj.target, 0xffffffff); // z0dd - ZOD, 4/17/02. Causes mpb sensor to be shown in middle of map on cmd screen instead of MPB as origin. no idea why +} + +function MobileTurretBase::onDamage(%data, %obj) +{ + %newDamageVal = %obj.getDamageLevel(); + if(%obj.lastDamageVal !$= "") + if(isObject(%obj.getObjectMount()) && %obj.lastDamageVal > %newDamageVal) + %obj.getObjectMount().setDamageLevel(%newDamageVal); + %obj.lastDamageVal = %newDamageVal; +} + +function MobileTurretBase::damageObject(%this, %targetObject, %sourceObject, %position, %amount, %damageType ,%vec, %client, %projectile) +{ + //If vehicle turret is hit then apply damage to the vehicle + %vehicle = %targetObject.getObjectMount(); + if(%vehicle) + %vehicle.getDataBlock().damageObject(%vehicle, %sourceObject, %position, %amount, %damageType, %vec, %client, %projectile); +} + +function MobileTurretBase::onEndSequence(%data, %obj, %thread) +{ + //Used so that the parent wont be called.. +} + +function AssaultPlasmaTurret::onDamage(%data, %obj) +{ + %newDamageVal = %obj.getDamageLevel(); + if(%obj.lastDamageVal !$= "") + if(isObject(%obj.getObjectMount()) && %obj.lastDamageVal > %newDamageVal) + %obj.getObjectMount().setDamageLevel(%newDamageVal); + %obj.lastDamageVal = %newDamageVal; +} + +function AssaultPlasmaTurret::damageObject(%this, %targetObject, %sourceObject, %position, %amount, %damageType ,%vec, %client, %projectile) +{ + //If vehicle turret is hit then apply damage to the vehicle + %vehicle = %targetObject.getObjectMount(); + if(%vehicle) + %vehicle.getDataBlock().damageObject(%vehicle, %sourceObject, %position, %amount, %damageType, %vec, %client, %projectile); +} + +function AssaultPlasmaTurret::onTrigger(%data, %obj, %trigger, %state) +{ + switch (%trigger) { + case 0: + %obj.fireTrigger = %state; + if(%obj.selectedWeapon == 1) + { + %obj.setImageTrigger(4, false); + if(%state) + %obj.setImageTrigger(2, true); + else + %obj.setImageTrigger(2, false); + } + else + { + %obj.setImageTrigger(2, false); + if(%state) + %obj.setImageTrigger(4, true); + else + %obj.setImageTrigger(4, false); + } + case 2: + if(%state) + { + %obj.getDataBlock().playerDismount(%obj); + } + } +} + +function AssaultPlasmaTurret::playerDismount(%data, %obj) +{ + //Passenger Exiting + %obj.fireTrigger = 0; + %obj.setImageTrigger(2, false); + %obj.setImageTrigger(4, false); + %client = %obj.getControllingClient(); +// %client.setControlObject(%client.player); + %client.player.mountImage(%client.player.lastWeapon, $WeaponSlot); + %client.player.mountVehicle = false; + setTargetSensorGroup(%obj.getTarget(), 0); + setTargetNeverVisMask(%obj.getTarget(), 0xffffffff); +// %client.player.getDataBlock().doDismount(%client.player); +} + +//function AssaultPlasmaTurret::getHudNum(%data, %num) +//{ +// if(%num == 1) +// return 1; +// else +// return 3; +//} + + +// ------------------------------------------ +// camera functions +// ------------------------------------------ + +$CameraDeployTime = 1000; +$CameraDeployCheckMax = 6; +$CameraMinVelocity = 0.1; + +function CameraGrenadeThrown::onThrow(%this, %gren) +{ + // schedule a check to see if the camera is at rest but not deployed + %gren.checkCount = 0; + %gren.velocCheck = %this.schedule($CameraDeployTime, "checkCameraDeploy", %gren); +} + +function CameraGrenadeThrown::onStickyCollision(%data, %obj) +{ + cancel(%obj.velocCheck); + %pos = %obj.getLastStickyPos(); + %norm = %obj.getLastStickyNormal(); + + %intAngle = getTerrainAngle(%norm); // staticShape.cs + %rotAxis = vectorNormalize(vectorCross(%norm, "0 0 1")); + if (getWord(%norm, 2) == 1 || getWord(%norm, 2) == -1) + %rotAxis = vectorNormalize(vectorCross(%norm, "0 1 0")); + + %rotation = %rotAxis @ " " @ %intAngle; + %dcSucc = activateCamera(%pos, %rotation, %obj.sourceObject, %obj.sourceObject.team); + if(%dcSucc == 0) + messageClient(%obj.sourceObject.client, 'MsgDeployFailed', '\c2Your team\'s control network has reached its capacity for this item.~wfx/misc/misc.error.wav'); + %obj.schedule(50,"delete"); +} + +function CameraGrenadeThrown::checkCameraDeploy(%this, %gren) +{ + %gren.checkCount++; + if(VectorLen(%gren.getVelocity()) < $CameraMinVelocity) + { + // camera has come to rest but not deployed -- probably on a staticshape (station, gen, etc) + // no resolution, so get rid of it + %gren.schedule(50, "delete"); + } + else if(%gren.checkCount >= $CameraDeployCheckMax) + { + // camera's still moving but it's been check several times -- it was thrown from too great + // a height or off the edge of the world -- delete it + %gren.schedule(50, "delete"); + } + else + { + // check back in a little while + %gren.velocCheck = %this.schedule($CameraDeployTime, "checkCameraDeploy", %gren); + } +} + +function activateCamera(%position, %rotation, %sourceObj, %team) +{ + if($TeamDeployedCount[%team, DeployedCamera] >= $TeamDeployableMax[DeployedCamera]) + { + // team has too many cameras deployed already, don't deploy this one + return 0; + } + %dCam = new Turret() + { + dataBlock = "TurretDeployedCamera"; + team = %team; + needsNoPower = true; + owner = %sourceObj.client; + ownerHandle = %sourceObj.client.handle; + position = %position; + rotation = %rotation; + }; + addToDeployGroup(%dCam); + + if(%dCam.getTarget() != -1) + setTargetSensorGroup(%dCam.getTarget(), %team); + + %dCam.playAudio($DeploySound, CameraGrenadeAttachSound); + %dCam.deploy(); + %dCam.playThread($AmbientThread, "ambient"); + + // increment team's deployed count for cameras + $TeamDeployedCount[%team, DeployedCamera]++; + return 1; +} + +function FlareGrenade::onUse(%this, %obj) +{ + // a stripped-down version of HandInventory::onUse from weapons.cs + if(Game.handInvOnUse(%data, %obj)) { + %obj.decInventory(%this, 1); + %p = new FlareProjectile() { + dataBlock = FlareGrenadeProj; + initialDirection = %obj.getEyeVector(); + initialPosition = getBoxCenter(%obj.getWorldBox()); + sourceObject = %obj; + sourceSlot = 0; + }; + FlareSet.add(%p); + MissionCleanup.add(%p); + serverPlay3D(GrenadeThrowSound, getBoxCenter(%obj.getWorldBox())); + %p.schedule(6000, "delete"); + // miscellaneous grenade-throwing cleanup stuff + %obj.lastThrowTime[%data] = getSimTime(); + %obj.throwStrength = 0; + } +} + +// uncomment when explosion type can be set from script (dont want underwater explosion here) +//function grenadeOnEnterLiquid(%data, %obj, %coverage, %type, %flash) +//{ +// // 4: Lava +// // 5: Hot Lava +// // 6: Crusty Lava +// if(%type >=4 && %type <= 6) +// { +// if(%obj.getDamageState() !$= "Destroyed") +// { +// cancel(%obj.detThread); +// if(%flash) +// detonateFlashGrenade(%obj); +// else +// detonateGrenade(%obj); +// return(true); +// } +// } +// +// // flash grenades do not ignore quicksand +// if((%type == 7) && !%flash) +// return(true); +// +// return(false); +//} + +function GrenadeThrown::onThrow(%this, %gren) +{ + AIGrenadeThrown(%gren); + %gren.detThread = schedule(1500, %gren, "detonateGrenade", %gren); +} + +//function GrenadeThrown::onEnterLiquid(%data, %obj, %coverage, %type) +//{ +// if(!grenadeOnEnterLiquid(%data, %obj, %coverage, %type, false)) +// Parent::onEnterLiquid(%data, %obj, %coverage, %type); +//} + +function ConcussionGrenadeThrown::onThrow(%this, %gren) +{ + AIGrenadeThrown(%gren); + %gren.detThread = schedule(2000, %gren, "detonateGrenade", %gren); +} + +//function ConcussionGrenadeThrown::onEnterLiquid(%data, %obj, %coverage, %type) +//{ +// if(!grenadeOnEnterLiquid(%data, %obj, %coverage, %type, false)) +// Parent::onEnterLiquid(%data, %obj, %coverage, %type); +//} + +function detonateGrenade(%obj) +{ + %obj.setDamageState(Destroyed); + %data = %obj.getDataBlock(); + RadiusExplosion( %obj, %obj.getPosition(), %data.damageRadius, %data.indirectDamage, + %data.kickBackStrength, %obj.sourceObject, %data.radiusDamageType); + %obj.schedule(500,"delete"); +} + +function FlashGrenadeThrown::onThrow(%this, %gren) +{ + %gren.detThread = schedule(2000, %gren, "detonateFlashGrenade", %gren); +} + +//function FlashGrenadeThrown::onEnterLiquid(%data, %obj, %coverage, %type) +//{ +// if(!grenadeOnEnterLiquid(%data, %obj, %coverage, %type, true)) +// Parent::onEnterLiquid(%data, %obj, %coverage, %type); +//} + +function detonateFlashGrenade(%hg) +{ + %maxWhiteout = %hg.getDataBlock().maxWhiteout; + %thrower = %hg.sourceObject.client; + %hg.setDamageState(Destroyed); + %hgt = %hg.getTransform(); + %plX = firstword(%hgt); + %plY = getWord(%hgt, 1); + %plZ = getWord(%hgt, 2); + %pos = %plX @ " " @ %plY @ " " @ %plZ; + //all this stuff below ripped from projectiles.cs + + InitContainerRadiusSearch(%pos, 100.0, $TypeMasks::PlayerObjectType | + $TypeMasks::TurretObjectType); + + while ((%damage = containerSearchNext()) != 0) + { + %dist = containerSearchCurrDist(); + + %eyeXF = %damage.getEyeTransform(); + %epX = firstword(%eyeXF); + %epY = getWord(%eyeXF, 1); + %epZ = getWord(%eyeXF, 2); + %eyePos = %epX @ " " @ %epY @ " " @ %epZ; + %eyeVec = %damage.getEyeVector(); + + // Make sure we can see the thing... + if (ContainerRayCast(%eyePos, %pos, $TypeMasks::TerrainObjectType | + $TypeMasks::InteriorObjectType | + $TypeMasks::StaticObjectType, %damage) !$= "0") + { + continue; + } + + %distFactor = 1.0; + if (%dist >= 100) + %distFactor = 0.0; + else if (%dist >= 20) { + %distFactor = 1.0 - ((%dist - 20.0) / 80.0); + } + + %dif = VectorNormalize(VectorSub(%pos, %eyePos)); + %dot = VectorDot(%eyeVec, %dif); + + %difAcos = mRadToDeg(mAcos(%dot)); + %dotFactor = 1.0; + if (%difAcos > 60) + %dotFactor = ((1.0 - ((%difAcos - 60.0) / 120.0)) * 0.2) + 0.3; + else if (%difAcos > 45) + %dotFactor = ((1.0 - ((%difAcos - 45.0) / 15.0)) * 0.5) + 0.5; + + %totalFactor = %dotFactor * %distFactor; + + %prevWhiteOut = %damage.getWhiteOut(); + + if(!%prevWhiteOut) + if(!$teamDamage) + { + if(%damage.client != %thrower && %damage.client.team == %thrower.team) + messageClient(%damage.client, 'teamWhiteOut', '\c1You were hit by %1\'s whiteout grenade.', getTaggedString(%thrower.name)); + } + + %whiteoutVal = %prevWhiteOut + %totalFactor; + if(%whiteoutVal > %maxWhiteout) + { + //error("whitout at max"); + %whiteoutVal = %maxWhiteout; + } + + %damage.setWhiteOut( %whiteoutVal ); + } + %hg.schedule( 500, "delete" ); +} + +// ---------------------------------------------- +// mine functions +// ---------------------------------------------- + + +function MineDeployed::onThrow(%this, %mine, %thrower) +{ + %mine.armed = false; + %mine.damaged = 0; + %mine.detonated = false; + %mine.depCount = 0; + %mine.theClient = %thrower.client; + $TeamDeployedCount[%mine.sourceObject.team, MineDeployed]++; // z0dd - ZOD, 8/13/02, Moved this from deployMineCheck to here. Fixes mine count bug + + schedule(1500, %mine, "deployMineCheck", %mine, %thrower); +} + +function deployMineCheck(%mineObj, %player) +{ + if(%mineObj.depCount > %mineObj.getDatablock().maxDepCount) + explodeMine(%mineObj, true); + + // wait until the mine comes to rest + if(%mineObj.getVelocity() $= "0 0 0") + { + // 2-second delay before mine is armed -- let deploy thread play out etc. + schedule(%mineObj.getDatablock().armTime, %mineObj, "armDeployedMine", %mineObj); + + // check for other deployed mines in the vicinity + InitContainerRadiusSearch(%mineObj.getWorldBoxCenter(), %mineObj.getDatablock().spacing, $TypeMasks::ItemObjectType); + while((%itemObj = containerSearchNext()) != 0) + { + if(%itemObj == %mineObj) + continue; + %ioType = %itemObj.getDatablock().getName(); + if(%ioType $= "MineDeployed") + schedule(100, %mineObj, "explodeMine", %mineObj, true); + else + continue; + } + // play "deploy" thread + %mineObj.playThread(0, "deploy"); + serverPlay3D(MineDeploySound, %mineObj.getTransform()); + %mineTeam = %mineObj.sourceObject.team; + //$TeamDeployedCount[%mineTeam, MineDeployed]++; // z0dd - ZOD, 8/13/02, Moved the increment to MineDeployed::onThrow. Fixes mine count bug + if($TeamDeployedCount[%mineTeam, MineDeployed] > $TeamDeployableMax[MineDeployed]) + { + messageClient( %player.client, '', 'Maximum allowable mines deployed.' ); + schedule(100, %mineObj, "explodeMine", %mineObj, true); + } + else + { + //start the thread that keeps checking for objects near the mine... + mineCheckVicinity(%mineObj); + + //let the AI know *after* it's come to rest... + AIDeployMine(%mineObj); + + //let the game know there's a deployed mine + Game.notifyMineDeployed(%mineObj); + } + } + else + { + //schedule this deploy check again a little later + %mineObj.depCount++; + schedule(500, %mineObj, "deployMineCheck", %mineObj, %player); + } +} + +function armDeployedMine(%mine) +{ + %mine.armed = true; +} + +function mineCheckVicinity(%mine) +{ + // this function is called after the mine has been deployed. It will check the + // immediate area around the mine (2.5 meters at present) for players or vehicles + // passing by, and detonate if any are found. This is to extend the range of the + // mine so players don't have to collide with them to set them off. + + // don't bother to check if mine isn't armed yet + if(%mine.armed) + // don't keep checking if mine is already detonating + if(!%mine.boom) + { + // the actual check for objects in the area + %mineLoc = %mine.getWorldBoxCenter(); + %masks = $TypeMasks::PlayerObjectType | $TypeMasks::VehicleObjectType; + %detonateRange = %mine.getDatablock().proximity; + + InitContainerRadiusSearch(%mineLoc, %detonateRange, %masks); + while((%tgt = containerSearchNext()) != 0) + { + %mine.detonated = true; + schedule(50, %mine, "explodeMine", %mine, false); + break; + } + } + // if nothing set off the mine, schedule another check + if(!%mine.detonated) + schedule(300, %mine, "mineCheckVicinity", %mine); +} + +function MineDeployed::onCollision(%data, %obj, %col) +{ + // don't detonate if mine isn't armed yet + if(!%obj.armed) + return; + + // don't detonate if mine is already detonating + if(%obj.boom) + return; + + //check to see what it is that collided with the mine + %struck = %col.getClassName(); + if(%struck $= "Player" || %struck $= "WheeledVehicle" || %struck $= "FlyingVehicle") + { + //error("Mine detonated due to collision with #"@%col@" ("@%struck@"); armed = "@%obj.armed); + explodeMine(%obj, false); + } +} + +function explodeMine(%mo, %noDamage) +{ + %mo.noDamage = %noDamage; + %mo.setDamageState(Destroyed); +} + +function MineDeployed::damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType) +{ + // ----------------------------- + // z0dd - ZOD, 4/17/02. added minedisk + //if(!%targetObject.armed) + // return; + // ----------------------------- + + if(%targetObject.boom) + return; + + %targetObject.damaged += %amount; + + if(%targetObject.damaged >= %data.maxDamage) + { + %targetObject.setDamageState(Destroyed); + } +} + +function MineDeployed::onDestroyed(%data, %obj, %lastState) +{ + %obj.boom = true; + %mineTeam = %obj.team; + $TeamDeployedCount[%mineTeam, MineDeployed]--; + // %noDamage is a boolean flag -- don't want to set off all other mines in + // vicinity if there's a "mine overload", so apply no damage/impulse if true + if(!%obj.noDamage) + RadiusExplosion(%obj, + %obj.getPosition(), + %data.damageRadius, + %data.indirectDamage, + %data.kickBackStrength, + %obj.sourceObject, + %data.radiusDamageType); + + %obj.schedule(600, "delete"); +} diff --git a/scripts/weapons.cs b/scripts/weapons.cs index 1cd7882..a84d98f 100644 --- a/scripts/weapons.cs +++ b/scripts/weapons.cs @@ -1,362 +1,362 @@ -$HandInvThrowTimeout = 0.8 * 1000; // 1/2 second between throwing grenades or mines - -// z0dd - ZOD, 9/13/02. Added global array for serverside weapon reticles and "visible" -$WeaponsHudData[0, bitmapName] = "gui/hud_blaster"; -$WeaponsHudData[0, itemDataName] = "Blaster"; -//$WeaponsHudData[0, ammoDataName] = ""; -$WeaponsHudData[0, reticle] = "gui/ret_blaster"; -$WeaponsHudData[0, visible] = "true"; -$WeaponsHudData[1, bitmapName] = "gui/hud_plasma"; -$WeaponsHudData[1, itemDataName] = "Plasma"; -$WeaponsHudData[1, ammoDataName] = "PlasmaAmmo"; -$WeaponsHudData[1, reticle] = "gui/ret_plasma"; -$WeaponsHudData[1, visible] = "true"; -$WeaponsHudData[2, bitmapName] = "gui/hud_chaingun"; -$WeaponsHudData[2, itemDataName] = "Chaingun"; -$WeaponsHudData[2, ammoDataName] = "ChaingunAmmo"; -$WeaponsHudData[2, reticle] = "gui/ret_chaingun"; -$WeaponsHudData[2, visible] = "true"; -$WeaponsHudData[3, bitmapName] = "gui/hud_disc"; -$WeaponsHudData[3, itemDataName] = "Disc"; -$WeaponsHudData[3, ammoDataName] = "DiscAmmo"; -$WeaponsHudData[3, reticle] = "gui/ret_disc"; -$WeaponsHudData[3, visible] = "true"; -$WeaponsHudData[4, bitmapName] = "gui/hud_grenlaunch"; -$WeaponsHudData[4, itemDataName] = "GrenadeLauncher"; -$WeaponsHudData[4, ammoDataName] = "GrenadeLauncherAmmo"; -$WeaponsHudData[4, reticle] = "gui/ret_grenade"; -$WeaponsHudData[4, visible] = "true"; -$WeaponsHudData[5, bitmapName] = "gui/hud_sniper"; -$WeaponsHudData[5, itemDataName] = "SniperRifle"; -//$WeaponsHudData[5, ammoDataName] = ""; -$WeaponsHudData[5, reticle] = "gui/hud_ret_sniper"; -$WeaponsHudData[5, visible] = "false"; -$WeaponsHudData[6, bitmapName] = "gui/hud_elfgun"; -$WeaponsHudData[6, itemDataName] = "ELFGun"; -//$WeaponsHudData[6, ammoDataName] = ""; -$WeaponsHudData[6, reticle] = "gui/ret_elf"; -$WeaponsHudData[6, visible] = "true"; -$WeaponsHudData[7, bitmapName] = "gui/hud_mortor"; -$WeaponsHudData[7, itemDataName] = "Mortar"; -$WeaponsHudData[7, ammoDataName] = "MortarAmmo"; -$WeaponsHudData[7, reticle] = "gui/ret_mortor"; -$WeaponsHudData[7, visible] = "true"; -$WeaponsHudData[8, bitmapName] = "gui/hud_missiles"; -$WeaponsHudData[8, itemDataName] = "MissileLauncher"; -$WeaponsHudData[8, ammoDataName] = "MissileLauncherAmmo"; -$WeaponsHudData[8, reticle] = "gui/ret_missile"; -$WeaponsHudData[8, visible] = "true"; -// WARNING!!! If you change the weapon index of the targeting laser, -// you must change the HudWeaponInvBase::addWeapon function to test -// for the new value! -$WeaponsHudData[9, bitmapName] = "gui/hud_targetlaser"; -$WeaponsHudData[9, itemDataName] = "TargetingLaser"; -//$WeaponsHudData[9, ammoDataName] = ""; -$WeaponsHudData[9, reticle] = "gui/hud_ret_targlaser"; -$WeaponsHudData[9, visible] = "false"; -$WeaponsHudData[10, bitmapName] = "gui/hud_shocklance"; -$WeaponsHudData[10, itemDataName] = "ShockLance"; -//$WeaponsHudData[10, ammoDataName] = ""; -$WeaponsHudData[10, reticle] = "gui/hud_ret_shocklance"; -$WeaponsHudData[10, visible] = "false"; - -// z0dd - ZOD, 9/13/02. TR2 weapons for compatability. -$WeaponsHudData[11, bitmapName] = "gui/hud_disc"; -$WeaponsHudData[11, itemDataName] = "TR2Disc"; -$WeaponsHudData[11, ammoDataName] = "TR2DiscAmmo"; -$WeaponsHudData[11, reticle] = "gui/ret_disc"; -$WeaponsHudData[11, visible] = "true"; -$WeaponsHudData[12, bitmapName] = "gui/hud_grenlaunch"; -$WeaponsHudData[12, itemDataName] = "TR2GrenadeLauncher"; -$WeaponsHudData[12, ammoDataName] = "TR2GrenadeLauncherAmmo"; -$WeaponsHudData[12, reticle] = "gui/ret_grenade"; -$WeaponsHudData[12, visible] = "true"; -$WeaponsHudData[13, bitmapName] = "gui/hud_chaingun"; -$WeaponsHudData[13, itemDataName] = "TR2Chaingun"; -$WeaponsHudData[13, ammoDataName] = "TR2ChaingunAmmo"; -$WeaponsHudData[13, reticle] = "gui/ret_chaingun"; -$WeaponsHudData[13, visible] = "true"; -$WeaponsHudData[14, bitmapName] = "gui/hud_targetlaser"; -$WeaponsHudData[14, itemDataName] = "TR2GoldTargetingLaser"; -$WeaponsHudData[14, reticle] = "gui/hud_ret_targlaser"; -$WeaponsHudData[14, visible] = "false"; -$WeaponsHudData[15, bitmapName] = "gui/hud_targetlaser"; -$WeaponsHudData[15, itemDataName] = "TR2SilverTargetingLaser"; -$WeaponsHudData[15, reticle] = "gui/hud_ret_targlaser"; -$WeaponsHudData[15, visible] = "false"; -$WeaponsHudData[16, bitmapName] = "gui/hud_shocklance"; -$WeaponsHudData[16, itemDataName] = "TR2ShockLance"; -$WeaponsHudData[16, reticle] = "gui/hud_ret_shocklance"; -$WeaponsHudData[16, visible] = "false"; -$WeaponsHudData[17, bitmapName] = "gui/hud_mortor"; -$WeaponsHudData[17, itemDataName] = "TR2Mortar"; -$WeaponsHudData[17, ammoDataName] = "TR2MortarAmmo"; -$WeaponsHudData[17, reticle] = "gui/ret_mortor"; -$WeaponsHudData[17, visible] = "true"; -$WeaponsHudData[18, bitmapName] = "gui/hud_mortor"; -$WeaponsHudData[18, itemDataName] = "Flamer"; -$WeaponsHudData[18, reticle] = "gui/ret_mortor"; -$WeaponsHudData[18, visible] = "true"; -$WeaponsHudData[19, bitmapName] = "gui/hud_sniper"; -$WeaponsHudData[19, itemDataName] = "R700"; -//$WeaponsHudData[5, ammoDataName] = ""; -$WeaponsHudData[19, reticle] = "gui/hud_ret_sniper"; -$WeaponsHudData[19, visible] = "false"; - -$WeaponsHudCount = 20; - -$AmmoIncrement[PlasmaAmmo] = 10; -$AmmoIncrement[ChaingunAmmo] = 25; -$AmmoIncrement[DiscAmmo] = 5; -$AmmoIncrement[GrenadeLauncherAmmo] = 5; -$AmmoIncrement[MortarAmmo] = 5; -$AmmoIncrement[MissileLauncherAmmo] = 2; -$AmmoIncrement[Mine] = 3; -$AmmoIncrement[Grenade] = 5; -$AmmoIncrement[FlashGrenade] = 5; -$AmmoIncrement[FlareGrenade] = 5; -$AmmoIncrement[ConcussionGrenade] = 5; -$AmmoIncrement[CameraGrenade] = 2; // z0dd - ZOD, 4/17/02. Camera ammo pickup fix. -$AmmoIncrement[RepairKit] = 1; -$AmmoIncrement[Beacon] = 1; // z0dd - ZOD, 4/17/02. Beacon ammo pickup fix. - -// ------------------------------------------------------------ -// z0dd - ZOD, 9/12/02. TR2 need -$AmmoIncrement[TR2DiscAmmo] = 5; -$AmmoIncrement[TR2GrenadeLauncherAmmo] = 5; -$AmmoIncrement[TR2ChaingunAmmo] = 25; -$AmmoIncrement[TR2MortarAmmo] = 5; -$AmmoIncrement[TR2Grenade] = 5; -// ------------------------------------------------------------ - -//---------------------------------------------------------------------------- -// Weapons scripts -//-------------------------------------- - -// --- Mounting weapons -exec("scripts/weapons/blaster.cs"); -exec("scripts/weapons/plasma.cs"); -exec("scripts/weapons/chaingun.cs"); -exec("scripts/weapons/disc.cs"); -exec("scripts/weapons/grenadeLauncher.cs"); -exec("scripts/weapons/sniperRifle.cs"); -exec("scripts/weapons/R700.cs"); -exec("scripts/weapons/ELFGun.cs"); -exec("scripts/weapons/mortar.cs"); -exec("scripts/weapons/missileLauncher.cs"); -exec("scripts/weapons/targetingLaser.cs"); -exec("scripts/weapons/shockLance.cs"); -exec("scripts/weapons/drakeFlame.cs"); - -// --- Throwing weapons -exec("scripts/weapons/mine.cs"); -exec("scripts/weapons/grenade.cs"); -exec("scripts/weapons/flashGrenade.cs"); -exec("scripts/weapons/flareGrenade.cs"); -exec("scripts/weapons/concussionGrenade.cs"); -exec("scripts/weapons/cameraGrenade.cs"); - -//---------------------------------------------------------------------------- - -function Weapon::onUse(%data, %obj) -{ - if(Game.weaponOnUse(%data, %obj)) - if (%obj.getDataBlock().className $= Armor) - %obj.mountImage(%data.image, $WeaponSlot); -} - -function WeaponImage::onMount(%this,%obj,%slot) -{ - //MES -- is call below useful at all? - //Parent::onMount(%this, %obj, %slot); - if(%obj.getClassName() !$= "Player") - return; - - //messageClient(%obj.client, 'MsgWeaponMount', "", %this, %obj, %slot); - // Looks arm position - if (%this.armthread $= "") - { - %obj.setArmThread(look); - } - else - { - %obj.setArmThread(%this.armThread); - } - - // Initial ammo state - if(%obj.getMountedImage($WeaponSlot).ammo !$= "") - if (%obj.getInventory(%this.ammo)) - %obj.setImageAmmo(%slot,true); - - %obj.client.setWeaponsHudActive(%this.item); - if(%obj.getMountedImage($WeaponSlot).ammo !$= "") - %obj.client.setAmmoHudCount(%obj.getInventory(%this.ammo)); - else - %obj.client.setAmmoHudCount(-1); -} - -function WeaponImage::onUnmount(%this,%obj,%slot) -{ - %obj.client.setWeaponsHudActive(%this.item, 1); - %obj.client.setAmmoHudCount(-1); - commandToClient(%obj.client,'removeReticle'); - // try to avoid running around with sniper/missile arm thread and no weapon - %obj.setArmThread(look); - Parent::onUnmount(%this, %obj, %slot); -} - -function Ammo::onInventory(%this,%obj,%amount) -{ - // Loop through and make sure the images using this ammo have - // their ammo states set. - for (%i = 0; %i < 8; %i++) { - %image = %obj.getMountedImage(%i); - if (%image > 0) - { - if (isObject(%image.ammo) && %image.ammo.getId() == %this.getId()) - %obj.setImageAmmo(%i,%amount != 0); - } - } - ItemData::onInventory(%this,%obj,%amount); - // Uh, don't update the hud ammo counters if this is a corpse...that's bad. - if ( %obj.getClassname() $= "Player" && %obj.getState() !$= "Dead" ) - { - %obj.client.setWeaponsHudAmmo(%this.getName(), %amount); - if(%obj.getMountedImage($WeaponSlot).ammo $= %this.getName()) - %obj.client.setAmmoHudCount(%amount); - } -} - -function Weapon::onInventory(%this,%obj,%amount) -{ - if(Game.weaponOnInventory(%this, %obj, %amount)) - { - // Do not update the hud if this object is a corpse: - if ( %obj.getState() !$= "Dead" ) - %obj.client.setWeaponsHudItem(%this.getName(), 0, 1); - ItemData::onInventory(%this,%obj,%amount); - // if a player threw a weapon (which means that player isn't currently - // holding a weapon), set armthread to "no weapon" - // MES - taken out to avoid v-menu animation problems (bug #4749) - //if((%amount == 0) && (%obj.getClassName() $= "Player")) - // %obj.setArmThread(looknw); - } -} - -function Weapon::onPickup(%this, %obj, %shape, %amount) -{ - // If player doesn't have a weapon in hand, use this one... - if ( %shape.getClassName() $= "Player" - && %shape.getMountedImage( $WeaponSlot ) == 0 ) - %shape.use( %this.getName() ); -} - -function HandInventory::onInventory(%this,%obj,%amount) -{ - // prevent console errors when throwing ammo pack - if(%obj.getClassName() $= "Player") - %obj.client.setInventoryHudAmount(%this.getName(), %amount); - ItemData::onInventory(%this,%obj,%amount); -} - -function HandInventory::onUse(%data, %obj) -{ - // %obj = player %data = datablock of what's being thrown - if(Game.handInvOnUse(%data, %obj)) - { - //AI HOOK - If you change the %throwStren, tell Tinman!!! - //Or edit aiInventory.cs and search for: use(%grenadeType); - - // z0dd - ZOD, 6/11/02. Toss grenades and your invincibility and cloaking goes away. - if(%obj.station $= "" && %obj.isCloaked()) - { - if( %obj.respawnCloakThread !$= "" ) - { - Cancel(%obj.respawnCloakThread); - %obj.setCloaked( false ); - %obj.respawnCloakThread = ""; - } - } - if( %obj.client > 0 ) - { - %obj.setInvincibleMode(0, 0.00); - %obj.setInvincible( false ); - } - - %tossTimeout = getSimTime() - %obj.lastThrowTime[%data]; - if(%tossTimeout < $HandInvThrowTimeout) - return; - - %throwStren = %obj.throwStrength; - - %obj.decInventory(%data, 1); - %thrownItem = new Item() - { - dataBlock = %data.thrownItem; - sourceObject = %obj; - }; - MissionCleanup.add(%thrownItem); - - // throw it - %eye = %obj.getEyeVector(); - %vec = vectorScale(%eye, (%throwStren * 20.0)); - - // add a vertical component to give it a better arc - %dot = vectorDot("0 0 1", %eye); - if(%dot < 0) - %dot = -%dot; - %vec = vectorAdd(%vec, vectorScale("0 0 10", 1 - %dot)); // z0dd - ZOD, 8/4/02. Add a higher arc to the toss. was 0 0 4 - - // add player's velocity - %vec = vectorAdd(%vec, vectorScale(%obj.getVelocity(), 0.65)); // z0dd - ZOD, 8/4/02. Add more of the players vel to the toss. was 0.4 - %pos = getBoxCenter(%obj.getWorldBox()); - - %thrownItem.sourceObject = %obj; - %thrownItem.team = %obj.team; - %thrownItem.setTransform(%pos); - - %thrownItem.applyImpulse(%pos, %vec); - %thrownItem.setCollisionTimeout(%obj); - serverPlay3D(GrenadeThrowSound, %pos); - %obj.lastThrowTime[%data] = getSimTime(); - - %thrownItem.getDataBlock().onThrow(%thrownItem, %obj); - %obj.throwStrength = 0; - } -} - -function HandInventoryImage::onMount(%this,%obj,%slot) -{ - messageClient(%col.client, 'MsgHandInventoryMount', "", %this, %obj, %slot); - // Looks arm position - if (%this.armthread $= "") - %obj.setArmThread(look); - else - %obj.setArmThread(%this.armThread); - - // Initial ammo state - if (%obj.getInventory(%this.ammo)) - %obj.setImageAmmo(%slot,true); - - %obj.client.setWeaponsHudActive(%this.item); -} - -function Weapon::incCatagory(%data, %obj) -{ - // Don't count the targeting laser as a weapon slot: - if ( %data.getName() !$= "TargetingLaser" ) - %obj.weaponCount++; -} - -function Weapon::decCatagory(%data, %obj) -{ - // Don't count the targeting laser as a weapon slot: - if ( %data.getName() !$= "TargetingLaser" ) - %obj.weaponCount--; -} - -function SimObject::damageObject(%data) -{ - //function was added to reduce console err msg spam -} - +$HandInvThrowTimeout = 0.8 * 1000; // 1/2 second between throwing grenades or mines + +// z0dd - ZOD, 9/13/02. Added global array for serverside weapon reticles and "visible" +$WeaponsHudData[0, bitmapName] = "gui/hud_blaster"; +$WeaponsHudData[0, itemDataName] = "Blaster"; +//$WeaponsHudData[0, ammoDataName] = ""; +$WeaponsHudData[0, reticle] = "gui/ret_blaster"; +$WeaponsHudData[0, visible] = "true"; +$WeaponsHudData[1, bitmapName] = "gui/hud_plasma"; +$WeaponsHudData[1, itemDataName] = "Plasma"; +$WeaponsHudData[1, ammoDataName] = "PlasmaAmmo"; +$WeaponsHudData[1, reticle] = "gui/ret_plasma"; +$WeaponsHudData[1, visible] = "true"; +$WeaponsHudData[2, bitmapName] = "gui/hud_chaingun"; +$WeaponsHudData[2, itemDataName] = "Chaingun"; +$WeaponsHudData[2, ammoDataName] = "ChaingunAmmo"; +$WeaponsHudData[2, reticle] = "gui/ret_chaingun"; +$WeaponsHudData[2, visible] = "true"; +$WeaponsHudData[3, bitmapName] = "gui/hud_disc"; +$WeaponsHudData[3, itemDataName] = "Disc"; +$WeaponsHudData[3, ammoDataName] = "DiscAmmo"; +$WeaponsHudData[3, reticle] = "gui/ret_disc"; +$WeaponsHudData[3, visible] = "true"; +$WeaponsHudData[4, bitmapName] = "gui/hud_grenlaunch"; +$WeaponsHudData[4, itemDataName] = "GrenadeLauncher"; +$WeaponsHudData[4, ammoDataName] = "GrenadeLauncherAmmo"; +$WeaponsHudData[4, reticle] = "gui/ret_grenade"; +$WeaponsHudData[4, visible] = "true"; +$WeaponsHudData[5, bitmapName] = "gui/hud_sniper"; +$WeaponsHudData[5, itemDataName] = "SniperRifle"; +//$WeaponsHudData[5, ammoDataName] = ""; +$WeaponsHudData[5, reticle] = "gui/hud_ret_sniper"; +$WeaponsHudData[5, visible] = "false"; +$WeaponsHudData[6, bitmapName] = "gui/hud_elfgun"; +$WeaponsHudData[6, itemDataName] = "ELFGun"; +//$WeaponsHudData[6, ammoDataName] = ""; +$WeaponsHudData[6, reticle] = "gui/ret_elf"; +$WeaponsHudData[6, visible] = "true"; +$WeaponsHudData[7, bitmapName] = "gui/hud_mortor"; +$WeaponsHudData[7, itemDataName] = "Mortar"; +$WeaponsHudData[7, ammoDataName] = "MortarAmmo"; +$WeaponsHudData[7, reticle] = "gui/ret_mortor"; +$WeaponsHudData[7, visible] = "true"; +$WeaponsHudData[8, bitmapName] = "gui/hud_missiles"; +$WeaponsHudData[8, itemDataName] = "MissileLauncher"; +$WeaponsHudData[8, ammoDataName] = "MissileLauncherAmmo"; +$WeaponsHudData[8, reticle] = "gui/ret_missile"; +$WeaponsHudData[8, visible] = "true"; +// WARNING!!! If you change the weapon index of the targeting laser, +// you must change the HudWeaponInvBase::addWeapon function to test +// for the new value! +$WeaponsHudData[9, bitmapName] = "gui/hud_targetlaser"; +$WeaponsHudData[9, itemDataName] = "TargetingLaser"; +//$WeaponsHudData[9, ammoDataName] = ""; +$WeaponsHudData[9, reticle] = "gui/hud_ret_targlaser"; +$WeaponsHudData[9, visible] = "false"; +$WeaponsHudData[10, bitmapName] = "gui/hud_shocklance"; +$WeaponsHudData[10, itemDataName] = "ShockLance"; +//$WeaponsHudData[10, ammoDataName] = ""; +$WeaponsHudData[10, reticle] = "gui/hud_ret_shocklance"; +$WeaponsHudData[10, visible] = "false"; + +// z0dd - ZOD, 9/13/02. TR2 weapons for compatability. +$WeaponsHudData[11, bitmapName] = "gui/hud_disc"; +$WeaponsHudData[11, itemDataName] = "TR2Disc"; +$WeaponsHudData[11, ammoDataName] = "TR2DiscAmmo"; +$WeaponsHudData[11, reticle] = "gui/ret_disc"; +$WeaponsHudData[11, visible] = "true"; +$WeaponsHudData[12, bitmapName] = "gui/hud_grenlaunch"; +$WeaponsHudData[12, itemDataName] = "TR2GrenadeLauncher"; +$WeaponsHudData[12, ammoDataName] = "TR2GrenadeLauncherAmmo"; +$WeaponsHudData[12, reticle] = "gui/ret_grenade"; +$WeaponsHudData[12, visible] = "true"; +$WeaponsHudData[13, bitmapName] = "gui/hud_chaingun"; +$WeaponsHudData[13, itemDataName] = "TR2Chaingun"; +$WeaponsHudData[13, ammoDataName] = "TR2ChaingunAmmo"; +$WeaponsHudData[13, reticle] = "gui/ret_chaingun"; +$WeaponsHudData[13, visible] = "true"; +$WeaponsHudData[14, bitmapName] = "gui/hud_targetlaser"; +$WeaponsHudData[14, itemDataName] = "TR2GoldTargetingLaser"; +$WeaponsHudData[14, reticle] = "gui/hud_ret_targlaser"; +$WeaponsHudData[14, visible] = "false"; +$WeaponsHudData[15, bitmapName] = "gui/hud_targetlaser"; +$WeaponsHudData[15, itemDataName] = "TR2SilverTargetingLaser"; +$WeaponsHudData[15, reticle] = "gui/hud_ret_targlaser"; +$WeaponsHudData[15, visible] = "false"; +$WeaponsHudData[16, bitmapName] = "gui/hud_shocklance"; +$WeaponsHudData[16, itemDataName] = "TR2ShockLance"; +$WeaponsHudData[16, reticle] = "gui/hud_ret_shocklance"; +$WeaponsHudData[16, visible] = "false"; +$WeaponsHudData[17, bitmapName] = "gui/hud_mortor"; +$WeaponsHudData[17, itemDataName] = "TR2Mortar"; +$WeaponsHudData[17, ammoDataName] = "TR2MortarAmmo"; +$WeaponsHudData[17, reticle] = "gui/ret_mortor"; +$WeaponsHudData[17, visible] = "true"; +$WeaponsHudData[18, bitmapName] = "gui/hud_mortor"; +$WeaponsHudData[18, itemDataName] = "Flamer"; +$WeaponsHudData[18, reticle] = "gui/ret_mortor"; +$WeaponsHudData[18, visible] = "true"; +$WeaponsHudData[19, bitmapName] = "gui/hud_sniper"; +$WeaponsHudData[19, itemDataName] = "R700"; +//$WeaponsHudData[5, ammoDataName] = ""; +$WeaponsHudData[19, reticle] = "gui/hud_ret_sniper"; +$WeaponsHudData[19, visible] = "false"; + +$WeaponsHudCount = 20; + +$AmmoIncrement[PlasmaAmmo] = 10; +$AmmoIncrement[ChaingunAmmo] = 25; +$AmmoIncrement[DiscAmmo] = 5; +$AmmoIncrement[GrenadeLauncherAmmo] = 5; +$AmmoIncrement[MortarAmmo] = 5; +$AmmoIncrement[MissileLauncherAmmo] = 2; +$AmmoIncrement[Mine] = 3; +$AmmoIncrement[Grenade] = 5; +$AmmoIncrement[FlashGrenade] = 5; +$AmmoIncrement[FlareGrenade] = 5; +$AmmoIncrement[ConcussionGrenade] = 5; +$AmmoIncrement[CameraGrenade] = 2; // z0dd - ZOD, 4/17/02. Camera ammo pickup fix. +$AmmoIncrement[RepairKit] = 1; +$AmmoIncrement[Beacon] = 1; // z0dd - ZOD, 4/17/02. Beacon ammo pickup fix. + +// ------------------------------------------------------------ +// z0dd - ZOD, 9/12/02. TR2 need +$AmmoIncrement[TR2DiscAmmo] = 5; +$AmmoIncrement[TR2GrenadeLauncherAmmo] = 5; +$AmmoIncrement[TR2ChaingunAmmo] = 25; +$AmmoIncrement[TR2MortarAmmo] = 5; +$AmmoIncrement[TR2Grenade] = 5; +// ------------------------------------------------------------ + +//---------------------------------------------------------------------------- +// Weapons scripts +//-------------------------------------- + +// --- Mounting weapons +exec("scripts/weapons/blaster.cs"); +exec("scripts/weapons/plasma.cs"); +exec("scripts/weapons/chaingun.cs"); +exec("scripts/weapons/disc.cs"); +exec("scripts/weapons/grenadeLauncher.cs"); +exec("scripts/weapons/sniperRifle.cs"); +exec("scripts/weapons/R700.cs"); +exec("scripts/weapons/ELFGun.cs"); +exec("scripts/weapons/mortar.cs"); +exec("scripts/weapons/missileLauncher.cs"); +exec("scripts/weapons/targetingLaser.cs"); +exec("scripts/weapons/shockLance.cs"); +exec("scripts/weapons/drakeFlame.cs"); + +// --- Throwing weapons +exec("scripts/weapons/mine.cs"); +exec("scripts/weapons/grenade.cs"); +exec("scripts/weapons/flashGrenade.cs"); +exec("scripts/weapons/flareGrenade.cs"); +exec("scripts/weapons/concussionGrenade.cs"); +exec("scripts/weapons/cameraGrenade.cs"); + +//---------------------------------------------------------------------------- + +function Weapon::onUse(%data, %obj) +{ + if(Game.weaponOnUse(%data, %obj)) + if (%obj.getDataBlock().className $= Armor) + %obj.mountImage(%data.image, $WeaponSlot); +} + +function WeaponImage::onMount(%this,%obj,%slot) +{ + //MES -- is call below useful at all? + //Parent::onMount(%this, %obj, %slot); + if(%obj.getClassName() !$= "Player") + return; + + //messageClient(%obj.client, 'MsgWeaponMount', "", %this, %obj, %slot); + // Looks arm position + if (%this.armthread $= "") + { + %obj.setArmThread(look); + } + else + { + %obj.setArmThread(%this.armThread); + } + + // Initial ammo state + if(%obj.getMountedImage($WeaponSlot).ammo !$= "") + if (%obj.getInventory(%this.ammo)) + %obj.setImageAmmo(%slot,true); + + %obj.client.setWeaponsHudActive(%this.item); + if(%obj.getMountedImage($WeaponSlot).ammo !$= "") + %obj.client.setAmmoHudCount(%obj.getInventory(%this.ammo)); + else + %obj.client.setAmmoHudCount(-1); +} + +function WeaponImage::onUnmount(%this,%obj,%slot) +{ + %obj.client.setWeaponsHudActive(%this.item, 1); + %obj.client.setAmmoHudCount(-1); + commandToClient(%obj.client,'removeReticle'); + // try to avoid running around with sniper/missile arm thread and no weapon + %obj.setArmThread(look); + Parent::onUnmount(%this, %obj, %slot); +} + +function Ammo::onInventory(%this,%obj,%amount) +{ + // Loop through and make sure the images using this ammo have + // their ammo states set. + for (%i = 0; %i < 8; %i++) { + %image = %obj.getMountedImage(%i); + if (%image > 0) + { + if (isObject(%image.ammo) && %image.ammo.getId() == %this.getId()) + %obj.setImageAmmo(%i,%amount != 0); + } + } + ItemData::onInventory(%this,%obj,%amount); + // Uh, don't update the hud ammo counters if this is a corpse...that's bad. + if ( %obj.getClassname() $= "Player" && %obj.getState() !$= "Dead" ) + { + %obj.client.setWeaponsHudAmmo(%this.getName(), %amount); + if(%obj.getMountedImage($WeaponSlot).ammo $= %this.getName()) + %obj.client.setAmmoHudCount(%amount); + } +} + +function Weapon::onInventory(%this,%obj,%amount) +{ + if(Game.weaponOnInventory(%this, %obj, %amount)) + { + // Do not update the hud if this object is a corpse: + if ( %obj.getState() !$= "Dead" ) + %obj.client.setWeaponsHudItem(%this.getName(), 0, 1); + ItemData::onInventory(%this,%obj,%amount); + // if a player threw a weapon (which means that player isn't currently + // holding a weapon), set armthread to "no weapon" + // MES - taken out to avoid v-menu animation problems (bug #4749) + //if((%amount == 0) && (%obj.getClassName() $= "Player")) + // %obj.setArmThread(looknw); + } +} + +function Weapon::onPickup(%this, %obj, %shape, %amount) +{ + // If player doesn't have a weapon in hand, use this one... + if ( %shape.getClassName() $= "Player" + && %shape.getMountedImage( $WeaponSlot ) == 0 ) + %shape.use( %this.getName() ); +} + +function HandInventory::onInventory(%this,%obj,%amount) +{ + // prevent console errors when throwing ammo pack + if(%obj.getClassName() $= "Player") + %obj.client.setInventoryHudAmount(%this.getName(), %amount); + ItemData::onInventory(%this,%obj,%amount); +} + +function HandInventory::onUse(%data, %obj) +{ + // %obj = player %data = datablock of what's being thrown + if(Game.handInvOnUse(%data, %obj)) + { + //AI HOOK - If you change the %throwStren, tell Tinman!!! + //Or edit aiInventory.cs and search for: use(%grenadeType); + + // z0dd - ZOD, 6/11/02. Toss grenades and your invincibility and cloaking goes away. + if(%obj.station $= "" && %obj.isCloaked()) + { + if( %obj.respawnCloakThread !$= "" ) + { + Cancel(%obj.respawnCloakThread); + %obj.setCloaked( false ); + %obj.respawnCloakThread = ""; + } + } + if( %obj.client > 0 ) + { + %obj.setInvincibleMode(0, 0.00); + %obj.setInvincible( false ); + } + + %tossTimeout = getSimTime() - %obj.lastThrowTime[%data]; + if(%tossTimeout < $HandInvThrowTimeout) + return; + + %throwStren = %obj.throwStrength; + + %obj.decInventory(%data, 1); + %thrownItem = new Item() + { + dataBlock = %data.thrownItem; + sourceObject = %obj; + }; + MissionCleanup.add(%thrownItem); + + // throw it + %eye = %obj.getEyeVector(); + %vec = vectorScale(%eye, (%throwStren * 20.0)); + + // add a vertical component to give it a better arc + %dot = vectorDot("0 0 1", %eye); + if(%dot < 0) + %dot = -%dot; + %vec = vectorAdd(%vec, vectorScale("0 0 10", 1 - %dot)); // z0dd - ZOD, 8/4/02. Add a higher arc to the toss. was 0 0 4 + + // add player's velocity + %vec = vectorAdd(%vec, vectorScale(%obj.getVelocity(), 0.65)); // z0dd - ZOD, 8/4/02. Add more of the players vel to the toss. was 0.4 + %pos = getBoxCenter(%obj.getWorldBox()); + + %thrownItem.sourceObject = %obj; + %thrownItem.team = %obj.team; + %thrownItem.setTransform(%pos); + + %thrownItem.applyImpulse(%pos, %vec); + %thrownItem.setCollisionTimeout(%obj); + serverPlay3D(GrenadeThrowSound, %pos); + %obj.lastThrowTime[%data] = getSimTime(); + + %thrownItem.getDataBlock().onThrow(%thrownItem, %obj); + %obj.throwStrength = 0; + } +} + +function HandInventoryImage::onMount(%this,%obj,%slot) +{ + messageClient(%col.client, 'MsgHandInventoryMount', "", %this, %obj, %slot); + // Looks arm position + if (%this.armthread $= "") + %obj.setArmThread(look); + else + %obj.setArmThread(%this.armThread); + + // Initial ammo state + if (%obj.getInventory(%this.ammo)) + %obj.setImageAmmo(%slot,true); + + %obj.client.setWeaponsHudActive(%this.item); +} + +function Weapon::incCatagory(%data, %obj) +{ + // Don't count the targeting laser as a weapon slot: + if ( %data.getName() !$= "TargetingLaser" ) + %obj.weaponCount++; +} + +function Weapon::decCatagory(%data, %obj) +{ + // Don't count the targeting laser as a weapon slot: + if ( %data.getName() !$= "TargetingLaser" ) + %obj.weaponCount--; +} + +function SimObject::damageObject(%data) +{ + //function was added to reduce console err msg spam +} + diff --git a/scripts/weapons/DrakeFlame.cs b/scripts/weapons/DrakeFlame.cs index d2ba319..bd81f72 100644 --- a/scripts/weapons/DrakeFlame.cs +++ b/scripts/weapons/DrakeFlame.cs @@ -1,356 +1,356 @@ - //-------------------------------------- -// Draakan Flame "Breath" - Is CCM's flameThrower edited to suit the mod -//-------------------------------------- - -//color tent for EVERYTHING its red really red -//1 r -//0.18 g -//0.03 b - -//-------------------------------------- -// Trail -//-------------------------------------- - -datablock ParticleData(flameParticle) -{ - dragCoeffiecient = 0.0; - gravityCoefficient = -0.1; - inheritedVelFactor = 0.1; - - lifetimeMS = 500; - lifetimeVarianceMS = 50; - - textureName = "ParticleTest"; - - spinRandomMin = -10.0; - spinRandomMax = 10.0; - - colors[0] = "1 0.18 0.03 0.4"; - colors[1] = "1 0.18 0.03 0.3"; - colors[2] = "1 0.18 0.03 0.0"; - sizes[0] = 2.0; - sizes[1] = 1.0; - sizes[2] = 0.8; - times[0] = 0.0; - times[1] = 0.6; - times[2] = 1.0; -}; - -datablock ParticleEmitterData(flameEmitter) -{ - ejectionPeriodMS = 3; - periodVarianceMS = 0; - - ejectionOffset = 0.2; - ejectionVelocity = 10.0; - velocityVariance = 0.0; - - thetaMin = 0.0; - thetaMax = 10.0; - - particles = "flameParticle"; -}; - -//-------------------------------------------------------------------------- -// Sounds -//-------------------------------------- -//This will eventually be some "choking" sound -//datablock AudioProfile(FlamerDryFireSound) -//{ -// filename = "fx/weapons/plasma_dryfire.wav"; -// description = AudioClose3d; -// preload = true; -// effect = PlasmaDryFireEffect; -//}; - -//-------------------------------------------------------------------------- -// Explosion -//-------------------------------------------------------------------------- -datablock ParticleData(flameExplosionParticle) -{ - dragCoefficient = 2; - gravityCoefficient = 0.2; - inheritedVelFactor = 0.2; - constantAcceleration = 0.0; - lifetimeMS = 500; - lifetimeVarianceMS = 0; - textureName = "ParticleTest"; - colors[0] = "1 0.18 0.03 0.6"; - colors[1] = "1 0.18 0.03 0.0"; - sizes[0] = 2; - sizes[1] = 2.5; -}; - -datablock ParticleEmitterData(flameExplosionEmitter) -{ - ejectionPeriodMS = 1; - periodVarianceMS = 0; - ejectionOffset = 2.0; - ejectionVelocity = 4.0; - velocityVariance = 0.0; - thetaMin = 60.0; - thetaMax = 90.0; - lifetimeMS = 250; - - particles = "flameExplosionParticle"; -}; - -datablock ExplosionData(flameBoltExplosion) -{ - particleEmitter = flameExplosionEmitter; - particleDensity = 150; - particleRadius = 1.25; - faceViewer = true; -}; - -//-------------------------------------------------------------------------- -// Projectiles -//-------------------------------------------------------------------------- -datablock LinearFlareProjectileData(FlameboltMain) -{ - projectileShapeName = "turret_muzzlepoint.dts"; - scale = "1.0 1.0 1.0"; - faceViewer = true; - directDamage = 0.1; - hasDamageRadius = true; - indirectDamage = 0.08; - damageRadius = 4.0; - kickBackStrength = 0.0; - radiusDamageType = $DamageType::Flame; - directDamageType = $DamageType::Flame; - - explosion = "flameBoltExplosion"; - splash = PlasmaSplash; - - baseEmitter = FlameEmitter; - - dryVelocity = 50.0; // z0dd - ZOD, 7/20/02. Faster plasma projectile. was 55 - wetVelocity = -1; - velInheritFactor = 0.3; - fizzleTimeMS = 250; - lifetimeMS = 2000; - explodeOnDeath = false; - reflectOnWaterImpactAngle = 0.0; - explodeOnWaterImpact = true; - deflectionOnWaterImpact = 0.0; - fizzleUnderwaterMS = -1; - - //activateDelayMS = 100; - activateDelayMS = -1; - - size[0] = 0.2; - size[1] = 0.5; - size[2] = 0.1; - - - numFlares = 35; - flareColor = "1 0.18 0.03"; - flareModTexture = "flaremod"; - flareBaseTexture = "flarebase"; - - sound = PlasmaProjectileSound; - fireSound = PlasmaFireSound; - wetFireSound = PlasmaFireWetSound; - - hasLight = true; - lightRadius = 10.0; - lightColor = "0.94 0.03 0.12"; -}; - -//-------------------------------------------------------------------------- -// Weapon -//-------------------------------------------------------------------------- -datablock ItemData(flamer) -{ - className = Weapon; - catagory = "Spawn Items"; - shapeFile = "weapon_plasma.dts"; - image = flamerImage; - mass = 1.0; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - pickUpName = "you should not see this"; //Players should never be able to pick this up.. -}; - -datablock ShapeBaseImageData(flamerImage) -{ - className = WeaponImage; - shapeFile = "turret_muzzlepoint.dts"; - mass = 10; - item = flamer; - offset = "-0.45 1 0.5"; // L/R - F/B - T/B - rotation = "0 1 0 180"; // L/R - F/B - T/B - // armThread = looknw; -- For some odd reason, this adds a little tiny white triangle next to the reticle - - UsesEnergy = true; - MinEnergy = 1; //At least one point of energy to fire - fireEnergy = 5.5; //The Draakan Flame uses a fuck load of energy to keep the armor & body cool - HasTimeout = true; - TimeoutMS = 6000; - - projectileSpread = 7.0 / 1000.0; - - projectile = flameBoltmain; - projectileType = LinearFlareProjectile; - - stateName[0] = "Activate"; - stateTransitionOnTimeout[0] = "ActivateReady"; - stateTimeoutValue[0] = 0.5; - stateSequence[0] = "Activate"; - stateSound[0] = PlasmaSwitchSound; - - stateName[1] = "ActivateReady"; - stateTransitionOnLoaded[1] = "Ready"; - stateTransitionOnNoAmmo[1] = "NoAmmo"; - - stateName[2] = "Ready"; - stateEmitterTime[2] = 10000; - stateTransitionOnNoAmmo[2] = "NoAmmo"; - stateTransitionOnTriggerDown[2] = "CheckWet"; //Drakes can't use flames underwater. :) - - stateName[3] = "Fire"; - stateTransitionOnTimeout[3] = "Reload"; - stateTimeoutValue[3] = 0.05; - stateFire[3] = true; - stateAllowImageChange[3] = false; - stateScript[3] = "onFire"; - stateEmitterTime[3] = 0.05; - - stateName[4] = "Reload"; - stateTransitionOnNoAmmo[4] = "NoAmmo"; - stateTransitionOnTimeout[4] = "Ready"; - stateTimeoutValue[4] = 0.05; - stateAllowImageChange[4] = false; - stateSequence[4] = "Reload"; - stateSound[4] = PlasmaReloadSound; - - stateName[5] = "NoAmmo"; - stateTransitionOnAmmo[5] = "Reload"; - stateSequence[5] = "NoAmmo"; - stateTransitionOnTriggerDown[5] = "DryFire"; - - stateName[6] = "DryFire"; - stateSound[6] = PlasmaDryFireSound; //I should make this some 'choking' sound - stateTimeoutValue[6] = 1.0; - stateTransitionOnTimeout[6] = "NoAmmo"; - - stateName[7] = "WetFire"; - stateSound[7] = PlasmaFireWetSound; - stateTimeoutValue[7] = 1.0; - stateTransitionOnTimeout[7] = "Ready"; - - stateName[8] = "CheckWet"; - stateTransitionOnWet[8] = "WetFire"; - stateTransitionOnNotWet[8] = "Fire"; -}; - -//-------------------------------------------------------------------------- -// Bound Functions -//-------------------------------------------------------------------------- -function flamerImage::OnFire(%this,%obj,%slot) -{ -%p = parent::onfire(%this,%obj,%slot); -} - -function flamerImage::onMount(%this,%obj,%slot) -{ -if (%obj.client.race !$= "Draakan") //If we're not a Drake -%obj.setInventory("Flamer",0,true); -else -Parent::onMount(%this,%obj,%slot); -} - -function flamerImage::onUnmount(%this,%obj,%slot) -{ -Parent::onUnmount(%this,%obj,%slot); -} - -//-------------------------------------------------------------------------- -// Functions -//-------------------------------------------------------------------------- -function burnloop(%obj,%sourceObj, %DMG, %DmgTpe) //TODO: Organize this entire weapon file.. -{ -cancel(%obj.burnloop); - -if(!isobject(%obj) || %obj.client.race $= "draakan" || %obj.getclassname() !$= "player" || !%obj.shouldburn) -{ -%obj.isburning = false; -%obj.client.shouldscream = false; //Only applies to AI clients. -return; -} - -if (%obj.client.shouldscream $="") //Used for bots.. -%obj.client.shouldscream = true; - -if (%obj.client.shouldscream) -{ - -%rnd = getrandom(0,1); -switch(%rnd) -{ -case 0: schedule(250, %obj.client, "AIPlayAnimSound", %obj.client, "0 0 0", "vqk.help", $AIAnimWave, $AIAnimWave, 0); -case 1: schedule(250, %obj.client, "AIPlayAnimSound", %obj.client, "0 0 0", "gbl.shazbot", $AIAnimWave, $AIAnimWave, 0); -} -%obj.client.shouldscream = false; -} - -%obj.damage(%sourceObj, %obj.getposition(), %DMG, %DmgTpe); - -if (%obj.getstate() $="dead") -%fire = new ParticleEmissionDummy(){ -position = vectoradd(%obj.getPosition(),"0 0 0.2"); -dataBlock = "defaultEmissionDummy"; -emitter = "FlameEmitter"; -}; -else -%fire = new ParticleEmissionDummy(){ -position = vectoradd(%obj.getPosition(),"0 0 0.5"); -dataBlock = "defaultEmissionDummy"; -emitter = "FlameEmitter"; -}; - - -if (IsObject(%obj.client) && %obj.client.isaicontrolled()) -%obj.client.setblinded(1); - -if (%obj.burntime $="") -%obj.burntime = 0; - -%time = %obj.burntime * 1000; - -if (%time == $Host::BurnTime || %time > $Host::BurnTime) -{ -%obj.burntime = 0; -Cancel(%obj.burnloop); - -if (IsObject(%fire)) -%fire.delete(); -return; -} -else -{ -%obj.burntime++; -} - -MissionCleanup.add(%fire); -%fire.schedule(100, "delete"); -%obj.burnloop = schedule(100, 0, "burnloop", %obj, %sourceObj.client, 0.007, %DmgTpe); -%obj.isburning = true; -} - - -function flamer::onadd(%this,%obj) //Move the object to 0 0 0 as soon as it's created - .delete likes to crash. -{ -schedule(1,0,"delete",%obj); -} - -function settransform(%obj,%trans) -{ -%obj.settransform(%trans); -} - -function delete(%obj) -{ -%obj.delete(); -} + //-------------------------------------- +// Draakan Flame "Breath" - Is CCM's flameThrower edited to suit the mod +//-------------------------------------- + +//color tent for EVERYTHING its red really red +//1 r +//0.18 g +//0.03 b + +//-------------------------------------- +// Trail +//-------------------------------------- + +datablock ParticleData(flameParticle) +{ + dragCoeffiecient = 0.0; + gravityCoefficient = -0.1; + inheritedVelFactor = 0.1; + + lifetimeMS = 500; + lifetimeVarianceMS = 50; + + textureName = "ParticleTest"; + + spinRandomMin = -10.0; + spinRandomMax = 10.0; + + colors[0] = "1 0.18 0.03 0.4"; + colors[1] = "1 0.18 0.03 0.3"; + colors[2] = "1 0.18 0.03 0.0"; + sizes[0] = 2.0; + sizes[1] = 1.0; + sizes[2] = 0.8; + times[0] = 0.0; + times[1] = 0.6; + times[2] = 1.0; +}; + +datablock ParticleEmitterData(flameEmitter) +{ + ejectionPeriodMS = 3; + periodVarianceMS = 0; + + ejectionOffset = 0.2; + ejectionVelocity = 10.0; + velocityVariance = 0.0; + + thetaMin = 0.0; + thetaMax = 10.0; + + particles = "flameParticle"; +}; + +//-------------------------------------------------------------------------- +// Sounds +//-------------------------------------- +//This will eventually be some "choking" sound +//datablock AudioProfile(FlamerDryFireSound) +//{ +// filename = "fx/weapons/plasma_dryfire.wav"; +// description = AudioClose3d; +// preload = true; +// effect = PlasmaDryFireEffect; +//}; + +//-------------------------------------------------------------------------- +// Explosion +//-------------------------------------------------------------------------- +datablock ParticleData(flameExplosionParticle) +{ + dragCoefficient = 2; + gravityCoefficient = 0.2; + inheritedVelFactor = 0.2; + constantAcceleration = 0.0; + lifetimeMS = 500; + lifetimeVarianceMS = 0; + textureName = "ParticleTest"; + colors[0] = "1 0.18 0.03 0.6"; + colors[1] = "1 0.18 0.03 0.0"; + sizes[0] = 2; + sizes[1] = 2.5; +}; + +datablock ParticleEmitterData(flameExplosionEmitter) +{ + ejectionPeriodMS = 1; + periodVarianceMS = 0; + ejectionOffset = 2.0; + ejectionVelocity = 4.0; + velocityVariance = 0.0; + thetaMin = 60.0; + thetaMax = 90.0; + lifetimeMS = 250; + + particles = "flameExplosionParticle"; +}; + +datablock ExplosionData(flameBoltExplosion) +{ + particleEmitter = flameExplosionEmitter; + particleDensity = 150; + particleRadius = 1.25; + faceViewer = true; +}; + +//-------------------------------------------------------------------------- +// Projectiles +//-------------------------------------------------------------------------- +datablock LinearFlareProjectileData(FlameboltMain) +{ + projectileShapeName = "turret_muzzlepoint.dts"; + scale = "1.0 1.0 1.0"; + faceViewer = true; + directDamage = 0.1; + hasDamageRadius = true; + indirectDamage = 0.08; + damageRadius = 4.0; + kickBackStrength = 0.0; + radiusDamageType = $DamageType::Flame; + directDamageType = $DamageType::Flame; + + explosion = "flameBoltExplosion"; + splash = PlasmaSplash; + + baseEmitter = FlameEmitter; + + dryVelocity = 50.0; // z0dd - ZOD, 7/20/02. Faster plasma projectile. was 55 + wetVelocity = -1; + velInheritFactor = 0.3; + fizzleTimeMS = 250; + lifetimeMS = 2000; + explodeOnDeath = false; + reflectOnWaterImpactAngle = 0.0; + explodeOnWaterImpact = true; + deflectionOnWaterImpact = 0.0; + fizzleUnderwaterMS = -1; + + //activateDelayMS = 100; + activateDelayMS = -1; + + size[0] = 0.2; + size[1] = 0.5; + size[2] = 0.1; + + + numFlares = 35; + flareColor = "1 0.18 0.03"; + flareModTexture = "flaremod"; + flareBaseTexture = "flarebase"; + + sound = PlasmaProjectileSound; + fireSound = PlasmaFireSound; + wetFireSound = PlasmaFireWetSound; + + hasLight = true; + lightRadius = 10.0; + lightColor = "0.94 0.03 0.12"; +}; + +//-------------------------------------------------------------------------- +// Weapon +//-------------------------------------------------------------------------- +datablock ItemData(flamer) +{ + className = Weapon; + catagory = "Spawn Items"; + shapeFile = "weapon_plasma.dts"; + image = flamerImage; + mass = 1.0; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 2; + pickUpName = "you should not see this"; //Players should never be able to pick this up.. +}; + +datablock ShapeBaseImageData(flamerImage) +{ + className = WeaponImage; + shapeFile = "turret_muzzlepoint.dts"; + mass = 10; + item = flamer; + offset = "-0.45 1 0.5"; // L/R - F/B - T/B + rotation = "0 1 0 180"; // L/R - F/B - T/B + // armThread = looknw; -- For some odd reason, this adds a little tiny white triangle next to the reticle + + UsesEnergy = true; + MinEnergy = 1; //At least one point of energy to fire + fireEnergy = 5.5; //The Draakan Flame uses a fuck load of energy to keep the armor & body cool + HasTimeout = true; + TimeoutMS = 6000; + + projectileSpread = 7.0 / 1000.0; + + projectile = flameBoltmain; + projectileType = LinearFlareProjectile; + + stateName[0] = "Activate"; + stateTransitionOnTimeout[0] = "ActivateReady"; + stateTimeoutValue[0] = 0.5; + stateSequence[0] = "Activate"; + stateSound[0] = PlasmaSwitchSound; + + stateName[1] = "ActivateReady"; + stateTransitionOnLoaded[1] = "Ready"; + stateTransitionOnNoAmmo[1] = "NoAmmo"; + + stateName[2] = "Ready"; + stateEmitterTime[2] = 10000; + stateTransitionOnNoAmmo[2] = "NoAmmo"; + stateTransitionOnTriggerDown[2] = "CheckWet"; //Drakes can't use flames underwater. :) + + stateName[3] = "Fire"; + stateTransitionOnTimeout[3] = "Reload"; + stateTimeoutValue[3] = 0.05; + stateFire[3] = true; + stateAllowImageChange[3] = false; + stateScript[3] = "onFire"; + stateEmitterTime[3] = 0.05; + + stateName[4] = "Reload"; + stateTransitionOnNoAmmo[4] = "NoAmmo"; + stateTransitionOnTimeout[4] = "Ready"; + stateTimeoutValue[4] = 0.05; + stateAllowImageChange[4] = false; + stateSequence[4] = "Reload"; + stateSound[4] = PlasmaReloadSound; + + stateName[5] = "NoAmmo"; + stateTransitionOnAmmo[5] = "Reload"; + stateSequence[5] = "NoAmmo"; + stateTransitionOnTriggerDown[5] = "DryFire"; + + stateName[6] = "DryFire"; + stateSound[6] = PlasmaDryFireSound; //I should make this some 'choking' sound + stateTimeoutValue[6] = 1.0; + stateTransitionOnTimeout[6] = "NoAmmo"; + + stateName[7] = "WetFire"; + stateSound[7] = PlasmaFireWetSound; + stateTimeoutValue[7] = 1.0; + stateTransitionOnTimeout[7] = "Ready"; + + stateName[8] = "CheckWet"; + stateTransitionOnWet[8] = "WetFire"; + stateTransitionOnNotWet[8] = "Fire"; +}; + +//-------------------------------------------------------------------------- +// Bound Functions +//-------------------------------------------------------------------------- +function flamerImage::OnFire(%this,%obj,%slot) +{ +%p = parent::onfire(%this,%obj,%slot); +} + +function flamerImage::onMount(%this,%obj,%slot) +{ +if (%obj.client.race !$= "Draakan") //If we're not a Drake +%obj.setInventory("Flamer",0,true); +else +Parent::onMount(%this,%obj,%slot); +} + +function flamerImage::onUnmount(%this,%obj,%slot) +{ +Parent::onUnmount(%this,%obj,%slot); +} + +//-------------------------------------------------------------------------- +// Functions +//-------------------------------------------------------------------------- +function burnloop(%obj,%sourceObj, %DMG, %DmgTpe) //TODO: Organize this entire weapon file.. +{ +cancel(%obj.burnloop); + +if(!isobject(%obj) || %obj.client.race $= "draakan" || %obj.getclassname() !$= "player" || !%obj.shouldburn) +{ +%obj.isburning = false; +%obj.client.shouldscream = false; //Only applies to AI clients. +return; +} + +if (%obj.client.shouldscream $="" && %obj.client.isAIControlled()) //Used for bots.. +%obj.client.shouldscream = true; + +if (%obj.client.shouldscream) +{ + +%rnd = getrandom(0,1); +switch(%rnd) +{ +case 0: schedule(250, %obj.client, "AIPlayAnimSound", %obj.client, "0 0 0", "vqk.help", $AIAnimWave, $AIAnimWave, 0); +case 1: schedule(250, %obj.client, "AIPlayAnimSound", %obj.client, "0 0 0", "gbl.shazbot", $AIAnimWave, $AIAnimWave, 0); +} +%obj.client.shouldscream = false; +} + +%obj.damage(%sourceObj, %obj.getposition(), %DMG, %DmgTpe); + +if (%obj.getstate() $="dead") +%fire = new ParticleEmissionDummy(){ +position = vectoradd(%obj.getPosition(),"0 0 0.2"); +dataBlock = "defaultEmissionDummy"; +emitter = "FlameEmitter"; +}; +else +%fire = new ParticleEmissionDummy(){ +position = vectoradd(%obj.getPosition(),"0 0 0.5"); +dataBlock = "defaultEmissionDummy"; +emitter = "FlameEmitter"; +}; + + +if (IsObject(%obj.client) && %obj.client.isaicontrolled()) +%obj.client.setblinded(1); + +if (%obj.burntime $="") +%obj.burntime = 0; + +%time = %obj.burntime * 1000; + +if (%time == $Host::BurnTime || %time > $Host::BurnTime) +{ +%obj.burntime = 0; +Cancel(%obj.burnloop); + +if (IsObject(%fire)) +%fire.delete(); +return; +} +else +{ +%obj.burntime++; +} + +MissionCleanup.add(%fire); +%fire.schedule(100, "delete"); +%obj.burnloop = schedule(100, 0, "burnloop", %obj, %sourceObj.client, 0.007, %DmgTpe); +%obj.isburning = true; +} + + +function flamer::onadd(%this,%obj) //Move the object to 0 0 0 as soon as it's created - .delete likes to crash. +{ +schedule(1,0,"delete",%obj); +} + +function settransform(%obj,%trans) +{ +%obj.settransform(%trans); +} + +function delete(%obj) +{ +%obj.delete(); +} diff --git a/scripts/weapons/ELFGun.cs b/scripts/weapons/ELFGun.cs index c1e9c7c..e34a974 100644 --- a/scripts/weapons/ELFGun.cs +++ b/scripts/weapons/ELFGun.cs @@ -1,204 +1,204 @@ -//-------------------------------------------------------------------------- -// ELF Gun -//-------------------------------------------------------------------------- -datablock EffectProfile(ELFGunSwitchEffect) -{ - effectname = "weapons/generic_switch"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(ELFGunFireEffect) -{ - effectname = "weapons/ELF_fire"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(ELFGunFireWetEffect) -{ - effectname = "weapons/ELF_underwater"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock AudioProfile(ELFGunSwitchSound) -{ - filename = "fx/weapons/generic_switch.wav"; - description = AudioClosest3d; - preload = true; - effect = ELFGunSwitchEffect; -}; - -datablock AudioProfile(ELFGunFireSound) -{ - filename = "fx/weapons/ELF_fire.wav"; - description = CloseLooping3d; - preload = true; - effect = ELFGunFireEffect; -}; - -datablock AudioProfile(ElfFireWetSound) -{ - filename = "fx/weapons/ELF_underwater.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(ELFHitTargetSound) -{ - filename = "fx/weapons/ELF_hit.wav"; - description = CloseLooping3d; - preload = true; - effect = ELFGunFireEffect; -}; - -//-------------------------------------- -// Sparks -//-------------------------------------- -datablock ParticleData(ELFSparks) -{ - dragCoefficient = 1; - gravityCoefficient = 0.0; - inheritedVelFactor = 0.2; - constantAcceleration = 0.0; - lifetimeMS = 200; - lifetimeVarianceMS = 0; - textureName = "special/blueSpark"; - colors[0] = "0.8 0.8 1.0 1.0"; - colors[1] = "0.8 0.8 1.0 1.0"; - colors[2] = "0.8 0.8 1.0 0.0"; - sizes[0] = 0.35; - sizes[1] = 0.15; - sizes[2] = 0.0; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - -}; - -datablock ParticleEmitterData(ELFSparksEmitter) -{ - ejectionPeriodMS = 5; - periodVarianceMS = 0; - ejectionVelocity = 4; - velocityVariance = 2; - ejectionOffset = 0.0; - thetaMin = 0; - thetaMax = 180; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - orientParticles = true; -// lifetimeMS = 100; - particles = "ELFSparks"; -}; - - -//-------------------------------------- -// Projectile -//-------------------------------------- -datablock ELFProjectileData(BasicELF) -{ - beamRange = 38; // z0dd - ZOD, 5/18/02. WHAT?? INCREASE ELF RANGE?!!? was 37 - numControlPoints = 8; - restorativeFactor = 3.75; - dragFactor = 4.5; - endFactor = 2.25; - randForceFactor = 2; - randForceTime = 0.125; - drainEnergy = 1.0; - drainHealth = 0.0; - directDamageType = $DamageType::ELF; - mainBeamWidth = 0.1; // width of blue wave beam - mainBeamSpeed = 9.0; // speed that the beam travels forward - mainBeamRepeat = 0.25; // number of times the texture repeats - lightningWidth = 0.1; - lightningDist = 0.15; // distance of lightning from main beam - - fireSound = ElfGunFireSound; - wetFireSound = ElfFireWetSound; - - textures[0] = "special/ELFBeam"; - textures[1] = "special/ELFLightning"; - textures[2] = "special/BlueImpact"; - - emitter = ELFSparksEmitter; -}; - -//-------------------------------------- -// Rifle and item... -//-------------------------------------- -datablock ItemData(ELFGun) -{ - className = Weapon; - catagory = "Spawn Items"; - shapeFile = "weapon_elf.dts"; - image = ELFGunImage; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - pickUpName = "an ELF gun"; - - computeCRC = true; - emap = true; -}; - -datablock ShapeBaseImageData(ELFGunImage) -{ - className = WeaponImage; - - shapeFile = "weapon_elf.dts"; - item = ELFGun; - offset = "0 0 0"; - - projectile = BasicELF; - projectileType = ELFProjectile; - deleteLastProjectile = true; - emap = true; - - - usesEnergy = true; - minEnergy = 3; - - stateName[0] = "Activate"; - stateSequence[0] = "Activate"; - stateSound[0] = ELFGunSwitchSound; - stateTimeoutValue[0] = 0.5; - stateTransitionOnTimeout[0] = "ActivateReady"; - - stateName[1] = "ActivateReady"; - stateTransitionOnAmmo[1] = "Ready"; - stateTransitionOnNoAmmo[1] = "NoAmmo"; - - stateName[2] = "Ready"; - stateTransitionOnNoAmmo[2] = "NoAmmo"; - stateTransitionOnTriggerDown[2] = "CheckWet"; - - stateName[3] = "Fire"; - stateEnergyDrain[3] = 5; - stateFire[3] = true; - stateAllowImageChange[3] = false; - stateScript[3] = "onFire"; - stateTransitionOnTriggerUp[3] = "Deconstruction"; - stateTransitionOnNoAmmo[3] = "Deconstruction"; - //stateSound[3] = ElfFireWetSound; - - stateName[4] = "NoAmmo"; - stateTransitionOnAmmo[4] = "Ready"; - - stateName[5] = "Deconstruction"; - stateScript[5] = "deconstruct"; - stateTransitionOnTimeout[5] = "Ready"; - stateTransitionOnNoAmmo[6] = "NoAmmo"; - - stateName[6] = "DryFire"; - stateSound[6] = ElfFireWetSound; - stateTimeoutValue[6] = 0.5; - stateTransitionOnTimeout[6] = "Ready"; - - stateName[7] = "CheckWet"; - stateTransitionOnWet[7] = "DryFire"; - stateTransitionOnNotWet[7] = "Fire"; -}; +//-------------------------------------------------------------------------- +// ELF Gun +//-------------------------------------------------------------------------- +datablock EffectProfile(ELFGunSwitchEffect) +{ + effectname = "weapons/generic_switch"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock EffectProfile(ELFGunFireEffect) +{ + effectname = "weapons/ELF_fire"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock EffectProfile(ELFGunFireWetEffect) +{ + effectname = "weapons/ELF_underwater"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock AudioProfile(ELFGunSwitchSound) +{ + filename = "fx/weapons/generic_switch.wav"; + description = AudioClosest3d; + preload = true; + effect = ELFGunSwitchEffect; +}; + +datablock AudioProfile(ELFGunFireSound) +{ + filename = "fx/weapons/ELF_fire.wav"; + description = CloseLooping3d; + preload = true; + effect = ELFGunFireEffect; +}; + +datablock AudioProfile(ElfFireWetSound) +{ + filename = "fx/weapons/ELF_underwater.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(ELFHitTargetSound) +{ + filename = "fx/weapons/ELF_hit.wav"; + description = CloseLooping3d; + preload = true; + effect = ELFGunFireEffect; +}; + +//-------------------------------------- +// Sparks +//-------------------------------------- +datablock ParticleData(ELFSparks) +{ + dragCoefficient = 1; + gravityCoefficient = 0.0; + inheritedVelFactor = 0.2; + constantAcceleration = 0.0; + lifetimeMS = 200; + lifetimeVarianceMS = 0; + textureName = "special/blueSpark"; + colors[0] = "0.8 0.8 1.0 1.0"; + colors[1] = "0.8 0.8 1.0 1.0"; + colors[2] = "0.8 0.8 1.0 0.0"; + sizes[0] = 0.35; + sizes[1] = 0.15; + sizes[2] = 0.0; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; + +}; + +datablock ParticleEmitterData(ELFSparksEmitter) +{ + ejectionPeriodMS = 5; + periodVarianceMS = 0; + ejectionVelocity = 4; + velocityVariance = 2; + ejectionOffset = 0.0; + thetaMin = 0; + thetaMax = 180; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + orientParticles = true; +// lifetimeMS = 100; + particles = "ELFSparks"; +}; + + +//-------------------------------------- +// Projectile +//-------------------------------------- +datablock ELFProjectileData(BasicELF) +{ + beamRange = 38; // z0dd - ZOD, 5/18/02. WHAT?? INCREASE ELF RANGE?!!? was 37 + numControlPoints = 8; + restorativeFactor = 3.75; + dragFactor = 4.5; + endFactor = 2.25; + randForceFactor = 2; + randForceTime = 0.125; + drainEnergy = 1.0; + drainHealth = 0.0; + directDamageType = $DamageType::ELF; + mainBeamWidth = 0.1; // width of blue wave beam + mainBeamSpeed = 9.0; // speed that the beam travels forward + mainBeamRepeat = 0.25; // number of times the texture repeats + lightningWidth = 0.1; + lightningDist = 0.15; // distance of lightning from main beam + + fireSound = ElfGunFireSound; + wetFireSound = ElfFireWetSound; + + textures[0] = "special/ELFBeam"; + textures[1] = "special/ELFLightning"; + textures[2] = "special/BlueImpact"; + + emitter = ELFSparksEmitter; +}; + +//-------------------------------------- +// Rifle and item... +//-------------------------------------- +datablock ItemData(ELFGun) +{ + className = Weapon; + catagory = "Spawn Items"; + shapeFile = "weapon_elf.dts"; + image = ELFGunImage; + mass = 1; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 2; + pickUpName = "an ELF gun"; + + computeCRC = true; + emap = true; +}; + +datablock ShapeBaseImageData(ELFGunImage) +{ + className = WeaponImage; + + shapeFile = "weapon_elf.dts"; + item = ELFGun; + offset = "0 0 0"; + + projectile = BasicELF; + projectileType = ELFProjectile; + deleteLastProjectile = true; + emap = true; + + + usesEnergy = true; + minEnergy = 3; + + stateName[0] = "Activate"; + stateSequence[0] = "Activate"; + stateSound[0] = ELFGunSwitchSound; + stateTimeoutValue[0] = 0.5; + stateTransitionOnTimeout[0] = "ActivateReady"; + + stateName[1] = "ActivateReady"; + stateTransitionOnAmmo[1] = "Ready"; + stateTransitionOnNoAmmo[1] = "NoAmmo"; + + stateName[2] = "Ready"; + stateTransitionOnNoAmmo[2] = "NoAmmo"; + stateTransitionOnTriggerDown[2] = "CheckWet"; + + stateName[3] = "Fire"; + stateEnergyDrain[3] = 5; + stateFire[3] = true; + stateAllowImageChange[3] = false; + stateScript[3] = "onFire"; + stateTransitionOnTriggerUp[3] = "Deconstruction"; + stateTransitionOnNoAmmo[3] = "Deconstruction"; + //stateSound[3] = ElfFireWetSound; + + stateName[4] = "NoAmmo"; + stateTransitionOnAmmo[4] = "Ready"; + + stateName[5] = "Deconstruction"; + stateScript[5] = "deconstruct"; + stateTransitionOnTimeout[5] = "Ready"; + stateTransitionOnNoAmmo[6] = "NoAmmo"; + + stateName[6] = "DryFire"; + stateSound[6] = ElfFireWetSound; + stateTimeoutValue[6] = 0.5; + stateTransitionOnTimeout[6] = "Ready"; + + stateName[7] = "CheckWet"; + stateTransitionOnWet[7] = "DryFire"; + stateTransitionOnNotWet[7] = "Fire"; +}; diff --git a/scripts/weapons/R700.cs b/scripts/weapons/R700.cs index 5b5f30d..e03c53d 100644 --- a/scripts/weapons/R700.cs +++ b/scripts/weapons/R700.cs @@ -1,165 +1,165 @@ -//-------------------------------------------------------------------------- -// R700 -// -// -//-------------------------------------------------------------------------- - -datablock AudioProfile(R700SwitchSound) -{ - filename = "fx/weapons/sniper_activate.wav"; - description = AudioClosest3d; - preload = true; - effect = SniperRifleSwitchEffect; -}; - -datablock AudioProfile(R700RifleFireSound) -{ - filename = "fx/weapons/sniper_fire.wav"; - description = AudioClose3d; - preload = true; - effect = SniperRifleFireEffect; -}; - -datablock AudioProfile(R700FireWetSound) -{ - filename = "fx/weapons/sniper_underwater.wav"; - description = AudioClose3d; - preload = true; - effect = SniperRifleFireWetEffect; -}; - -datablock AudioProfile(R700RifleDryFireSound) -{ - filename = "fx/weapons/chaingun_dryfire.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(R700RifleProjectileSound) -{ - filename = "fx/weapons/sniper_miss.wav"; - description = AudioClose3d; - preload = true; -}; - -//-------------------------------------- -// Projectile -//-------------------------------------- -datablock TracerProjectileData(R700Bullet) -{ - doDynamicClientHits = true; - - directDamage = 0.0842; // z0dd - ZOD, 9-27-02. Was 0.0825 - directDamageType = $DamageType::Bullet; - explosion = "ChaingunExplosion"; - splash = ChaingunSplash; - - kickBackStrength = 0.0; - sound = ChaingunProjectile; - - //dryVelocity = 425.0; - dryVelocity = 700.0; // z0dd - ZOD, 8-12-02. Was 425.0 - wetVelocity = 100.0; - velInheritFactor = 1.0; - fizzleTimeMS = 3000; - lifetimeMS = 3000; - explodeOnDeath = false; - reflectOnWaterImpactAngle = 0.0; - explodeOnWaterImpact = false; - deflectionOnWaterImpact = 0.0; - fizzleUnderwaterMS = 3000; - - tracerLength = 15.0; - tracerAlpha = false; - tracerMinPixels = 6; - tracerColor = 211.0/255.0 @ " " @ 215.0/255.0 @ " " @ 120.0/255.0 @ " 0.75"; - tracerTex[0] = "special/tracer00"; - tracerTex[1] = "special/tracercross"; - tracerWidth = 0.10; - crossSize = 0.20; - crossViewAng = 0.990; - renderCross = true; - - decalData[0] = ChaingunDecal1; - decalData[1] = ChaingunDecal2; - decalData[2] = ChaingunDecal3; - decalData[3] = ChaingunDecal4; - decalData[4] = ChaingunDecal5; - decalData[5] = ChaingunDecal6; -}; - - - -//-------------------------------------- -// Rifle and item... -//-------------------------------------- -datablock ItemData(R700) -{ - className = Weapon; - catagory = "Spawn Items"; - shapeFile = "weapon_sniper.dts"; - image = R700Image; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - pickUpName = "an R700"; - - computeCRC = true; - -}; - -datablock ShapeBaseImageData(R700Image) -{ - className = WeaponImage; - shapeFile = "weapon_sniper.dts"; - item = R700; - projectile = R700Bullet; - projectileType = TracerProjectile; - armThread = looksn; - - usesEnergy = false; - minEnergy = 0; - - stateName[0] = "Activate"; - stateTransitionOnTimeout[0] = "ActivateReady"; - stateSound[0] = SniperRifleSwitchSound; - stateTimeoutValue[0] = 0.5; - stateSequence[0] = "Activate"; - - stateName[1] = "ActivateReady"; - stateTransitionOnLoaded[1] = "Ready"; - stateTransitionOnNoAmmo[1] = "NoAmmo"; - - stateName[2] = "Ready"; - stateTransitionOnNoAmmo[2] = "NoAmmo"; - stateTransitionOnTriggerDown[2] = "CheckWet"; - - stateName[3] = "Fire"; - stateTransitionOnTimeout[3] = "Reload"; - stateTimeoutValue[3] = 0.5; - stateFire[3] = true; - stateAllowImageChange[3] = false; - stateSequence[3] = "Fire"; - stateScript[3] = "onFire"; - - stateName[4] = "Reload"; - stateTransitionOnTimeout[4] = "Ready"; - stateTimeoutValue[4] = 0.5; - stateAllowImageChange[4] = false; - - stateName[5] = "CheckWet"; - stateTransitionOnWet[5] = "DryFire"; - stateTransitionOnNotWet[5] = "Fire"; - - stateName[6] = "NoAmmo"; - stateTransitionOnAmmo[6] = "Reload"; - stateTransitionOnTriggerDown[6] = "DryFire"; - stateSequence[6] = "NoAmmo"; - - stateName[7] = "DryFire"; - stateSound[7] = SniperRifleDryFireSound; - stateTimeoutValue[7] = 0.5; - stateTransitionOnTimeout[7] = "Ready"; -}; - +//-------------------------------------------------------------------------- +// R700 +// +// +//-------------------------------------------------------------------------- + +datablock AudioProfile(R700SwitchSound) +{ + filename = "fx/weapons/sniper_activate.wav"; + description = AudioClosest3d; + preload = true; + effect = SniperRifleSwitchEffect; +}; + +datablock AudioProfile(R700RifleFireSound) +{ + filename = "fx/weapons/sniper_fire.wav"; + description = AudioClose3d; + preload = true; + effect = SniperRifleFireEffect; +}; + +datablock AudioProfile(R700FireWetSound) +{ + filename = "fx/weapons/sniper_underwater.wav"; + description = AudioClose3d; + preload = true; + effect = SniperRifleFireWetEffect; +}; + +datablock AudioProfile(R700RifleDryFireSound) +{ + filename = "fx/weapons/chaingun_dryfire.wav"; + description = AudioClose3d; + preload = true; +}; + +datablock AudioProfile(R700RifleProjectileSound) +{ + filename = "fx/weapons/sniper_miss.wav"; + description = AudioClose3d; + preload = true; +}; + +//-------------------------------------- +// Projectile +//-------------------------------------- +datablock TracerProjectileData(R700Bullet) +{ + doDynamicClientHits = true; + + directDamage = 0.0842; // z0dd - ZOD, 9-27-02. Was 0.0825 + directDamageType = $DamageType::Bullet; + explosion = "ChaingunExplosion"; + splash = ChaingunSplash; + + kickBackStrength = 0.0; + sound = ChaingunProjectile; + + //dryVelocity = 425.0; + dryVelocity = 700.0; // z0dd - ZOD, 8-12-02. Was 425.0 + wetVelocity = 100.0; + velInheritFactor = 1.0; + fizzleTimeMS = 3000; + lifetimeMS = 3000; + explodeOnDeath = false; + reflectOnWaterImpactAngle = 0.0; + explodeOnWaterImpact = false; + deflectionOnWaterImpact = 0.0; + fizzleUnderwaterMS = 3000; + + tracerLength = 15.0; + tracerAlpha = false; + tracerMinPixels = 6; + tracerColor = 211.0/255.0 @ " " @ 215.0/255.0 @ " " @ 120.0/255.0 @ " 0.75"; + tracerTex[0] = "special/tracer00"; + tracerTex[1] = "special/tracercross"; + tracerWidth = 0.10; + crossSize = 0.20; + crossViewAng = 0.990; + renderCross = true; + + decalData[0] = ChaingunDecal1; + decalData[1] = ChaingunDecal2; + decalData[2] = ChaingunDecal3; + decalData[3] = ChaingunDecal4; + decalData[4] = ChaingunDecal5; + decalData[5] = ChaingunDecal6; +}; + + + +//-------------------------------------- +// Rifle and item... +//-------------------------------------- +datablock ItemData(R700) +{ + className = Weapon; + catagory = "Spawn Items"; + shapeFile = "weapon_sniper.dts"; + image = R700Image; + mass = 1; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 2; + pickUpName = "an R700"; + + computeCRC = true; + +}; + +datablock ShapeBaseImageData(R700Image) +{ + className = WeaponImage; + shapeFile = "weapon_sniper.dts"; + item = R700; + projectile = R700Bullet; + projectileType = TracerProjectile; + armThread = looksn; + + usesEnergy = false; + minEnergy = 0; + + stateName[0] = "Activate"; + stateTransitionOnTimeout[0] = "ActivateReady"; + stateSound[0] = SniperRifleSwitchSound; + stateTimeoutValue[0] = 0.5; + stateSequence[0] = "Activate"; + + stateName[1] = "ActivateReady"; + stateTransitionOnLoaded[1] = "Ready"; + stateTransitionOnNoAmmo[1] = "NoAmmo"; + + stateName[2] = "Ready"; + stateTransitionOnNoAmmo[2] = "NoAmmo"; + stateTransitionOnTriggerDown[2] = "CheckWet"; + + stateName[3] = "Fire"; + stateTransitionOnTimeout[3] = "Reload"; + stateTimeoutValue[3] = 0.5; + stateFire[3] = true; + stateAllowImageChange[3] = false; + stateSequence[3] = "Fire"; + stateScript[3] = "onFire"; + + stateName[4] = "Reload"; + stateTransitionOnTimeout[4] = "Ready"; + stateTimeoutValue[4] = 0.5; + stateAllowImageChange[4] = false; + + stateName[5] = "CheckWet"; + stateTransitionOnWet[5] = "DryFire"; + stateTransitionOnNotWet[5] = "Fire"; + + stateName[6] = "NoAmmo"; + stateTransitionOnAmmo[6] = "Reload"; + stateTransitionOnTriggerDown[6] = "DryFire"; + stateSequence[6] = "NoAmmo"; + + stateName[7] = "DryFire"; + stateSound[7] = SniperRifleDryFireSound; + stateTimeoutValue[7] = 0.5; + stateTransitionOnTimeout[7] = "Ready"; +}; + diff --git a/scripts/weapons/cameraGrenade.cs b/scripts/weapons/cameraGrenade.cs index e11834a..b27bf04 100644 --- a/scripts/weapons/cameraGrenade.cs +++ b/scripts/weapons/cameraGrenade.cs @@ -1,193 +1,193 @@ -// ------------------------------------------------------------------ -// Deployable camera script -// -// Cameras will occupy grenade slots vice backpack slots. The player -// will "throw" them like grenades, and they should stick to (and -// deploy on) interior surfaces and terrain. -// ------------------------------------------------------------------ - -$TeamDeployableMax[DeployedCamera] = 15; - -// ------------------------------------------ -// force-feedback effect datablocks -// ------------------------------------------ - -datablock EffectProfile(CameraGrenadeActivateEffect) -{ - effectname = "weapons/grenade_camera_activate"; - minDistance = 2.5; - maxDistance = 5.0; -}; - -datablock EffectProfile(CameraGrenadeAttachEffect) -{ - effectname = "weapons/grenade_camera_activate"; - minDistance = 2.5; - maxDistance = 5.0; -}; - -datablock EffectProfile(CameraGrenadeExplosionEffect) -{ - effectname = "explosions/explosion.xpl10"; - minDistance = 10; - maxDistance = 30; -}; - -// ------------------------------------------ -// sound datablocks -// ------------------------------------------ - -datablock AudioProfile(CameraGrenadeActivateSound) -{ - filename = "fx/weapons/grenade_camera_activate.wav"; - description = AudioClosest3d; - preload = true; - effect = CameraGrenadeActivateEffect; -}; - -datablock AudioProfile(CameraGrenadeAttachSound) -{ - filename = "fx/weapons/grenade_camera_attach.wav"; - description = AudioClosest3d; - preload = true; - effect = CameraGrenadeAttachEffect; -}; - -datablock AudioProfile(CameraGrenadeExplosionSound) -{ - filename = "fx/explosions/explosion.xpl10.wav"; - description = AudioExplosion3d; - preload = true; - effect = CameraGrenadeExplosionEffect; -}; - -//-------------------------------------------------------------------------- -// Camera explosion particle effects -//-------------------------------------------------------------------------- -datablock ExplosionData(CameraGrenadeExplosion) -{ - soundProfile = CameraGrenadeExplosionSound; - faceViewer = true; - - explosionShape = "effect_plasma_explosion.dts"; - playSpeed = 1.0; - sizes[0] = "0.2 0.2 0.2"; - sizes[1] = "0.3 0.3 0.3"; -}; - - -// ------------------------------------------ -// other datablocks -// ------------------------------------------ - -datablock ItemData(CameraGrenadeThrown) -{ - shapeFile = "camera.dts"; - mass = 0.7; - elasticity = 0.2; - friction = 1; - pickupRadius = 2; - maxDamage = 0.8; - sticky = true; - emap = true; - -}; - -datablock ItemData(CameraGrenade) -{ - className = HandInventory; - catagory = "Handheld"; - shapeFile = "camera.dts"; - mass = 0.7; - elasticity = 0.2; - friction = 1; - pickupRadius = 2; - thrownItem = CameraGrenadeThrown; - pickUpName = "a deployable camera"; - - computeCRC = true; - emap = true; -}; - -datablock SensorData(CameraSensorObject) -{ - detects = true; - detectsUsingLOS = true; - detectionPings = false; - detectsPassiveJammed = true; - detectsActiveJammed = true; // z0dd - ZOD, 4/24/02. Was false - detectRadius = 40; - detectsFOVOnly = true; - useObjectFOV = true; -}; - -datablock TurretData(TurretDeployedCamera) : TurretDamageProfile -{ - className = CameraTurret; - shapeFile = "camera.dts"; - - mass = 0.7; - maxDamage = 0.2; - destroyedLevel = 0.2; - disabledLevel = 0.2; - repairRate = 0; - explosion = CameraGrenadeExplosion; - - thetaMin = 0; - thetaMax = 180; - //thetaNull = 90; - - deployedObject = true; - - isShielded = false; - energyPerDamagePoint = 40; - maxEnergy = 30; - renderWhenDestroyed = false; - rechargeRate = 0.05; - - cameraDefaultFov = 90; // z0dd - ZOD, 4/24/02 Camera gren tweaks. was 150 - cameraMinFov = 5; // z0dd - ZOD, 4/24/02. Camera gren tweaks. was 150 - cameraMaxFov = 120; // z0dd - ZOD, 4/24/02. Camera gren tweaks. was 150 - - neverUpdateControl = false; // z0dd - ZOD, 4/24/02. Enable controllable camera view - - canControl = true; - canObserve = false; // z0dd - ZOD, 4/24/02. Turned off 3rd person camera viewing. - observeThroughObject = true; - cmdCategory = "DSupport"; - cmdIcon = CMDCameraIcon; - cmdMiniIconName = "commander/MiniIcons/com_camera_grey"; - targetNameTag = 'Deployed'; - targetTypeTag = 'Camera'; - sensorData = CameraSensorObject; - sensorRadius = CameraSensorObject.detectRadius; - - firstPersonOnly = true; - observeParameters = "0.5 4.5 4.5"; - - debrisShapeName = "debris_generic_small.dts"; - debris = SmallShapeDebris; -}; - -datablock TurretImageData(DeployableCameraBarrel) -{ - shapeFile = "turret_muzzlepoint.dts"; - - usesEnergy = false; - - // Turret parameters - activationMS = 100; - deactivateDelayMS = 100; - thinkTimeMS = 100; - degPerSecTheta = 180; - degPerSecPhi = 360; -}; - -//------------------------------------------------------------------------------ -// Functions: -//------------------------------------------------------------------------------ -function CameraGrenadeThrown::onCollision( %data, %obj, %col ) -{ - // Do nothing... -} - +// ------------------------------------------------------------------ +// Deployable camera script +// +// Cameras will occupy grenade slots vice backpack slots. The player +// will "throw" them like grenades, and they should stick to (and +// deploy on) interior surfaces and terrain. +// ------------------------------------------------------------------ + +$TeamDeployableMax[DeployedCamera] = 15; + +// ------------------------------------------ +// force-feedback effect datablocks +// ------------------------------------------ + +datablock EffectProfile(CameraGrenadeActivateEffect) +{ + effectname = "weapons/grenade_camera_activate"; + minDistance = 2.5; + maxDistance = 5.0; +}; + +datablock EffectProfile(CameraGrenadeAttachEffect) +{ + effectname = "weapons/grenade_camera_activate"; + minDistance = 2.5; + maxDistance = 5.0; +}; + +datablock EffectProfile(CameraGrenadeExplosionEffect) +{ + effectname = "explosions/explosion.xpl10"; + minDistance = 10; + maxDistance = 30; +}; + +// ------------------------------------------ +// sound datablocks +// ------------------------------------------ + +datablock AudioProfile(CameraGrenadeActivateSound) +{ + filename = "fx/weapons/grenade_camera_activate.wav"; + description = AudioClosest3d; + preload = true; + effect = CameraGrenadeActivateEffect; +}; + +datablock AudioProfile(CameraGrenadeAttachSound) +{ + filename = "fx/weapons/grenade_camera_attach.wav"; + description = AudioClosest3d; + preload = true; + effect = CameraGrenadeAttachEffect; +}; + +datablock AudioProfile(CameraGrenadeExplosionSound) +{ + filename = "fx/explosions/explosion.xpl10.wav"; + description = AudioExplosion3d; + preload = true; + effect = CameraGrenadeExplosionEffect; +}; + +//-------------------------------------------------------------------------- +// Camera explosion particle effects +//-------------------------------------------------------------------------- +datablock ExplosionData(CameraGrenadeExplosion) +{ + soundProfile = CameraGrenadeExplosionSound; + faceViewer = true; + + explosionShape = "effect_plasma_explosion.dts"; + playSpeed = 1.0; + sizes[0] = "0.2 0.2 0.2"; + sizes[1] = "0.3 0.3 0.3"; +}; + + +// ------------------------------------------ +// other datablocks +// ------------------------------------------ + +datablock ItemData(CameraGrenadeThrown) +{ + shapeFile = "camera.dts"; + mass = 0.7; + elasticity = 0.2; + friction = 1; + pickupRadius = 2; + maxDamage = 0.8; + sticky = true; + emap = true; + +}; + +datablock ItemData(CameraGrenade) +{ + className = HandInventory; + catagory = "Handheld"; + shapeFile = "camera.dts"; + mass = 0.7; + elasticity = 0.2; + friction = 1; + pickupRadius = 2; + thrownItem = CameraGrenadeThrown; + pickUpName = "a deployable camera"; + + computeCRC = true; + emap = true; +}; + +datablock SensorData(CameraSensorObject) +{ + detects = true; + detectsUsingLOS = true; + detectionPings = false; + detectsPassiveJammed = true; + detectsActiveJammed = true; // z0dd - ZOD, 4/24/02. Was false + detectRadius = 40; + detectsFOVOnly = true; + useObjectFOV = true; +}; + +datablock TurretData(TurretDeployedCamera) : TurretDamageProfile +{ + className = CameraTurret; + shapeFile = "camera.dts"; + + mass = 0.7; + maxDamage = 0.2; + destroyedLevel = 0.2; + disabledLevel = 0.2; + repairRate = 0; + explosion = CameraGrenadeExplosion; + + thetaMin = 0; + thetaMax = 180; + //thetaNull = 90; + + deployedObject = true; + + isShielded = false; + energyPerDamagePoint = 40; + maxEnergy = 30; + renderWhenDestroyed = false; + rechargeRate = 0.05; + + cameraDefaultFov = 90; // z0dd - ZOD, 4/24/02 Camera gren tweaks. was 150 + cameraMinFov = 5; // z0dd - ZOD, 4/24/02. Camera gren tweaks. was 150 + cameraMaxFov = 120; // z0dd - ZOD, 4/24/02. Camera gren tweaks. was 150 + + neverUpdateControl = false; // z0dd - ZOD, 4/24/02. Enable controllable camera view + + canControl = true; + canObserve = false; // z0dd - ZOD, 4/24/02. Turned off 3rd person camera viewing. + observeThroughObject = true; + cmdCategory = "DSupport"; + cmdIcon = CMDCameraIcon; + cmdMiniIconName = "commander/MiniIcons/com_camera_grey"; + targetNameTag = 'Deployed'; + targetTypeTag = 'Camera'; + sensorData = CameraSensorObject; + sensorRadius = CameraSensorObject.detectRadius; + + firstPersonOnly = true; + observeParameters = "0.5 4.5 4.5"; + + debrisShapeName = "debris_generic_small.dts"; + debris = SmallShapeDebris; +}; + +datablock TurretImageData(DeployableCameraBarrel) +{ + shapeFile = "turret_muzzlepoint.dts"; + + usesEnergy = false; + + // Turret parameters + activationMS = 100; + deactivateDelayMS = 100; + thinkTimeMS = 100; + degPerSecTheta = 180; + degPerSecPhi = 360; +}; + +//------------------------------------------------------------------------------ +// Functions: +//------------------------------------------------------------------------------ +function CameraGrenadeThrown::onCollision( %data, %obj, %col ) +{ + // Do nothing... +} + diff --git a/scripts/weapons/chaingun.cs b/scripts/weapons/chaingun.cs index 6d1a6e8..d02dee7 100644 --- a/scripts/weapons/chaingun.cs +++ b/scripts/weapons/chaingun.cs @@ -1,676 +1,676 @@ -//-------------------------------------- -// Chaingun -//-------------------------------------- - -//-------------------------------------------------------------------------- -// Force-Feedback Effects -//-------------------------------------- -datablock EffectProfile(ChaingunSwitchEffect) -{ - effectname = "weapons/chaingun_activate"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(ChaingunFireEffect) -{ - effectname = "weapons/chaingun_fire"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(ChaingunSpinUpEffect) -{ - effectname = "weapons/chaingun_spinup"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(ChaingunSpinDownEffect) -{ - effectname = "weapons/chaingun_spindown"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(ChaingunDryFire) -{ - effectname = "weapons/chaingun_dryfire"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -//-------------------------------------------------------------------------- -// Sounds -//-------------------------------------- -datablock AudioProfile(ChaingunSwitchSound) -{ - filename = "fx/weapons/chaingun_activate.wav"; - description = AudioClosest3d; - preload = true; - effect = ChaingunSwitchEffect; -}; - -datablock AudioProfile(ChaingunFireSound) -{ - filename = "fx/weapons/chaingun_fire.wav"; - description = AudioDefaultLooping3d; - preload = true; - effect = ChaingunFireEffect; -}; - -datablock AudioProfile(ChaingunProjectile) -{ - filename = "fx/weapons/chaingun_projectile.wav"; - description = ProjectileLooping3d; - preload = true; -}; - -datablock AudioProfile(ChaingunImpact) -{ - filename = "fx/weapons/chaingun_impact.WAV"; - description = AudioClosest3d; - preload = true; -}; - -datablock AudioProfile(ChaingunSpinDownSound) -{ - filename = "fx/weapons/chaingun_spindown.wav"; - description = AudioClosest3d; - preload = true; - effect = ChaingunSpinDownEffect; -}; - -datablock AudioProfile(ChaingunSpinUpSound) -{ - filename = "fx/weapons/chaingun_spinup.wav"; - description = AudioClosest3d; - preload = true; - effect = ChaingunSpinUpEffect; -}; - -datablock AudioProfile(ChaingunDryFireSound) -{ - filename = "fx/weapons/chaingun_dryfire.wav"; - description = AudioClose3d; - preload = true; - effect = ChaingunDryFire; -}; - -datablock AudioProfile(ShrikeBlasterProjectileSound) -{ - filename = "fx/vehicles/shrike_blaster_projectile.wav"; - description = ProjectileLooping3d; - preload = true; -}; - - -//-------------------------------------------------------------------------- -// Splash -//-------------------------------------------------------------------------- - -datablock ParticleData( ChaingunSplashParticle ) -{ - dragCoefficient = 1; - gravityCoefficient = 0.0; - inheritedVelFactor = 0.2; - constantAcceleration = -1.4; - lifetimeMS = 300; - lifetimeVarianceMS = 0; - textureName = "special/droplet"; - colors[0] = "0.7 0.8 1.0 1.0"; - colors[1] = "0.7 0.8 1.0 0.5"; - colors[2] = "0.7 0.8 1.0 0.0"; - sizes[0] = 0.05; - sizes[1] = 0.2; - sizes[2] = 0.2; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData( ChaingunSplashEmitter ) -{ - ejectionPeriodMS = 4; - periodVarianceMS = 0; - ejectionVelocity = 3; - velocityVariance = 1.0; - ejectionOffset = 0.0; - thetaMin = 0; - thetaMax = 50; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - orientParticles = true; - lifetimeMS = 100; - particles = "ChaingunSplashParticle"; -}; - - -datablock SplashData(ChaingunSplash) -{ - numSegments = 10; - ejectionFreq = 10; - ejectionAngle = 20; - ringLifetime = 0.4; - lifetimeMS = 400; - velocity = 3.0; - startRadius = 0.0; - acceleration = -3.0; - texWrap = 5.0; - - texture = "special/water2"; - - emitter[0] = ChaingunSplashEmitter; - - colors[0] = "0.7 0.8 1.0 0.0"; - colors[1] = "0.7 0.8 1.0 1.0"; - colors[2] = "0.7 0.8 1.0 0.0"; - colors[3] = "0.7 0.8 1.0 0.0"; - times[0] = 0.0; - times[1] = 0.4; - times[2] = 0.8; - times[3] = 1.0; -}; - -//-------------------------------------------------------------------------- -// Particle Effects -//-------------------------------------- -datablock ParticleData(ChaingunFireParticle) -{ - dragCoefficient = 2.75; - gravityCoefficient = 0.1; - inheritedVelFactor = 0.0; - constantAcceleration = 0.0; - lifetimeMS = 550; - lifetimeVarianceMS = 0; - textureName = "particleTest"; - colors[0] = "0.46 0.36 0.26 1.0"; - colors[1] = "0.46 0.36 0.26 0.0"; - sizes[0] = 0.25; - sizes[1] = 0.20; -}; - -datablock ParticleEmitterData(ChaingunFireEmitter) -{ - ejectionPeriodMS = 6; - periodVarianceMS = 0; - ejectionVelocity = 10; - velocityVariance = 1.0; - ejectionOffset = 0.0; - thetaMin = 0; - thetaMax = 12; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvance = true; - particles = "ChaingunFireParticle"; -}; - -//-------------------------------------------------------------------------- -// Explosions -//-------------------------------------- -datablock ParticleData(ChaingunExplosionParticle1) -{ - dragCoefficient = 0.65; - gravityCoefficient = 0.3; - inheritedVelFactor = 0.0; - constantAcceleration = 0.0; - lifetimeMS = 500; - lifetimeVarianceMS = 150; - textureName = "particleTest"; - colors[0] = "0.56 0.36 0.26 1.0"; - colors[1] = "0.56 0.36 0.26 0.0"; - sizes[0] = 0.0625; - sizes[1] = 0.2; -}; - -datablock ParticleEmitterData(ChaingunExplosionEmitter) -{ - ejectionPeriodMS = 10; - periodVarianceMS = 0; - ejectionVelocity = 0.75; - velocityVariance = 0.25; - ejectionOffset = 0.0; - thetaMin = 0; - thetaMax = 60; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - particles = "ChaingunExplosionParticle1"; -}; - - - - -datablock ParticleData(ChaingunImpactSmokeParticle) -{ - dragCoefficient = 0.0; - gravityCoefficient = -0.2; - inheritedVelFactor = 0.0; - constantAcceleration = 0.0; - lifetimeMS = 1000; - lifetimeVarianceMS = 200; - useInvAlpha = true; - spinRandomMin = -90.0; - spinRandomMax = 90.0; - textureName = "particleTest"; - colors[0] = "0.7 0.7 0.7 0.0"; - colors[1] = "0.7 0.7 0.7 0.4"; - colors[2] = "0.7 0.7 0.7 0.0"; - sizes[0] = 0.5; - sizes[1] = 0.5; - sizes[2] = 1.0; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData(ChaingunImpactSmoke) -{ - ejectionPeriodMS = 8; - periodVarianceMS = 1; - ejectionVelocity = 1.0; - velocityVariance = 0.5; - ejectionOffset = 0.0; - thetaMin = 0; - thetaMax = 35; - overrideAdvances = false; - particles = "ChaingunImpactSmokeParticle"; - lifetimeMS = 50; -}; - - -datablock ParticleData(ChaingunSparks) -{ - dragCoefficient = 1; - gravityCoefficient = 0.0; - inheritedVelFactor = 0.2; - constantAcceleration = 0.0; - lifetimeMS = 300; - lifetimeVarianceMS = 0; - textureName = "special/spark00"; - colors[0] = "0.56 0.36 0.26 1.0"; - colors[1] = "0.56 0.36 0.26 1.0"; - colors[2] = "1.0 0.36 0.26 0.0"; - sizes[0] = 0.6; - sizes[1] = 0.2; - sizes[2] = 0.05; - times[0] = 0.0; - times[1] = 0.2; - times[2] = 1.0; - -}; - -datablock ParticleEmitterData(ChaingunSparkEmitter) -{ - ejectionPeriodMS = 4; - periodVarianceMS = 0; - ejectionVelocity = 4; - velocityVariance = 2.0; - ejectionOffset = 0.0; - thetaMin = 0; - thetaMax = 50; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - orientParticles = true; - lifetimeMS = 100; - particles = "ChaingunSparks"; -}; - - -datablock ExplosionData(ChaingunExplosion) -{ - soundProfile = ChaingunImpact; - - emitter[0] = ChaingunImpactSmoke; - emitter[1] = ChaingunSparkEmitter; - - faceViewer = false; -}; - - -datablock ShockwaveData(ScoutChaingunHit) -{ - width = 0.5; - numSegments = 13; - numVertSegments = 1; - velocity = 0.5; - acceleration = 2.0; - lifetimeMS = 900; - height = 0.1; - verticalCurve = 0.5; - - mapToTerrain = false; - renderBottom = false; - orientToNormal = true; - - texture[0] = "special/shockwave5"; - texture[1] = "special/gradient"; - texWrap = 3.0; - - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - - colors[0] = "0.6 0.6 1.0 1.0"; - colors[1] = "0.6 0.3 1.0 0.5"; - colors[2] = "0.0 0.0 1.0 0.0"; -}; - -datablock ParticleData(ScoutChaingunExplosionParticle1) -{ - dragCoefficient = 2; - gravityCoefficient = 0.0; - inheritedVelFactor = 0.2; - constantAcceleration = -0.0; - lifetimeMS = 600; - lifetimeVarianceMS = 000; - textureName = "special/crescent4"; - colors[0] = "0.6 0.6 1.0 1.0"; - colors[1] = "0.6 0.3 1.0 1.0"; - colors[2] = "0.0 0.0 1.0 0.0"; - sizes[0] = 0.25; - sizes[1] = 0.5; - sizes[2] = 1.0; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData(ScoutChaingunExplosionEmitter) -{ - ejectionPeriodMS = 10; - periodVarianceMS = 0; - ejectionVelocity = 2; - velocityVariance = 1.5; - ejectionOffset = 0.0; - thetaMin = 80; - thetaMax = 90; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - orientParticles = true; - lifetimeMS = 200; - particles = "ScoutChaingunExplosionParticle1"; -}; - -datablock ExplosionData(ScoutChaingunExplosion) -{ - soundProfile = blasterExpSound; - shockwave = ScoutChaingunHit; - emitter[0] = ScoutChaingunExplosionEmitter; -}; - - -//-------------------------------------------------------------------------- -// Particle effects -//-------------------------------------- - - -datablock DebrisData( ShellDebris ) -{ - shapeName = "weapon_chaingun_ammocasing.dts"; - - lifetime = 3.0; - - minSpinSpeed = 300.0; - maxSpinSpeed = 400.0; - - elasticity = 0.5; - friction = 0.2; - - numBounces = 3; - - fade = true; - staticOnMaxBounce = true; - snapOnMaxBounce = true; -}; - - -//-------------------------------------------------------------------------- -// Projectile -//-------------------------------------- -datablock DecalData(ChaingunDecal1) -{ - sizeX = 0.05; - sizeY = 0.05; - textureName = "special/bullethole1"; -}; -datablock DecalData(ChaingunDecal2) : ChaingunDecal1 -{ - textureName = "special/bullethole2"; -}; - -datablock DecalData(ChaingunDecal3) : ChaingunDecal1 -{ - textureName = "special/bullethole3"; -}; -datablock DecalData(ChaingunDecal4) : ChaingunDecal1 -{ - textureName = "special/bullethole4"; -}; -datablock DecalData(ChaingunDecal5) : ChaingunDecal1 -{ - textureName = "special/bullethole5"; -}; -datablock DecalData(ChaingunDecal6) : ChaingunDecal1 -{ - textureName = "special/bullethole6"; -}; - - -datablock TracerProjectileData(ChaingunBullet) -{ - doDynamicClientHits = true; - - directDamage = 0.0842; // z0dd - ZOD, 9-27-02. Was 0.0825 - directDamageType = $DamageType::Bullet; - explosion = "ChaingunExplosion"; - splash = ChaingunSplash; - - kickBackStrength = 0.0; - sound = ChaingunProjectile; - - //dryVelocity = 425.0; - dryVelocity = 700.0; // z0dd - ZOD, 8-12-02. Was 425.0 - wetVelocity = 100.0; - velInheritFactor = 1.0; - fizzleTimeMS = 3000; - lifetimeMS = 3000; - explodeOnDeath = false; - reflectOnWaterImpactAngle = 0.0; - explodeOnWaterImpact = false; - deflectionOnWaterImpact = 0.0; - fizzleUnderwaterMS = 3000; - - tracerLength = 15.0; - tracerAlpha = false; - tracerMinPixels = 6; - tracerColor = 211.0/255.0 @ " " @ 215.0/255.0 @ " " @ 120.0/255.0 @ " 0.75"; - tracerTex[0] = "special/tracer00"; - tracerTex[1] = "special/tracercross"; - tracerWidth = 0.10; - crossSize = 0.20; - crossViewAng = 0.990; - renderCross = true; - - decalData[0] = ChaingunDecal1; - decalData[1] = ChaingunDecal2; - decalData[2] = ChaingunDecal3; - decalData[3] = ChaingunDecal4; - decalData[4] = ChaingunDecal5; - decalData[5] = ChaingunDecal6; -}; - -//-------------------------------------------------------------------------- -// Scout Projectile -//-------------------------------------- -datablock TracerProjectileData(ScoutChaingunBullet) -{ - doDynamicClientHits = true; - - directDamage = 0.125; - explosion = "ScoutChaingunExplosion"; - splash = ChaingunSplash; - - directDamageType = $DamageType::ShrikeBlaster; - kickBackStrength = 0.0; - - sound = ShrikeBlasterProjectileSound; - - dryVelocity = 425.0; - wetVelocity = 100.0; - velInheritFactor = 1.0; - fizzleTimeMS = 1000; - lifetimeMS = 1000; - explodeOnDeath = false; - reflectOnWaterImpactAngle = 0.0; - explodeOnWaterImpact = false; - deflectionOnWaterImpact = 0.0; - fizzleUnderwaterMS = 3000; - - tracerLength = 45.0; - tracerAlpha = false; - tracerMinPixels = 6; - tracerColor = "1.0 1.0 1.0 1.0"; - tracerTex[0] = "special/shrikeBolt"; - tracerTex[1] = "special/shrikeBoltCross"; - tracerWidth = 0.55; - crossSize = 0.99; - crossViewAng = 0.990; - renderCross = true; - -}; - -//-------------------------------------------------------------------------- -// Ammo -//-------------------------------------- - -datablock ItemData(ChaingunAmmo) -{ - className = Ammo; - catagory = "Ammo"; - shapeFile = "ammo_chaingun.dts"; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - pickUpName = "some chaingun ammo"; - - computeCRC = true; - -}; - -//-------------------------------------------------------------------------- -// Weapon -//-------------------------------------- -datablock ShapeBaseImageData(ChaingunImage) -{ - className = WeaponImage; - shapeFile = "weapon_chaingun.dts"; - item = Chaingun; - ammo = ChaingunAmmo; - projectile = ChaingunBullet; - projectileType = TracerProjectile; - emap = true; - - casing = ShellDebris; - shellExitDir = "1.0 0.3 1.0"; - shellExitOffset = "0.15 -0.56 -0.1"; - shellExitVariance = 15.0; - shellVelocity = 3.0; - - projectileSpread = 7.0 / 1000.0; // z0dd - ZOD, 8/6/02. Was: 8.0 / 1000.0 - - //-------------------------------------- - stateName[0] = "Activate"; - stateSequence[0] = "Activate"; - stateSound[0] = ChaingunSwitchSound; - stateAllowImageChange[0] = false; - // - stateTimeoutValue[0] = 0.5; - stateTransitionOnTimeout[0] = "Ready"; - stateTransitionOnNoAmmo[0] = "NoAmmo"; - - //-------------------------------------- - stateName[1] = "Ready"; - stateSpinThread[1] = Stop; - // - stateTransitionOnTriggerDown[1] = "Spinup"; - stateTransitionOnNoAmmo[1] = "NoAmmo"; - - //-------------------------------------- - stateName[2] = "NoAmmo"; - stateTransitionOnAmmo[2] = "Ready"; - stateSpinThread[2] = Stop; - stateTransitionOnTriggerDown[2] = "DryFire"; - - //-------------------------------------- - stateName[3] = "Spinup"; - stateSpinThread[3] = SpinUp; - stateSound[3] = ChaingunSpinupSound; - // - stateTimeoutValue[3] = 0.5; - stateWaitForTimeout[3] = false; - stateTransitionOnTimeout[3] = "Fire"; - stateTransitionOnTriggerUp[3] = "Spindown"; - - //-------------------------------------- - stateName[4] = "Fire"; - stateSequence[4] = "Fire"; - stateSequenceRandomFlash[4] = true; - stateSpinThread[4] = FullSpeed; - stateSound[4] = ChaingunFireSound; - //stateRecoil[4] = LightRecoil; - stateAllowImageChange[4] = false; - stateScript[4] = "onFire"; - stateFire[4] = true; - stateEjectShell[4] = true; - // - stateTimeoutValue[4] = 0.15; - stateTransitionOnTimeout[4] = "Fire"; - stateTransitionOnTriggerUp[4] = "Spindown"; - stateTransitionOnNoAmmo[4] = "EmptySpindown"; - - //-------------------------------------- - stateName[5] = "Spindown"; - stateSound[5] = ChaingunSpinDownSound; - stateSpinThread[5] = SpinDown; - // - stateTimeoutValue[5] = 1.0; - stateWaitForTimeout[5] = true; - stateTransitionOnTimeout[5] = "Ready"; - stateTransitionOnTriggerDown[5] = "Spinup"; - - //-------------------------------------- - stateName[6] = "EmptySpindown"; - stateSound[6] = ChaingunSpinDownSound; - stateSpinThread[6] = SpinDown; - // - stateTimeoutValue[6] = 0.5; - stateTransitionOnTimeout[6] = "NoAmmo"; - - //-------------------------------------- - stateName[7] = "DryFire"; - stateSound[7] = ChaingunDryFireSound; - stateTimeoutValue[7] = 0.5; - stateTransitionOnTimeout[7] = "NoAmmo"; -}; - -datablock ItemData(Chaingun) -{ - className = Weapon; - catagory = "Spawn Items"; - shapeFile = "weapon_chaingun.dts"; - image = ChaingunImage; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - pickUpName = "a chaingun"; - - computeCRC = true; - emap = true; -}; - +//-------------------------------------- +// Chaingun +//-------------------------------------- + +//-------------------------------------------------------------------------- +// Force-Feedback Effects +//-------------------------------------- +datablock EffectProfile(ChaingunSwitchEffect) +{ + effectname = "weapons/chaingun_activate"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock EffectProfile(ChaingunFireEffect) +{ + effectname = "weapons/chaingun_fire"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock EffectProfile(ChaingunSpinUpEffect) +{ + effectname = "weapons/chaingun_spinup"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock EffectProfile(ChaingunSpinDownEffect) +{ + effectname = "weapons/chaingun_spindown"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock EffectProfile(ChaingunDryFire) +{ + effectname = "weapons/chaingun_dryfire"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +//-------------------------------------------------------------------------- +// Sounds +//-------------------------------------- +datablock AudioProfile(ChaingunSwitchSound) +{ + filename = "fx/weapons/chaingun_activate.wav"; + description = AudioClosest3d; + preload = true; + effect = ChaingunSwitchEffect; +}; + +datablock AudioProfile(ChaingunFireSound) +{ + filename = "fx/weapons/chaingun_fire.wav"; + description = AudioDefaultLooping3d; + preload = true; + effect = ChaingunFireEffect; +}; + +datablock AudioProfile(ChaingunProjectile) +{ + filename = "fx/weapons/chaingun_projectile.wav"; + description = ProjectileLooping3d; + preload = true; +}; + +datablock AudioProfile(ChaingunImpact) +{ + filename = "fx/weapons/chaingun_impact.WAV"; + description = AudioClosest3d; + preload = true; +}; + +datablock AudioProfile(ChaingunSpinDownSound) +{ + filename = "fx/weapons/chaingun_spindown.wav"; + description = AudioClosest3d; + preload = true; + effect = ChaingunSpinDownEffect; +}; + +datablock AudioProfile(ChaingunSpinUpSound) +{ + filename = "fx/weapons/chaingun_spinup.wav"; + description = AudioClosest3d; + preload = true; + effect = ChaingunSpinUpEffect; +}; + +datablock AudioProfile(ChaingunDryFireSound) +{ + filename = "fx/weapons/chaingun_dryfire.wav"; + description = AudioClose3d; + preload = true; + effect = ChaingunDryFire; +}; + +datablock AudioProfile(ShrikeBlasterProjectileSound) +{ + filename = "fx/vehicles/shrike_blaster_projectile.wav"; + description = ProjectileLooping3d; + preload = true; +}; + + +//-------------------------------------------------------------------------- +// Splash +//-------------------------------------------------------------------------- + +datablock ParticleData( ChaingunSplashParticle ) +{ + dragCoefficient = 1; + gravityCoefficient = 0.0; + inheritedVelFactor = 0.2; + constantAcceleration = -1.4; + lifetimeMS = 300; + lifetimeVarianceMS = 0; + textureName = "special/droplet"; + colors[0] = "0.7 0.8 1.0 1.0"; + colors[1] = "0.7 0.8 1.0 0.5"; + colors[2] = "0.7 0.8 1.0 0.0"; + sizes[0] = 0.05; + sizes[1] = 0.2; + sizes[2] = 0.2; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; +}; + +datablock ParticleEmitterData( ChaingunSplashEmitter ) +{ + ejectionPeriodMS = 4; + periodVarianceMS = 0; + ejectionVelocity = 3; + velocityVariance = 1.0; + ejectionOffset = 0.0; + thetaMin = 0; + thetaMax = 50; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + orientParticles = true; + lifetimeMS = 100; + particles = "ChaingunSplashParticle"; +}; + + +datablock SplashData(ChaingunSplash) +{ + numSegments = 10; + ejectionFreq = 10; + ejectionAngle = 20; + ringLifetime = 0.4; + lifetimeMS = 400; + velocity = 3.0; + startRadius = 0.0; + acceleration = -3.0; + texWrap = 5.0; + + texture = "special/water2"; + + emitter[0] = ChaingunSplashEmitter; + + colors[0] = "0.7 0.8 1.0 0.0"; + colors[1] = "0.7 0.8 1.0 1.0"; + colors[2] = "0.7 0.8 1.0 0.0"; + colors[3] = "0.7 0.8 1.0 0.0"; + times[0] = 0.0; + times[1] = 0.4; + times[2] = 0.8; + times[3] = 1.0; +}; + +//-------------------------------------------------------------------------- +// Particle Effects +//-------------------------------------- +datablock ParticleData(ChaingunFireParticle) +{ + dragCoefficient = 2.75; + gravityCoefficient = 0.1; + inheritedVelFactor = 0.0; + constantAcceleration = 0.0; + lifetimeMS = 550; + lifetimeVarianceMS = 0; + textureName = "particleTest"; + colors[0] = "0.46 0.36 0.26 1.0"; + colors[1] = "0.46 0.36 0.26 0.0"; + sizes[0] = 0.25; + sizes[1] = 0.20; +}; + +datablock ParticleEmitterData(ChaingunFireEmitter) +{ + ejectionPeriodMS = 6; + periodVarianceMS = 0; + ejectionVelocity = 10; + velocityVariance = 1.0; + ejectionOffset = 0.0; + thetaMin = 0; + thetaMax = 12; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvance = true; + particles = "ChaingunFireParticle"; +}; + +//-------------------------------------------------------------------------- +// Explosions +//-------------------------------------- +datablock ParticleData(ChaingunExplosionParticle1) +{ + dragCoefficient = 0.65; + gravityCoefficient = 0.3; + inheritedVelFactor = 0.0; + constantAcceleration = 0.0; + lifetimeMS = 500; + lifetimeVarianceMS = 150; + textureName = "particleTest"; + colors[0] = "0.56 0.36 0.26 1.0"; + colors[1] = "0.56 0.36 0.26 0.0"; + sizes[0] = 0.0625; + sizes[1] = 0.2; +}; + +datablock ParticleEmitterData(ChaingunExplosionEmitter) +{ + ejectionPeriodMS = 10; + periodVarianceMS = 0; + ejectionVelocity = 0.75; + velocityVariance = 0.25; + ejectionOffset = 0.0; + thetaMin = 0; + thetaMax = 60; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + particles = "ChaingunExplosionParticle1"; +}; + + + + +datablock ParticleData(ChaingunImpactSmokeParticle) +{ + dragCoefficient = 0.0; + gravityCoefficient = -0.2; + inheritedVelFactor = 0.0; + constantAcceleration = 0.0; + lifetimeMS = 1000; + lifetimeVarianceMS = 200; + useInvAlpha = true; + spinRandomMin = -90.0; + spinRandomMax = 90.0; + textureName = "particleTest"; + colors[0] = "0.7 0.7 0.7 0.0"; + colors[1] = "0.7 0.7 0.7 0.4"; + colors[2] = "0.7 0.7 0.7 0.0"; + sizes[0] = 0.5; + sizes[1] = 0.5; + sizes[2] = 1.0; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; +}; + +datablock ParticleEmitterData(ChaingunImpactSmoke) +{ + ejectionPeriodMS = 8; + periodVarianceMS = 1; + ejectionVelocity = 1.0; + velocityVariance = 0.5; + ejectionOffset = 0.0; + thetaMin = 0; + thetaMax = 35; + overrideAdvances = false; + particles = "ChaingunImpactSmokeParticle"; + lifetimeMS = 50; +}; + + +datablock ParticleData(ChaingunSparks) +{ + dragCoefficient = 1; + gravityCoefficient = 0.0; + inheritedVelFactor = 0.2; + constantAcceleration = 0.0; + lifetimeMS = 300; + lifetimeVarianceMS = 0; + textureName = "special/spark00"; + colors[0] = "0.56 0.36 0.26 1.0"; + colors[1] = "0.56 0.36 0.26 1.0"; + colors[2] = "1.0 0.36 0.26 0.0"; + sizes[0] = 0.6; + sizes[1] = 0.2; + sizes[2] = 0.05; + times[0] = 0.0; + times[1] = 0.2; + times[2] = 1.0; + +}; + +datablock ParticleEmitterData(ChaingunSparkEmitter) +{ + ejectionPeriodMS = 4; + periodVarianceMS = 0; + ejectionVelocity = 4; + velocityVariance = 2.0; + ejectionOffset = 0.0; + thetaMin = 0; + thetaMax = 50; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + orientParticles = true; + lifetimeMS = 100; + particles = "ChaingunSparks"; +}; + + +datablock ExplosionData(ChaingunExplosion) +{ + soundProfile = ChaingunImpact; + + emitter[0] = ChaingunImpactSmoke; + emitter[1] = ChaingunSparkEmitter; + + faceViewer = false; +}; + + +datablock ShockwaveData(ScoutChaingunHit) +{ + width = 0.5; + numSegments = 13; + numVertSegments = 1; + velocity = 0.5; + acceleration = 2.0; + lifetimeMS = 900; + height = 0.1; + verticalCurve = 0.5; + + mapToTerrain = false; + renderBottom = false; + orientToNormal = true; + + texture[0] = "special/shockwave5"; + texture[1] = "special/gradient"; + texWrap = 3.0; + + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; + + colors[0] = "0.6 0.6 1.0 1.0"; + colors[1] = "0.6 0.3 1.0 0.5"; + colors[2] = "0.0 0.0 1.0 0.0"; +}; + +datablock ParticleData(ScoutChaingunExplosionParticle1) +{ + dragCoefficient = 2; + gravityCoefficient = 0.0; + inheritedVelFactor = 0.2; + constantAcceleration = -0.0; + lifetimeMS = 600; + lifetimeVarianceMS = 000; + textureName = "special/crescent4"; + colors[0] = "0.6 0.6 1.0 1.0"; + colors[1] = "0.6 0.3 1.0 1.0"; + colors[2] = "0.0 0.0 1.0 0.0"; + sizes[0] = 0.25; + sizes[1] = 0.5; + sizes[2] = 1.0; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; +}; + +datablock ParticleEmitterData(ScoutChaingunExplosionEmitter) +{ + ejectionPeriodMS = 10; + periodVarianceMS = 0; + ejectionVelocity = 2; + velocityVariance = 1.5; + ejectionOffset = 0.0; + thetaMin = 80; + thetaMax = 90; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + orientParticles = true; + lifetimeMS = 200; + particles = "ScoutChaingunExplosionParticle1"; +}; + +datablock ExplosionData(ScoutChaingunExplosion) +{ + soundProfile = blasterExpSound; + shockwave = ScoutChaingunHit; + emitter[0] = ScoutChaingunExplosionEmitter; +}; + + +//-------------------------------------------------------------------------- +// Particle effects +//-------------------------------------- + + +datablock DebrisData( ShellDebris ) +{ + shapeName = "weapon_chaingun_ammocasing.dts"; + + lifetime = 3.0; + + minSpinSpeed = 300.0; + maxSpinSpeed = 400.0; + + elasticity = 0.5; + friction = 0.2; + + numBounces = 3; + + fade = true; + staticOnMaxBounce = true; + snapOnMaxBounce = true; +}; + + +//-------------------------------------------------------------------------- +// Projectile +//-------------------------------------- +datablock DecalData(ChaingunDecal1) +{ + sizeX = 0.05; + sizeY = 0.05; + textureName = "special/bullethole1"; +}; +datablock DecalData(ChaingunDecal2) : ChaingunDecal1 +{ + textureName = "special/bullethole2"; +}; + +datablock DecalData(ChaingunDecal3) : ChaingunDecal1 +{ + textureName = "special/bullethole3"; +}; +datablock DecalData(ChaingunDecal4) : ChaingunDecal1 +{ + textureName = "special/bullethole4"; +}; +datablock DecalData(ChaingunDecal5) : ChaingunDecal1 +{ + textureName = "special/bullethole5"; +}; +datablock DecalData(ChaingunDecal6) : ChaingunDecal1 +{ + textureName = "special/bullethole6"; +}; + + +datablock TracerProjectileData(ChaingunBullet) +{ + doDynamicClientHits = true; + + directDamage = 0.0842; // z0dd - ZOD, 9-27-02. Was 0.0825 + directDamageType = $DamageType::Bullet; + explosion = "ChaingunExplosion"; + splash = ChaingunSplash; + + kickBackStrength = 0.0; + sound = ChaingunProjectile; + + //dryVelocity = 425.0; + dryVelocity = 700.0; // z0dd - ZOD, 8-12-02. Was 425.0 + wetVelocity = 100.0; + velInheritFactor = 1.0; + fizzleTimeMS = 3000; + lifetimeMS = 3000; + explodeOnDeath = false; + reflectOnWaterImpactAngle = 0.0; + explodeOnWaterImpact = false; + deflectionOnWaterImpact = 0.0; + fizzleUnderwaterMS = 3000; + + tracerLength = 15.0; + tracerAlpha = false; + tracerMinPixels = 6; + tracerColor = 211.0/255.0 @ " " @ 215.0/255.0 @ " " @ 120.0/255.0 @ " 0.75"; + tracerTex[0] = "special/tracer00"; + tracerTex[1] = "special/tracercross"; + tracerWidth = 0.10; + crossSize = 0.20; + crossViewAng = 0.990; + renderCross = true; + + decalData[0] = ChaingunDecal1; + decalData[1] = ChaingunDecal2; + decalData[2] = ChaingunDecal3; + decalData[3] = ChaingunDecal4; + decalData[4] = ChaingunDecal5; + decalData[5] = ChaingunDecal6; +}; + +//-------------------------------------------------------------------------- +// Scout Projectile +//-------------------------------------- +datablock TracerProjectileData(ScoutChaingunBullet) +{ + doDynamicClientHits = true; + + directDamage = 0.125; + explosion = "ScoutChaingunExplosion"; + splash = ChaingunSplash; + + directDamageType = $DamageType::ShrikeBlaster; + kickBackStrength = 0.0; + + sound = ShrikeBlasterProjectileSound; + + dryVelocity = 425.0; + wetVelocity = 100.0; + velInheritFactor = 1.0; + fizzleTimeMS = 1000; + lifetimeMS = 1000; + explodeOnDeath = false; + reflectOnWaterImpactAngle = 0.0; + explodeOnWaterImpact = false; + deflectionOnWaterImpact = 0.0; + fizzleUnderwaterMS = 3000; + + tracerLength = 45.0; + tracerAlpha = false; + tracerMinPixels = 6; + tracerColor = "1.0 1.0 1.0 1.0"; + tracerTex[0] = "special/shrikeBolt"; + tracerTex[1] = "special/shrikeBoltCross"; + tracerWidth = 0.55; + crossSize = 0.99; + crossViewAng = 0.990; + renderCross = true; + +}; + +//-------------------------------------------------------------------------- +// Ammo +//-------------------------------------- + +datablock ItemData(ChaingunAmmo) +{ + className = Ammo; + catagory = "Ammo"; + shapeFile = "ammo_chaingun.dts"; + mass = 1; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 2; + pickUpName = "some chaingun ammo"; + + computeCRC = true; + +}; + +//-------------------------------------------------------------------------- +// Weapon +//-------------------------------------- +datablock ShapeBaseImageData(ChaingunImage) +{ + className = WeaponImage; + shapeFile = "weapon_chaingun.dts"; + item = Chaingun; + ammo = ChaingunAmmo; + projectile = ChaingunBullet; + projectileType = TracerProjectile; + emap = true; + + casing = ShellDebris; + shellExitDir = "1.0 0.3 1.0"; + shellExitOffset = "0.15 -0.56 -0.1"; + shellExitVariance = 15.0; + shellVelocity = 3.0; + + projectileSpread = 7.0 / 1000.0; // z0dd - ZOD, 8/6/02. Was: 8.0 / 1000.0 + + //-------------------------------------- + stateName[0] = "Activate"; + stateSequence[0] = "Activate"; + stateSound[0] = ChaingunSwitchSound; + stateAllowImageChange[0] = false; + // + stateTimeoutValue[0] = 0.5; + stateTransitionOnTimeout[0] = "Ready"; + stateTransitionOnNoAmmo[0] = "NoAmmo"; + + //-------------------------------------- + stateName[1] = "Ready"; + stateSpinThread[1] = Stop; + // + stateTransitionOnTriggerDown[1] = "Spinup"; + stateTransitionOnNoAmmo[1] = "NoAmmo"; + + //-------------------------------------- + stateName[2] = "NoAmmo"; + stateTransitionOnAmmo[2] = "Ready"; + stateSpinThread[2] = Stop; + stateTransitionOnTriggerDown[2] = "DryFire"; + + //-------------------------------------- + stateName[3] = "Spinup"; + stateSpinThread[3] = SpinUp; + stateSound[3] = ChaingunSpinupSound; + // + stateTimeoutValue[3] = 0.5; + stateWaitForTimeout[3] = false; + stateTransitionOnTimeout[3] = "Fire"; + stateTransitionOnTriggerUp[3] = "Spindown"; + + //-------------------------------------- + stateName[4] = "Fire"; + stateSequence[4] = "Fire"; + stateSequenceRandomFlash[4] = true; + stateSpinThread[4] = FullSpeed; + stateSound[4] = ChaingunFireSound; + //stateRecoil[4] = LightRecoil; + stateAllowImageChange[4] = false; + stateScript[4] = "onFire"; + stateFire[4] = true; + stateEjectShell[4] = true; + // + stateTimeoutValue[4] = 0.15; + stateTransitionOnTimeout[4] = "Fire"; + stateTransitionOnTriggerUp[4] = "Spindown"; + stateTransitionOnNoAmmo[4] = "EmptySpindown"; + + //-------------------------------------- + stateName[5] = "Spindown"; + stateSound[5] = ChaingunSpinDownSound; + stateSpinThread[5] = SpinDown; + // + stateTimeoutValue[5] = 1.0; + stateWaitForTimeout[5] = true; + stateTransitionOnTimeout[5] = "Ready"; + stateTransitionOnTriggerDown[5] = "Spinup"; + + //-------------------------------------- + stateName[6] = "EmptySpindown"; + stateSound[6] = ChaingunSpinDownSound; + stateSpinThread[6] = SpinDown; + // + stateTimeoutValue[6] = 0.5; + stateTransitionOnTimeout[6] = "NoAmmo"; + + //-------------------------------------- + stateName[7] = "DryFire"; + stateSound[7] = ChaingunDryFireSound; + stateTimeoutValue[7] = 0.5; + stateTransitionOnTimeout[7] = "NoAmmo"; +}; + +datablock ItemData(Chaingun) +{ + className = Weapon; + catagory = "Spawn Items"; + shapeFile = "weapon_chaingun.dts"; + image = ChaingunImage; + mass = 1; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 2; + pickUpName = "a chaingun"; + + computeCRC = true; + emap = true; +}; + diff --git a/scripts/weapons/disc.cs b/scripts/weapons/disc.cs index 8f9a366..e97b6cf 100644 --- a/scripts/weapons/disc.cs +++ b/scripts/weapons/disc.cs @@ -1,483 +1,483 @@ -//-------------------------------------- -// Disc launcher -//-------------------------------------- - -//-------------------------------------------------------------------------- -// Force-Feedback Effects -//-------------------------------------- -datablock EffectProfile(DiscFireEffect) -{ - effectname = "weapons/spinfusor_fire"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(DiscSwitchEffect) -{ - effectname = "weapons/spinfusor_activate"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(DiscDryFireEffect) -{ - effectname = "weapons/spinfusor_dryfire"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(DiscIdleEffect) -{ - effectname = "weapons/spinfusor_idle"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(DiscReloadEffect) -{ - effectname = "weapons/spinfusor_reload"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(DiscExpEffect) -{ - effectname = "explosions/grenade_explode"; - minDistance = 5; - maxDistance = 20; -}; - -//-------------------------------------------------------------------------- -// Sounds -//-------------------------------------- -datablock AudioProfile(DiscSwitchSound) -{ - filename = "fx/weapons/blaster_activate.wav"; - description = AudioClosest3d; - preload = true; - effect = DiscSwitchEffect; -}; - -datablock AudioProfile(DiscLoopSound) -{ - filename = "fx/weapons/spinfusor_idle.wav"; - description = ClosestLooping3d; - effect = DiscIdleEffect; -}; - - -datablock AudioProfile(DiscFireSound) -{ - filename = "fx/weapons/spinfusor_fire.wav"; - description = AudioDefault3d; - preload = true; - effect = DiscFireEffect; -}; - -datablock AudioProfile(DiscReloadSound) -{ - filename = "fx/weapons/spinfusor_reload.wav"; - description = AudioClosest3d; - preload = true; - effect = DiscReloadEffect; -}; - -datablock AudioProfile(discExpSound) -{ - filename = "fx/weapons/spinfusor_impact.wav"; - description = AudioExplosion3d; - preload = true; - effect = DiscExpEffect; -}; - -datablock AudioProfile(underwaterDiscExpSound) -{ - filename = "fx/weapons/spinfusor_impact_UW.wav"; - description = AudioExplosion3d; - preload = true; - effect = DiscExpEffect; -}; - -datablock AudioProfile(discProjectileSound) -{ - filename = "fx/weapons/spinfusor_projectile.wav"; - description = ProjectileLooping3d; - preload = true; -}; - -datablock AudioProfile(DiscDryFireSound) -{ - filename = "fx/weapons/spinfusor_dryfire.wav"; - description = AudioClose3d; - preload = true; - effect = DiscDryFireEffect; -}; - -//-------------------------------------------------------------------------- -// Explosion -//-------------------------------------- -datablock ParticleData(DiscExplosionBubbleParticle) -{ - dragCoefficient = 0.0; - gravityCoefficient = -0.25; - inheritedVelFactor = 0.0; - constantAcceleration = 0.0; - lifetimeMS = 2000; - lifetimeVarianceMS = 750; - useInvAlpha = false; - textureName = "special/bubbles"; - - spinRandomMin = -100.0; - spinRandomMax = 100.0; - - colors[0] = "0.7 0.8 1.0 0.0"; - colors[1] = "0.7 0.8 1.0 0.4"; - colors[2] = "0.7 0.8 1.0 0.0"; - sizes[0] = 1.0; - sizes[1] = 1.0; - sizes[2] = 1.0; - times[0] = 0.0; - times[1] = 0.3; - times[2] = 1.0; -}; -datablock ParticleEmitterData(DiscExplosionBubbleEmitter) -{ - ejectionPeriodMS = 7; - periodVarianceMS = 0; - ejectionVelocity = 1.0; - ejectionOffset = 3.0; - velocityVariance = 0.5; - thetaMin = 0; - thetaMax = 80; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - particles = "DiscExplosionBubbleParticle"; -}; - -datablock ExplosionData(UnderwaterDiscExplosion) -{ - explosionShape = "disc_explosion.dts"; - soundProfile = underwaterDiscExpSound; - - faceViewer = true; - - sizes[0] = "1.3 1.3 1.3"; - sizes[1] = "0.75 0.75 0.75"; - sizes[2] = "0.4 0.4 0.4"; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - - emitter[0] = "DiscExplosionBubbleEmitter"; - - shakeCamera = true; - camShakeFreq = "10.0 11.0 10.0"; - camShakeAmp = "20.0 20.0 20.0"; - camShakeDuration = 0.5; - camShakeRadius = 10.0; -}; - -datablock ExplosionData(DiscExplosion) -{ - explosionShape = "disc_explosion.dts"; - soundProfile = discExpSound; - - faceViewer = true; - explosionScale = "1 1 1"; - - shakeCamera = true; - camShakeFreq = "10.0 11.0 10.0"; - camShakeAmp = "20.0 20.0 20.0"; - camShakeDuration = 0.5; - camShakeRadius = 10.0; - - sizes[0] = "1.0 1.0 1.0"; - sizes[1] = "1.0 1.0 1.0"; - times[0] = 0.0; - times[1] = 1.0; -}; - -//-------------------------------------------------------------------------- -// Splash -//-------------------------------------------------------------------------- -datablock ParticleData(DiscMist) -{ - dragCoefficient = 2.0; - gravityCoefficient = -0.05; - inheritedVelFactor = 0.0; - constantAcceleration = 0.0; - lifetimeMS = 400; - lifetimeVarianceMS = 100; - useInvAlpha = false; - spinRandomMin = -90.0; - spinRandomMax = 500.0; - textureName = "particleTest"; - colors[0] = "0.7 0.8 1.0 1.0"; - colors[1] = "0.7 0.8 1.0 0.5"; - colors[2] = "0.7 0.8 1.0 0.0"; - sizes[0] = 0.5; - sizes[1] = 0.5; - sizes[2] = 0.8; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData(DiscMistEmitter) -{ - ejectionPeriodMS = 5; - periodVarianceMS = 0; - ejectionVelocity = 3.0; - velocityVariance = 2.0; - ejectionOffset = 0.0; - thetaMin = 85; - thetaMax = 85; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - lifetimeMS = 250; - particles = "DiscMist"; -}; - -datablock ParticleData( DiscSplashParticle2 ) -{ - - dragCoeffiecient = 0.4; - gravityCoefficient = -0.03; // rises slowly - inheritedVelFactor = 0.025; - - lifetimeMS = 600; - lifetimeVarianceMS = 300; - - textureName = "particleTest"; - - useInvAlpha = false; - spinRandomMin = -200.0; - spinRandomMax = 200.0; - - - colors[0] = "0.7 0.8 1.0 1.0"; - colors[1] = "0.7 0.8 1.0 0.5"; - colors[2] = "0.7 0.8 1.0 0.0"; - sizes[0] = 0.5; - sizes[1] = 1.0; - sizes[2] = 2.0; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData( DiscSplashEmitter2 ) -{ - ejectionPeriodMS = 25; - ejectionOffset = 0.2; - periodVarianceMS = 0; - ejectionVelocity = 2.25; - velocityVariance = 0.50; - thetaMin = 0.0; - thetaMax = 30.0; - lifetimeMS = 250; - - particles = "DiscSplashParticle2"; -}; - - -datablock ParticleData( DiscSplashParticle ) -{ - dragCoefficient = 1; - gravityCoefficient = 0.2; - inheritedVelFactor = 0.2; - constantAcceleration = -0.0; - lifetimeMS = 600; - lifetimeVarianceMS = 0; - textureName = "special/droplet"; - colors[0] = "0.7 0.8 1.0 1.0"; - colors[1] = "0.7 0.8 1.0 0.5"; - colors[2] = "0.7 0.8 1.0 0.0"; - sizes[0] = 0.5; - sizes[1] = 0.5; - sizes[2] = 0.5; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData( DiscSplashEmitter ) -{ - ejectionPeriodMS = 1; - periodVarianceMS = 0; - ejectionVelocity = 3; - velocityVariance = 1.0; - ejectionOffset = 0.0; - thetaMin = 60; - thetaMax = 80; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - orientParticles = true; - lifetimeMS = 100; - particles = "DiscSplashParticle"; -}; - - -datablock SplashData(DiscSplash) -{ - numSegments = 15; - ejectionFreq = 0.0001; - ejectionAngle = 45; - ringLifetime = 0.5; - lifetimeMS = 400; - velocity = 5.0; - startRadius = 0.0; - acceleration = -3.0; - texWrap = 5.0; - - texture = "special/water2"; - - emitter[0] = DiscSplashEmitter; - emitter[1] = DiscMistEmitter; - - colors[0] = "0.7 0.8 1.0 0.0"; - colors[1] = "0.7 0.8 1.0 1.0"; - colors[2] = "0.7 0.8 1.0 0.0"; - colors[3] = "0.7 0.8 1.0 0.0"; - times[0] = 0.0; - times[1] = 0.4; - times[2] = 0.8; - times[3] = 1.0; -}; - - -//-------------------------------------------------------------------------- -// Projectile -//-------------------------------------- -datablock LinearProjectileData(DiscProjectile) -{ - projectileShapeName = "disc.dts"; - emitterDelay = -1; - directDamage = 0.0; - hasDamageRadius = true; - indirectDamage = 0.50; - damageRadius = 7.5; - radiusDamageType = $DamageType::Disc; - kickBackStrength = 2000; // z0dd - ZOD, 4/24/02. Was 1750 - - sound = discProjectileSound; - explosion = "DiscExplosion"; - underwaterExplosion = "UnderwaterDiscExplosion"; - splash = DiscSplash; - - dryVelocity = 95; // z0dd - ZOD, 3/30/02. Slight disc speed up. was 90 - wetVelocity = 55; // z0dd - ZOD, 3/30/02. Slight disc speed up. was 50 - velInheritFactor = 0.75; // z0dd - ZOD, 3/30/02. was 0.5 - fizzleTimeMS = 5000; - lifetimeMS = 5000; - explodeOnDeath = true; - reflectOnWaterImpactAngle = 15.0; - explodeOnWaterImpact = true; - deflectionOnWaterImpact = 20.0; // z0dd - ZOD, 4/24/02. Was 0.0. 20 degrees skips off water - fizzleUnderwaterMS = 5000; - - activateDelayMS = 200; - - hasLight = true; - lightRadius = 6.0; - lightColor = "0.175 0.175 0.5"; -}; - - -//-------------------------------------------------------------------------- -// Ammo -//-------------------------------------- - -datablock ItemData(DiscAmmo) -{ - className = Ammo; - catagory = "Ammo"; - shapeFile = "ammo_disc.dts"; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - pickUpName = "some spinfusor discs"; -}; - -//-------------------------------------------------------------------------- -// Weapon -//-------------------------------------- - -datablock ShapeBaseImageData(DiscImage) -{ - className = WeaponImage; - shapeFile = "weapon_disc.dts"; - item = Disc; - ammo = DiscAmmo; - offset = "0 0 0"; - emap = true; - - //projectileSpread = 1.0 / 1000.0; // z0dd - ZOD, 4/14/02. No disc spread. - - projectile = DiscProjectile; - projectileType = LinearProjectile; - - // State Data - stateName[0] = "Preactivate"; - stateTransitionOnLoaded[0] = "Activate"; - stateTransitionOnNoAmmo[0] = "NoAmmo"; - - stateName[1] = "Activate"; - stateTransitionOnTimeout[1] = "Ready"; - stateTimeoutValue[1] = 0.5; - stateSequence[1] = "Activated"; - stateSound[1] = DiscSwitchSound; - - stateName[2] = "Ready"; - stateTransitionOnNoAmmo[2] = "NoAmmo"; - stateTransitionOnTriggerDown[2] = "Fire"; - stateSequence[2] = "DiscSpin"; - stateSound[2] = DiscLoopSound; - - stateName[3] = "Fire"; - stateTransitionOnTimeout[3] = "Reload"; - stateTimeoutValue[3] = 1.25; - stateFire[3] = true; - stateRecoil[3] = LightRecoil; - stateAllowImageChange[3] = false; - stateSequence[3] = "Fire"; - stateScript[3] = "onFire"; - stateSound[3] = DiscFireSound; - - stateName[4] = "Reload"; - stateTransitionOnNoAmmo[4] = "NoAmmo"; - stateTransitionOnTimeout[4] = "Ready"; - stateTimeoutValue[4] = 0.5; // 0.25 load, 0.25 spinup - stateAllowImageChange[4] = false; - stateSequence[4] = "Reload"; - stateSound[4] = DiscReloadSound; - - stateName[5] = "NoAmmo"; - stateTransitionOnAmmo[5] = "Reload"; - stateSequence[5] = "NoAmmo"; - stateTransitionOnTriggerDown[5] = "DryFire"; - - stateName[6] = "DryFire"; - stateSound[6] = DiscDryFireSound; - stateTimeoutValue[6] = 1.0; - stateTransitionOnTimeout[6] = "NoAmmo"; - -}; - -datablock ItemData(Disc) -{ - className = Weapon; - catagory = "Spawn Items"; - shapeFile = "weapon_disc.dts"; - image = DiscImage; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - pickUpName = "a spinfusor"; - emap = true; -}; +//-------------------------------------- +// Disc launcher +//-------------------------------------- + +//-------------------------------------------------------------------------- +// Force-Feedback Effects +//-------------------------------------- +datablock EffectProfile(DiscFireEffect) +{ + effectname = "weapons/spinfusor_fire"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock EffectProfile(DiscSwitchEffect) +{ + effectname = "weapons/spinfusor_activate"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock EffectProfile(DiscDryFireEffect) +{ + effectname = "weapons/spinfusor_dryfire"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock EffectProfile(DiscIdleEffect) +{ + effectname = "weapons/spinfusor_idle"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock EffectProfile(DiscReloadEffect) +{ + effectname = "weapons/spinfusor_reload"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock EffectProfile(DiscExpEffect) +{ + effectname = "explosions/grenade_explode"; + minDistance = 5; + maxDistance = 20; +}; + +//-------------------------------------------------------------------------- +// Sounds +//-------------------------------------- +datablock AudioProfile(DiscSwitchSound) +{ + filename = "fx/weapons/blaster_activate.wav"; + description = AudioClosest3d; + preload = true; + effect = DiscSwitchEffect; +}; + +datablock AudioProfile(DiscLoopSound) +{ + filename = "fx/weapons/spinfusor_idle.wav"; + description = ClosestLooping3d; + effect = DiscIdleEffect; +}; + + +datablock AudioProfile(DiscFireSound) +{ + filename = "fx/weapons/spinfusor_fire.wav"; + description = AudioDefault3d; + preload = true; + effect = DiscFireEffect; +}; + +datablock AudioProfile(DiscReloadSound) +{ + filename = "fx/weapons/spinfusor_reload.wav"; + description = AudioClosest3d; + preload = true; + effect = DiscReloadEffect; +}; + +datablock AudioProfile(discExpSound) +{ + filename = "fx/weapons/spinfusor_impact.wav"; + description = AudioExplosion3d; + preload = true; + effect = DiscExpEffect; +}; + +datablock AudioProfile(underwaterDiscExpSound) +{ + filename = "fx/weapons/spinfusor_impact_UW.wav"; + description = AudioExplosion3d; + preload = true; + effect = DiscExpEffect; +}; + +datablock AudioProfile(discProjectileSound) +{ + filename = "fx/weapons/spinfusor_projectile.wav"; + description = ProjectileLooping3d; + preload = true; +}; + +datablock AudioProfile(DiscDryFireSound) +{ + filename = "fx/weapons/spinfusor_dryfire.wav"; + description = AudioClose3d; + preload = true; + effect = DiscDryFireEffect; +}; + +//-------------------------------------------------------------------------- +// Explosion +//-------------------------------------- +datablock ParticleData(DiscExplosionBubbleParticle) +{ + dragCoefficient = 0.0; + gravityCoefficient = -0.25; + inheritedVelFactor = 0.0; + constantAcceleration = 0.0; + lifetimeMS = 2000; + lifetimeVarianceMS = 750; + useInvAlpha = false; + textureName = "special/bubbles"; + + spinRandomMin = -100.0; + spinRandomMax = 100.0; + + colors[0] = "0.7 0.8 1.0 0.0"; + colors[1] = "0.7 0.8 1.0 0.4"; + colors[2] = "0.7 0.8 1.0 0.0"; + sizes[0] = 1.0; + sizes[1] = 1.0; + sizes[2] = 1.0; + times[0] = 0.0; + times[1] = 0.3; + times[2] = 1.0; +}; +datablock ParticleEmitterData(DiscExplosionBubbleEmitter) +{ + ejectionPeriodMS = 7; + periodVarianceMS = 0; + ejectionVelocity = 1.0; + ejectionOffset = 3.0; + velocityVariance = 0.5; + thetaMin = 0; + thetaMax = 80; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + particles = "DiscExplosionBubbleParticle"; +}; + +datablock ExplosionData(UnderwaterDiscExplosion) +{ + explosionShape = "disc_explosion.dts"; + soundProfile = underwaterDiscExpSound; + + faceViewer = true; + + sizes[0] = "1.3 1.3 1.3"; + sizes[1] = "0.75 0.75 0.75"; + sizes[2] = "0.4 0.4 0.4"; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; + + emitter[0] = "DiscExplosionBubbleEmitter"; + + shakeCamera = true; + camShakeFreq = "10.0 11.0 10.0"; + camShakeAmp = "20.0 20.0 20.0"; + camShakeDuration = 0.5; + camShakeRadius = 10.0; +}; + +datablock ExplosionData(DiscExplosion) +{ + explosionShape = "disc_explosion.dts"; + soundProfile = discExpSound; + + faceViewer = true; + explosionScale = "1 1 1"; + + shakeCamera = true; + camShakeFreq = "10.0 11.0 10.0"; + camShakeAmp = "20.0 20.0 20.0"; + camShakeDuration = 0.5; + camShakeRadius = 10.0; + + sizes[0] = "1.0 1.0 1.0"; + sizes[1] = "1.0 1.0 1.0"; + times[0] = 0.0; + times[1] = 1.0; +}; + +//-------------------------------------------------------------------------- +// Splash +//-------------------------------------------------------------------------- +datablock ParticleData(DiscMist) +{ + dragCoefficient = 2.0; + gravityCoefficient = -0.05; + inheritedVelFactor = 0.0; + constantAcceleration = 0.0; + lifetimeMS = 400; + lifetimeVarianceMS = 100; + useInvAlpha = false; + spinRandomMin = -90.0; + spinRandomMax = 500.0; + textureName = "particleTest"; + colors[0] = "0.7 0.8 1.0 1.0"; + colors[1] = "0.7 0.8 1.0 0.5"; + colors[2] = "0.7 0.8 1.0 0.0"; + sizes[0] = 0.5; + sizes[1] = 0.5; + sizes[2] = 0.8; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; +}; + +datablock ParticleEmitterData(DiscMistEmitter) +{ + ejectionPeriodMS = 5; + periodVarianceMS = 0; + ejectionVelocity = 3.0; + velocityVariance = 2.0; + ejectionOffset = 0.0; + thetaMin = 85; + thetaMax = 85; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + lifetimeMS = 250; + particles = "DiscMist"; +}; + +datablock ParticleData( DiscSplashParticle2 ) +{ + + dragCoeffiecient = 0.4; + gravityCoefficient = -0.03; // rises slowly + inheritedVelFactor = 0.025; + + lifetimeMS = 600; + lifetimeVarianceMS = 300; + + textureName = "particleTest"; + + useInvAlpha = false; + spinRandomMin = -200.0; + spinRandomMax = 200.0; + + + colors[0] = "0.7 0.8 1.0 1.0"; + colors[1] = "0.7 0.8 1.0 0.5"; + colors[2] = "0.7 0.8 1.0 0.0"; + sizes[0] = 0.5; + sizes[1] = 1.0; + sizes[2] = 2.0; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; +}; + +datablock ParticleEmitterData( DiscSplashEmitter2 ) +{ + ejectionPeriodMS = 25; + ejectionOffset = 0.2; + periodVarianceMS = 0; + ejectionVelocity = 2.25; + velocityVariance = 0.50; + thetaMin = 0.0; + thetaMax = 30.0; + lifetimeMS = 250; + + particles = "DiscSplashParticle2"; +}; + + +datablock ParticleData( DiscSplashParticle ) +{ + dragCoefficient = 1; + gravityCoefficient = 0.2; + inheritedVelFactor = 0.2; + constantAcceleration = -0.0; + lifetimeMS = 600; + lifetimeVarianceMS = 0; + textureName = "special/droplet"; + colors[0] = "0.7 0.8 1.0 1.0"; + colors[1] = "0.7 0.8 1.0 0.5"; + colors[2] = "0.7 0.8 1.0 0.0"; + sizes[0] = 0.5; + sizes[1] = 0.5; + sizes[2] = 0.5; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; +}; + +datablock ParticleEmitterData( DiscSplashEmitter ) +{ + ejectionPeriodMS = 1; + periodVarianceMS = 0; + ejectionVelocity = 3; + velocityVariance = 1.0; + ejectionOffset = 0.0; + thetaMin = 60; + thetaMax = 80; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + orientParticles = true; + lifetimeMS = 100; + particles = "DiscSplashParticle"; +}; + + +datablock SplashData(DiscSplash) +{ + numSegments = 15; + ejectionFreq = 0.0001; + ejectionAngle = 45; + ringLifetime = 0.5; + lifetimeMS = 400; + velocity = 5.0; + startRadius = 0.0; + acceleration = -3.0; + texWrap = 5.0; + + texture = "special/water2"; + + emitter[0] = DiscSplashEmitter; + emitter[1] = DiscMistEmitter; + + colors[0] = "0.7 0.8 1.0 0.0"; + colors[1] = "0.7 0.8 1.0 1.0"; + colors[2] = "0.7 0.8 1.0 0.0"; + colors[3] = "0.7 0.8 1.0 0.0"; + times[0] = 0.0; + times[1] = 0.4; + times[2] = 0.8; + times[3] = 1.0; +}; + + +//-------------------------------------------------------------------------- +// Projectile +//-------------------------------------- +datablock LinearProjectileData(DiscProjectile) +{ + projectileShapeName = "disc.dts"; + emitterDelay = -1; + directDamage = 0.0; + hasDamageRadius = true; + indirectDamage = 0.50; + damageRadius = 7.5; + radiusDamageType = $DamageType::Disc; + kickBackStrength = 2000; // z0dd - ZOD, 4/24/02. Was 1750 + + sound = discProjectileSound; + explosion = "DiscExplosion"; + underwaterExplosion = "UnderwaterDiscExplosion"; + splash = DiscSplash; + + dryVelocity = 95; // z0dd - ZOD, 3/30/02. Slight disc speed up. was 90 + wetVelocity = 55; // z0dd - ZOD, 3/30/02. Slight disc speed up. was 50 + velInheritFactor = 0.75; // z0dd - ZOD, 3/30/02. was 0.5 + fizzleTimeMS = 5000; + lifetimeMS = 5000; + explodeOnDeath = true; + reflectOnWaterImpactAngle = 15.0; + explodeOnWaterImpact = true; + deflectionOnWaterImpact = 20.0; // z0dd - ZOD, 4/24/02. Was 0.0. 20 degrees skips off water + fizzleUnderwaterMS = 5000; + + activateDelayMS = 200; + + hasLight = true; + lightRadius = 6.0; + lightColor = "0.175 0.175 0.5"; +}; + + +//-------------------------------------------------------------------------- +// Ammo +//-------------------------------------- + +datablock ItemData(DiscAmmo) +{ + className = Ammo; + catagory = "Ammo"; + shapeFile = "ammo_disc.dts"; + mass = 1; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 2; + pickUpName = "some spinfusor discs"; +}; + +//-------------------------------------------------------------------------- +// Weapon +//-------------------------------------- + +datablock ShapeBaseImageData(DiscImage) +{ + className = WeaponImage; + shapeFile = "weapon_disc.dts"; + item = Disc; + ammo = DiscAmmo; + offset = "0 0 0"; + emap = true; + + //projectileSpread = 1.0 / 1000.0; // z0dd - ZOD, 4/14/02. No disc spread. + + projectile = DiscProjectile; + projectileType = LinearProjectile; + + // State Data + stateName[0] = "Preactivate"; + stateTransitionOnLoaded[0] = "Activate"; + stateTransitionOnNoAmmo[0] = "NoAmmo"; + + stateName[1] = "Activate"; + stateTransitionOnTimeout[1] = "Ready"; + stateTimeoutValue[1] = 0.5; + stateSequence[1] = "Activated"; + stateSound[1] = DiscSwitchSound; + + stateName[2] = "Ready"; + stateTransitionOnNoAmmo[2] = "NoAmmo"; + stateTransitionOnTriggerDown[2] = "Fire"; + stateSequence[2] = "DiscSpin"; + stateSound[2] = DiscLoopSound; + + stateName[3] = "Fire"; + stateTransitionOnTimeout[3] = "Reload"; + stateTimeoutValue[3] = 1.25; + stateFire[3] = true; + stateRecoil[3] = LightRecoil; + stateAllowImageChange[3] = false; + stateSequence[3] = "Fire"; + stateScript[3] = "onFire"; + stateSound[3] = DiscFireSound; + + stateName[4] = "Reload"; + stateTransitionOnNoAmmo[4] = "NoAmmo"; + stateTransitionOnTimeout[4] = "Ready"; + stateTimeoutValue[4] = 0.5; // 0.25 load, 0.25 spinup + stateAllowImageChange[4] = false; + stateSequence[4] = "Reload"; + stateSound[4] = DiscReloadSound; + + stateName[5] = "NoAmmo"; + stateTransitionOnAmmo[5] = "Reload"; + stateSequence[5] = "NoAmmo"; + stateTransitionOnTriggerDown[5] = "DryFire"; + + stateName[6] = "DryFire"; + stateSound[6] = DiscDryFireSound; + stateTimeoutValue[6] = 1.0; + stateTransitionOnTimeout[6] = "NoAmmo"; + +}; + +datablock ItemData(Disc) +{ + className = Weapon; + catagory = "Spawn Items"; + shapeFile = "weapon_disc.dts"; + image = DiscImage; + mass = 1; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 2; + pickUpName = "a spinfusor"; + emap = true; +}; diff --git a/scripts/weapons/flashGrenade.cs b/scripts/weapons/flashGrenade.cs index 110a65e..13357c8 100644 --- a/scripts/weapons/flashGrenade.cs +++ b/scripts/weapons/flashGrenade.cs @@ -1,69 +1,69 @@ -// grenade (thrown by hand) script -// ------------------------------------------------------------------------ -datablock EffectProfile(FlashGrenadeExplosionEffect) -{ - effectname = "explosions/grenade_flash_explode"; - minDistance = 10; - maxDistance = 30; -}; - -datablock AudioProfile(FlashGrenadeExplosionSound) -{ - filename = "fx/explosions/grenade_flash_explode.wav"; - description = AudioExplosion3d; - preload = true; - effect = FlashGrenadeExplosionEffect; -}; - -datablock ExplosionData(FlashGrenadeExplosion) -{ - explosionShape = "disc_explosion.dts"; - soundProfile = FlashGrenadeExplosionSound; - - faceViewer = true; -}; - -datablock ItemData(FlashGrenadeThrown) -{ - shapeFile = "grenade.dts"; - mass = 0.7; - elasticity = 0.2; - friction = 1; - pickupRadius = 2; - maxDamage = 0.4; - explosion = FlashGrenadeExplosion; - indirectDamage = 0.5; - damageRadius = 10.0; - radiusDamageType = $DamageType::Grenade; - kickBackStrength = 1000; - - computeCRC = true; - - maxWhiteout = 0.9; // z0dd - ZOD, 9/8/02. Was 1.2 -}; - -datablock ItemData(FlashGrenade) -{ - className = HandInventory; - catagory = "Handheld"; - shapeFile = "grenade.dts"; - mass = 0.7; - elasticity = 0.2; - friction = 1; - pickupRadius = 2; - thrownItem = FlashGrenadeThrown; - pickUpName = "some flash grenades"; - isGrenade = true; - - computeCRC = true; - -}; - -//-------------------------------------------------------------------------- -// Functions: -//-------------------------------------------------------------------------- -function FlashGrenadeThrown::onCollision( %data, %obj, %col ) -{ - // Do nothing... -} - +// grenade (thrown by hand) script +// ------------------------------------------------------------------------ +datablock EffectProfile(FlashGrenadeExplosionEffect) +{ + effectname = "explosions/grenade_flash_explode"; + minDistance = 10; + maxDistance = 30; +}; + +datablock AudioProfile(FlashGrenadeExplosionSound) +{ + filename = "fx/explosions/grenade_flash_explode.wav"; + description = AudioExplosion3d; + preload = true; + effect = FlashGrenadeExplosionEffect; +}; + +datablock ExplosionData(FlashGrenadeExplosion) +{ + explosionShape = "disc_explosion.dts"; + soundProfile = FlashGrenadeExplosionSound; + + faceViewer = true; +}; + +datablock ItemData(FlashGrenadeThrown) +{ + shapeFile = "grenade.dts"; + mass = 0.7; + elasticity = 0.2; + friction = 1; + pickupRadius = 2; + maxDamage = 0.4; + explosion = FlashGrenadeExplosion; + indirectDamage = 0.5; + damageRadius = 10.0; + radiusDamageType = $DamageType::Grenade; + kickBackStrength = 1000; + + computeCRC = true; + + maxWhiteout = 0.9; // z0dd - ZOD, 9/8/02. Was 1.2 +}; + +datablock ItemData(FlashGrenade) +{ + className = HandInventory; + catagory = "Handheld"; + shapeFile = "grenade.dts"; + mass = 0.7; + elasticity = 0.2; + friction = 1; + pickupRadius = 2; + thrownItem = FlashGrenadeThrown; + pickUpName = "some flash grenades"; + isGrenade = true; + + computeCRC = true; + +}; + +//-------------------------------------------------------------------------- +// Functions: +//-------------------------------------------------------------------------- +function FlashGrenadeThrown::onCollision( %data, %obj, %col ) +{ + // Do nothing... +} + diff --git a/scripts/weapons/grenadeLauncher.cs b/scripts/weapons/grenadeLauncher.cs index f1610e1..bf2277a 100644 --- a/scripts/weapons/grenadeLauncher.cs +++ b/scripts/weapons/grenadeLauncher.cs @@ -1,787 +1,787 @@ -//-------------------------------------- -// Grenade launcher -//-------------------------------------- - -//-------------------------------------------------------------------------- -// Force-Feedback Effects -//-------------------------------------- -datablock EffectProfile(GrenadeSwitchEffect) -{ - effectname = "weapons/generic_switch"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(GrenadeFireEffect) -{ - effectname = "weapons/grenadelauncher_fire"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(GrenadeDryFireEffect) -{ - effectname = "weapons/grenadelauncher_dryfire"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(GrenadeReloadEffect) -{ - effectname = "weapons/generic_switch"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(GrenadeExplosionEffect) -{ - effectname = "explosions/grenade_explode"; - minDistance = 10; - maxDistance = 35; -}; - -//-------------------------------------------------------------------------- -// Sounds -//-------------------------------------- -datablock AudioProfile(GrenadeSwitchSound) -{ - filename = "fx/weapons/generic_switch.wav"; - description = AudioClosest3d; - preload = true; - effect = GrenadeSwitchEffect; -}; - -datablock AudioProfile(GrenadeFireSound) -{ - filename = "fx/weapons/grenadelauncher_fire.wav"; - description = AudioDefault3d; - preload = true; - effect = GrenadeFireEffect; -}; - -datablock AudioProfile(GrenadeProjectileSound) -{ - filename = "fx/weapons/grenadelauncher_projectile.wav"; - description = ProjectileLooping3d; - preload = true; -}; - -datablock AudioProfile(GrenadeReloadSound) -{ - filename = "fx/weapons/generic_switch.wav"; - description = AudioClosest3d; - preload = true; - effect = GrenadeReloadEffect; -}; - -datablock AudioProfile(GrenadeExplosionSound) -{ - filename = "fx/weapons/grenade_explode.wav"; - description = AudioExplosion3d; - preload = true; - effect = GrenadeExplosionEffect; -}; - -datablock AudioProfile(UnderwaterGrenadeExplosionSound) -{ - filename = "fx/weapons/grenade_explode_UW.wav"; - description = AudioExplosion3d; - preload = true; - effect = GrenadeExplosionEffect; -}; - -datablock AudioProfile(GrenadeDryFireSound) -{ - filename = "fx/weapons/grenadelauncher_dryfire.wav"; - description = AudioClose3d; - preload = true; - effect = GrenadeDryFireEffect; -}; - -//---------------------------------------------------------------------------- -// Underwater fx -//---------------------------------------------------------------------------- -datablock ParticleData(GrenadeExplosionBubbleParticle) -{ - dragCoefficient = 0.0; - gravityCoefficient = -0.25; - inheritedVelFactor = 0.0; - constantAcceleration = 0.0; - lifetimeMS = 1500; - lifetimeVarianceMS = 600; - useInvAlpha = false; - textureName = "special/bubbles"; - - spinRandomMin = -100.0; - spinRandomMax = 100.0; - - colors[0] = "0.7 0.8 1.0 0.0"; - colors[1] = "0.7 0.8 1.0 0.4"; - colors[2] = "0.7 0.8 1.0 0.0"; - sizes[0] = 1.0; - sizes[1] = 1.0; - sizes[2] = 1.0; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; -datablock ParticleEmitterData(GrenadeExplosionBubbleEmitter) -{ - ejectionPeriodMS = 5; - periodVarianceMS = 0; - ejectionVelocity = 1.0; - ejectionOffset = 3.0; - velocityVariance = 0.5; - thetaMin = 0; - thetaMax = 80; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - particles = "GrenadeExplosionBubbleParticle"; -}; - -datablock ParticleData(UnderwaterGrenadeDust) -{ - dragCoefficient = 1.0; - gravityCoefficient = -0.01; - inheritedVelFactor = 0.0; - constantAcceleration = -1.1; - lifetimeMS = 1000; - lifetimeVarianceMS = 100; - useInvAlpha = false; - spinRandomMin = -90.0; - spinRandomMax = 500.0; - textureName = "particleTest"; - colors[0] = "0.6 0.6 1.0 0.5"; - colors[1] = "0.6 0.6 1.0 0.5"; - colors[2] = "0.6 0.6 1.0 0.0"; - sizes[0] = 3.0; - sizes[1] = 3.0; - sizes[2] = 3.0; - times[0] = 0.0; - times[1] = 0.7; - times[2] = 1.0; -}; - -datablock ParticleEmitterData(UnderwaterGrenadeDustEmitter) -{ - ejectionPeriodMS = 15; - periodVarianceMS = 0; - ejectionVelocity = 15.0; - velocityVariance = 0.0; - ejectionOffset = 0.0; - thetaMin = 70; - thetaMax = 70; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - lifetimeMS = 250; - particles = "UnderwaterGrenadeDust"; -}; - - -datablock ParticleData(UnderwaterGrenadeExplosionSmoke) -{ - dragCoeffiecient = 0.4; - gravityCoefficient = -0.25; // rises slowly - inheritedVelFactor = 0.025; - constantAcceleration = -1.1; - - lifetimeMS = 1250; - lifetimeVarianceMS = 0; - - textureName = "particleTest"; - - useInvAlpha = false; - spinRandomMin = -200.0; - spinRandomMax = 200.0; - - textureName = "special/Smoke/smoke_001"; - - colors[0] = "0.1 0.1 1.0 1.0"; - colors[1] = "0.4 0.4 1.0 1.0"; - colors[2] = "0.4 0.4 1.0 0.0"; - sizes[0] = 2.0; - sizes[1] = 6.0; - sizes[2] = 2.0; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - -}; - -datablock ParticleEmitterData(UnderwaterGExplosionSmokeEmitter) -{ - ejectionPeriodMS = 15; - periodVarianceMS = 0; - - ejectionVelocity = 6.25; - velocityVariance = 0.25; - - thetaMin = 0.0; - thetaMax = 90.0; - - lifetimeMS = 250; - - particles = "UnderwaterGrenadeExplosionSmoke"; -}; - - - -datablock ParticleData(UnderwaterGrenadeSparks) -{ - dragCoefficient = 1; - gravityCoefficient = 0.0; - inheritedVelFactor = 0.2; - constantAcceleration = 0.0; - lifetimeMS = 500; - lifetimeVarianceMS = 350; - textureName = "special/underwaterSpark"; - colors[0] = "0.6 0.6 1.0 1.0"; - colors[1] = "0.6 0.6 1.0 1.0"; - colors[2] = "0.6 0.6 1.0 0.0"; - sizes[0] = 0.5; - sizes[1] = 0.5; - sizes[2] = 0.75; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - -}; - -datablock ParticleEmitterData(UnderwaterGrenadeSparksEmitter) -{ - 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 = "UnderwaterGrenadeSparks"; -}; - -datablock ExplosionData(UnderwaterGrenadeExplosion) -{ - soundProfile = UnderwaterGrenadeExplosionSound; - - faceViewer = true; - explosionScale = "0.8 0.8 0.8"; - - emitter[0] = UnderwaterGrenadeDustEmitter; - emitter[1] = UnderwaterGExplosionSmokeEmitter; - emitter[2] = UnderwaterGrenadeSparksEmitter; - emitter[3] = GrenadeExplosionBubbleEmitter; - - shakeCamera = true; - camShakeFreq = "10.0 6.0 9.0"; - camShakeAmp = "20.0 20.0 20.0"; - camShakeDuration = 0.5; - camShakeRadius = 20.0; -}; - - -//---------------------------------------------------------------------------- -// Bubbles -//---------------------------------------------------------------------------- -datablock ParticleData(GrenadeBubbleParticle) -{ - dragCoefficient = 0.0; - gravityCoefficient = -0.25; - inheritedVelFactor = 0.0; - constantAcceleration = 0.0; - lifetimeMS = 1500; - lifetimeVarianceMS = 600; - useInvAlpha = false; - textureName = "special/bubbles"; - - spinRandomMin = -100.0; - spinRandomMax = 100.0; - - colors[0] = "0.7 0.8 1.0 0.4"; - colors[1] = "0.7 0.8 1.0 0.4"; - colors[2] = "0.7 0.8 1.0 0.0"; - sizes[0] = 0.5; - sizes[1] = 0.5; - sizes[2] = 0.5; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData(GrenadeBubbleEmitter) -{ - ejectionPeriodMS = 5; - periodVarianceMS = 0; - ejectionVelocity = 1.0; - ejectionOffset = 0.1; - velocityVariance = 0.5; - thetaMin = 0; - thetaMax = 80; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - particles = "GrenadeBubbleParticle"; -}; - -//---------------------------------------------------------------------------- -// Debris -//---------------------------------------------------------------------------- - -datablock ParticleData( GDebrisSmokeParticle ) -{ - dragCoeffiecient = 1.0; - gravityCoefficient = 0.0; - inheritedVelFactor = 0.2; - - lifetimeMS = 1000; - lifetimeVarianceMS = 100; - - textureName = "particleTest"; - - useInvAlpha = true; - - spinRandomMin = -60.0; - spinRandomMax = 60.0; - - colors[0] = "0.4 0.4 0.4 1.0"; - colors[1] = "0.3 0.3 0.3 0.5"; - colors[2] = "0.0 0.0 0.0 0.0"; - sizes[0] = 0.0; - sizes[1] = 1.0; - sizes[2] = 1.0; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData( GDebrisSmokeEmitter ) -{ - ejectionPeriodMS = 7; - periodVarianceMS = 1; - - ejectionVelocity = 1.0; // A little oomph at the back end - velocityVariance = 0.2; - - thetaMin = 0.0; - thetaMax = 40.0; - - particles = "GDebrisSmokeParticle"; -}; - - -datablock DebrisData( GrenadeDebris ) -{ - emitters[0] = GDebrisSmokeEmitter; - - explodeOnMaxBounce = true; - - elasticity = 0.4; - friction = 0.2; - - lifetime = 0.3; - lifetimeVariance = 0.02; - - numBounces = 1; -}; - -//-------------------------------------------------------------------------- -// Splash -//-------------------------------------------------------------------------- - -datablock ParticleData( GrenadeSplashParticle ) -{ - dragCoefficient = 1; - gravityCoefficient = 0.0; - inheritedVelFactor = 0.2; - constantAcceleration = -1.4; - lifetimeMS = 300; - lifetimeVarianceMS = 0; - textureName = "special/droplet"; - colors[0] = "0.7 0.8 1.0 1.0"; - colors[1] = "0.7 0.8 1.0 0.5"; - colors[2] = "0.7 0.8 1.0 0.0"; - sizes[0] = 0.05; - sizes[1] = 0.2; - sizes[2] = 0.2; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData( GrenadeSplashEmitter ) -{ - ejectionPeriodMS = 4; - periodVarianceMS = 0; - ejectionVelocity = 4; - velocityVariance = 1.0; - ejectionOffset = 0.0; - thetaMin = 0; - thetaMax = 50; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - orientParticles = true; - lifetimeMS = 100; - particles = "BlasterSplashParticle"; -}; - - -datablock SplashData(GrenadeSplash) -{ - numSegments = 15; - ejectionFreq = 15; - ejectionAngle = 40; - ringLifetime = 0.35; - lifetimeMS = 300; - velocity = 3.0; - startRadius = 0.0; - acceleration = -3.0; - texWrap = 5.0; - - texture = "special/water2"; - - emitter[0] = BlasterSplashEmitter; - - colors[0] = "0.7 0.8 1.0 1.0"; - colors[1] = "0.7 0.8 1.0 1.0"; - colors[2] = "0.7 0.8 1.0 1.0"; - colors[3] = "0.7 0.8 1.0 1.0"; - times[0] = 0.0; - times[1] = 0.4; - times[2] = 0.8; - times[3] = 1.0; -}; - -//-------------------------------------------------------------------------- -// Particle effects -//-------------------------------------- -datablock ParticleData(GrenadeSmokeParticle) -{ - dragCoeffiecient = 0.0; - gravityCoefficient = -0.2; // rises slowly - inheritedVelFactor = 0.00; - - lifetimeMS = 700; // lasts 2 second - lifetimeVarianceMS = 150; // ...more or less - - textureName = "particleTest"; - - useInvAlpha = true; - spinRandomMin = -30.0; - spinRandomMax = 30.0; - - colors[0] = "0.9 0.9 0.9 1.0"; - colors[1] = "0.6 0.6 0.6 1.0"; - colors[2] = "0.4 0.4 0.4 0.0"; - - sizes[0] = 0.25; - sizes[1] = 1.0; - sizes[2] = 3.0; - - times[0] = 0.0; - times[1] = 0.2; - times[2] = 1.0; -}; - -datablock ParticleEmitterData(GrenadeSmokeEmitter) -{ - ejectionPeriodMS = 15; - periodVarianceMS = 5; - - ejectionVelocity = 1.25; - velocityVariance = 0.50; - - thetaMin = 0.0; - thetaMax = 90.0; - - particles = "GrenadeSmokeParticle"; -}; - - -datablock ParticleData(GrenadeDust) -{ - dragCoefficient = 1.0; - gravityCoefficient = -0.01; - inheritedVelFactor = 0.0; - constantAcceleration = 0.0; - lifetimeMS = 1000; - lifetimeVarianceMS = 100; - useInvAlpha = true; - spinRandomMin = -90.0; - spinRandomMax = 500.0; - textureName = "particleTest"; - colors[0] = "0.3 0.3 0.3 0.5"; - colors[1] = "0.3 0.3 0.3 0.5"; - colors[2] = "0.3 0.3 0.3 0.0"; - sizes[0] = 3.2; - sizes[1] = 4.6; - sizes[2] = 5.0; - times[0] = 0.0; - times[1] = 0.7; - times[2] = 1.0; -}; - -datablock ParticleEmitterData(GrenadeDustEmitter) -{ - ejectionPeriodMS = 5; - periodVarianceMS = 0; - ejectionVelocity = 15.0; - velocityVariance = 0.0; - ejectionOffset = 0.0; - thetaMin = 85; - thetaMax = 85; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - lifetimeMS = 250; - particles = "GrenadeDust"; -}; - - -datablock ParticleData(GrenadeExplosionSmoke) -{ - dragCoeffiecient = 0.4; - gravityCoefficient = -0.5; // rises slowly - inheritedVelFactor = 0.025; - - lifetimeMS = 1250; - lifetimeVarianceMS = 0; - - textureName = "particleTest"; - - useInvAlpha = true; - spinRandomMin = -200.0; - spinRandomMax = 200.0; - - textureName = "special/Smoke/smoke_001"; - - colors[0] = "0.7 0.7 0.7 1.0"; - colors[1] = "0.2 0.2 0.2 1.0"; - colors[2] = "0.1 0.1 0.1 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(GExplosionSmokeEmitter) -{ - ejectionPeriodMS = 5; - periodVarianceMS = 0; - - ejectionVelocity = 6.25; - velocityVariance = 0.25; - - thetaMin = 0.0; - thetaMax = 90.0; - - lifetimeMS = 250; - - particles = "GrenadeExplosionSmoke"; -}; - - - -datablock ParticleData(GrenadeSparks) -{ - dragCoefficient = 1; - gravityCoefficient = 0.0; - inheritedVelFactor = 0.2; - constantAcceleration = 0.0; - lifetimeMS = 500; - lifetimeVarianceMS = 350; - textureName = "special/bigspark"; - colors[0] = "0.56 0.36 0.26 1.0"; - colors[1] = "0.56 0.36 0.26 1.0"; - colors[2] = "1.0 0.36 0.26 0.0"; - sizes[0] = 0.5; - sizes[1] = 0.5; - sizes[2] = 0.75; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - -}; - -datablock ParticleEmitterData(GrenadeSparksEmitter) -{ - 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 = "GrenadeSparks"; -}; - - - - -//---------------------------------------------------- -// Explosion -//---------------------------------------------------- -datablock ExplosionData(GrenadeExplosion) -{ - soundProfile = GrenadeExplosionSound; - - faceViewer = true; - explosionScale = "0.8 0.8 0.8"; - - debris = GrenadeDebris; - debrisThetaMin = 10; - debrisThetaMax = 50; - debrisNum = 8; - debrisVelocity = 26.0; - debrisVelocityVariance = 7.0; - - emitter[0] = GrenadeDustEmitter; - emitter[1] = GExplosionSmokeEmitter; - emitter[2] = GrenadeSparksEmitter; - - shakeCamera = true; - camShakeFreq = "10.0 6.0 9.0"; - camShakeAmp = "20.0 20.0 20.0"; - camShakeDuration = 0.5; - camShakeRadius = 20.0; -}; - -//-------------------------------------------------------------------------- -// Projectile -//-------------------------------------- -datablock GrenadeProjectileData(BasicGrenade) -{ - projectileShapeName = "grenade_projectile.dts"; - emitterDelay = -1; - directDamage = 0.0; - hasDamageRadius = true; - indirectDamage = 0.40; - damageRadius = 15.0; - radiusDamageType = $DamageType::Grenade; - kickBackStrength = 1500; - bubbleEmitTime = 1.0; - - sound = GrenadeProjectileSound; - explosion = "GrenadeExplosion"; - underwaterExplosion = "UnderwaterGrenadeExplosion"; - velInheritFactor = 0.85; // z0dd - ZOD, 3/30/02. Was 0.5 - splash = GrenadeSplash; - - baseEmitter = GrenadeSmokeEmitter; - bubbleEmitter = GrenadeBubbleEmitter; - - grenadeElasticity = 0.30; // z0dd - ZOD, 9/13/02. Was 0.35 - grenadeFriction = 0.2; - armingDelayMS = 650; // z0dd - ZOD, 9/13/02. Was 1000 - muzzleVelocity = 75.00; // z0dd - ZOD, 3/30/02. GL projectile is faster. Was 47.00 - //drag = 0.1; // z0dd - ZOD, 3/30/02. No drag. - gravityMod = 1.9; // z0dd - ZOD, 5/18/02. Make GL projectile heavier, less floaty -}; - - -//-------------------------------------------------------------------------- -// Ammo -//-------------------------------------- - -datablock ItemData(GrenadeLauncherAmmo) -{ - className = Ammo; - catagory = "Ammo"; - shapeFile = "ammo_grenade.dts"; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - pickUpName = "some grenade launcher ammo"; - - computeCRC = true; - emap = true; -}; - -//-------------------------------------------------------------------------- -// Weapon -//-------------------------------------- -datablock ItemData(GrenadeLauncher) -{ - className = Weapon; - catagory = "Spawn Items"; - shapeFile = "weapon_grenade_launcher.dts"; - image = GrenadeLauncherImage; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - pickUpName = "a grenade launcher"; - - computeCRC = true; - -}; - -datablock ShapeBaseImageData(GrenadeLauncherImage) -{ - className = WeaponImage; - shapeFile = "weapon_grenade_launcher.dts"; - item = GrenadeLauncher; - ammo = GrenadeLauncherAmmo; - offset = "0 0 0"; - emap = true; - - projectile = BasicGrenade; - projectileType = GrenadeProjectile; - - stateName[0] = "Activate"; - stateTransitionOnTimeout[0] = "ActivateReady"; - stateTimeoutValue[0] = 0.5; - stateSequence[0] = "Activate"; - stateSound[0] = GrenadeSwitchSound; - - stateName[1] = "ActivateReady"; - stateTransitionOnLoaded[1] = "Ready"; - stateTransitionOnNoAmmo[1] = "NoAmmo"; - - stateName[2] = "Ready"; - stateTransitionOnNoAmmo[2] = "NoAmmo"; - stateTransitionOnTriggerDown[2] = "Fire"; - - stateName[3] = "Fire"; - stateTransitionOnTimeout[3] = "Reload"; - stateTimeoutValue[3] = 0.4; - stateFire[3] = true; - stateRecoil[3] = LightRecoil; - stateAllowImageChange[3] = false; - stateSequence[3] = "Fire"; - stateScript[3] = "onFire"; - stateSound[3] = GrenadeFireSound; - - stateName[4] = "Reload"; - stateTransitionOnNoAmmo[4] = "NoAmmo"; - stateTransitionOnTimeout[4] = "Ready"; - stateTimeoutValue[4] = 0.5; - stateAllowImageChange[4] = false; - stateSequence[4] = "Reload"; - stateSound[4] = GrenadeReloadSound; - - stateName[5] = "NoAmmo"; - stateTransitionOnAmmo[5] = "Reload"; - stateSequence[5] = "NoAmmo"; - stateTransitionOnTriggerDown[5] = "DryFire"; - - stateName[6] = "DryFire"; - stateSound[6] = GrenadeDryFireSound; - stateTimeoutValue[6] = 1.5; - stateTransitionOnTimeout[6] = "NoAmmo"; -}; +//-------------------------------------- +// Grenade launcher +//-------------------------------------- + +//-------------------------------------------------------------------------- +// Force-Feedback Effects +//-------------------------------------- +datablock EffectProfile(GrenadeSwitchEffect) +{ + effectname = "weapons/generic_switch"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock EffectProfile(GrenadeFireEffect) +{ + effectname = "weapons/grenadelauncher_fire"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock EffectProfile(GrenadeDryFireEffect) +{ + effectname = "weapons/grenadelauncher_dryfire"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock EffectProfile(GrenadeReloadEffect) +{ + effectname = "weapons/generic_switch"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock EffectProfile(GrenadeExplosionEffect) +{ + effectname = "explosions/grenade_explode"; + minDistance = 10; + maxDistance = 35; +}; + +//-------------------------------------------------------------------------- +// Sounds +//-------------------------------------- +datablock AudioProfile(GrenadeSwitchSound) +{ + filename = "fx/weapons/generic_switch.wav"; + description = AudioClosest3d; + preload = true; + effect = GrenadeSwitchEffect; +}; + +datablock AudioProfile(GrenadeFireSound) +{ + filename = "fx/weapons/grenadelauncher_fire.wav"; + description = AudioDefault3d; + preload = true; + effect = GrenadeFireEffect; +}; + +datablock AudioProfile(GrenadeProjectileSound) +{ + filename = "fx/weapons/grenadelauncher_projectile.wav"; + description = ProjectileLooping3d; + preload = true; +}; + +datablock AudioProfile(GrenadeReloadSound) +{ + filename = "fx/weapons/generic_switch.wav"; + description = AudioClosest3d; + preload = true; + effect = GrenadeReloadEffect; +}; + +datablock AudioProfile(GrenadeExplosionSound) +{ + filename = "fx/weapons/grenade_explode.wav"; + description = AudioExplosion3d; + preload = true; + effect = GrenadeExplosionEffect; +}; + +datablock AudioProfile(UnderwaterGrenadeExplosionSound) +{ + filename = "fx/weapons/grenade_explode_UW.wav"; + description = AudioExplosion3d; + preload = true; + effect = GrenadeExplosionEffect; +}; + +datablock AudioProfile(GrenadeDryFireSound) +{ + filename = "fx/weapons/grenadelauncher_dryfire.wav"; + description = AudioClose3d; + preload = true; + effect = GrenadeDryFireEffect; +}; + +//---------------------------------------------------------------------------- +// Underwater fx +//---------------------------------------------------------------------------- +datablock ParticleData(GrenadeExplosionBubbleParticle) +{ + dragCoefficient = 0.0; + gravityCoefficient = -0.25; + inheritedVelFactor = 0.0; + constantAcceleration = 0.0; + lifetimeMS = 1500; + lifetimeVarianceMS = 600; + useInvAlpha = false; + textureName = "special/bubbles"; + + spinRandomMin = -100.0; + spinRandomMax = 100.0; + + colors[0] = "0.7 0.8 1.0 0.0"; + colors[1] = "0.7 0.8 1.0 0.4"; + colors[2] = "0.7 0.8 1.0 0.0"; + sizes[0] = 1.0; + sizes[1] = 1.0; + sizes[2] = 1.0; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; +}; +datablock ParticleEmitterData(GrenadeExplosionBubbleEmitter) +{ + ejectionPeriodMS = 5; + periodVarianceMS = 0; + ejectionVelocity = 1.0; + ejectionOffset = 3.0; + velocityVariance = 0.5; + thetaMin = 0; + thetaMax = 80; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + particles = "GrenadeExplosionBubbleParticle"; +}; + +datablock ParticleData(UnderwaterGrenadeDust) +{ + dragCoefficient = 1.0; + gravityCoefficient = -0.01; + inheritedVelFactor = 0.0; + constantAcceleration = -1.1; + lifetimeMS = 1000; + lifetimeVarianceMS = 100; + useInvAlpha = false; + spinRandomMin = -90.0; + spinRandomMax = 500.0; + textureName = "particleTest"; + colors[0] = "0.6 0.6 1.0 0.5"; + colors[1] = "0.6 0.6 1.0 0.5"; + colors[2] = "0.6 0.6 1.0 0.0"; + sizes[0] = 3.0; + sizes[1] = 3.0; + sizes[2] = 3.0; + times[0] = 0.0; + times[1] = 0.7; + times[2] = 1.0; +}; + +datablock ParticleEmitterData(UnderwaterGrenadeDustEmitter) +{ + ejectionPeriodMS = 15; + periodVarianceMS = 0; + ejectionVelocity = 15.0; + velocityVariance = 0.0; + ejectionOffset = 0.0; + thetaMin = 70; + thetaMax = 70; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + lifetimeMS = 250; + particles = "UnderwaterGrenadeDust"; +}; + + +datablock ParticleData(UnderwaterGrenadeExplosionSmoke) +{ + dragCoeffiecient = 0.4; + gravityCoefficient = -0.25; // rises slowly + inheritedVelFactor = 0.025; + constantAcceleration = -1.1; + + lifetimeMS = 1250; + lifetimeVarianceMS = 0; + + textureName = "particleTest"; + + useInvAlpha = false; + spinRandomMin = -200.0; + spinRandomMax = 200.0; + + textureName = "special/Smoke/smoke_001"; + + colors[0] = "0.1 0.1 1.0 1.0"; + colors[1] = "0.4 0.4 1.0 1.0"; + colors[2] = "0.4 0.4 1.0 0.0"; + sizes[0] = 2.0; + sizes[1] = 6.0; + sizes[2] = 2.0; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; + +}; + +datablock ParticleEmitterData(UnderwaterGExplosionSmokeEmitter) +{ + ejectionPeriodMS = 15; + periodVarianceMS = 0; + + ejectionVelocity = 6.25; + velocityVariance = 0.25; + + thetaMin = 0.0; + thetaMax = 90.0; + + lifetimeMS = 250; + + particles = "UnderwaterGrenadeExplosionSmoke"; +}; + + + +datablock ParticleData(UnderwaterGrenadeSparks) +{ + dragCoefficient = 1; + gravityCoefficient = 0.0; + inheritedVelFactor = 0.2; + constantAcceleration = 0.0; + lifetimeMS = 500; + lifetimeVarianceMS = 350; + textureName = "special/underwaterSpark"; + colors[0] = "0.6 0.6 1.0 1.0"; + colors[1] = "0.6 0.6 1.0 1.0"; + colors[2] = "0.6 0.6 1.0 0.0"; + sizes[0] = 0.5; + sizes[1] = 0.5; + sizes[2] = 0.75; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; + +}; + +datablock ParticleEmitterData(UnderwaterGrenadeSparksEmitter) +{ + 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 = "UnderwaterGrenadeSparks"; +}; + +datablock ExplosionData(UnderwaterGrenadeExplosion) +{ + soundProfile = UnderwaterGrenadeExplosionSound; + + faceViewer = true; + explosionScale = "0.8 0.8 0.8"; + + emitter[0] = UnderwaterGrenadeDustEmitter; + emitter[1] = UnderwaterGExplosionSmokeEmitter; + emitter[2] = UnderwaterGrenadeSparksEmitter; + emitter[3] = GrenadeExplosionBubbleEmitter; + + shakeCamera = true; + camShakeFreq = "10.0 6.0 9.0"; + camShakeAmp = "20.0 20.0 20.0"; + camShakeDuration = 0.5; + camShakeRadius = 20.0; +}; + + +//---------------------------------------------------------------------------- +// Bubbles +//---------------------------------------------------------------------------- +datablock ParticleData(GrenadeBubbleParticle) +{ + dragCoefficient = 0.0; + gravityCoefficient = -0.25; + inheritedVelFactor = 0.0; + constantAcceleration = 0.0; + lifetimeMS = 1500; + lifetimeVarianceMS = 600; + useInvAlpha = false; + textureName = "special/bubbles"; + + spinRandomMin = -100.0; + spinRandomMax = 100.0; + + colors[0] = "0.7 0.8 1.0 0.4"; + colors[1] = "0.7 0.8 1.0 0.4"; + colors[2] = "0.7 0.8 1.0 0.0"; + sizes[0] = 0.5; + sizes[1] = 0.5; + sizes[2] = 0.5; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; +}; + +datablock ParticleEmitterData(GrenadeBubbleEmitter) +{ + ejectionPeriodMS = 5; + periodVarianceMS = 0; + ejectionVelocity = 1.0; + ejectionOffset = 0.1; + velocityVariance = 0.5; + thetaMin = 0; + thetaMax = 80; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + particles = "GrenadeBubbleParticle"; +}; + +//---------------------------------------------------------------------------- +// Debris +//---------------------------------------------------------------------------- + +datablock ParticleData( GDebrisSmokeParticle ) +{ + dragCoeffiecient = 1.0; + gravityCoefficient = 0.0; + inheritedVelFactor = 0.2; + + lifetimeMS = 1000; + lifetimeVarianceMS = 100; + + textureName = "particleTest"; + + useInvAlpha = true; + + spinRandomMin = -60.0; + spinRandomMax = 60.0; + + colors[0] = "0.4 0.4 0.4 1.0"; + colors[1] = "0.3 0.3 0.3 0.5"; + colors[2] = "0.0 0.0 0.0 0.0"; + sizes[0] = 0.0; + sizes[1] = 1.0; + sizes[2] = 1.0; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; +}; + +datablock ParticleEmitterData( GDebrisSmokeEmitter ) +{ + ejectionPeriodMS = 7; + periodVarianceMS = 1; + + ejectionVelocity = 1.0; // A little oomph at the back end + velocityVariance = 0.2; + + thetaMin = 0.0; + thetaMax = 40.0; + + particles = "GDebrisSmokeParticle"; +}; + + +datablock DebrisData( GrenadeDebris ) +{ + emitters[0] = GDebrisSmokeEmitter; + + explodeOnMaxBounce = true; + + elasticity = 0.4; + friction = 0.2; + + lifetime = 0.3; + lifetimeVariance = 0.02; + + numBounces = 1; +}; + +//-------------------------------------------------------------------------- +// Splash +//-------------------------------------------------------------------------- + +datablock ParticleData( GrenadeSplashParticle ) +{ + dragCoefficient = 1; + gravityCoefficient = 0.0; + inheritedVelFactor = 0.2; + constantAcceleration = -1.4; + lifetimeMS = 300; + lifetimeVarianceMS = 0; + textureName = "special/droplet"; + colors[0] = "0.7 0.8 1.0 1.0"; + colors[1] = "0.7 0.8 1.0 0.5"; + colors[2] = "0.7 0.8 1.0 0.0"; + sizes[0] = 0.05; + sizes[1] = 0.2; + sizes[2] = 0.2; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; +}; + +datablock ParticleEmitterData( GrenadeSplashEmitter ) +{ + ejectionPeriodMS = 4; + periodVarianceMS = 0; + ejectionVelocity = 4; + velocityVariance = 1.0; + ejectionOffset = 0.0; + thetaMin = 0; + thetaMax = 50; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + orientParticles = true; + lifetimeMS = 100; + particles = "BlasterSplashParticle"; +}; + + +datablock SplashData(GrenadeSplash) +{ + numSegments = 15; + ejectionFreq = 15; + ejectionAngle = 40; + ringLifetime = 0.35; + lifetimeMS = 300; + velocity = 3.0; + startRadius = 0.0; + acceleration = -3.0; + texWrap = 5.0; + + texture = "special/water2"; + + emitter[0] = BlasterSplashEmitter; + + colors[0] = "0.7 0.8 1.0 1.0"; + colors[1] = "0.7 0.8 1.0 1.0"; + colors[2] = "0.7 0.8 1.0 1.0"; + colors[3] = "0.7 0.8 1.0 1.0"; + times[0] = 0.0; + times[1] = 0.4; + times[2] = 0.8; + times[3] = 1.0; +}; + +//-------------------------------------------------------------------------- +// Particle effects +//-------------------------------------- +datablock ParticleData(GrenadeSmokeParticle) +{ + dragCoeffiecient = 0.0; + gravityCoefficient = -0.2; // rises slowly + inheritedVelFactor = 0.00; + + lifetimeMS = 700; // lasts 2 second + lifetimeVarianceMS = 150; // ...more or less + + textureName = "particleTest"; + + useInvAlpha = true; + spinRandomMin = -30.0; + spinRandomMax = 30.0; + + colors[0] = "0.9 0.9 0.9 1.0"; + colors[1] = "0.6 0.6 0.6 1.0"; + colors[2] = "0.4 0.4 0.4 0.0"; + + sizes[0] = 0.25; + sizes[1] = 1.0; + sizes[2] = 3.0; + + times[0] = 0.0; + times[1] = 0.2; + times[2] = 1.0; +}; + +datablock ParticleEmitterData(GrenadeSmokeEmitter) +{ + ejectionPeriodMS = 15; + periodVarianceMS = 5; + + ejectionVelocity = 1.25; + velocityVariance = 0.50; + + thetaMin = 0.0; + thetaMax = 90.0; + + particles = "GrenadeSmokeParticle"; +}; + + +datablock ParticleData(GrenadeDust) +{ + dragCoefficient = 1.0; + gravityCoefficient = -0.01; + inheritedVelFactor = 0.0; + constantAcceleration = 0.0; + lifetimeMS = 1000; + lifetimeVarianceMS = 100; + useInvAlpha = true; + spinRandomMin = -90.0; + spinRandomMax = 500.0; + textureName = "particleTest"; + colors[0] = "0.3 0.3 0.3 0.5"; + colors[1] = "0.3 0.3 0.3 0.5"; + colors[2] = "0.3 0.3 0.3 0.0"; + sizes[0] = 3.2; + sizes[1] = 4.6; + sizes[2] = 5.0; + times[0] = 0.0; + times[1] = 0.7; + times[2] = 1.0; +}; + +datablock ParticleEmitterData(GrenadeDustEmitter) +{ + ejectionPeriodMS = 5; + periodVarianceMS = 0; + ejectionVelocity = 15.0; + velocityVariance = 0.0; + ejectionOffset = 0.0; + thetaMin = 85; + thetaMax = 85; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + lifetimeMS = 250; + particles = "GrenadeDust"; +}; + + +datablock ParticleData(GrenadeExplosionSmoke) +{ + dragCoeffiecient = 0.4; + gravityCoefficient = -0.5; // rises slowly + inheritedVelFactor = 0.025; + + lifetimeMS = 1250; + lifetimeVarianceMS = 0; + + textureName = "particleTest"; + + useInvAlpha = true; + spinRandomMin = -200.0; + spinRandomMax = 200.0; + + textureName = "special/Smoke/smoke_001"; + + colors[0] = "0.7 0.7 0.7 1.0"; + colors[1] = "0.2 0.2 0.2 1.0"; + colors[2] = "0.1 0.1 0.1 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(GExplosionSmokeEmitter) +{ + ejectionPeriodMS = 5; + periodVarianceMS = 0; + + ejectionVelocity = 6.25; + velocityVariance = 0.25; + + thetaMin = 0.0; + thetaMax = 90.0; + + lifetimeMS = 250; + + particles = "GrenadeExplosionSmoke"; +}; + + + +datablock ParticleData(GrenadeSparks) +{ + dragCoefficient = 1; + gravityCoefficient = 0.0; + inheritedVelFactor = 0.2; + constantAcceleration = 0.0; + lifetimeMS = 500; + lifetimeVarianceMS = 350; + textureName = "special/bigspark"; + colors[0] = "0.56 0.36 0.26 1.0"; + colors[1] = "0.56 0.36 0.26 1.0"; + colors[2] = "1.0 0.36 0.26 0.0"; + sizes[0] = 0.5; + sizes[1] = 0.5; + sizes[2] = 0.75; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; + +}; + +datablock ParticleEmitterData(GrenadeSparksEmitter) +{ + 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 = "GrenadeSparks"; +}; + + + + +//---------------------------------------------------- +// Explosion +//---------------------------------------------------- +datablock ExplosionData(GrenadeExplosion) +{ + soundProfile = GrenadeExplosionSound; + + faceViewer = true; + explosionScale = "0.8 0.8 0.8"; + + debris = GrenadeDebris; + debrisThetaMin = 10; + debrisThetaMax = 50; + debrisNum = 8; + debrisVelocity = 26.0; + debrisVelocityVariance = 7.0; + + emitter[0] = GrenadeDustEmitter; + emitter[1] = GExplosionSmokeEmitter; + emitter[2] = GrenadeSparksEmitter; + + shakeCamera = true; + camShakeFreq = "10.0 6.0 9.0"; + camShakeAmp = "20.0 20.0 20.0"; + camShakeDuration = 0.5; + camShakeRadius = 20.0; +}; + +//-------------------------------------------------------------------------- +// Projectile +//-------------------------------------- +datablock GrenadeProjectileData(BasicGrenade) +{ + projectileShapeName = "grenade_projectile.dts"; + emitterDelay = -1; + directDamage = 0.0; + hasDamageRadius = true; + indirectDamage = 0.40; + damageRadius = 15.0; + radiusDamageType = $DamageType::Grenade; + kickBackStrength = 1500; + bubbleEmitTime = 1.0; + + sound = GrenadeProjectileSound; + explosion = "GrenadeExplosion"; + underwaterExplosion = "UnderwaterGrenadeExplosion"; + velInheritFactor = 0.85; // z0dd - ZOD, 3/30/02. Was 0.5 + splash = GrenadeSplash; + + baseEmitter = GrenadeSmokeEmitter; + bubbleEmitter = GrenadeBubbleEmitter; + + grenadeElasticity = 0.30; // z0dd - ZOD, 9/13/02. Was 0.35 + grenadeFriction = 0.2; + armingDelayMS = 650; // z0dd - ZOD, 9/13/02. Was 1000 + muzzleVelocity = 75.00; // z0dd - ZOD, 3/30/02. GL projectile is faster. Was 47.00 + //drag = 0.1; // z0dd - ZOD, 3/30/02. No drag. + gravityMod = 1.9; // z0dd - ZOD, 5/18/02. Make GL projectile heavier, less floaty +}; + + +//-------------------------------------------------------------------------- +// Ammo +//-------------------------------------- + +datablock ItemData(GrenadeLauncherAmmo) +{ + className = Ammo; + catagory = "Ammo"; + shapeFile = "ammo_grenade.dts"; + mass = 1; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 2; + pickUpName = "some grenade launcher ammo"; + + computeCRC = true; + emap = true; +}; + +//-------------------------------------------------------------------------- +// Weapon +//-------------------------------------- +datablock ItemData(GrenadeLauncher) +{ + className = Weapon; + catagory = "Spawn Items"; + shapeFile = "weapon_grenade_launcher.dts"; + image = GrenadeLauncherImage; + mass = 1; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 2; + pickUpName = "a grenade launcher"; + + computeCRC = true; + +}; + +datablock ShapeBaseImageData(GrenadeLauncherImage) +{ + className = WeaponImage; + shapeFile = "weapon_grenade_launcher.dts"; + item = GrenadeLauncher; + ammo = GrenadeLauncherAmmo; + offset = "0 0 0"; + emap = true; + + projectile = BasicGrenade; + projectileType = GrenadeProjectile; + + stateName[0] = "Activate"; + stateTransitionOnTimeout[0] = "ActivateReady"; + stateTimeoutValue[0] = 0.5; + stateSequence[0] = "Activate"; + stateSound[0] = GrenadeSwitchSound; + + stateName[1] = "ActivateReady"; + stateTransitionOnLoaded[1] = "Ready"; + stateTransitionOnNoAmmo[1] = "NoAmmo"; + + stateName[2] = "Ready"; + stateTransitionOnNoAmmo[2] = "NoAmmo"; + stateTransitionOnTriggerDown[2] = "Fire"; + + stateName[3] = "Fire"; + stateTransitionOnTimeout[3] = "Reload"; + stateTimeoutValue[3] = 0.4; + stateFire[3] = true; + stateRecoil[3] = LightRecoil; + stateAllowImageChange[3] = false; + stateSequence[3] = "Fire"; + stateScript[3] = "onFire"; + stateSound[3] = GrenadeFireSound; + + stateName[4] = "Reload"; + stateTransitionOnNoAmmo[4] = "NoAmmo"; + stateTransitionOnTimeout[4] = "Ready"; + stateTimeoutValue[4] = 0.5; + stateAllowImageChange[4] = false; + stateSequence[4] = "Reload"; + stateSound[4] = GrenadeReloadSound; + + stateName[5] = "NoAmmo"; + stateTransitionOnAmmo[5] = "Reload"; + stateSequence[5] = "NoAmmo"; + stateTransitionOnTriggerDown[5] = "DryFire"; + + stateName[6] = "DryFire"; + stateSound[6] = GrenadeDryFireSound; + stateTimeoutValue[6] = 1.5; + stateTransitionOnTimeout[6] = "NoAmmo"; +}; diff --git a/scripts/weapons/mine.cs b/scripts/weapons/mine.cs index aae0e58..9bc72a4 100644 --- a/scripts/weapons/mine.cs +++ b/scripts/weapons/mine.cs @@ -1,340 +1,340 @@ -// ---------------------------------------------- -// mine script -// ---------------------------------------------- - -$TeamDeployableMax[MineDeployed] = 25; // z0dd - ZOD, 6/10/02. Was 20. - -// ---------------------------------------------- -// force-feedback datablocks -// ---------------------------------------------- - -datablock EffectProfile(MineExplosionEffect) -{ - effectname = "explosions/mine_detonate"; - minDistance = 10; - maxDistance = 50; -}; - -// ---------------------------------------------- -// audio datablocks -// ---------------------------------------------- - -datablock AudioProfile(MineDeploySound) -{ - filename = "fx/weapons/mine_deploy.wav"; - description = AudioClose3D; - preload = true; -}; - -datablock AudioProfile(MineExplosionSound) -{ - filename = "fx/weapons/mine_detonate.wav"; - description = AudioBIGExplosion3d; - preload = true; - effect = MineExplosionEffect; -}; - -datablock AudioProfile(UnderwaterMineExplosionSound) -{ - filename = "fx/weapons/mine_detonate_UW.wav"; - description = AudioBIGExplosion3d; - preload = true; - effect = MineExplosionEffect; -}; - -//-------------------------------------------------------------------------- -// Mine Particle effects -//-------------------------------------------------------------------------- -datablock ParticleData(MineExplosionBubbleParticle) -{ - dragCoefficient = 0.0; - gravityCoefficient = -0.25; - inheritedVelFactor = 0.0; - constantAcceleration = 0.0; - lifetimeMS = 2000; - lifetimeVarianceMS = 750; - useInvAlpha = false; - textureName = "special/bubbles"; - - spinRandomMin = -100.0; - spinRandomMax = 100.0; - - colors[0] = "0.7 0.8 1.0 0.0"; - colors[1] = "0.7 0.8 1.0 0.4"; - colors[2] = "0.7 0.8 1.0 0.0"; - sizes[0] = 1.0; - sizes[1] = 1.0; - sizes[2] = 1.0; - times[0] = 0.0; - times[1] = 0.3; - times[2] = 1.0; -}; -datablock ParticleEmitterData(MineExplosionBubbleEmitter) -{ - ejectionPeriodMS = 7; - periodVarianceMS = 0; - ejectionVelocity = 1.0; - ejectionOffset = 2.0; - velocityVariance = 0.5; - thetaMin = 0; - thetaMax = 80; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - particles = "MineExplosionBubbleParticle"; -}; -datablock ParticleData( UnderwaterMineCrescentParticle ) -{ - dragCoefficient = 2; - gravityCoefficient = 0.0; - inheritedVelFactor = 0.2; - constantAcceleration = -0.0; - lifetimeMS = 600; - lifetimeVarianceMS = 000; - textureName = "special/crescent3"; - colors[0] = "0.5 0.5 1.0 1.0"; - colors[1] = "0.5 0.5 1.0 1.0"; - colors[2] = "0.5 0.5 1.0 0.0"; - sizes[0] = 0.5; - sizes[1] = 1.0; - sizes[2] = 2.0; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData( UnderwaterMineCrescentEmitter ) -{ - ejectionPeriodMS = 10; - periodVarianceMS = 0; - ejectionVelocity = 10; - velocityVariance = 5.0; - ejectionOffset = 0.0; - thetaMin = 0; - thetaMax = 80; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - orientParticles = true; - lifetimeMS = 200; - particles = "UnderwaterMineCrescentParticle"; -}; - -datablock ParticleData(UnderwaterMineExplosionSmoke) -{ - dragCoeffiecient = 105.0; - gravityCoefficient = -0.0; - inheritedVelFactor = 0.025; - constantAcceleration = -1.0; - - lifetimeMS = 1200; - lifetimeVarianceMS = 00; - - textureName = "particleTest"; - - useInvAlpha = false; - spinRandomMin = -200.0; - spinRandomMax = 200.0; - - textureName = "special/Smoke/smoke_001"; - - colors[0] = "0.7 0.7 1.0 1.0"; - colors[1] = "0.3 0.3 1.0 1.0"; - colors[2] = "0.0 0.0 1.0 0.0"; - sizes[0] = 1.0; - sizes[1] = 3.0; - sizes[2] = 1.0; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - -}; - -datablock ParticleEmitterData(UnderwaterMineExplosionSmokeEmitter) -{ - ejectionPeriodMS = 8; - periodVarianceMS = 0; - - ejectionVelocity = 4.25; - velocityVariance = 1.25; - - thetaMin = 0.0; - thetaMax = 80.0; - - lifetimeMS = 250; - - particles = "UnderwaterMineExplosionSmoke"; -}; - -datablock ExplosionData(UnderwaterMineExplosion) -{ - explosionShape = "disc_explosion.dts"; - playSpeed = 1.0; - sizes[0] = "0.4 0.4 0.4"; - sizes[1] = "0.4 0.4 0.4"; - soundProfile = UnderwaterMineExplosionSound; - faceViewer = true; - - emitter[0] = UnderwaterMineExplosionSmokeEmitter; - emitter[1] = UnderwaterMineCrescentEmitter; - emitter[2] = MineExplosionBubbleEmitter; - - shakeCamera = true; - camShakeFreq = "8.0 7.0 9.0"; - camShakeAmp = "50.0 50.0 50.0"; - camShakeDuration = 1.0; - camShakeRadius = 10.0; -}; - -//-------------------------------------------------------------------------- -// Mine Particle effects -//-------------------------------------------------------------------------- -datablock ParticleData( MineCrescentParticle ) -{ - dragCoefficient = 2; - gravityCoefficient = 0.0; - inheritedVelFactor = 0.2; - constantAcceleration = -0.0; - lifetimeMS = 600; - lifetimeVarianceMS = 000; - textureName = "special/crescent3"; - colors[0] = "1.0 0.8 0.2 1.0"; - colors[1] = "1.0 0.4 0.2 1.0"; - colors[2] = "1.0 0.0 0.0 0.0"; - sizes[0] = 0.5; - sizes[1] = 1.0; - sizes[2] = 2.0; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData( MineCrescentEmitter ) -{ - ejectionPeriodMS = 10; - periodVarianceMS = 0; - ejectionVelocity = 10; - velocityVariance = 5.0; - ejectionOffset = 0.0; - thetaMin = 0; - thetaMax = 80; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - orientParticles = true; - lifetimeMS = 200; - particles = "MineCrescentParticle"; -}; - -datablock ParticleData(MineExplosionSmoke) -{ - dragCoeffiecient = 105.0; - gravityCoefficient = -0.0; - inheritedVelFactor = 0.025; - - lifetimeMS = 1200; - lifetimeVarianceMS = 00; - - textureName = "particleTest"; - - useInvAlpha = true; - spinRandomMin = -200.0; - spinRandomMax = 200.0; - - textureName = "special/Smoke/smoke_001"; - - colors[0] = "1.0 0.7 0.0 1.0"; - colors[1] = "0.2 0.2 0.2 1.0"; - colors[2] = "0.0 0.0 0.0 0.0"; - sizes[0] = 1.0; - sizes[1] = 3.0; - sizes[2] = 1.0; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - -}; - -datablock ParticleEmitterData(MineExplosionSmokeEmitter) -{ - ejectionPeriodMS = 8; - periodVarianceMS = 0; - - ejectionVelocity = 4.25; - velocityVariance = 1.25; - - thetaMin = 0.0; - thetaMax = 80.0; - - lifetimeMS = 250; - - particles = "MineExplosionSmoke"; -}; - - - -datablock ExplosionData(MineExplosion) -{ - explosionShape = "effect_plasma_explosion.dts"; - playSpeed = 1.0; - sizes[0] = "0.5 0.5 0.5"; - sizes[1] = "0.5 0.5 0.5"; - soundProfile = MineExplosionSound; - faceViewer = true; - - emitter[0] = MineExplosionSmokeEmitter; - emitter[1] = MineCrescentEmitter; - - shakeCamera = true; - camShakeFreq = "8.0 7.0 9.0"; - camShakeAmp = "50.0 50.0 50.0"; - camShakeDuration = 1.0; - camShakeRadius = 10.0; -}; - -// ---------------------------------------------- -// Item datablocks -// ---------------------------------------------- - -datablock ItemData(MineDeployed) -{ - className = Weapon; - shapeFile = "mine.dts"; - mass = 0.75; - elasticity = 0.2; - friction = 0.8; // z0dd - ZOD, 9/27/03. was 0.6 - pickupRadius = 3; - maxDamage = 0.01; // z0dd - ZOD, 9/27/03. was 0.2 - explosion = MineExplosion; - underwaterExplosion = UnderwaterMineExplosion; - indirectDamage = 0.57; // z0dd - ZOD, 7/14/03. Slight increase to dmg. Was 0.55 - damageRadius = 10.0; // z0dd - ZOD, 7/14/03. Slight increase to det range. Was 6.0 - radiusDamageType = $DamageType::Mine; - kickBackStrength = 1500; - aiAvoidThis = true; - dynamicType = $TypeMasks::DamagableItemObjectType; - spacing = 6.0; // how close together mines can be - proximity = 2.5; // how close causes a detonation (by player/vehicle) - armTime = 2200; // 2.2 seconds to arm a mine after it comes to rest - maxDepCount = 5; // try to deploy this many times before detonating. // z0dd - ZOD, 9/27/02. Was 9 - - computeCRC = true; - -}; - -datablock ItemData(Mine) -{ - className = HandInventory; - catagory = "Handheld"; - shapeFile = "ammo_mine.dts"; - mass = 1; - elasticity = 0.2; - friction = 0.7; - pickupRadius = 2; - - thrownItem = MineDeployed; - pickUpName = "some mines"; - - computeCRC = true; -}; - +// ---------------------------------------------- +// mine script +// ---------------------------------------------- + +$TeamDeployableMax[MineDeployed] = 25; // z0dd - ZOD, 6/10/02. Was 20. + +// ---------------------------------------------- +// force-feedback datablocks +// ---------------------------------------------- + +datablock EffectProfile(MineExplosionEffect) +{ + effectname = "explosions/mine_detonate"; + minDistance = 10; + maxDistance = 50; +}; + +// ---------------------------------------------- +// audio datablocks +// ---------------------------------------------- + +datablock AudioProfile(MineDeploySound) +{ + filename = "fx/weapons/mine_deploy.wav"; + description = AudioClose3D; + preload = true; +}; + +datablock AudioProfile(MineExplosionSound) +{ + filename = "fx/weapons/mine_detonate.wav"; + description = AudioBIGExplosion3d; + preload = true; + effect = MineExplosionEffect; +}; + +datablock AudioProfile(UnderwaterMineExplosionSound) +{ + filename = "fx/weapons/mine_detonate_UW.wav"; + description = AudioBIGExplosion3d; + preload = true; + effect = MineExplosionEffect; +}; + +//-------------------------------------------------------------------------- +// Mine Particle effects +//-------------------------------------------------------------------------- +datablock ParticleData(MineExplosionBubbleParticle) +{ + dragCoefficient = 0.0; + gravityCoefficient = -0.25; + inheritedVelFactor = 0.0; + constantAcceleration = 0.0; + lifetimeMS = 2000; + lifetimeVarianceMS = 750; + useInvAlpha = false; + textureName = "special/bubbles"; + + spinRandomMin = -100.0; + spinRandomMax = 100.0; + + colors[0] = "0.7 0.8 1.0 0.0"; + colors[1] = "0.7 0.8 1.0 0.4"; + colors[2] = "0.7 0.8 1.0 0.0"; + sizes[0] = 1.0; + sizes[1] = 1.0; + sizes[2] = 1.0; + times[0] = 0.0; + times[1] = 0.3; + times[2] = 1.0; +}; +datablock ParticleEmitterData(MineExplosionBubbleEmitter) +{ + ejectionPeriodMS = 7; + periodVarianceMS = 0; + ejectionVelocity = 1.0; + ejectionOffset = 2.0; + velocityVariance = 0.5; + thetaMin = 0; + thetaMax = 80; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + particles = "MineExplosionBubbleParticle"; +}; +datablock ParticleData( UnderwaterMineCrescentParticle ) +{ + dragCoefficient = 2; + gravityCoefficient = 0.0; + inheritedVelFactor = 0.2; + constantAcceleration = -0.0; + lifetimeMS = 600; + lifetimeVarianceMS = 000; + textureName = "special/crescent3"; + colors[0] = "0.5 0.5 1.0 1.0"; + colors[1] = "0.5 0.5 1.0 1.0"; + colors[2] = "0.5 0.5 1.0 0.0"; + sizes[0] = 0.5; + sizes[1] = 1.0; + sizes[2] = 2.0; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; +}; + +datablock ParticleEmitterData( UnderwaterMineCrescentEmitter ) +{ + ejectionPeriodMS = 10; + periodVarianceMS = 0; + ejectionVelocity = 10; + velocityVariance = 5.0; + ejectionOffset = 0.0; + thetaMin = 0; + thetaMax = 80; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + orientParticles = true; + lifetimeMS = 200; + particles = "UnderwaterMineCrescentParticle"; +}; + +datablock ParticleData(UnderwaterMineExplosionSmoke) +{ + dragCoeffiecient = 105.0; + gravityCoefficient = -0.0; + inheritedVelFactor = 0.025; + constantAcceleration = -1.0; + + lifetimeMS = 1200; + lifetimeVarianceMS = 00; + + textureName = "particleTest"; + + useInvAlpha = false; + spinRandomMin = -200.0; + spinRandomMax = 200.0; + + textureName = "special/Smoke/smoke_001"; + + colors[0] = "0.7 0.7 1.0 1.0"; + colors[1] = "0.3 0.3 1.0 1.0"; + colors[2] = "0.0 0.0 1.0 0.0"; + sizes[0] = 1.0; + sizes[1] = 3.0; + sizes[2] = 1.0; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; + +}; + +datablock ParticleEmitterData(UnderwaterMineExplosionSmokeEmitter) +{ + ejectionPeriodMS = 8; + periodVarianceMS = 0; + + ejectionVelocity = 4.25; + velocityVariance = 1.25; + + thetaMin = 0.0; + thetaMax = 80.0; + + lifetimeMS = 250; + + particles = "UnderwaterMineExplosionSmoke"; +}; + +datablock ExplosionData(UnderwaterMineExplosion) +{ + explosionShape = "disc_explosion.dts"; + playSpeed = 1.0; + sizes[0] = "0.4 0.4 0.4"; + sizes[1] = "0.4 0.4 0.4"; + soundProfile = UnderwaterMineExplosionSound; + faceViewer = true; + + emitter[0] = UnderwaterMineExplosionSmokeEmitter; + emitter[1] = UnderwaterMineCrescentEmitter; + emitter[2] = MineExplosionBubbleEmitter; + + shakeCamera = true; + camShakeFreq = "8.0 7.0 9.0"; + camShakeAmp = "50.0 50.0 50.0"; + camShakeDuration = 1.0; + camShakeRadius = 10.0; +}; + +//-------------------------------------------------------------------------- +// Mine Particle effects +//-------------------------------------------------------------------------- +datablock ParticleData( MineCrescentParticle ) +{ + dragCoefficient = 2; + gravityCoefficient = 0.0; + inheritedVelFactor = 0.2; + constantAcceleration = -0.0; + lifetimeMS = 600; + lifetimeVarianceMS = 000; + textureName = "special/crescent3"; + colors[0] = "1.0 0.8 0.2 1.0"; + colors[1] = "1.0 0.4 0.2 1.0"; + colors[2] = "1.0 0.0 0.0 0.0"; + sizes[0] = 0.5; + sizes[1] = 1.0; + sizes[2] = 2.0; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; +}; + +datablock ParticleEmitterData( MineCrescentEmitter ) +{ + ejectionPeriodMS = 10; + periodVarianceMS = 0; + ejectionVelocity = 10; + velocityVariance = 5.0; + ejectionOffset = 0.0; + thetaMin = 0; + thetaMax = 80; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + orientParticles = true; + lifetimeMS = 200; + particles = "MineCrescentParticle"; +}; + +datablock ParticleData(MineExplosionSmoke) +{ + dragCoeffiecient = 105.0; + gravityCoefficient = -0.0; + inheritedVelFactor = 0.025; + + lifetimeMS = 1200; + lifetimeVarianceMS = 00; + + textureName = "particleTest"; + + useInvAlpha = true; + spinRandomMin = -200.0; + spinRandomMax = 200.0; + + textureName = "special/Smoke/smoke_001"; + + colors[0] = "1.0 0.7 0.0 1.0"; + colors[1] = "0.2 0.2 0.2 1.0"; + colors[2] = "0.0 0.0 0.0 0.0"; + sizes[0] = 1.0; + sizes[1] = 3.0; + sizes[2] = 1.0; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; + +}; + +datablock ParticleEmitterData(MineExplosionSmokeEmitter) +{ + ejectionPeriodMS = 8; + periodVarianceMS = 0; + + ejectionVelocity = 4.25; + velocityVariance = 1.25; + + thetaMin = 0.0; + thetaMax = 80.0; + + lifetimeMS = 250; + + particles = "MineExplosionSmoke"; +}; + + + +datablock ExplosionData(MineExplosion) +{ + explosionShape = "effect_plasma_explosion.dts"; + playSpeed = 1.0; + sizes[0] = "0.5 0.5 0.5"; + sizes[1] = "0.5 0.5 0.5"; + soundProfile = MineExplosionSound; + faceViewer = true; + + emitter[0] = MineExplosionSmokeEmitter; + emitter[1] = MineCrescentEmitter; + + shakeCamera = true; + camShakeFreq = "8.0 7.0 9.0"; + camShakeAmp = "50.0 50.0 50.0"; + camShakeDuration = 1.0; + camShakeRadius = 10.0; +}; + +// ---------------------------------------------- +// Item datablocks +// ---------------------------------------------- + +datablock ItemData(MineDeployed) +{ + className = Weapon; + shapeFile = "mine.dts"; + mass = 0.75; + elasticity = 0.2; + friction = 0.8; // z0dd - ZOD, 9/27/03. was 0.6 + pickupRadius = 3; + maxDamage = 0.01; // z0dd - ZOD, 9/27/03. was 0.2 + explosion = MineExplosion; + underwaterExplosion = UnderwaterMineExplosion; + indirectDamage = 0.57; // z0dd - ZOD, 7/14/03. Slight increase to dmg. Was 0.55 + damageRadius = 10.0; // z0dd - ZOD, 7/14/03. Slight increase to det range. Was 6.0 + radiusDamageType = $DamageType::Mine; + kickBackStrength = 1500; + aiAvoidThis = true; + dynamicType = $TypeMasks::DamagableItemObjectType; + spacing = 6.0; // how close together mines can be + proximity = 2.5; // how close causes a detonation (by player/vehicle) + armTime = 2200; // 2.2 seconds to arm a mine after it comes to rest + maxDepCount = 5; // try to deploy this many times before detonating. // z0dd - ZOD, 9/27/02. Was 9 + + computeCRC = true; + +}; + +datablock ItemData(Mine) +{ + className = HandInventory; + catagory = "Handheld"; + shapeFile = "ammo_mine.dts"; + mass = 1; + elasticity = 0.2; + friction = 0.7; + pickupRadius = 2; + + thrownItem = MineDeployed; + pickUpName = "some mines"; + + computeCRC = true; +}; + diff --git a/scripts/weapons/missileLauncher.cs b/scripts/weapons/missileLauncher.cs index d6f413f..a09fef2 100644 --- a/scripts/weapons/missileLauncher.cs +++ b/scripts/weapons/missileLauncher.cs @@ -1,795 +1,795 @@ -//-------------------------------------- -// Missile launcher -//-------------------------------------- - -//-------------------------------------------------------------------------- -// Force-Feedback Effects -//-------------------------------------- -datablock EffectProfile(MissileSwitchEffect) -{ - effectname = "weapons/missile_launcher_activate"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(MissileFireEffect) -{ - effectname = "weapons/missile_fire"; - minDistance = 2.5; - maxDistance = 5.0; -}; - -datablock EffectProfile(MissileDryFireEffect) -{ - effectname = "weapons/missile_launcher_dryfire"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(MissileExplosionEffect) -{ - effectname = "explosions/explosion.xpl23"; - minDistance = 10; - maxDistance = 30; -}; - -//-------------------------------------------------------------------------- -// Sounds -//-------------------------------------- -datablock AudioProfile(MissileSwitchSound) -{ - filename = "fx/weapons/missile_launcher_activate.wav"; - description = AudioClosest3d; - preload = true; - effect = MissileSwitchEffect; -}; - -datablock AudioProfile(MissileFireSound) -{ - filename = "fx/weapons/missile_fire.WAV"; - description = AudioDefault3d; - preload = true; - effect = MissileFireEffect; -}; - -datablock AudioProfile(MissileProjectileSound) -{ - filename = "fx/weapons/missile_projectile.wav"; - description = ProjectileLooping3d; - preload = true; -}; - -datablock AudioProfile(MissileReloadSound) -{ - filename = "fx/weapons/weapon.missilereload.wav"; - description = AudioClosest3d; - preload = true; -}; - -datablock AudioProfile(MissileLockSound) -{ - filename = "fx/weapons/missile_launcher_searching.WAV"; - description = AudioClosest3d; - preload = true; -}; - -datablock AudioProfile(MissileExplosionSound) -{ - filename = "fx/explosions/explosion.xpl23.wav"; - description = AudioBIGExplosion3d; - preload = true; - effect = MissileExplosionEffect; -}; - -datablock AudioProfile(MissileDryFireSound) -{ - filename = "fx/weapons/missile_launcher_dryfire.wav"; - description = AudioClose3d; - preload = true; - effect = MissileDryFireEffect; -}; - - -//---------------------------------------------------------------------------- -// Splash Debris -//---------------------------------------------------------------------------- -datablock ParticleData( MDebrisSmokeParticle ) -{ - dragCoeffiecient = 1.0; - gravityCoefficient = 0.10; - inheritedVelFactor = 0.1; - - lifetimeMS = 1000; - lifetimeVarianceMS = 100; - - textureName = "particleTest"; - -// useInvAlpha = true; - - spinRandomMin = -60.0; - spinRandomMax = 60.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.0; - sizes[1] = 0.8; - sizes[2] = 0.8; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData( MDebrisSmokeEmitter ) -{ - ejectionPeriodMS = 10; - periodVarianceMS = 1; - - ejectionVelocity = 1.0; // A little oomph at the back end - velocityVariance = 0.2; - - thetaMin = 0.0; - thetaMax = 40.0; - - particles = "MDebrisSmokeParticle"; -}; - - -datablock DebrisData( MissileSplashDebris ) -{ - emitters[0] = MDebrisSmokeEmitter; - - explodeOnMaxBounce = true; - - elasticity = 0.4; - friction = 0.2; - - lifetime = 0.3; - lifetimeVariance = 0.1; - - numBounces = 1; -}; - - -//---------------------------------------------------------------------------- -// Missile smoke spike (for debris) -//---------------------------------------------------------------------------- -datablock ParticleData( MissileSmokeSpike ) -{ - dragCoeffiecient = 1.0; - gravityCoefficient = 0.0; - inheritedVelFactor = 0.2; - - lifetimeMS = 1000; - lifetimeVarianceMS = 100; - - textureName = "particleTest"; - - useInvAlpha = true; - - spinRandomMin = -60.0; - spinRandomMax = 60.0; - - colors[0] = "0.6 0.6 0.6 1.0"; - colors[1] = "0.4 0.4 0.4 0.5"; - colors[2] = "0.4 0.4 0.4 0.0"; - sizes[0] = 0.0; - sizes[1] = 1.0; - sizes[2] = 0.5; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData( MissileSmokeSpikeEmitter ) -{ - ejectionPeriodMS = 7; - periodVarianceMS = 1; - - ejectionVelocity = 1.0; // A little oomph at the back end - velocityVariance = 0.2; - - thetaMin = 0.0; - thetaMax = 40.0; - - particles = "MissileSmokeSpike"; -}; - - -//---------------------------------------------------------------------------- -// Explosion smoke particles -//---------------------------------------------------------------------------- - -datablock ParticleData(MissileExplosionSmoke) -{ - dragCoeffiecient = 0.3; - gravityCoefficient = -0.2; - inheritedVelFactor = 0.025; - - lifetimeMS = 1250; - lifetimeVarianceMS = 0; - - textureName = "particleTest"; - - useInvAlpha = true; - spinRandomMin = -100.0; - spinRandomMax = 100.0; - - textureName = "special/Smoke/bigSmoke"; - - colors[0] = "1.0 0.7 0.0 1.0"; - colors[1] = "0.4 0.4 0.4 0.5"; - colors[2] = "0.4 0.4 0.4 0.0"; - sizes[0] = 1.0; - sizes[1] = 3.0; - sizes[2] = 1.0; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - -}; - -datablock ParticleEmitterData(MissileExplosionSmokeEMitter) -{ - ejectionOffset = 0.0; - ejectionPeriodMS = 5; - periodVarianceMS = 0; - - ejectionVelocity = 3.25; - velocityVariance = 0.25; - - thetaMin = 0.0; - thetaMax = 180.0; - - lifetimeMS = 250; - - particles = "MissileExplosionSmoke"; -}; - - - -datablock DebrisData( MissileSpikeDebris ) -{ - emitters[0] = MissileSmokeSpikeEmitter; - explodeOnMaxBounce = true; - elasticity = 0.4; - friction = 0.2; - lifetime = 0.3; - lifetimeVariance = 0.02; -}; - - -//--------------------------------------------------------------------------- -// Explosions -//--------------------------------------------------------------------------- -datablock ExplosionData(MissileExplosion) -{ - explosionShape = "effect_plasma_explosion.dts"; - playSpeed = 1.5; - soundProfile = MissileExplosionSound; - faceViewer = true; - - sizes[0] = "0.5 0.5 0.5"; - sizes[1] = "0.5 0.5 0.5"; - sizes[2] = "0.5 0.5 0.5"; - - emitter[0] = MissileExplosionSmokeEmitter; - - debris = MissileSpikeDebris; - debrisThetaMin = 10; - debrisThetaMax = 170; - debrisNum = 8; - debrisNumVariance = 6; - debrisVelocity = 15.0; - debrisVelocityVariance = 2.0; - - shakeCamera = true; - camShakeFreq = "6.0 7.0 7.0"; - camShakeAmp = "70.0 70.0 70.0"; - camShakeDuration = 1.0; - camShakeRadius = 7.0; -}; - - - -datablock ExplosionData(MissileSplashExplosion) -{ - explosionShape = "disc_explosion.dts"; - - faceViewer = true; - explosionScale = "1.0 1.0 1.0"; - - debris = MissileSplashDebris; - debrisThetaMin = 10; - debrisThetaMax = 80; - debrisNum = 10; - debrisVelocity = 10.0; - debrisVelocityVariance = 4.0; - - sizes[0] = "0.35 0.35 0.35"; - sizes[1] = "0.15 0.15 0.15"; - sizes[2] = "0.15 0.15 0.15"; - sizes[3] = "0.15 0.15 0.15"; - - times[0] = 0.0; - times[1] = 0.333; - times[2] = 0.666; - times[3] = 1.0; - -}; - - -//-------------------------------------------------------------------------- -// Splash -//-------------------------------------------------------------------------- -datablock ParticleData(MissileMist) -{ - dragCoefficient = 2.0; - gravityCoefficient = -0.05; - inheritedVelFactor = 0.0; - constantAcceleration = 0.0; - lifetimeMS = 400; - lifetimeVarianceMS = 100; - useInvAlpha = false; - spinRandomMin = -90.0; - spinRandomMax = 500.0; - textureName = "particleTest"; - colors[0] = "0.7 0.8 1.0 1.0"; - colors[1] = "0.7 0.8 1.0 0.5"; - colors[2] = "0.7 0.8 1.0 0.0"; - sizes[0] = 0.5; - sizes[1] = 0.5; - sizes[2] = 0.8; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData(MissileMistEmitter) -{ - ejectionPeriodMS = 5; - periodVarianceMS = 0; - ejectionVelocity = 6.0; - velocityVariance = 4.0; - ejectionOffset = 0.0; - thetaMin = 85; - thetaMax = 85; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - lifetimeMS = 250; - particles = "MissileMist"; -}; - - - -datablock ParticleData( MissileSplashParticle ) -{ - dragCoefficient = 1; - gravityCoefficient = 0.2; - inheritedVelFactor = 0.2; - constantAcceleration = -0.0; - lifetimeMS = 600; - lifetimeVarianceMS = 0; - textureName = "special/droplet"; - colors[0] = "0.7 0.8 1.0 1.0"; - colors[1] = "0.7 0.8 1.0 0.5"; - colors[2] = "0.7 0.8 1.0 0.0"; - sizes[0] = 0.5; - sizes[1] = 0.5; - sizes[2] = 0.5; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData( MissileSplashEmitter ) -{ - ejectionPeriodMS = 1; - periodVarianceMS = 0; - ejectionVelocity = 6; - velocityVariance = 3.0; - ejectionOffset = 0.0; - thetaMin = 60; - thetaMax = 80; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - orientParticles = true; - lifetimeMS = 100; - particles = "MissileSplashParticle"; -}; - - -datablock SplashData(MissileSplash) -{ - numSegments = 15; - ejectionFreq = 0.0001; - ejectionAngle = 45; - ringLifetime = 0.5; - lifetimeMS = 400; - velocity = 5.0; - startRadius = 0.0; - acceleration = -3.0; - texWrap = 5.0; - - explosion = MissileSplashExplosion; - - texture = "special/water2"; - - emitter[0] = MissileSplashEmitter; - emitter[1] = MissileMistEmitter; - - colors[0] = "0.7 0.8 1.0 0.0"; - colors[1] = "0.7 0.8 1.0 1.0"; - colors[2] = "0.7 0.8 1.0 0.0"; - colors[3] = "0.7 0.8 1.0 0.0"; - times[0] = 0.0; - times[1] = 0.4; - times[2] = 0.8; - times[3] = 1.0; -}; - -//-------------------------------------------------------------------------- -// Particle effects -//-------------------------------------- -datablock ParticleData(MissileSmokeParticle) -{ - dragCoeffiecient = 0.0; - gravityCoefficient = -0.02; - inheritedVelFactor = 0.1; - - lifetimeMS = 1200; - lifetimeVarianceMS = 100; - - textureName = "particleTest"; - - useInvAlpha = true; - spinRandomMin = -90.0; - spinRandomMax = 90.0; - - colors[0] = "1.0 0.75 0.0 0.0"; - colors[1] = "0.5 0.5 0.5 1.0"; - colors[2] = "0.3 0.3 0.3 0.0"; - sizes[0] = 1; - sizes[1] = 2; - sizes[2] = 3; - times[0] = 0.0; - times[1] = 0.1; - times[2] = 1.0; - -}; - -datablock ParticleEmitterData(MissileSmokeEmitter) -{ - ejectionPeriodMS = 10; - periodVarianceMS = 0; - - ejectionVelocity = 1.5; - velocityVariance = 0.3; - - thetaMin = 0.0; - thetaMax = 50.0; - - particles = "MissileSmokeParticle"; -}; - - -datablock ParticleData(MissileFireParticle) -{ - dragCoeffiecient = 0.0; - gravityCoefficient = 0.0; - inheritedVelFactor = 1.0; - - lifetimeMS = 300; - lifetimeVarianceMS = 000; - - textureName = "particleTest"; - - spinRandomMin = -135; - spinRandomMax = 135; - - colors[0] = "1.0 0.75 0.2 1.0"; - colors[1] = "1.0 0.5 0.0 1.0"; - colors[2] = "1.0 0.40 0.0 0.0"; - sizes[0] = 0; - sizes[1] = 1; - sizes[2] = 1.5; - times[0] = 0.0; - times[1] = 0.3; - times[2] = 1.0; -}; - -datablock ParticleEmitterData(MissileFireEmitter) -{ - ejectionPeriodMS = 15; - periodVarianceMS = 0; - - ejectionVelocity = 15.0; - velocityVariance = 0.0; - - thetaMin = 0.0; - thetaMax = 0.0; - - particles = "MissileFireParticle"; -}; - - - -datablock ParticleData(MissilePuffParticle) -{ - dragCoeffiecient = 0.0; - gravityCoefficient = 0.0; - inheritedVelFactor = 0.0; - - lifetimeMS = 500; - lifetimeVarianceMS = 300; - - textureName = "particleTest"; - - spinRandomMin = -135; - spinRandomMax = 135; - - colors[0] = "1.0 1.0 1.0 0.5"; - colors[1] = "0.7 0.7 0.7 0.0"; - sizes[0] = 0.25; - sizes[1] = 1.0; - times[0] = 0.0; - times[1] = 1.0; -}; - -datablock ParticleEmitterData(MissilePuffEmitter) -{ - ejectionPeriodMS = 50; - periodVarianceMS = 3; - - ejectionVelocity = 0.5; - velocityVariance = 0.0; - - thetaMin = 0.0; - thetaMax = 90.0; - - particles = "MissilePuffParticle"; -}; - - -datablock ParticleData(MissileLauncherExhaustParticle) -{ - dragCoeffiecient = 0.0; - gravityCoefficient = 0.01; - inheritedVelFactor = 1.0; - - lifetimeMS = 500; - lifetimeVarianceMS = 300; - - textureName = "particleTest"; - - useInvAlpha = true; - spinRandomMin = -135; - spinRandomMax = 135; - - colors[0] = "1.0 1.0 1.0 0.5"; - colors[1] = "0.7 0.7 0.7 0.0"; - sizes[0] = 0.25; - sizes[1] = 1.0; - times[0] = 0.0; - times[1] = 1.0; -}; - -datablock ParticleEmitterData(MissileLauncherExhaustEmitter) -{ - ejectionPeriodMS = 15; - periodVarianceMS = 0; - - ejectionVelocity = 3.0; - velocityVariance = 0.0; - - thetaMin = 0.0; - thetaMax = 20.0; - - particles = "MissileLauncherExhaustParticle"; -}; - -//-------------------------------------------------------------------------- -// Debris -//-------------------------------------- -datablock DebrisData( FlechetteDebris ) -{ - shapeName = "weapon_missile_fleschette.dts"; - - lifetime = 5.0; - - minSpinSpeed = -320.0; - maxSpinSpeed = 320.0; - - elasticity = 0.2; - friction = 0.3; - - numBounces = 3; - - gravModifier = 0.40; - - staticOnMaxBounce = true; -}; - -//-------------------------------------------------------------------------- -// Projectile -//-------------------------------------- -datablock SeekerProjectileData(ShoulderMissile) -{ - casingShapeName = "weapon_missile_casement.dts"; - projectileShapeName = "weapon_missile_projectile.dts"; - hasDamageRadius = true; - indirectDamage = 0.8; - damageRadius = 8.0; - radiusDamageType = $DamageType::Missile; - kickBackStrength = 2000; - - explosion = "MissileExplosion"; - splash = MissileSplash; - velInheritFactor = 1.0; // to compensate for slow starting velocity, this value - // is cranked up to full so the missile doesn't start - // out behind the player when the player is moving - // very quickly - bramage - - baseEmitter = MissileSmokeEmitter; - delayEmitter = MissileFireEmitter; - puffEmitter = MissilePuffEmitter; - bubbleEmitter = GrenadeBubbleEmitter; - bubbleEmitTime = 1.0; - - exhaustEmitter = MissileLauncherExhaustEmitter; - exhaustTimeMs = 300; - exhaustNodeName = "muzzlePoint1"; - - lifetimeMS = 7000; // z0dd - ZOD, 4/14/02. Was 6000 - muzzleVelocity = 10.0; - maxVelocity = 90.0; // z0dd - ZOD, 4/14/02. Was 80.0 - turningSpeed = 110.0; - acceleration = 200.0; - - proximityRadius = 3; - - terrainAvoidanceSpeed = 180; - terrainScanAhead = 25; - terrainHeightFail = 12; - terrainAvoidanceRadius = 100; - - flareDistance = 200; - flareAngle = 30; - - sound = MissileProjectileSound; - - hasLight = true; - lightRadius = 5.0; - lightColor = "0.2 0.05 0"; - - useFlechette = true; - flechetteDelayMs = 550; - casingDeb = FlechetteDebris; - - explodeOnWaterImpact = false; -}; - - - -//-------------------------------------------------------------------------- -// Ammo -//-------------------------------------- - -datablock ItemData(MissileLauncherAmmo) -{ - className = Ammo; - catagory = "Ammo"; - shapeFile = "ammo_missile.dts"; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - pickUpName = "some missiles"; - - computeCRC = true; - -}; - -//-------------------------------------------------------------------------- -// Weapon -//-------------------------------------- -datablock ItemData(MissileLauncher) -{ - className = Weapon; - catagory = "Spawn Items"; - shapeFile = "weapon_missile.dts"; - image = MissileLauncherImage; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - pickUpName = "a missile launcher"; - - computeCRC = true; - emap = true; -}; - -datablock ShapeBaseImageData(MissileLauncherImage) -{ - className = WeaponImage; - shapeFile = "weapon_missile.dts"; - item = MissileLauncher; - ammo = MissileLauncherAmmo; - offset = "0 0 0"; - armThread = lookms; - emap = true; - - projectile = ShoulderMissile; - projectileType = SeekerProjectile; - - isSeeker = true; - seekRadius = 400; - maxSeekAngle = 8; - seekTime = 0.5; - minSeekHeat = 0.6; // the heat that must be present on a target to lock it. // z0dd - ZOD, 8/22/02. Was 0.7 - - // only target objects outside this range - minTargetingDistance = 40; - - stateName[0] = "Activate"; - stateTransitionOnTimeout[0] = "ActivateReady"; - stateTimeoutValue[0] = 0.5; - stateSequence[0] = "Activate"; - stateSound[0] = MissileSwitchSound; - - stateName[1] = "ActivateReady"; - stateTransitionOnLoaded[1] = "Ready"; - stateTransitionOnNoAmmo[1] = "NoAmmo"; - - stateName[2] = "Ready"; - stateTransitionOnNoAmmo[2] = "NoAmmo"; - stateTransitionOnTriggerDown[2] = "CheckWet"; - - stateName[3] = "Fire"; - stateTransitionOnTimeout[3] = "Reload"; - stateTimeoutValue[3] = 0.4; - stateFire[3] = true; - stateRecoil[3] = LightRecoil; - stateAllowImageChange[3] = false; - stateSequence[3] = "Fire"; - stateScript[3] = "onFire"; - stateSound[3] = MissileFireSound; - - stateName[4] = "Reload"; - stateTransitionOnNoAmmo[4] = "NoAmmo"; - stateTransitionOnTimeout[4] = "Ready"; - stateTimeoutValue[4] = 2.5; - stateAllowImageChange[4] = false; - stateSequence[4] = "Reload"; - stateSound[4] = MissileReloadSound; - - stateName[5] = "NoAmmo"; - stateTransitionOnAmmo[5] = "Reload"; - stateSequence[5] = "NoAmmo"; - stateTransitionOnTriggerDown[5] = "DryFire"; - - stateName[6] = "DryFire"; - stateSound[6] = MissileDryFireSound; - stateTimeoutValue[6] = 1.0; - stateTransitionOnTimeout[6] = "ActivateReady"; - - stateName[7] = "CheckTarget"; - stateTransitionOnNoTarget[7] = "DryFire"; - stateTransitionOnTarget[7] = "Fire"; - - stateName[8] = "CheckWet"; - stateTransitionOnWet[8] = "WetFire"; - stateTransitionOnNotWet[8] = "CheckTarget"; - - stateName[9] = "WetFire"; - stateTransitionOnNoAmmo[9] = "NoAmmo"; - stateTransitionOnTimeout[9] = "Reload"; - stateSound[9] = MissileFireSound; - stateRecoil[3] = LightRecoil; - stateTimeoutValue[9] = 0.4; - stateSequence[3] = "Fire"; - stateScript[9] = "onWetFire"; - stateAllowImageChange[9] = false; -}; +//-------------------------------------- +// Missile launcher +//-------------------------------------- + +//-------------------------------------------------------------------------- +// Force-Feedback Effects +//-------------------------------------- +datablock EffectProfile(MissileSwitchEffect) +{ + effectname = "weapons/missile_launcher_activate"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock EffectProfile(MissileFireEffect) +{ + effectname = "weapons/missile_fire"; + minDistance = 2.5; + maxDistance = 5.0; +}; + +datablock EffectProfile(MissileDryFireEffect) +{ + effectname = "weapons/missile_launcher_dryfire"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock EffectProfile(MissileExplosionEffect) +{ + effectname = "explosions/explosion.xpl23"; + minDistance = 10; + maxDistance = 30; +}; + +//-------------------------------------------------------------------------- +// Sounds +//-------------------------------------- +datablock AudioProfile(MissileSwitchSound) +{ + filename = "fx/weapons/missile_launcher_activate.wav"; + description = AudioClosest3d; + preload = true; + effect = MissileSwitchEffect; +}; + +datablock AudioProfile(MissileFireSound) +{ + filename = "fx/weapons/missile_fire.WAV"; + description = AudioDefault3d; + preload = true; + effect = MissileFireEffect; +}; + +datablock AudioProfile(MissileProjectileSound) +{ + filename = "fx/weapons/missile_projectile.wav"; + description = ProjectileLooping3d; + preload = true; +}; + +datablock AudioProfile(MissileReloadSound) +{ + filename = "fx/weapons/weapon.missilereload.wav"; + description = AudioClosest3d; + preload = true; +}; + +datablock AudioProfile(MissileLockSound) +{ + filename = "fx/weapons/missile_launcher_searching.WAV"; + description = AudioClosest3d; + preload = true; +}; + +datablock AudioProfile(MissileExplosionSound) +{ + filename = "fx/explosions/explosion.xpl23.wav"; + description = AudioBIGExplosion3d; + preload = true; + effect = MissileExplosionEffect; +}; + +datablock AudioProfile(MissileDryFireSound) +{ + filename = "fx/weapons/missile_launcher_dryfire.wav"; + description = AudioClose3d; + preload = true; + effect = MissileDryFireEffect; +}; + + +//---------------------------------------------------------------------------- +// Splash Debris +//---------------------------------------------------------------------------- +datablock ParticleData( MDebrisSmokeParticle ) +{ + dragCoeffiecient = 1.0; + gravityCoefficient = 0.10; + inheritedVelFactor = 0.1; + + lifetimeMS = 1000; + lifetimeVarianceMS = 100; + + textureName = "particleTest"; + +// useInvAlpha = true; + + spinRandomMin = -60.0; + spinRandomMax = 60.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.0; + sizes[1] = 0.8; + sizes[2] = 0.8; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; +}; + +datablock ParticleEmitterData( MDebrisSmokeEmitter ) +{ + ejectionPeriodMS = 10; + periodVarianceMS = 1; + + ejectionVelocity = 1.0; // A little oomph at the back end + velocityVariance = 0.2; + + thetaMin = 0.0; + thetaMax = 40.0; + + particles = "MDebrisSmokeParticle"; +}; + + +datablock DebrisData( MissileSplashDebris ) +{ + emitters[0] = MDebrisSmokeEmitter; + + explodeOnMaxBounce = true; + + elasticity = 0.4; + friction = 0.2; + + lifetime = 0.3; + lifetimeVariance = 0.1; + + numBounces = 1; +}; + + +//---------------------------------------------------------------------------- +// Missile smoke spike (for debris) +//---------------------------------------------------------------------------- +datablock ParticleData( MissileSmokeSpike ) +{ + dragCoeffiecient = 1.0; + gravityCoefficient = 0.0; + inheritedVelFactor = 0.2; + + lifetimeMS = 1000; + lifetimeVarianceMS = 100; + + textureName = "particleTest"; + + useInvAlpha = true; + + spinRandomMin = -60.0; + spinRandomMax = 60.0; + + colors[0] = "0.6 0.6 0.6 1.0"; + colors[1] = "0.4 0.4 0.4 0.5"; + colors[2] = "0.4 0.4 0.4 0.0"; + sizes[0] = 0.0; + sizes[1] = 1.0; + sizes[2] = 0.5; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; +}; + +datablock ParticleEmitterData( MissileSmokeSpikeEmitter ) +{ + ejectionPeriodMS = 7; + periodVarianceMS = 1; + + ejectionVelocity = 1.0; // A little oomph at the back end + velocityVariance = 0.2; + + thetaMin = 0.0; + thetaMax = 40.0; + + particles = "MissileSmokeSpike"; +}; + + +//---------------------------------------------------------------------------- +// Explosion smoke particles +//---------------------------------------------------------------------------- + +datablock ParticleData(MissileExplosionSmoke) +{ + dragCoeffiecient = 0.3; + gravityCoefficient = -0.2; + inheritedVelFactor = 0.025; + + lifetimeMS = 1250; + lifetimeVarianceMS = 0; + + textureName = "particleTest"; + + useInvAlpha = true; + spinRandomMin = -100.0; + spinRandomMax = 100.0; + + textureName = "special/Smoke/bigSmoke"; + + colors[0] = "1.0 0.7 0.0 1.0"; + colors[1] = "0.4 0.4 0.4 0.5"; + colors[2] = "0.4 0.4 0.4 0.0"; + sizes[0] = 1.0; + sizes[1] = 3.0; + sizes[2] = 1.0; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; + +}; + +datablock ParticleEmitterData(MissileExplosionSmokeEMitter) +{ + ejectionOffset = 0.0; + ejectionPeriodMS = 5; + periodVarianceMS = 0; + + ejectionVelocity = 3.25; + velocityVariance = 0.25; + + thetaMin = 0.0; + thetaMax = 180.0; + + lifetimeMS = 250; + + particles = "MissileExplosionSmoke"; +}; + + + +datablock DebrisData( MissileSpikeDebris ) +{ + emitters[0] = MissileSmokeSpikeEmitter; + explodeOnMaxBounce = true; + elasticity = 0.4; + friction = 0.2; + lifetime = 0.3; + lifetimeVariance = 0.02; +}; + + +//--------------------------------------------------------------------------- +// Explosions +//--------------------------------------------------------------------------- +datablock ExplosionData(MissileExplosion) +{ + explosionShape = "effect_plasma_explosion.dts"; + playSpeed = 1.5; + soundProfile = MissileExplosionSound; + faceViewer = true; + + sizes[0] = "0.5 0.5 0.5"; + sizes[1] = "0.5 0.5 0.5"; + sizes[2] = "0.5 0.5 0.5"; + + emitter[0] = MissileExplosionSmokeEmitter; + + debris = MissileSpikeDebris; + debrisThetaMin = 10; + debrisThetaMax = 170; + debrisNum = 8; + debrisNumVariance = 6; + debrisVelocity = 15.0; + debrisVelocityVariance = 2.0; + + shakeCamera = true; + camShakeFreq = "6.0 7.0 7.0"; + camShakeAmp = "70.0 70.0 70.0"; + camShakeDuration = 1.0; + camShakeRadius = 7.0; +}; + + + +datablock ExplosionData(MissileSplashExplosion) +{ + explosionShape = "disc_explosion.dts"; + + faceViewer = true; + explosionScale = "1.0 1.0 1.0"; + + debris = MissileSplashDebris; + debrisThetaMin = 10; + debrisThetaMax = 80; + debrisNum = 10; + debrisVelocity = 10.0; + debrisVelocityVariance = 4.0; + + sizes[0] = "0.35 0.35 0.35"; + sizes[1] = "0.15 0.15 0.15"; + sizes[2] = "0.15 0.15 0.15"; + sizes[3] = "0.15 0.15 0.15"; + + times[0] = 0.0; + times[1] = 0.333; + times[2] = 0.666; + times[3] = 1.0; + +}; + + +//-------------------------------------------------------------------------- +// Splash +//-------------------------------------------------------------------------- +datablock ParticleData(MissileMist) +{ + dragCoefficient = 2.0; + gravityCoefficient = -0.05; + inheritedVelFactor = 0.0; + constantAcceleration = 0.0; + lifetimeMS = 400; + lifetimeVarianceMS = 100; + useInvAlpha = false; + spinRandomMin = -90.0; + spinRandomMax = 500.0; + textureName = "particleTest"; + colors[0] = "0.7 0.8 1.0 1.0"; + colors[1] = "0.7 0.8 1.0 0.5"; + colors[2] = "0.7 0.8 1.0 0.0"; + sizes[0] = 0.5; + sizes[1] = 0.5; + sizes[2] = 0.8; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; +}; + +datablock ParticleEmitterData(MissileMistEmitter) +{ + ejectionPeriodMS = 5; + periodVarianceMS = 0; + ejectionVelocity = 6.0; + velocityVariance = 4.0; + ejectionOffset = 0.0; + thetaMin = 85; + thetaMax = 85; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + lifetimeMS = 250; + particles = "MissileMist"; +}; + + + +datablock ParticleData( MissileSplashParticle ) +{ + dragCoefficient = 1; + gravityCoefficient = 0.2; + inheritedVelFactor = 0.2; + constantAcceleration = -0.0; + lifetimeMS = 600; + lifetimeVarianceMS = 0; + textureName = "special/droplet"; + colors[0] = "0.7 0.8 1.0 1.0"; + colors[1] = "0.7 0.8 1.0 0.5"; + colors[2] = "0.7 0.8 1.0 0.0"; + sizes[0] = 0.5; + sizes[1] = 0.5; + sizes[2] = 0.5; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; +}; + +datablock ParticleEmitterData( MissileSplashEmitter ) +{ + ejectionPeriodMS = 1; + periodVarianceMS = 0; + ejectionVelocity = 6; + velocityVariance = 3.0; + ejectionOffset = 0.0; + thetaMin = 60; + thetaMax = 80; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + orientParticles = true; + lifetimeMS = 100; + particles = "MissileSplashParticle"; +}; + + +datablock SplashData(MissileSplash) +{ + numSegments = 15; + ejectionFreq = 0.0001; + ejectionAngle = 45; + ringLifetime = 0.5; + lifetimeMS = 400; + velocity = 5.0; + startRadius = 0.0; + acceleration = -3.0; + texWrap = 5.0; + + explosion = MissileSplashExplosion; + + texture = "special/water2"; + + emitter[0] = MissileSplashEmitter; + emitter[1] = MissileMistEmitter; + + colors[0] = "0.7 0.8 1.0 0.0"; + colors[1] = "0.7 0.8 1.0 1.0"; + colors[2] = "0.7 0.8 1.0 0.0"; + colors[3] = "0.7 0.8 1.0 0.0"; + times[0] = 0.0; + times[1] = 0.4; + times[2] = 0.8; + times[3] = 1.0; +}; + +//-------------------------------------------------------------------------- +// Particle effects +//-------------------------------------- +datablock ParticleData(MissileSmokeParticle) +{ + dragCoeffiecient = 0.0; + gravityCoefficient = -0.02; + inheritedVelFactor = 0.1; + + lifetimeMS = 1200; + lifetimeVarianceMS = 100; + + textureName = "particleTest"; + + useInvAlpha = true; + spinRandomMin = -90.0; + spinRandomMax = 90.0; + + colors[0] = "1.0 0.75 0.0 0.0"; + colors[1] = "0.5 0.5 0.5 1.0"; + colors[2] = "0.3 0.3 0.3 0.0"; + sizes[0] = 1; + sizes[1] = 2; + sizes[2] = 3; + times[0] = 0.0; + times[1] = 0.1; + times[2] = 1.0; + +}; + +datablock ParticleEmitterData(MissileSmokeEmitter) +{ + ejectionPeriodMS = 10; + periodVarianceMS = 0; + + ejectionVelocity = 1.5; + velocityVariance = 0.3; + + thetaMin = 0.0; + thetaMax = 50.0; + + particles = "MissileSmokeParticle"; +}; + + +datablock ParticleData(MissileFireParticle) +{ + dragCoeffiecient = 0.0; + gravityCoefficient = 0.0; + inheritedVelFactor = 1.0; + + lifetimeMS = 300; + lifetimeVarianceMS = 000; + + textureName = "particleTest"; + + spinRandomMin = -135; + spinRandomMax = 135; + + colors[0] = "1.0 0.75 0.2 1.0"; + colors[1] = "1.0 0.5 0.0 1.0"; + colors[2] = "1.0 0.40 0.0 0.0"; + sizes[0] = 0; + sizes[1] = 1; + sizes[2] = 1.5; + times[0] = 0.0; + times[1] = 0.3; + times[2] = 1.0; +}; + +datablock ParticleEmitterData(MissileFireEmitter) +{ + ejectionPeriodMS = 15; + periodVarianceMS = 0; + + ejectionVelocity = 15.0; + velocityVariance = 0.0; + + thetaMin = 0.0; + thetaMax = 0.0; + + particles = "MissileFireParticle"; +}; + + + +datablock ParticleData(MissilePuffParticle) +{ + dragCoeffiecient = 0.0; + gravityCoefficient = 0.0; + inheritedVelFactor = 0.0; + + lifetimeMS = 500; + lifetimeVarianceMS = 300; + + textureName = "particleTest"; + + spinRandomMin = -135; + spinRandomMax = 135; + + colors[0] = "1.0 1.0 1.0 0.5"; + colors[1] = "0.7 0.7 0.7 0.0"; + sizes[0] = 0.25; + sizes[1] = 1.0; + times[0] = 0.0; + times[1] = 1.0; +}; + +datablock ParticleEmitterData(MissilePuffEmitter) +{ + ejectionPeriodMS = 50; + periodVarianceMS = 3; + + ejectionVelocity = 0.5; + velocityVariance = 0.0; + + thetaMin = 0.0; + thetaMax = 90.0; + + particles = "MissilePuffParticle"; +}; + + +datablock ParticleData(MissileLauncherExhaustParticle) +{ + dragCoeffiecient = 0.0; + gravityCoefficient = 0.01; + inheritedVelFactor = 1.0; + + lifetimeMS = 500; + lifetimeVarianceMS = 300; + + textureName = "particleTest"; + + useInvAlpha = true; + spinRandomMin = -135; + spinRandomMax = 135; + + colors[0] = "1.0 1.0 1.0 0.5"; + colors[1] = "0.7 0.7 0.7 0.0"; + sizes[0] = 0.25; + sizes[1] = 1.0; + times[0] = 0.0; + times[1] = 1.0; +}; + +datablock ParticleEmitterData(MissileLauncherExhaustEmitter) +{ + ejectionPeriodMS = 15; + periodVarianceMS = 0; + + ejectionVelocity = 3.0; + velocityVariance = 0.0; + + thetaMin = 0.0; + thetaMax = 20.0; + + particles = "MissileLauncherExhaustParticle"; +}; + +//-------------------------------------------------------------------------- +// Debris +//-------------------------------------- +datablock DebrisData( FlechetteDebris ) +{ + shapeName = "weapon_missile_fleschette.dts"; + + lifetime = 5.0; + + minSpinSpeed = -320.0; + maxSpinSpeed = 320.0; + + elasticity = 0.2; + friction = 0.3; + + numBounces = 3; + + gravModifier = 0.40; + + staticOnMaxBounce = true; +}; + +//-------------------------------------------------------------------------- +// Projectile +//-------------------------------------- +datablock SeekerProjectileData(ShoulderMissile) +{ + casingShapeName = "weapon_missile_casement.dts"; + projectileShapeName = "weapon_missile_projectile.dts"; + hasDamageRadius = true; + indirectDamage = 0.8; + damageRadius = 8.0; + radiusDamageType = $DamageType::Missile; + kickBackStrength = 2000; + + explosion = "MissileExplosion"; + splash = MissileSplash; + velInheritFactor = 1.0; // to compensate for slow starting velocity, this value + // is cranked up to full so the missile doesn't start + // out behind the player when the player is moving + // very quickly - bramage + + baseEmitter = MissileSmokeEmitter; + delayEmitter = MissileFireEmitter; + puffEmitter = MissilePuffEmitter; + bubbleEmitter = GrenadeBubbleEmitter; + bubbleEmitTime = 1.0; + + exhaustEmitter = MissileLauncherExhaustEmitter; + exhaustTimeMs = 300; + exhaustNodeName = "muzzlePoint1"; + + lifetimeMS = 7000; // z0dd - ZOD, 4/14/02. Was 6000 + muzzleVelocity = 10.0; + maxVelocity = 90.0; // z0dd - ZOD, 4/14/02. Was 80.0 + turningSpeed = 110.0; + acceleration = 200.0; + + proximityRadius = 3; + + terrainAvoidanceSpeed = 180; + terrainScanAhead = 25; + terrainHeightFail = 12; + terrainAvoidanceRadius = 100; + + flareDistance = 200; + flareAngle = 30; + + sound = MissileProjectileSound; + + hasLight = true; + lightRadius = 5.0; + lightColor = "0.2 0.05 0"; + + useFlechette = true; + flechetteDelayMs = 550; + casingDeb = FlechetteDebris; + + explodeOnWaterImpact = false; +}; + + + +//-------------------------------------------------------------------------- +// Ammo +//-------------------------------------- + +datablock ItemData(MissileLauncherAmmo) +{ + className = Ammo; + catagory = "Ammo"; + shapeFile = "ammo_missile.dts"; + mass = 1; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 2; + pickUpName = "some missiles"; + + computeCRC = true; + +}; + +//-------------------------------------------------------------------------- +// Weapon +//-------------------------------------- +datablock ItemData(MissileLauncher) +{ + className = Weapon; + catagory = "Spawn Items"; + shapeFile = "weapon_missile.dts"; + image = MissileLauncherImage; + mass = 1; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 2; + pickUpName = "a missile launcher"; + + computeCRC = true; + emap = true; +}; + +datablock ShapeBaseImageData(MissileLauncherImage) +{ + className = WeaponImage; + shapeFile = "weapon_missile.dts"; + item = MissileLauncher; + ammo = MissileLauncherAmmo; + offset = "0 0 0"; + armThread = lookms; + emap = true; + + projectile = ShoulderMissile; + projectileType = SeekerProjectile; + + isSeeker = true; + seekRadius = 400; + maxSeekAngle = 8; + seekTime = 0.5; + minSeekHeat = 0.6; // the heat that must be present on a target to lock it. // z0dd - ZOD, 8/22/02. Was 0.7 + + // only target objects outside this range + minTargetingDistance = 40; + + stateName[0] = "Activate"; + stateTransitionOnTimeout[0] = "ActivateReady"; + stateTimeoutValue[0] = 0.5; + stateSequence[0] = "Activate"; + stateSound[0] = MissileSwitchSound; + + stateName[1] = "ActivateReady"; + stateTransitionOnLoaded[1] = "Ready"; + stateTransitionOnNoAmmo[1] = "NoAmmo"; + + stateName[2] = "Ready"; + stateTransitionOnNoAmmo[2] = "NoAmmo"; + stateTransitionOnTriggerDown[2] = "CheckWet"; + + stateName[3] = "Fire"; + stateTransitionOnTimeout[3] = "Reload"; + stateTimeoutValue[3] = 0.4; + stateFire[3] = true; + stateRecoil[3] = LightRecoil; + stateAllowImageChange[3] = false; + stateSequence[3] = "Fire"; + stateScript[3] = "onFire"; + stateSound[3] = MissileFireSound; + + stateName[4] = "Reload"; + stateTransitionOnNoAmmo[4] = "NoAmmo"; + stateTransitionOnTimeout[4] = "Ready"; + stateTimeoutValue[4] = 2.5; + stateAllowImageChange[4] = false; + stateSequence[4] = "Reload"; + stateSound[4] = MissileReloadSound; + + stateName[5] = "NoAmmo"; + stateTransitionOnAmmo[5] = "Reload"; + stateSequence[5] = "NoAmmo"; + stateTransitionOnTriggerDown[5] = "DryFire"; + + stateName[6] = "DryFire"; + stateSound[6] = MissileDryFireSound; + stateTimeoutValue[6] = 1.0; + stateTransitionOnTimeout[6] = "ActivateReady"; + + stateName[7] = "CheckTarget"; + stateTransitionOnNoTarget[7] = "DryFire"; + stateTransitionOnTarget[7] = "Fire"; + + stateName[8] = "CheckWet"; + stateTransitionOnWet[8] = "WetFire"; + stateTransitionOnNotWet[8] = "CheckTarget"; + + stateName[9] = "WetFire"; + stateTransitionOnNoAmmo[9] = "NoAmmo"; + stateTransitionOnTimeout[9] = "Reload"; + stateSound[9] = MissileFireSound; + stateRecoil[3] = LightRecoil; + stateTimeoutValue[9] = 0.4; + stateSequence[3] = "Fire"; + stateScript[9] = "onWetFire"; + stateAllowImageChange[9] = false; +}; diff --git a/scripts/weapons/mortar.cs b/scripts/weapons/mortar.cs index 5f361bf..9f09009 100644 --- a/scripts/weapons/mortar.cs +++ b/scripts/weapons/mortar.cs @@ -1,798 +1,798 @@ -//-------------------------------------- -// Mortar -//-------------------------------------- - -//-------------------------------------------------------------------------- -// Force-Feedback Effects -//-------------------------------------- -datablock EffectProfile(MortarSwitchEffect) -{ - effectname = "weapons/mortar_activate"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(MortarFireEffect) -{ - effectname = "weapons/mortar_fire"; - minDistance = 2.5; - maxDistance = 5.0; -}; - -datablock EffectProfile(MortarReloadEffect) -{ - effectname = "weapons/mortar_reload"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(MortarDryFireEffect) -{ - effectname = "weapons/mortar_dryfire"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(MortarExplosionEffect) -{ - effectname = "explosions/explosion.xpl03"; - minDistance = 30; - maxDistance = 65; -}; - -//-------------------------------------------------------------------------- -// Sounds -//-------------------------------------- -datablock AudioProfile(MortarSwitchSound) -{ - filename = "fx/weapons/mortar_activate.wav"; - description = AudioClosest3d; - preload = true; - effect = MortarSwitchEffect; -}; - -datablock AudioProfile(MortarReloadSound) -{ - filename = "fx/weapons/mortar_reload.wav"; - description = AudioClosest3d; - preload = true; - effect = MortarReloadEffect; -}; - -// DELETE IF NOT NEEDED -//datablock AudioProfile(MortarIdleSound) -//{ -// filename = "fx/weapons/weapon.mortarIdle.wav"; -// description = ClosestLooping3d; -// preload = true; -//}; - -datablock AudioProfile(MortarFireSound) -{ - filename = "fx/weapons/mortar_fire.wav"; - description = AudioDefault3d; - preload = true; - effect = MortarFireEffect; -}; - -datablock AudioProfile(MortarProjectileSound) -{ - filename = "fx/weapons/mortar_projectile.wav"; - description = ProjectileLooping3d; - preload = true; -}; - -datablock AudioProfile(MortarExplosionSound) -{ - filename = "fx/weapons/mortar_explode.wav"; - description = AudioBIGExplosion3d; - preload = true; - effect = MortarExplosionEffect; -}; - -datablock AudioProfile(UnderwaterMortarExplosionSound) -{ - filename = "fx/weapons/mortar_explode_UW.wav"; - description = AudioBIGExplosion3d; - preload = true; - effect = MortarExplosionEffect; -}; - -datablock AudioProfile(MortarDryFireSound) -{ - filename = "fx/weapons/mortar_dryfire.wav"; - description = AudioClose3d; - preload = true; - effect = MortarDryFireEffect; -}; - -//---------------------------------------------------------------------------- -// Bubbles -//---------------------------------------------------------------------------- -datablock ParticleData(MortarBubbleParticle) -{ - dragCoefficient = 0.0; - gravityCoefficient = -0.25; - inheritedVelFactor = 0.0; - constantAcceleration = 0.0; - lifetimeMS = 1500; - lifetimeVarianceMS = 600; - useInvAlpha = false; - textureName = "special/bubbles"; - - spinRandomMin = -100.0; - spinRandomMax = 100.0; - - colors[0] = "0.7 0.8 1.0 0.4"; - colors[1] = "0.7 0.8 1.0 0.4"; - colors[2] = "0.7 0.8 1.0 0.0"; - sizes[0] = 0.8; - sizes[1] = 0.8; - sizes[2] = 0.8; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData(MortarBubbleEmitter) -{ - ejectionPeriodMS = 9; - periodVarianceMS = 0; - ejectionVelocity = 1.0; - ejectionOffset = 0.1; - velocityVariance = 0.5; - thetaMin = 0; - thetaMax = 80; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - particles = "MortarBubbleParticle"; -}; - -//-------------------------------------------------------------------------- -// Splash -//-------------------------------------------------------------------------- -datablock ParticleData( MortarSplashParticle ) -{ - dragCoefficient = 1; - gravityCoefficient = 0.0; - inheritedVelFactor = 0.2; - constantAcceleration = -1.4; - lifetimeMS = 300; - lifetimeVarianceMS = 0; - textureName = "special/droplet"; - colors[0] = "0.7 0.8 1.0 1.0"; - colors[1] = "0.7 0.8 1.0 0.5"; - colors[2] = "0.7 0.8 1.0 0.0"; - sizes[0] = 0.05; - sizes[1] = 0.2; - sizes[2] = 0.2; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData( MortarSplashEmitter ) -{ - ejectionPeriodMS = 4; - periodVarianceMS = 0; - ejectionVelocity = 3; - velocityVariance = 1.0; - ejectionOffset = 0.0; - thetaMin = 0; - thetaMax = 50; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - orientParticles = true; - lifetimeMS = 100; - particles = "MortarSplashParticle"; -}; - - -datablock SplashData(MortarSplash) -{ - numSegments = 10; - ejectionFreq = 10; - ejectionAngle = 20; - ringLifetime = 0.4; - lifetimeMS = 400; - velocity = 3.0; - startRadius = 0.0; - acceleration = -3.0; - texWrap = 5.0; - - texture = "special/water2"; - - emitter[0] = MortarSplashEmitter; - - colors[0] = "0.7 0.8 1.0 0.0"; - colors[1] = "0.7 0.8 1.0 1.0"; - colors[2] = "0.7 0.8 1.0 0.0"; - colors[3] = "0.7 0.8 1.0 0.0"; - times[0] = 0.0; - times[1] = 0.4; - times[2] = 0.8; - times[3] = 1.0; -}; - -//--------------------------------------------------------------------------- -// Mortar Shockwaves -//--------------------------------------------------------------------------- -datablock ShockwaveData(UnderwaterMortarShockwave) -{ - width = 6.0; - numSegments = 32; - numVertSegments = 6; - velocity = 10; - acceleration = 20.0; - lifetimeMS = 900; - height = 1.0; - verticalCurve = 0.5; - is2D = false; - - texture[0] = "special/shockwave4"; - texture[1] = "special/gradient"; - texWrap = 6.0; - - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - - colors[0] = "0.4 0.4 1.0 0.50"; - colors[1] = "0.4 0.4 1.0 0.25"; - colors[2] = "0.4 0.4 1.0 0.0"; - - mapToTerrain = true; - orientToNormal = false; - renderBottom = false; -}; - -datablock ShockwaveData(MortarShockwave) -{ - width = 6.0; - numSegments = 32; - numVertSegments = 6; - velocity = 15; - acceleration = 20.0; - lifetimeMS = 500; - height = 1.0; - verticalCurve = 0.5; - is2D = false; - - texture[0] = "special/shockwave4"; - texture[1] = "special/gradient"; - texWrap = 6.0; - - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - - colors[0] = "0.4 1.0 0.4 0.50"; - colors[1] = "0.4 1.0 0.4 0.25"; - colors[2] = "0.4 1.0 0.4 0.0"; - - mapToTerrain = true; - orientToNormal = false; - renderBottom = false; -}; - - -//-------------------------------------------------------------------------- -// Mortar Explosion Particle effects -//-------------------------------------- -datablock ParticleData( MortarCrescentParticle ) -{ - dragCoefficient = 2; - gravityCoefficient = 0.0; - inheritedVelFactor = 0.2; - constantAcceleration = -0.0; - lifetimeMS = 600; - lifetimeVarianceMS = 000; - textureName = "special/crescent3"; - colors[0] = "0.7 1.0 0.7 1.0"; - colors[1] = "0.7 1.0 0.7 0.5"; - colors[2] = "0.7 1.0 0.7 0.0"; - sizes[0] = 4.0; - sizes[1] = 8.0; - sizes[2] = 9.0; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData( MortarCrescentEmitter ) -{ - ejectionPeriodMS = 25; - periodVarianceMS = 0; - ejectionVelocity = 40; - velocityVariance = 5.0; - ejectionOffset = 0.0; - thetaMin = 0; - thetaMax = 80; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - orientParticles = true; - lifetimeMS = 200; - particles = "MortarCrescentParticle"; -}; - - -datablock ParticleData(MortarExplosionSmoke) -{ - dragCoeffiecient = 0.4; - gravityCoefficient = -0.30; // rises slowly - inheritedVelFactor = 0.025; - - lifetimeMS = 1250; - lifetimeVarianceMS = 500; - - textureName = "particleTest"; - - useInvAlpha = true; - spinRandomMin = -100.0; - spinRandomMax = 100.0; - - textureName = "special/Smoke/bigSmoke"; - - colors[0] = "0.7 0.7 0.7 0.0"; - colors[1] = "0.4 0.4 0.4 0.5"; - colors[2] = "0.4 0.4 0.4 0.5"; - colors[3] = "0.4 0.4 0.4 0.0"; - sizes[0] = 5.0; - sizes[1] = 6.0; - sizes[2] = 10.0; - sizes[3] = 12.0; - times[0] = 0.0; - times[1] = 0.333; - times[2] = 0.666; - times[3] = 1.0; - - - -}; - -datablock ParticleEmitterData(MortarExplosionSmokeEmitter) -{ - ejectionPeriodMS = 10; - periodVarianceMS = 0; - - ejectionOffset = 8.0; - - - ejectionVelocity = 1.25; - velocityVariance = 1.2; - - thetaMin = 0.0; - thetaMax = 90.0; - - lifetimeMS = 500; - - particles = "MortarExplosionSmoke"; - -}; - -//--------------------------------------------------------------------------- -// Underwater Explosion -//--------------------------------------------------------------------------- -datablock ParticleData(UnderwaterExplosionSparks) -{ - dragCoefficient = 0; - gravityCoefficient = 0.0; - inheritedVelFactor = 0.2; - constantAcceleration = 0.0; - lifetimeMS = 500; - lifetimeVarianceMS = 350; - textureName = "special/crescent3"; - colors[0] = "0.4 0.4 1.0 1.0"; - colors[1] = "0.4 0.4 1.0 1.0"; - colors[2] = "0.4 0.4 1.0 0.0"; - sizes[0] = 3.5; - sizes[1] = 3.5; - sizes[2] = 3.5; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - -}; - -datablock ParticleEmitterData(UnderwaterExplosionSparksEmitter) -{ - ejectionPeriodMS = 2; - periodVarianceMS = 0; - ejectionVelocity = 17; - velocityVariance = 4; - ejectionOffset = 0.0; - thetaMin = 0; - thetaMax = 60; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - orientParticles = true; - lifetimeMS = 100; - particles = "UnderwaterExplosionSparks"; -}; - -datablock ParticleData(MortarExplosionBubbleParticle) -{ - dragCoefficient = 0.0; - gravityCoefficient = -0.25; - inheritedVelFactor = 0.0; - constantAcceleration = 0.0; - lifetimeMS = 1500; - lifetimeVarianceMS = 600; - useInvAlpha = false; - textureName = "special/bubbles"; - - spinRandomMin = -100.0; - spinRandomMax = 100.0; - - colors[0] = "0.7 0.8 1.0 0.0"; - colors[1] = "0.7 0.8 1.0 0.4"; - colors[2] = "0.7 0.8 1.0 0.0"; - sizes[0] = 2.0; - sizes[1] = 2.0; - sizes[2] = 2.0; - times[0] = 0.0; - times[1] = 0.8; - times[2] = 1.0; -}; -datablock ParticleEmitterData(MortarExplosionBubbleEmitter) -{ - ejectionPeriodMS = 5; - periodVarianceMS = 0; - ejectionVelocity = 1.0; - ejectionOffset = 7.0; - velocityVariance = 0.5; - thetaMin = 0; - thetaMax = 80; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - particles = "MortarExplosionBubbleParticle"; -}; - -datablock DebrisData( UnderwaterMortarDebris ) -{ - emitters[0] = MortarExplosionBubbleEmitter; - - explodeOnMaxBounce = true; - - elasticity = 0.4; - friction = 0.2; - - lifetime = 1.5; - lifetimeVariance = 0.2; - - numBounces = 1; -}; - -datablock ExplosionData(UnderwaterMortarSubExplosion1) -{ - explosionShape = "disc_explosion.dts"; - faceViewer = true; - delayMS = 100; - offset = 3.0; - playSpeed = 1.5; - - sizes[0] = "0.75 0.75 0.75"; - sizes[1] = "1.0 1.0 1.0"; - sizes[2] = "0.5 0.5 0.5"; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - -}; - -datablock ExplosionData(UnderwaterMortarSubExplosion2) -{ - explosionShape = "disc_explosion.dts"; - faceViewer = true; - delayMS = 50; - offset = 3.0; - playSpeed = 0.75; - - sizes[0] = "1.5 1.5 1.5"; - sizes[1] = "1.5 1.5 1.5"; - sizes[2] = "1.0 1.0 1.0"; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ExplosionData(UnderwaterMortarSubExplosion3) -{ - explosionShape = "disc_explosion.dts"; - faceViewer = true; - delayMS = 0; - offset = 0.0; - playSpeed = 0.5; - - sizes[0] = "1.0 1.0 1.0"; - sizes[1] = "2.0 2.0 2.0"; - sizes[2] = "1.5 1.5 1.5"; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - -}; - -datablock ExplosionData(UnderwaterMortarExplosion) -{ - soundProfile = UnderwaterMortarExplosionSound; - - shockwave = UnderwaterMortarShockwave; - shockwaveOnTerrain = true; - - subExplosion[0] = UnderwaterMortarSubExplosion1; - subExplosion[1] = UnderwaterMortarSubExplosion2; - subExplosion[2] = UnderwaterMortarSubExplosion3; - - emitter[0] = MortarExplosionBubbleEmitter; - emitter[1] = UnderwaterExplosionSparksEmitter; - - shakeCamera = true; - camShakeFreq = "8.0 9.0 7.0"; - camShakeAmp = "100.0 100.0 100.0"; - camShakeDuration = 1.3; - camShakeRadius = 25.0; -}; - - -//--------------------------------------------------------------------------- -// Explosion -//--------------------------------------------------------------------------- - -datablock ExplosionData(MortarSubExplosion1) -{ - explosionShape = "mortar_explosion.dts"; - faceViewer = true; - - delayMS = 100; - - offset = 5.0; - - playSpeed = 1.5; - - sizes[0] = "0.5 0.5 0.5"; - sizes[1] = "0.5 0.5 0.5"; - times[0] = 0.0; - times[1] = 1.0; - -}; - -datablock ExplosionData(MortarSubExplosion2) -{ - explosionShape = "mortar_explosion.dts"; - faceViewer = true; - - delayMS = 50; - - offset = 5.0; - - playSpeed = 1.0; - - sizes[0] = "1.0 1.0 1.0"; - sizes[1] = "1.0 1.0 1.0"; - times[0] = 0.0; - times[1] = 1.0; -}; - -datablock ExplosionData(MortarSubExplosion3) -{ - explosionShape = "mortar_explosion.dts"; - faceViewer = true; - delayMS = 0; - offset = 0.0; - playSpeed = 0.7; - - sizes[0] = "1.0 1.0 1.0"; - sizes[1] = "2.0 2.0 2.0"; - times[0] = 0.0; - times[1] = 1.0; - -}; - -datablock ExplosionData(MortarExplosion) -{ - soundProfile = MortarExplosionSound; - - shockwave = MortarShockwave; - shockwaveOnTerrain = true; - - subExplosion[0] = MortarSubExplosion1; - subExplosion[1] = MortarSubExplosion2; - subExplosion[2] = MortarSubExplosion3; - - emitter[0] = MortarExplosionSmokeEmitter; - emitter[1] = MortarCrescentEmitter; - - shakeCamera = true; - camShakeFreq = "8.0 9.0 7.0"; - camShakeAmp = "100.0 100.0 100.0"; - camShakeDuration = 1.3; - camShakeRadius = 25.0; -}; - -//--------------------------------------------------------------------------- -// Smoke particles -//--------------------------------------------------------------------------- -datablock ParticleData(MortarSmokeParticle) -{ - dragCoeffiecient = 0.4; - gravityCoefficient = -0.3; // rises slowly - inheritedVelFactor = 0.125; - - lifetimeMS = 1200; - lifetimeVarianceMS = 200; - useInvAlpha = true; - spinRandomMin = -100.0; - spinRandomMax = 100.0; - - animateTexture = false; - - textureName = "special/Smoke/bigSmoke"; - - colors[0] = "0.7 1.0 0.7 0.5"; - colors[1] = "0.3 0.7 0.3 0.8"; - colors[2] = "0.0 0.0 0.0 0.0"; - sizes[0] = 1.0; - sizes[1] = 2.0; - sizes[2] = 4.5; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - -}; - - -datablock ParticleEmitterData(MortarSmokeEmitter) -{ - ejectionPeriodMS = 10; - periodVarianceMS = 3; - - ejectionVelocity = 2.25; - velocityVariance = 0.55; - - thetaMin = 0.0; - thetaMax = 40.0; - - particles = "MortarSmokeParticle"; -}; - - -//-------------------------------------------------------------------------- -// Projectile -//-------------------------------------- -datablock GrenadeProjectileData(MortarShot) -{ - projectileShapeName = "mortar_projectile.dts"; - emitterDelay = -1; - directDamage = 0.0; - hasDamageRadius = true; - indirectDamage = 1.0; - damageRadius = 19.0; // z0dd - ZOD, 8/13/02. Was 20.0 - radiusDamageType = $DamageType::Mortar; - kickBackStrength = 2500; - - explosion = "MortarExplosion"; - underwaterExplosion = "UnderwaterMortarExplosion"; - velInheritFactor = 0.5; - splash = MortarSplash; - depthTolerance = 10.0; // depth at which it uses underwater explosion - - baseEmitter = MortarSmokeEmitter; - bubbleEmitter = MortarBubbleEmitter; - - grenadeElasticity = 0.15; - grenadeFriction = 0.4; - armingDelayMS = 1500; // z0dd - ZOD, 4/14/02. Was 2000 - - gravityMod = 1.1; // z0dd - ZOD, 5/18/02. Make mortar projectile heavier, less floaty - muzzleVelocity = 75.95; // z0dd - ZOD, 8/13/02. More velocity to compensate for higher gravity. Was 63.7 - drag = 0.1; - sound = MortarProjectileSound; - - hasLight = true; - lightRadius = 4; - lightColor = "0.05 0.2 0.05"; - - hasLightUnderwaterColor = true; - underWaterLightColor = "0.05 0.075 0.2"; - -}; - -//-------------------------------------------------------------------------- -// Ammo -//-------------------------------------- - -datablock ItemData(MortarAmmo) -{ - className = Ammo; - catagory = "Ammo"; - shapeFile = "ammo_mortar.dts"; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - pickUpName = "some mortar ammo"; - - computeCRC = true; - -}; - -//-------------------------------------------------------------------------- -// Weapon -//-------------------------------------- -datablock ItemData(Mortar) -{ - className = Weapon; - catagory = "Spawn Items"; - shapeFile = "weapon_mortar.dts"; - image = MortarImage; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - pickUpName = "a mortar gun"; - - computeCRC = true; - emap = true; -}; - -datablock ShapeBaseImageData(MortarImage) -{ - className = WeaponImage; - shapeFile = "weapon_mortar.dts"; - item = Mortar; - ammo = MortarAmmo; - offset = "0 0 0"; - emap = true; - - projectile = MortarShot; - projectileType = GrenadeProjectile; - - stateName[0] = "Activate"; - stateTransitionOnTimeout[0] = "ActivateReady"; - stateTimeoutValue[0] = 0.5; - stateSequence[0] = "Activate"; - stateSound[0] = MortarSwitchSound; - - stateName[1] = "ActivateReady"; - stateTransitionOnLoaded[1] = "Ready"; - stateTransitionOnNoAmmo[1] = "NoAmmo"; - - stateName[2] = "Ready"; - stateTransitionOnNoAmmo[2] = "NoAmmo"; - stateTransitionOnTriggerDown[2] = "Fire"; - //stateSound[2] = MortarIdleSound; - - stateName[3] = "Fire"; - stateSequence[3] = "Recoil"; - stateTransitionOnTimeout[3] = "Reload"; - stateTimeoutValue[3] = 0.8; - stateFire[3] = true; - stateRecoil[3] = LightRecoil; - stateAllowImageChange[3] = false; - stateScript[3] = "onFire"; - stateSound[3] = MortarFireSound; - - stateName[4] = "Reload"; - stateTransitionOnNoAmmo[4] = "NoAmmo"; - stateTransitionOnTimeout[4] = "Ready"; - stateTimeoutValue[4] = 2.0; - stateAllowImageChange[4] = false; - stateSequence[4] = "Reload"; - stateSound[4] = MortarReloadSound; - - stateName[5] = "NoAmmo"; - stateTransitionOnAmmo[5] = "Reload"; - stateSequence[5] = "NoAmmo"; - stateTransitionOnTriggerDown[5] = "DryFire"; - - stateName[6] = "DryFire"; - stateSound[6] = MortarDryFireSound; - stateTimeoutValue[6] = 1.5; - stateTransitionOnTimeout[6] = "NoAmmo"; -}; +//-------------------------------------- +// Mortar +//-------------------------------------- + +//-------------------------------------------------------------------------- +// Force-Feedback Effects +//-------------------------------------- +datablock EffectProfile(MortarSwitchEffect) +{ + effectname = "weapons/mortar_activate"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock EffectProfile(MortarFireEffect) +{ + effectname = "weapons/mortar_fire"; + minDistance = 2.5; + maxDistance = 5.0; +}; + +datablock EffectProfile(MortarReloadEffect) +{ + effectname = "weapons/mortar_reload"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock EffectProfile(MortarDryFireEffect) +{ + effectname = "weapons/mortar_dryfire"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock EffectProfile(MortarExplosionEffect) +{ + effectname = "explosions/explosion.xpl03"; + minDistance = 30; + maxDistance = 65; +}; + +//-------------------------------------------------------------------------- +// Sounds +//-------------------------------------- +datablock AudioProfile(MortarSwitchSound) +{ + filename = "fx/weapons/mortar_activate.wav"; + description = AudioClosest3d; + preload = true; + effect = MortarSwitchEffect; +}; + +datablock AudioProfile(MortarReloadSound) +{ + filename = "fx/weapons/mortar_reload.wav"; + description = AudioClosest3d; + preload = true; + effect = MortarReloadEffect; +}; + +// DELETE IF NOT NEEDED +//datablock AudioProfile(MortarIdleSound) +//{ +// filename = "fx/weapons/weapon.mortarIdle.wav"; +// description = ClosestLooping3d; +// preload = true; +//}; + +datablock AudioProfile(MortarFireSound) +{ + filename = "fx/weapons/mortar_fire.wav"; + description = AudioDefault3d; + preload = true; + effect = MortarFireEffect; +}; + +datablock AudioProfile(MortarProjectileSound) +{ + filename = "fx/weapons/mortar_projectile.wav"; + description = ProjectileLooping3d; + preload = true; +}; + +datablock AudioProfile(MortarExplosionSound) +{ + filename = "fx/weapons/mortar_explode.wav"; + description = AudioBIGExplosion3d; + preload = true; + effect = MortarExplosionEffect; +}; + +datablock AudioProfile(UnderwaterMortarExplosionSound) +{ + filename = "fx/weapons/mortar_explode_UW.wav"; + description = AudioBIGExplosion3d; + preload = true; + effect = MortarExplosionEffect; +}; + +datablock AudioProfile(MortarDryFireSound) +{ + filename = "fx/weapons/mortar_dryfire.wav"; + description = AudioClose3d; + preload = true; + effect = MortarDryFireEffect; +}; + +//---------------------------------------------------------------------------- +// Bubbles +//---------------------------------------------------------------------------- +datablock ParticleData(MortarBubbleParticle) +{ + dragCoefficient = 0.0; + gravityCoefficient = -0.25; + inheritedVelFactor = 0.0; + constantAcceleration = 0.0; + lifetimeMS = 1500; + lifetimeVarianceMS = 600; + useInvAlpha = false; + textureName = "special/bubbles"; + + spinRandomMin = -100.0; + spinRandomMax = 100.0; + + colors[0] = "0.7 0.8 1.0 0.4"; + colors[1] = "0.7 0.8 1.0 0.4"; + colors[2] = "0.7 0.8 1.0 0.0"; + sizes[0] = 0.8; + sizes[1] = 0.8; + sizes[2] = 0.8; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; +}; + +datablock ParticleEmitterData(MortarBubbleEmitter) +{ + ejectionPeriodMS = 9; + periodVarianceMS = 0; + ejectionVelocity = 1.0; + ejectionOffset = 0.1; + velocityVariance = 0.5; + thetaMin = 0; + thetaMax = 80; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + particles = "MortarBubbleParticle"; +}; + +//-------------------------------------------------------------------------- +// Splash +//-------------------------------------------------------------------------- +datablock ParticleData( MortarSplashParticle ) +{ + dragCoefficient = 1; + gravityCoefficient = 0.0; + inheritedVelFactor = 0.2; + constantAcceleration = -1.4; + lifetimeMS = 300; + lifetimeVarianceMS = 0; + textureName = "special/droplet"; + colors[0] = "0.7 0.8 1.0 1.0"; + colors[1] = "0.7 0.8 1.0 0.5"; + colors[2] = "0.7 0.8 1.0 0.0"; + sizes[0] = 0.05; + sizes[1] = 0.2; + sizes[2] = 0.2; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; +}; + +datablock ParticleEmitterData( MortarSplashEmitter ) +{ + ejectionPeriodMS = 4; + periodVarianceMS = 0; + ejectionVelocity = 3; + velocityVariance = 1.0; + ejectionOffset = 0.0; + thetaMin = 0; + thetaMax = 50; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + orientParticles = true; + lifetimeMS = 100; + particles = "MortarSplashParticle"; +}; + + +datablock SplashData(MortarSplash) +{ + numSegments = 10; + ejectionFreq = 10; + ejectionAngle = 20; + ringLifetime = 0.4; + lifetimeMS = 400; + velocity = 3.0; + startRadius = 0.0; + acceleration = -3.0; + texWrap = 5.0; + + texture = "special/water2"; + + emitter[0] = MortarSplashEmitter; + + colors[0] = "0.7 0.8 1.0 0.0"; + colors[1] = "0.7 0.8 1.0 1.0"; + colors[2] = "0.7 0.8 1.0 0.0"; + colors[3] = "0.7 0.8 1.0 0.0"; + times[0] = 0.0; + times[1] = 0.4; + times[2] = 0.8; + times[3] = 1.0; +}; + +//--------------------------------------------------------------------------- +// Mortar Shockwaves +//--------------------------------------------------------------------------- +datablock ShockwaveData(UnderwaterMortarShockwave) +{ + width = 6.0; + numSegments = 32; + numVertSegments = 6; + velocity = 10; + acceleration = 20.0; + lifetimeMS = 900; + height = 1.0; + verticalCurve = 0.5; + is2D = false; + + texture[0] = "special/shockwave4"; + texture[1] = "special/gradient"; + texWrap = 6.0; + + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; + + colors[0] = "0.4 0.4 1.0 0.50"; + colors[1] = "0.4 0.4 1.0 0.25"; + colors[2] = "0.4 0.4 1.0 0.0"; + + mapToTerrain = true; + orientToNormal = false; + renderBottom = false; +}; + +datablock ShockwaveData(MortarShockwave) +{ + width = 6.0; + numSegments = 32; + numVertSegments = 6; + velocity = 15; + acceleration = 20.0; + lifetimeMS = 500; + height = 1.0; + verticalCurve = 0.5; + is2D = false; + + texture[0] = "special/shockwave4"; + texture[1] = "special/gradient"; + texWrap = 6.0; + + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; + + colors[0] = "0.4 1.0 0.4 0.50"; + colors[1] = "0.4 1.0 0.4 0.25"; + colors[2] = "0.4 1.0 0.4 0.0"; + + mapToTerrain = true; + orientToNormal = false; + renderBottom = false; +}; + + +//-------------------------------------------------------------------------- +// Mortar Explosion Particle effects +//-------------------------------------- +datablock ParticleData( MortarCrescentParticle ) +{ + dragCoefficient = 2; + gravityCoefficient = 0.0; + inheritedVelFactor = 0.2; + constantAcceleration = -0.0; + lifetimeMS = 600; + lifetimeVarianceMS = 000; + textureName = "special/crescent3"; + colors[0] = "0.7 1.0 0.7 1.0"; + colors[1] = "0.7 1.0 0.7 0.5"; + colors[2] = "0.7 1.0 0.7 0.0"; + sizes[0] = 4.0; + sizes[1] = 8.0; + sizes[2] = 9.0; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; +}; + +datablock ParticleEmitterData( MortarCrescentEmitter ) +{ + ejectionPeriodMS = 25; + periodVarianceMS = 0; + ejectionVelocity = 40; + velocityVariance = 5.0; + ejectionOffset = 0.0; + thetaMin = 0; + thetaMax = 80; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + orientParticles = true; + lifetimeMS = 200; + particles = "MortarCrescentParticle"; +}; + + +datablock ParticleData(MortarExplosionSmoke) +{ + dragCoeffiecient = 0.4; + gravityCoefficient = -0.30; // rises slowly + inheritedVelFactor = 0.025; + + lifetimeMS = 1250; + lifetimeVarianceMS = 500; + + textureName = "particleTest"; + + useInvAlpha = true; + spinRandomMin = -100.0; + spinRandomMax = 100.0; + + textureName = "special/Smoke/bigSmoke"; + + colors[0] = "0.7 0.7 0.7 0.0"; + colors[1] = "0.4 0.4 0.4 0.5"; + colors[2] = "0.4 0.4 0.4 0.5"; + colors[3] = "0.4 0.4 0.4 0.0"; + sizes[0] = 5.0; + sizes[1] = 6.0; + sizes[2] = 10.0; + sizes[3] = 12.0; + times[0] = 0.0; + times[1] = 0.333; + times[2] = 0.666; + times[3] = 1.0; + + + +}; + +datablock ParticleEmitterData(MortarExplosionSmokeEmitter) +{ + ejectionPeriodMS = 10; + periodVarianceMS = 0; + + ejectionOffset = 8.0; + + + ejectionVelocity = 1.25; + velocityVariance = 1.2; + + thetaMin = 0.0; + thetaMax = 90.0; + + lifetimeMS = 500; + + particles = "MortarExplosionSmoke"; + +}; + +//--------------------------------------------------------------------------- +// Underwater Explosion +//--------------------------------------------------------------------------- +datablock ParticleData(UnderwaterExplosionSparks) +{ + dragCoefficient = 0; + gravityCoefficient = 0.0; + inheritedVelFactor = 0.2; + constantAcceleration = 0.0; + lifetimeMS = 500; + lifetimeVarianceMS = 350; + textureName = "special/crescent3"; + colors[0] = "0.4 0.4 1.0 1.0"; + colors[1] = "0.4 0.4 1.0 1.0"; + colors[2] = "0.4 0.4 1.0 0.0"; + sizes[0] = 3.5; + sizes[1] = 3.5; + sizes[2] = 3.5; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; + +}; + +datablock ParticleEmitterData(UnderwaterExplosionSparksEmitter) +{ + ejectionPeriodMS = 2; + periodVarianceMS = 0; + ejectionVelocity = 17; + velocityVariance = 4; + ejectionOffset = 0.0; + thetaMin = 0; + thetaMax = 60; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + orientParticles = true; + lifetimeMS = 100; + particles = "UnderwaterExplosionSparks"; +}; + +datablock ParticleData(MortarExplosionBubbleParticle) +{ + dragCoefficient = 0.0; + gravityCoefficient = -0.25; + inheritedVelFactor = 0.0; + constantAcceleration = 0.0; + lifetimeMS = 1500; + lifetimeVarianceMS = 600; + useInvAlpha = false; + textureName = "special/bubbles"; + + spinRandomMin = -100.0; + spinRandomMax = 100.0; + + colors[0] = "0.7 0.8 1.0 0.0"; + colors[1] = "0.7 0.8 1.0 0.4"; + colors[2] = "0.7 0.8 1.0 0.0"; + sizes[0] = 2.0; + sizes[1] = 2.0; + sizes[2] = 2.0; + times[0] = 0.0; + times[1] = 0.8; + times[2] = 1.0; +}; +datablock ParticleEmitterData(MortarExplosionBubbleEmitter) +{ + ejectionPeriodMS = 5; + periodVarianceMS = 0; + ejectionVelocity = 1.0; + ejectionOffset = 7.0; + velocityVariance = 0.5; + thetaMin = 0; + thetaMax = 80; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + particles = "MortarExplosionBubbleParticle"; +}; + +datablock DebrisData( UnderwaterMortarDebris ) +{ + emitters[0] = MortarExplosionBubbleEmitter; + + explodeOnMaxBounce = true; + + elasticity = 0.4; + friction = 0.2; + + lifetime = 1.5; + lifetimeVariance = 0.2; + + numBounces = 1; +}; + +datablock ExplosionData(UnderwaterMortarSubExplosion1) +{ + explosionShape = "disc_explosion.dts"; + faceViewer = true; + delayMS = 100; + offset = 3.0; + playSpeed = 1.5; + + sizes[0] = "0.75 0.75 0.75"; + sizes[1] = "1.0 1.0 1.0"; + sizes[2] = "0.5 0.5 0.5"; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; + +}; + +datablock ExplosionData(UnderwaterMortarSubExplosion2) +{ + explosionShape = "disc_explosion.dts"; + faceViewer = true; + delayMS = 50; + offset = 3.0; + playSpeed = 0.75; + + sizes[0] = "1.5 1.5 1.5"; + sizes[1] = "1.5 1.5 1.5"; + sizes[2] = "1.0 1.0 1.0"; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; +}; + +datablock ExplosionData(UnderwaterMortarSubExplosion3) +{ + explosionShape = "disc_explosion.dts"; + faceViewer = true; + delayMS = 0; + offset = 0.0; + playSpeed = 0.5; + + sizes[0] = "1.0 1.0 1.0"; + sizes[1] = "2.0 2.0 2.0"; + sizes[2] = "1.5 1.5 1.5"; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; + +}; + +datablock ExplosionData(UnderwaterMortarExplosion) +{ + soundProfile = UnderwaterMortarExplosionSound; + + shockwave = UnderwaterMortarShockwave; + shockwaveOnTerrain = true; + + subExplosion[0] = UnderwaterMortarSubExplosion1; + subExplosion[1] = UnderwaterMortarSubExplosion2; + subExplosion[2] = UnderwaterMortarSubExplosion3; + + emitter[0] = MortarExplosionBubbleEmitter; + emitter[1] = UnderwaterExplosionSparksEmitter; + + shakeCamera = true; + camShakeFreq = "8.0 9.0 7.0"; + camShakeAmp = "100.0 100.0 100.0"; + camShakeDuration = 1.3; + camShakeRadius = 25.0; +}; + + +//--------------------------------------------------------------------------- +// Explosion +//--------------------------------------------------------------------------- + +datablock ExplosionData(MortarSubExplosion1) +{ + explosionShape = "mortar_explosion.dts"; + faceViewer = true; + + delayMS = 100; + + offset = 5.0; + + playSpeed = 1.5; + + sizes[0] = "0.5 0.5 0.5"; + sizes[1] = "0.5 0.5 0.5"; + times[0] = 0.0; + times[1] = 1.0; + +}; + +datablock ExplosionData(MortarSubExplosion2) +{ + explosionShape = "mortar_explosion.dts"; + faceViewer = true; + + delayMS = 50; + + offset = 5.0; + + playSpeed = 1.0; + + sizes[0] = "1.0 1.0 1.0"; + sizes[1] = "1.0 1.0 1.0"; + times[0] = 0.0; + times[1] = 1.0; +}; + +datablock ExplosionData(MortarSubExplosion3) +{ + explosionShape = "mortar_explosion.dts"; + faceViewer = true; + delayMS = 0; + offset = 0.0; + playSpeed = 0.7; + + sizes[0] = "1.0 1.0 1.0"; + sizes[1] = "2.0 2.0 2.0"; + times[0] = 0.0; + times[1] = 1.0; + +}; + +datablock ExplosionData(MortarExplosion) +{ + soundProfile = MortarExplosionSound; + + shockwave = MortarShockwave; + shockwaveOnTerrain = true; + + subExplosion[0] = MortarSubExplosion1; + subExplosion[1] = MortarSubExplosion2; + subExplosion[2] = MortarSubExplosion3; + + emitter[0] = MortarExplosionSmokeEmitter; + emitter[1] = MortarCrescentEmitter; + + shakeCamera = true; + camShakeFreq = "8.0 9.0 7.0"; + camShakeAmp = "100.0 100.0 100.0"; + camShakeDuration = 1.3; + camShakeRadius = 25.0; +}; + +//--------------------------------------------------------------------------- +// Smoke particles +//--------------------------------------------------------------------------- +datablock ParticleData(MortarSmokeParticle) +{ + dragCoeffiecient = 0.4; + gravityCoefficient = -0.3; // rises slowly + inheritedVelFactor = 0.125; + + lifetimeMS = 1200; + lifetimeVarianceMS = 200; + useInvAlpha = true; + spinRandomMin = -100.0; + spinRandomMax = 100.0; + + animateTexture = false; + + textureName = "special/Smoke/bigSmoke"; + + colors[0] = "0.7 1.0 0.7 0.5"; + colors[1] = "0.3 0.7 0.3 0.8"; + colors[2] = "0.0 0.0 0.0 0.0"; + sizes[0] = 1.0; + sizes[1] = 2.0; + sizes[2] = 4.5; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; + +}; + + +datablock ParticleEmitterData(MortarSmokeEmitter) +{ + ejectionPeriodMS = 10; + periodVarianceMS = 3; + + ejectionVelocity = 2.25; + velocityVariance = 0.55; + + thetaMin = 0.0; + thetaMax = 40.0; + + particles = "MortarSmokeParticle"; +}; + + +//-------------------------------------------------------------------------- +// Projectile +//-------------------------------------- +datablock GrenadeProjectileData(MortarShot) +{ + projectileShapeName = "mortar_projectile.dts"; + emitterDelay = -1; + directDamage = 0.0; + hasDamageRadius = true; + indirectDamage = 1.0; + damageRadius = 19.0; // z0dd - ZOD, 8/13/02. Was 20.0 + radiusDamageType = $DamageType::Mortar; + kickBackStrength = 2500; + + explosion = "MortarExplosion"; + underwaterExplosion = "UnderwaterMortarExplosion"; + velInheritFactor = 0.5; + splash = MortarSplash; + depthTolerance = 10.0; // depth at which it uses underwater explosion + + baseEmitter = MortarSmokeEmitter; + bubbleEmitter = MortarBubbleEmitter; + + grenadeElasticity = 0.15; + grenadeFriction = 0.4; + armingDelayMS = 1500; // z0dd - ZOD, 4/14/02. Was 2000 + + gravityMod = 1.1; // z0dd - ZOD, 5/18/02. Make mortar projectile heavier, less floaty + muzzleVelocity = 75.95; // z0dd - ZOD, 8/13/02. More velocity to compensate for higher gravity. Was 63.7 + drag = 0.1; + sound = MortarProjectileSound; + + hasLight = true; + lightRadius = 4; + lightColor = "0.05 0.2 0.05"; + + hasLightUnderwaterColor = true; + underWaterLightColor = "0.05 0.075 0.2"; + +}; + +//-------------------------------------------------------------------------- +// Ammo +//-------------------------------------- + +datablock ItemData(MortarAmmo) +{ + className = Ammo; + catagory = "Ammo"; + shapeFile = "ammo_mortar.dts"; + mass = 1; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 2; + pickUpName = "some mortar ammo"; + + computeCRC = true; + +}; + +//-------------------------------------------------------------------------- +// Weapon +//-------------------------------------- +datablock ItemData(Mortar) +{ + className = Weapon; + catagory = "Spawn Items"; + shapeFile = "weapon_mortar.dts"; + image = MortarImage; + mass = 1; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 2; + pickUpName = "a mortar gun"; + + computeCRC = true; + emap = true; +}; + +datablock ShapeBaseImageData(MortarImage) +{ + className = WeaponImage; + shapeFile = "weapon_mortar.dts"; + item = Mortar; + ammo = MortarAmmo; + offset = "0 0 0"; + emap = true; + + projectile = MortarShot; + projectileType = GrenadeProjectile; + + stateName[0] = "Activate"; + stateTransitionOnTimeout[0] = "ActivateReady"; + stateTimeoutValue[0] = 0.5; + stateSequence[0] = "Activate"; + stateSound[0] = MortarSwitchSound; + + stateName[1] = "ActivateReady"; + stateTransitionOnLoaded[1] = "Ready"; + stateTransitionOnNoAmmo[1] = "NoAmmo"; + + stateName[2] = "Ready"; + stateTransitionOnNoAmmo[2] = "NoAmmo"; + stateTransitionOnTriggerDown[2] = "Fire"; + //stateSound[2] = MortarIdleSound; + + stateName[3] = "Fire"; + stateSequence[3] = "Recoil"; + stateTransitionOnTimeout[3] = "Reload"; + stateTimeoutValue[3] = 0.8; + stateFire[3] = true; + stateRecoil[3] = LightRecoil; + stateAllowImageChange[3] = false; + stateScript[3] = "onFire"; + stateSound[3] = MortarFireSound; + + stateName[4] = "Reload"; + stateTransitionOnNoAmmo[4] = "NoAmmo"; + stateTransitionOnTimeout[4] = "Ready"; + stateTimeoutValue[4] = 2.0; + stateAllowImageChange[4] = false; + stateSequence[4] = "Reload"; + stateSound[4] = MortarReloadSound; + + stateName[5] = "NoAmmo"; + stateTransitionOnAmmo[5] = "Reload"; + stateSequence[5] = "NoAmmo"; + stateTransitionOnTriggerDown[5] = "DryFire"; + + stateName[6] = "DryFire"; + stateSound[6] = MortarDryFireSound; + stateTimeoutValue[6] = 1.5; + stateTransitionOnTimeout[6] = "NoAmmo"; +}; diff --git a/scripts/weapons/plasma.cs b/scripts/weapons/plasma.cs index e1bf1fd..0996108 100644 --- a/scripts/weapons/plasma.cs +++ b/scripts/weapons/plasma.cs @@ -1,493 +1,493 @@ -//-------------------------------------- -// Plasma rifle -//-------------------------------------- - -//-------------------------------------------------------------------------- -// Force-Feedback Effects -//-------------------------------------- -datablock EffectProfile(PlasmaSwitchEffect) -{ - effectname = "weapons/plasma_rifle_activate"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(PlasmaFireEffect) -{ - effectname = "weapons/plasma_fire"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(PlasmaDryFireEffect) -{ - effectname = "weapons/plasma_dryfire"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(PlasmaIdleEffect) -{ - effectname = "weapons/plasma_rifle_idle"; - minDistance = 2.5; -}; - -datablock EffectProfile(PlasmaReloadEffect) -{ - effectname = "weapons/plasma_rifle_reload"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(PlasmaExpEffect) -{ - effectname = "explosions/explosion.xpl10"; - minDistance = 10; - maxDistance = 25; -}; - -//-------------------------------------------------------------------------- -// Sounds -//-------------------------------------- -datablock AudioProfile(PlasmaSwitchSound) -{ - filename = "fx/weapons/plasma_rifle_activate.wav"; - description = AudioClosest3d; - preload = true; - effect = PlasmaSwitchEffect; -}; - -datablock AudioProfile(PlasmaFireSound) -{ - filename = "fx/weapons/plasma_rifle_fire.wav"; - description = AudioDefault3d; - preload = true; - effect = PlasmaFireEffect; -}; - -datablock AudioProfile(PlasmaIdleSound) -{ - filename = "fx/weapons/plasma_rifle_idle.wav"; - description = ClosestLooping3d; - preload = true; - //effect = PlasmaIdleEffect; -}; - -datablock AudioProfile(PlasmaReloadSound) -{ - filename = "fx/weapons/plasma_rifle_reload.wav"; - description = Audioclosest3d; - preload = true; - effect = PlasmaReloadEffect; -}; - -datablock AudioProfile(plasmaExpSound) -{ - filename = "fx/explosions/explosion.xpl10.wav"; - description = AudioExplosion3d; - effect = PlasmaExpEffect; -}; - -datablock AudioProfile(PlasmaProjectileSound) -{ - filename = "fx/weapons/plasma_rifle_projectile.WAV"; - description = ProjectileLooping3d; - preload = true; -}; - -datablock AudioProfile(PlasmaDryFireSound) -{ - filename = "fx/weapons/plasma_dryfire.wav"; - description = AudioClose3d; - preload = true; - effect = PlasmaDryFireEffect; -}; - -datablock AudioProfile(PlasmaFireWetSound) -{ - filename = "fx/weapons/plasma_fizzle.wav"; - description = AudioClose3d; - preload = true; -}; -//-------------------------------------------------------------------------- -// Explosion -//-------------------------------------- -datablock ParticleData(PlasmaExplosionParticle) -{ - dragCoefficient = 2; - gravityCoefficient = 0.2; - inheritedVelFactor = 0.2; - constantAcceleration = 0.0; - lifetimeMS = 750; - lifetimeVarianceMS = 150; - textureName = "particleTest"; - colors[0] = "0.56 0.36 0.26 1.0"; - colors[1] = "0.56 0.36 0.26 0.0"; - sizes[0] = 0.5; - sizes[1] = 2; -}; - -datablock ParticleEmitterData(PlasmaExplosionEmitter) -{ - ejectionPeriodMS = 7; - periodVarianceMS = 0; - ejectionVelocity = 5; - velocityVariance = 1.0; - ejectionOffset = 0.0; - thetaMin = 0; - thetaMax = 60; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - particles = "PlasmaExplosionParticle"; -}; - -datablock ExplosionData(PlasmaBoltExplosion) -{ - explosionShape = "effect_plasma_explosion.dts"; - soundProfile = plasmaExpSound; - particleEmitter = PlasmaExplosionEmitter; - particleDensity = 150; - particleRadius = 1.25; - faceViewer = true; - - sizes[0] = "1.0 1.0 1.0"; - sizes[1] = "1.0 1.0 1.0"; - times[0] = 0.0; - times[1] = 1.5; -}; - - -//-------------------------------------------------------------------------- -// Splash -//-------------------------------------------------------------------------- -datablock ParticleData(PlasmaMist) -{ - dragCoefficient = 2.0; - gravityCoefficient = -0.05; - inheritedVelFactor = 0.0; - constantAcceleration = 0.0; - lifetimeMS = 400; - lifetimeVarianceMS = 100; - useInvAlpha = false; - spinRandomMin = -90.0; - spinRandomMax = 500.0; - textureName = "particleTest"; - colors[0] = "0.7 0.8 1.0 1.0"; - colors[1] = "0.7 0.8 1.0 0.5"; - colors[2] = "0.7 0.8 1.0 0.0"; - sizes[0] = 0.5; - sizes[1] = 0.5; - sizes[2] = 0.8; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData(PlasmaMistEmitter) -{ - ejectionPeriodMS = 5; - periodVarianceMS = 0; - ejectionVelocity = 3.0; - velocityVariance = 2.0; - ejectionOffset = 0.0; - thetaMin = 85; - thetaMax = 85; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - lifetimeMS = 250; - particles = "PlasmaMist"; -}; - -datablock ParticleData( PlasmaSplashParticle2 ) -{ - - dragCoeffiecient = 0.4; - gravityCoefficient = -0.03; // rises slowly - inheritedVelFactor = 0.025; - - lifetimeMS = 600; - lifetimeVarianceMS = 300; - - textureName = "particleTest"; - - useInvAlpha = false; - spinRandomMin = -200.0; - spinRandomMax = 200.0; - - - colors[0] = "0.7 0.8 1.0 1.0"; - colors[1] = "0.7 0.8 1.0 0.5"; - colors[2] = "0.7 0.8 1.0 0.0"; - sizes[0] = 0.5; - sizes[1] = 1.0; - sizes[2] = 2.0; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData( PlasmaSplashEmitter2 ) -{ - ejectionPeriodMS = 25; - ejectionOffset = 0.2; - periodVarianceMS = 0; - ejectionVelocity = 2.25; - velocityVariance = 0.50; - thetaMin = 0.0; - thetaMax = 30.0; - lifetimeMS = 250; - - particles = "PlasmaSplashParticle2"; -}; - - -datablock ParticleData( PlasmaSplashParticle ) -{ - dragCoefficient = 1; - gravityCoefficient = 0.2; - inheritedVelFactor = 0.2; - constantAcceleration = -0.0; - lifetimeMS = 600; - lifetimeVarianceMS = 0; - textureName = "special/droplet"; - colors[0] = "0.7 0.8 1.0 1.0"; - colors[1] = "0.7 0.8 1.0 0.5"; - colors[2] = "0.7 0.8 1.0 0.0"; - sizes[0] = 0.5; - sizes[1] = 0.5; - sizes[2] = 0.5; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData( PlasmaSplashEmitter ) -{ - ejectionPeriodMS = 1; - periodVarianceMS = 0; - ejectionVelocity = 3; - velocityVariance = 1.0; - ejectionOffset = 0.0; - thetaMin = 60; - thetaMax = 80; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - orientParticles = true; - lifetimeMS = 100; - particles = "PlasmaSplashParticle"; -}; - - -datablock SplashData(PlasmaSplash) -{ - numSegments = 15; - ejectionFreq = 0.0001; - ejectionAngle = 45; - ringLifetime = 0.5; - lifetimeMS = 400; - velocity = 5.0; - startRadius = 0.0; - acceleration = -3.0; - texWrap = 5.0; - - texture = "special/water2"; - - emitter[0] = PlasmaSplashEmitter; - emitter[1] = PlasmaSplashEmitter2; - emitter[2] = PlasmaMistEmitter; - - colors[0] = "0.7 0.8 1.0 0.0"; - colors[1] = "0.7 0.8 1.0 1.0"; - colors[2] = "0.7 0.8 1.0 0.0"; - colors[3] = "0.7 0.8 1.0 0.0"; - times[0] = 0.0; - times[1] = 0.4; - times[2] = 0.8; - times[3] = 1.0; -}; - -//-------------------------------------------------------------------------- -// Projectile -//-------------------------------------- -datablock ParticleData(PlasmaRifleParticle) -{ - dragCoefficient = 2.75; - gravityCoefficient = 0.1; - inheritedVelFactor = 0.2; - constantAcceleration = 0.0; - lifetimeMS = 550; - lifetimeVarianceMS = 0; - textureName = "particleTest"; - colors[0] = "0.46 0.36 0.26 1.0"; - colors[1] = "0.46 0.36 0.26 0.0"; - sizes[0] = 0.25; - sizes[1] = 0.20; -}; - -datablock ParticleEmitterData(PlasmaRifleEmitter) -{ - ejectionPeriodMS = 3; - periodVarianceMS = 0; - ejectionVelocity = 10; - velocityVariance = 1.0; - ejectionOffset = 0.0; - thetaMin = 0; - thetaMax = 12; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvance = true; - particles = "PlasmaRifleParticle"; -}; - - - -//-------------------------------------------------------------------------- -// Projectile -//-------------------------------------- -datablock LinearFlareProjectileData(PlasmaBolt) -{ - projectileShapeName = "plasmabolt.dts"; - scale = "2.0 2.0 2.0"; - faceViewer = true; - directDamage = 0.0; - hasDamageRadius = true; - indirectDamage = 0.45; - damageRadius = 4.0; - kickBackStrength = 0.0; - radiusDamageType = $DamageType::Plasma; - - explosion = "PlasmaBoltExplosion"; - splash = PlasmaSplash; - - dryVelocity = 70.0; // z0dd - ZOD, 7/20/02. Faster plasma projectile. was 55 - wetVelocity = -1; - velInheritFactor = 0.3; - fizzleTimeMS = 2000; - lifetimeMS = 3000; - explodeOnDeath = false; - reflectOnWaterImpactAngle = 0.0; - explodeOnWaterImpact = true; - deflectionOnWaterImpact = 0.0; - fizzleUnderwaterMS = -1; - - //activateDelayMS = 100; - activateDelayMS = -1; - - size[0] = 0.2; - size[1] = 0.5; - size[2] = 0.1; - - - numFlares = 35; - flareColor = "1 0.75 0.25"; - flareModTexture = "flaremod"; - flareBaseTexture = "flarebase"; - - sound = PlasmaProjectileSound; - fireSound = PlasmaFireSound; - wetFireSound = PlasmaFireWetSound; - - hasLight = true; - lightRadius = 3.0; - lightColor = "1 0.75 0.25"; -}; - - -//-------------------------------------------------------------------------- -// Ammo -//-------------------------------------- - -datablock ItemData(PlasmaAmmo) -{ - className = Ammo; - catagory = "Ammo"; - shapeFile = "ammo_plasma.dts"; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - pickUpName = "some plasma gun ammo"; -}; - -//-------------------------------------------------------------------------- -// Weapon -//-------------------------------------- -datablock ItemData(Plasma) -{ - className = Weapon; - catagory = "Spawn Items"; - shapeFile = "weapon_plasma.dts"; - image = PlasmaImage; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - pickUpName = "a plasma gun"; -}; - -datablock ShapeBaseImageData(PlasmaImage) -{ - className = WeaponImage; - shapeFile = "weapon_plasma.dts"; - item = Plasma; - ammo = PlasmaAmmo; - offset = "0 0 0"; - - projectile = PlasmaBolt; - projectileType = LinearFlareProjectile; - - stateName[0] = "Activate"; - stateTransitionOnTimeout[0] = "ActivateReady"; - stateTimeoutValue[0] = 0.5; - stateSequence[0] = "Activate"; - stateSound[0] = PlasmaSwitchSound; - - stateName[1] = "ActivateReady"; - stateTransitionOnLoaded[1] = "Ready"; - stateTransitionOnNoAmmo[1] = "NoAmmo"; - - stateName[2] = "Ready"; - stateTransitionOnNoAmmo[2] = "NoAmmo"; - stateTransitionOnTriggerDown[2] = "CheckWet"; - - stateName[3] = "Fire"; - stateTransitionOnTimeout[3] = "Reload"; - stateTimeoutValue[3] = 0.1; - stateFire[3] = true; - stateRecoil[3] = LightRecoil; - stateAllowImageChange[3] = false; - stateScript[3] = "onFire"; - stateEmitterTime[3] = 0.2; - stateSound[3] = PlasmaFireSound; - - stateName[4] = "Reload"; - stateTransitionOnNoAmmo[4] = "NoAmmo"; - stateTransitionOnTimeout[4] = "Ready"; - stateTimeoutValue[4] = 0.6; - stateAllowImageChange[4] = false; - stateSequence[4] = "Reload"; - stateSound[4] = PlasmaReloadSound; - - stateName[5] = "NoAmmo"; - stateTransitionOnAmmo[5] = "Reload"; - stateSequence[5] = "NoAmmo"; - stateTransitionOnTriggerDown[5] = "DryFire"; - - stateName[6] = "DryFire"; - stateSound[6] = PlasmaDryFireSound; - stateTimeoutValue[6] = 1.5; - stateTransitionOnTimeout[6] = "NoAmmo"; - - stateName[7] = "WetFire"; - stateSound[7] = PlasmaFireWetSound; - stateTimeoutValue[7] = 1.5; - stateTransitionOnTimeout[7] = "Ready"; - - stateName[8] = "CheckWet"; - stateTransitionOnWet[8] = "WetFire"; - stateTransitionOnNotWet[8] = "Fire"; -}; - +//-------------------------------------- +// Plasma rifle +//-------------------------------------- + +//-------------------------------------------------------------------------- +// Force-Feedback Effects +//-------------------------------------- +datablock EffectProfile(PlasmaSwitchEffect) +{ + effectname = "weapons/plasma_rifle_activate"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock EffectProfile(PlasmaFireEffect) +{ + effectname = "weapons/plasma_fire"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock EffectProfile(PlasmaDryFireEffect) +{ + effectname = "weapons/plasma_dryfire"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock EffectProfile(PlasmaIdleEffect) +{ + effectname = "weapons/plasma_rifle_idle"; + minDistance = 2.5; +}; + +datablock EffectProfile(PlasmaReloadEffect) +{ + effectname = "weapons/plasma_rifle_reload"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock EffectProfile(PlasmaExpEffect) +{ + effectname = "explosions/explosion.xpl10"; + minDistance = 10; + maxDistance = 25; +}; + +//-------------------------------------------------------------------------- +// Sounds +//-------------------------------------- +datablock AudioProfile(PlasmaSwitchSound) +{ + filename = "fx/weapons/plasma_rifle_activate.wav"; + description = AudioClosest3d; + preload = true; + effect = PlasmaSwitchEffect; +}; + +datablock AudioProfile(PlasmaFireSound) +{ + filename = "fx/weapons/plasma_rifle_fire.wav"; + description = AudioDefault3d; + preload = true; + effect = PlasmaFireEffect; +}; + +datablock AudioProfile(PlasmaIdleSound) +{ + filename = "fx/weapons/plasma_rifle_idle.wav"; + description = ClosestLooping3d; + preload = true; + //effect = PlasmaIdleEffect; +}; + +datablock AudioProfile(PlasmaReloadSound) +{ + filename = "fx/weapons/plasma_rifle_reload.wav"; + description = Audioclosest3d; + preload = true; + effect = PlasmaReloadEffect; +}; + +datablock AudioProfile(plasmaExpSound) +{ + filename = "fx/explosions/explosion.xpl10.wav"; + description = AudioExplosion3d; + effect = PlasmaExpEffect; +}; + +datablock AudioProfile(PlasmaProjectileSound) +{ + filename = "fx/weapons/plasma_rifle_projectile.WAV"; + description = ProjectileLooping3d; + preload = true; +}; + +datablock AudioProfile(PlasmaDryFireSound) +{ + filename = "fx/weapons/plasma_dryfire.wav"; + description = AudioClose3d; + preload = true; + effect = PlasmaDryFireEffect; +}; + +datablock AudioProfile(PlasmaFireWetSound) +{ + filename = "fx/weapons/plasma_fizzle.wav"; + description = AudioClose3d; + preload = true; +}; +//-------------------------------------------------------------------------- +// Explosion +//-------------------------------------- +datablock ParticleData(PlasmaExplosionParticle) +{ + dragCoefficient = 2; + gravityCoefficient = 0.2; + inheritedVelFactor = 0.2; + constantAcceleration = 0.0; + lifetimeMS = 750; + lifetimeVarianceMS = 150; + textureName = "particleTest"; + colors[0] = "0.56 0.36 0.26 1.0"; + colors[1] = "0.56 0.36 0.26 0.0"; + sizes[0] = 0.5; + sizes[1] = 2; +}; + +datablock ParticleEmitterData(PlasmaExplosionEmitter) +{ + ejectionPeriodMS = 7; + periodVarianceMS = 0; + ejectionVelocity = 5; + velocityVariance = 1.0; + ejectionOffset = 0.0; + thetaMin = 0; + thetaMax = 60; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + particles = "PlasmaExplosionParticle"; +}; + +datablock ExplosionData(PlasmaBoltExplosion) +{ + explosionShape = "effect_plasma_explosion.dts"; + soundProfile = plasmaExpSound; + particleEmitter = PlasmaExplosionEmitter; + particleDensity = 150; + particleRadius = 1.25; + faceViewer = true; + + sizes[0] = "1.0 1.0 1.0"; + sizes[1] = "1.0 1.0 1.0"; + times[0] = 0.0; + times[1] = 1.5; +}; + + +//-------------------------------------------------------------------------- +// Splash +//-------------------------------------------------------------------------- +datablock ParticleData(PlasmaMist) +{ + dragCoefficient = 2.0; + gravityCoefficient = -0.05; + inheritedVelFactor = 0.0; + constantAcceleration = 0.0; + lifetimeMS = 400; + lifetimeVarianceMS = 100; + useInvAlpha = false; + spinRandomMin = -90.0; + spinRandomMax = 500.0; + textureName = "particleTest"; + colors[0] = "0.7 0.8 1.0 1.0"; + colors[1] = "0.7 0.8 1.0 0.5"; + colors[2] = "0.7 0.8 1.0 0.0"; + sizes[0] = 0.5; + sizes[1] = 0.5; + sizes[2] = 0.8; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; +}; + +datablock ParticleEmitterData(PlasmaMistEmitter) +{ + ejectionPeriodMS = 5; + periodVarianceMS = 0; + ejectionVelocity = 3.0; + velocityVariance = 2.0; + ejectionOffset = 0.0; + thetaMin = 85; + thetaMax = 85; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + lifetimeMS = 250; + particles = "PlasmaMist"; +}; + +datablock ParticleData( PlasmaSplashParticle2 ) +{ + + dragCoeffiecient = 0.4; + gravityCoefficient = -0.03; // rises slowly + inheritedVelFactor = 0.025; + + lifetimeMS = 600; + lifetimeVarianceMS = 300; + + textureName = "particleTest"; + + useInvAlpha = false; + spinRandomMin = -200.0; + spinRandomMax = 200.0; + + + colors[0] = "0.7 0.8 1.0 1.0"; + colors[1] = "0.7 0.8 1.0 0.5"; + colors[2] = "0.7 0.8 1.0 0.0"; + sizes[0] = 0.5; + sizes[1] = 1.0; + sizes[2] = 2.0; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; +}; + +datablock ParticleEmitterData( PlasmaSplashEmitter2 ) +{ + ejectionPeriodMS = 25; + ejectionOffset = 0.2; + periodVarianceMS = 0; + ejectionVelocity = 2.25; + velocityVariance = 0.50; + thetaMin = 0.0; + thetaMax = 30.0; + lifetimeMS = 250; + + particles = "PlasmaSplashParticle2"; +}; + + +datablock ParticleData( PlasmaSplashParticle ) +{ + dragCoefficient = 1; + gravityCoefficient = 0.2; + inheritedVelFactor = 0.2; + constantAcceleration = -0.0; + lifetimeMS = 600; + lifetimeVarianceMS = 0; + textureName = "special/droplet"; + colors[0] = "0.7 0.8 1.0 1.0"; + colors[1] = "0.7 0.8 1.0 0.5"; + colors[2] = "0.7 0.8 1.0 0.0"; + sizes[0] = 0.5; + sizes[1] = 0.5; + sizes[2] = 0.5; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; +}; + +datablock ParticleEmitterData( PlasmaSplashEmitter ) +{ + ejectionPeriodMS = 1; + periodVarianceMS = 0; + ejectionVelocity = 3; + velocityVariance = 1.0; + ejectionOffset = 0.0; + thetaMin = 60; + thetaMax = 80; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvances = false; + orientParticles = true; + lifetimeMS = 100; + particles = "PlasmaSplashParticle"; +}; + + +datablock SplashData(PlasmaSplash) +{ + numSegments = 15; + ejectionFreq = 0.0001; + ejectionAngle = 45; + ringLifetime = 0.5; + lifetimeMS = 400; + velocity = 5.0; + startRadius = 0.0; + acceleration = -3.0; + texWrap = 5.0; + + texture = "special/water2"; + + emitter[0] = PlasmaSplashEmitter; + emitter[1] = PlasmaSplashEmitter2; + emitter[2] = PlasmaMistEmitter; + + colors[0] = "0.7 0.8 1.0 0.0"; + colors[1] = "0.7 0.8 1.0 1.0"; + colors[2] = "0.7 0.8 1.0 0.0"; + colors[3] = "0.7 0.8 1.0 0.0"; + times[0] = 0.0; + times[1] = 0.4; + times[2] = 0.8; + times[3] = 1.0; +}; + +//-------------------------------------------------------------------------- +// Projectile +//-------------------------------------- +datablock ParticleData(PlasmaRifleParticle) +{ + dragCoefficient = 2.75; + gravityCoefficient = 0.1; + inheritedVelFactor = 0.2; + constantAcceleration = 0.0; + lifetimeMS = 550; + lifetimeVarianceMS = 0; + textureName = "particleTest"; + colors[0] = "0.46 0.36 0.26 1.0"; + colors[1] = "0.46 0.36 0.26 0.0"; + sizes[0] = 0.25; + sizes[1] = 0.20; +}; + +datablock ParticleEmitterData(PlasmaRifleEmitter) +{ + ejectionPeriodMS = 3; + periodVarianceMS = 0; + ejectionVelocity = 10; + velocityVariance = 1.0; + ejectionOffset = 0.0; + thetaMin = 0; + thetaMax = 12; + phiReferenceVel = 0; + phiVariance = 360; + overrideAdvance = true; + particles = "PlasmaRifleParticle"; +}; + + + +//-------------------------------------------------------------------------- +// Projectile +//-------------------------------------- +datablock LinearFlareProjectileData(PlasmaBolt) +{ + projectileShapeName = "plasmabolt.dts"; + scale = "2.0 2.0 2.0"; + faceViewer = true; + directDamage = 0.0; + hasDamageRadius = true; + indirectDamage = 0.45; + damageRadius = 4.0; + kickBackStrength = 0.0; + radiusDamageType = $DamageType::Plasma; + + explosion = "PlasmaBoltExplosion"; + splash = PlasmaSplash; + + dryVelocity = 70.0; // z0dd - ZOD, 7/20/02. Faster plasma projectile. was 55 + wetVelocity = -1; + velInheritFactor = 0.3; + fizzleTimeMS = 2000; + lifetimeMS = 3000; + explodeOnDeath = false; + reflectOnWaterImpactAngle = 0.0; + explodeOnWaterImpact = true; + deflectionOnWaterImpact = 0.0; + fizzleUnderwaterMS = -1; + + //activateDelayMS = 100; + activateDelayMS = -1; + + size[0] = 0.2; + size[1] = 0.5; + size[2] = 0.1; + + + numFlares = 35; + flareColor = "1 0.75 0.25"; + flareModTexture = "flaremod"; + flareBaseTexture = "flarebase"; + + sound = PlasmaProjectileSound; + fireSound = PlasmaFireSound; + wetFireSound = PlasmaFireWetSound; + + hasLight = true; + lightRadius = 3.0; + lightColor = "1 0.75 0.25"; +}; + + +//-------------------------------------------------------------------------- +// Ammo +//-------------------------------------- + +datablock ItemData(PlasmaAmmo) +{ + className = Ammo; + catagory = "Ammo"; + shapeFile = "ammo_plasma.dts"; + mass = 1; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 2; + pickUpName = "some plasma gun ammo"; +}; + +//-------------------------------------------------------------------------- +// Weapon +//-------------------------------------- +datablock ItemData(Plasma) +{ + className = Weapon; + catagory = "Spawn Items"; + shapeFile = "weapon_plasma.dts"; + image = PlasmaImage; + mass = 1; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 2; + pickUpName = "a plasma gun"; +}; + +datablock ShapeBaseImageData(PlasmaImage) +{ + className = WeaponImage; + shapeFile = "weapon_plasma.dts"; + item = Plasma; + ammo = PlasmaAmmo; + offset = "0 0 0"; + + projectile = PlasmaBolt; + projectileType = LinearFlareProjectile; + + stateName[0] = "Activate"; + stateTransitionOnTimeout[0] = "ActivateReady"; + stateTimeoutValue[0] = 0.5; + stateSequence[0] = "Activate"; + stateSound[0] = PlasmaSwitchSound; + + stateName[1] = "ActivateReady"; + stateTransitionOnLoaded[1] = "Ready"; + stateTransitionOnNoAmmo[1] = "NoAmmo"; + + stateName[2] = "Ready"; + stateTransitionOnNoAmmo[2] = "NoAmmo"; + stateTransitionOnTriggerDown[2] = "CheckWet"; + + stateName[3] = "Fire"; + stateTransitionOnTimeout[3] = "Reload"; + stateTimeoutValue[3] = 0.1; + stateFire[3] = true; + stateRecoil[3] = LightRecoil; + stateAllowImageChange[3] = false; + stateScript[3] = "onFire"; + stateEmitterTime[3] = 0.2; + stateSound[3] = PlasmaFireSound; + + stateName[4] = "Reload"; + stateTransitionOnNoAmmo[4] = "NoAmmo"; + stateTransitionOnTimeout[4] = "Ready"; + stateTimeoutValue[4] = 0.6; + stateAllowImageChange[4] = false; + stateSequence[4] = "Reload"; + stateSound[4] = PlasmaReloadSound; + + stateName[5] = "NoAmmo"; + stateTransitionOnAmmo[5] = "Reload"; + stateSequence[5] = "NoAmmo"; + stateTransitionOnTriggerDown[5] = "DryFire"; + + stateName[6] = "DryFire"; + stateSound[6] = PlasmaDryFireSound; + stateTimeoutValue[6] = 1.5; + stateTransitionOnTimeout[6] = "NoAmmo"; + + stateName[7] = "WetFire"; + stateSound[7] = PlasmaFireWetSound; + stateTimeoutValue[7] = 1.5; + stateTransitionOnTimeout[7] = "Ready"; + + stateName[8] = "CheckWet"; + stateTransitionOnWet[8] = "WetFire"; + stateTransitionOnNotWet[8] = "Fire"; +}; + diff --git a/scripts/weapons/shockLance.cs b/scripts/weapons/shockLance.cs index 507e76b..6a67620 100644 --- a/scripts/weapons/shockLance.cs +++ b/scripts/weapons/shockLance.cs @@ -1,297 +1,297 @@ -//-------------------------------------------------------------------------- -// Shock Lance -// -// -//-------------------------------------------------------------------------- - -datablock EffectProfile(ShockLanceSwitchEffect) -{ - effectname = "weapons/shocklance_activate"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(ShockLanceFireEffect) -{ - effectname = "weapons/shocklance_fire"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(ShockLanceReloadEffect) -{ - effectname = "weapons/shocklance_reload"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock AudioProfile(ShockLanceSwitchSound) -{ - filename = "fx/weapons/shocklance_activate.wav"; - description = AudioClosest3d; - preload = true; - effect = ShockLanceSwitchEffect; -}; - -//-------------------------------------------------------------------------- -// Explosion -//-------------------------------------- -datablock AudioProfile(ShockLanceHitSound) -{ - filename = "fx/weapons/shocklance_fire.WAV"; - description = AudioClose3d; - preload = true; - effect = ShockLanceFireEffect; -}; - -datablock AudioProfile(ShockLanceReloadSound) -{ - filename = "fx/weapons/shocklance_reload.WAV"; - description = AudioClosest3d; - preload = true; - effect = ShockLanceReloadEffect; -}; - -datablock AudioProfile(ShockLanceDryFireSound) -{ - filename = "fx/weapons/shocklance_dryfire.WAV"; - description = AudioClose3d; - preload = true; - effect = ShockLanceReloadEffect; -}; - -datablock AudioProfile(ShockLanceMissSound) -{ - filename = "fx/weapons/shocklance_miss.WAV"; - description = AudioExplosion3d; - preload = true; -}; - -//-------------------------------------------------------------------------- -// Particle data -//-------------------------------------------------------------------------- -datablock ParticleData(ShockParticle) -{ - dragCoeffiecient = 0.0; - gravityCoefficient = -0.0; - inheritedVelFactor = 0.0; - - lifetimeMS = 1000; - lifetimeVarianceMS = 0; - - textureName = "particleTest"; - - useInvAlpha = false; - spinRandomMin = -100.0; - spinRandomMax = 100.0; - - numParts = 50; - - animateTexture = true; - framesPerSec = 26; - - animTexName[00] = "special/Explosion/exp_0002"; - animTexName[01] = "special/Explosion/exp_0004"; - animTexName[02] = "special/Explosion/exp_0006"; - animTexName[03] = "special/Explosion/exp_0008"; - animTexName[04] = "special/Explosion/exp_0010"; - animTexName[05] = "special/Explosion/exp_0012"; - animTexName[06] = "special/Explosion/exp_0014"; - animTexName[07] = "special/Explosion/exp_0016"; - animTexName[08] = "special/Explosion/exp_0018"; - animTexName[09] = "special/Explosion/exp_0020"; - animTexName[10] = "special/Explosion/exp_0022"; - animTexName[11] = "special/Explosion/exp_0024"; - animTexName[12] = "special/Explosion/exp_0026"; - animTexName[13] = "special/Explosion/exp_0028"; - animTexName[14] = "special/Explosion/exp_0030"; - animTexName[15] = "special/Explosion/exp_0032"; - animTexName[16] = "special/Explosion/exp_0034"; - animTexName[17] = "special/Explosion/exp_0036"; - animTexName[18] = "special/Explosion/exp_0038"; - animTexName[19] = "special/Explosion/exp_0040"; - animTexName[20] = "special/Explosion/exp_0042"; - animTexName[21] = "special/Explosion/exp_0044"; - animTexName[22] = "special/Explosion/exp_0046"; - animTexName[23] = "special/Explosion/exp_0048"; - animTexName[24] = "special/Explosion/exp_0050"; - animTexName[25] = "special/Explosion/exp_0052"; - - - colors[0] = "0.5 0.5 1.0 1.0"; - colors[1] = "0.5 0.5 1.0 0.5"; - colors[2] = "0.25 0.25 1.0 0.0"; - sizes[0] = 0.5; - sizes[1] = 0.5; - sizes[2] = 0.5; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData(ShockParticleEmitter) -{ - ejectionPeriodMS = 1; - periodVarianceMS = 0; - - ejectionVelocity = 0.25; - velocityVariance = 0.0; - - thetaMin = 0.0; - thetaMax = 30.0; - - particles = "ShockParticle"; -}; - -//-------------------------------------------------------------------------- -// Shockwave -//-------------------------------------------------------------------------- -datablock ShockwaveData( ShocklanceHit ) -{ - width = 0.5; - numSegments = 20; - numVertSegments = 1; - velocity = 0.25; - acceleration = 1.0; - lifetimeMS = 600; - height = 0.1; - verticalCurve = 0.5; - - mapToTerrain = false; - renderBottom = false; - orientToNormal = true; - - texture[0] = "special/shocklanceHit"; - texture[1] = "special/gradient"; - texWrap = 3.0; - - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - - colors[0] = "1.0 1.0 1.0 1.0"; - colors[1] = "1.0 1.0 1.0 0.5"; - colors[2] = "1.0 1.0 1.0 0.0"; -}; - - -//-------------------------------------- -// Projectile -//-------------------------------------- -datablock ShockLanceProjectileData(BasicShocker) -{ - directDamage = 0.45; - radiusDamageType = $DamageType::ShockLance; - kickBackStrength = 2600; // z0dd - ZOD, 3/30/02. More lance kick. was 2500 - velInheritFactor = 0; - sound = ""; - - zapDuration = 1.0; - impulse = 1800; - boltLength = 16.0; // z0dd - ZOD, 3/30/02. was 14.0 - extension = 16.0; // script variable indicating distance you can shock people from. // z0dd - ZOD, 3/30/02. Was 14.0 - lightningFreq = 25.0; - lightningDensity = 3.0; - lightningAmp = 0.25; - lightningWidth = 0.05; - - shockwave = ShocklanceHit; - - boltSpeed[0] = 2.0; - boltSpeed[1] = -0.5; - - texWrap[0] = 1.5; - texWrap[1] = 1.5; - - startWidth[0] = 0.3; - endWidth[0] = 0.6; - startWidth[1] = 0.3; - endWidth[1] = 0.6; - - texture[0] = "special/shockLightning01"; - texture[1] = "special/shockLightning02"; - texture[2] = "special/shockLightning03"; - texture[3] = "special/ELFBeam"; - - emitter[0] = ShockParticleEmitter; -}; - - -//-------------------------------------- -// Rifle and item... -//-------------------------------------- -datablock ItemData(ShockLance) -{ - className = Weapon; - catagory = "Spawn Items"; - shapeFile = "weapon_shocklance.dts"; - image = ShockLanceImage; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - pickUpName = "a shocklance"; - - computeCRC = true; - emap = true; -}; - -datablock ShapeBaseImageData(ShockLanceImage) -{ - classname = WeaponImage; - shapeFile = "weapon_shocklance.dts"; - item = ShockLance; - offset = "0 0 0"; - emap = true; - - projectile = BasicShocker; - - usesEnergy = true; - missEnergy = 0; - hitEnergy = 3; // z0dd - ZOD, 8/20/02. Was 15. - minEnergy = 3; // z0dd - ZOD, 8/20/02. Was 15. // needs to change to be datablock's energy drain for a hit - - stateName[0] = "Activate"; - stateTransitionOnTimeout[0] = "ActivateReady"; - stateSound[0] = ShockLanceSwitchSound; - stateTimeoutValue[0] = 0.5; - stateSequence[0] = "Activate"; - - stateName[1] = "ActivateReady"; - stateTransitionOnLoaded[1] = "Ready"; - stateTransitionOnNoAmmo[1] = "NoAmmo"; - - stateName[2] = "Ready"; - stateTransitionOnNoAmmo[2] = "NoAmmo"; - stateTransitionOnTriggerDown[2] = "CheckWet"; - - stateName[3] = "Fire"; - stateTransitionOnTimeout[3] = "Reload"; - stateTimeoutValue[3] = 0.5; - stateFire[3] = true; - stateAllowImageChange[3] = false; - stateSequence[3] = "Fire"; - stateScript[3] = "onFire"; - stateSound[3] = ShockLanceDryFireSound; - - stateName[4] = "Reload"; - stateTransitionOnNoAmmo[4] = "NoAmmo"; - stateTransitionOnTimeout[4] = "Ready"; - stateTimeoutValue[4] = 2.0; - stateAllowImageChange[4] = false; - stateSequence[4] = "Reload"; - stateSound[4] = ShockLanceReloadSound; - - stateName[5] = "NoAmmo"; - stateTransitionOnAmmo[5] = "Ready"; - - stateName[6] = "DryFire"; - stateSound[6] = ShockLanceDryFireSound; - stateTimeoutValue[6] = 1.0; - stateTransitionOnTimeout[6] = "Ready"; - - stateName[7] = "CheckWet"; - stateTransitionOnWet[7] = "DryFire"; - stateTransitionOnNotWet[7] = "Fire"; -}; - +//-------------------------------------------------------------------------- +// Shock Lance +// +// +//-------------------------------------------------------------------------- + +datablock EffectProfile(ShockLanceSwitchEffect) +{ + effectname = "weapons/shocklance_activate"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock EffectProfile(ShockLanceFireEffect) +{ + effectname = "weapons/shocklance_fire"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock EffectProfile(ShockLanceReloadEffect) +{ + effectname = "weapons/shocklance_reload"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock AudioProfile(ShockLanceSwitchSound) +{ + filename = "fx/weapons/shocklance_activate.wav"; + description = AudioClosest3d; + preload = true; + effect = ShockLanceSwitchEffect; +}; + +//-------------------------------------------------------------------------- +// Explosion +//-------------------------------------- +datablock AudioProfile(ShockLanceHitSound) +{ + filename = "fx/weapons/shocklance_fire.WAV"; + description = AudioClose3d; + preload = true; + effect = ShockLanceFireEffect; +}; + +datablock AudioProfile(ShockLanceReloadSound) +{ + filename = "fx/weapons/shocklance_reload.WAV"; + description = AudioClosest3d; + preload = true; + effect = ShockLanceReloadEffect; +}; + +datablock AudioProfile(ShockLanceDryFireSound) +{ + filename = "fx/weapons/shocklance_dryfire.WAV"; + description = AudioClose3d; + preload = true; + effect = ShockLanceReloadEffect; +}; + +datablock AudioProfile(ShockLanceMissSound) +{ + filename = "fx/weapons/shocklance_miss.WAV"; + description = AudioExplosion3d; + preload = true; +}; + +//-------------------------------------------------------------------------- +// Particle data +//-------------------------------------------------------------------------- +datablock ParticleData(ShockParticle) +{ + dragCoeffiecient = 0.0; + gravityCoefficient = -0.0; + inheritedVelFactor = 0.0; + + lifetimeMS = 1000; + lifetimeVarianceMS = 0; + + textureName = "particleTest"; + + useInvAlpha = false; + spinRandomMin = -100.0; + spinRandomMax = 100.0; + + numParts = 50; + + animateTexture = true; + framesPerSec = 26; + + animTexName[00] = "special/Explosion/exp_0002"; + animTexName[01] = "special/Explosion/exp_0004"; + animTexName[02] = "special/Explosion/exp_0006"; + animTexName[03] = "special/Explosion/exp_0008"; + animTexName[04] = "special/Explosion/exp_0010"; + animTexName[05] = "special/Explosion/exp_0012"; + animTexName[06] = "special/Explosion/exp_0014"; + animTexName[07] = "special/Explosion/exp_0016"; + animTexName[08] = "special/Explosion/exp_0018"; + animTexName[09] = "special/Explosion/exp_0020"; + animTexName[10] = "special/Explosion/exp_0022"; + animTexName[11] = "special/Explosion/exp_0024"; + animTexName[12] = "special/Explosion/exp_0026"; + animTexName[13] = "special/Explosion/exp_0028"; + animTexName[14] = "special/Explosion/exp_0030"; + animTexName[15] = "special/Explosion/exp_0032"; + animTexName[16] = "special/Explosion/exp_0034"; + animTexName[17] = "special/Explosion/exp_0036"; + animTexName[18] = "special/Explosion/exp_0038"; + animTexName[19] = "special/Explosion/exp_0040"; + animTexName[20] = "special/Explosion/exp_0042"; + animTexName[21] = "special/Explosion/exp_0044"; + animTexName[22] = "special/Explosion/exp_0046"; + animTexName[23] = "special/Explosion/exp_0048"; + animTexName[24] = "special/Explosion/exp_0050"; + animTexName[25] = "special/Explosion/exp_0052"; + + + colors[0] = "0.5 0.5 1.0 1.0"; + colors[1] = "0.5 0.5 1.0 0.5"; + colors[2] = "0.25 0.25 1.0 0.0"; + sizes[0] = 0.5; + sizes[1] = 0.5; + sizes[2] = 0.5; + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; +}; + +datablock ParticleEmitterData(ShockParticleEmitter) +{ + ejectionPeriodMS = 1; + periodVarianceMS = 0; + + ejectionVelocity = 0.25; + velocityVariance = 0.0; + + thetaMin = 0.0; + thetaMax = 30.0; + + particles = "ShockParticle"; +}; + +//-------------------------------------------------------------------------- +// Shockwave +//-------------------------------------------------------------------------- +datablock ShockwaveData( ShocklanceHit ) +{ + width = 0.5; + numSegments = 20; + numVertSegments = 1; + velocity = 0.25; + acceleration = 1.0; + lifetimeMS = 600; + height = 0.1; + verticalCurve = 0.5; + + mapToTerrain = false; + renderBottom = false; + orientToNormal = true; + + texture[0] = "special/shocklanceHit"; + texture[1] = "special/gradient"; + texWrap = 3.0; + + times[0] = 0.0; + times[1] = 0.5; + times[2] = 1.0; + + colors[0] = "1.0 1.0 1.0 1.0"; + colors[1] = "1.0 1.0 1.0 0.5"; + colors[2] = "1.0 1.0 1.0 0.0"; +}; + + +//-------------------------------------- +// Projectile +//-------------------------------------- +datablock ShockLanceProjectileData(BasicShocker) +{ + directDamage = 0.45; + radiusDamageType = $DamageType::ShockLance; + kickBackStrength = 2600; // z0dd - ZOD, 3/30/02. More lance kick. was 2500 + velInheritFactor = 0; + sound = ""; + + zapDuration = 1.0; + impulse = 1800; + boltLength = 16.0; // z0dd - ZOD, 3/30/02. was 14.0 + extension = 16.0; // script variable indicating distance you can shock people from. // z0dd - ZOD, 3/30/02. Was 14.0 + lightningFreq = 25.0; + lightningDensity = 3.0; + lightningAmp = 0.25; + lightningWidth = 0.05; + + shockwave = ShocklanceHit; + + boltSpeed[0] = 2.0; + boltSpeed[1] = -0.5; + + texWrap[0] = 1.5; + texWrap[1] = 1.5; + + startWidth[0] = 0.3; + endWidth[0] = 0.6; + startWidth[1] = 0.3; + endWidth[1] = 0.6; + + texture[0] = "special/shockLightning01"; + texture[1] = "special/shockLightning02"; + texture[2] = "special/shockLightning03"; + texture[3] = "special/ELFBeam"; + + emitter[0] = ShockParticleEmitter; +}; + + +//-------------------------------------- +// Rifle and item... +//-------------------------------------- +datablock ItemData(ShockLance) +{ + className = Weapon; + catagory = "Spawn Items"; + shapeFile = "weapon_shocklance.dts"; + image = ShockLanceImage; + mass = 1; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 2; + pickUpName = "a shocklance"; + + computeCRC = true; + emap = true; +}; + +datablock ShapeBaseImageData(ShockLanceImage) +{ + classname = WeaponImage; + shapeFile = "weapon_shocklance.dts"; + item = ShockLance; + offset = "0 0 0"; + emap = true; + + projectile = BasicShocker; + + usesEnergy = true; + missEnergy = 0; + hitEnergy = 3; // z0dd - ZOD, 8/20/02. Was 15. + minEnergy = 3; // z0dd - ZOD, 8/20/02. Was 15. // needs to change to be datablock's energy drain for a hit + + stateName[0] = "Activate"; + stateTransitionOnTimeout[0] = "ActivateReady"; + stateSound[0] = ShockLanceSwitchSound; + stateTimeoutValue[0] = 0.5; + stateSequence[0] = "Activate"; + + stateName[1] = "ActivateReady"; + stateTransitionOnLoaded[1] = "Ready"; + stateTransitionOnNoAmmo[1] = "NoAmmo"; + + stateName[2] = "Ready"; + stateTransitionOnNoAmmo[2] = "NoAmmo"; + stateTransitionOnTriggerDown[2] = "CheckWet"; + + stateName[3] = "Fire"; + stateTransitionOnTimeout[3] = "Reload"; + stateTimeoutValue[3] = 0.5; + stateFire[3] = true; + stateAllowImageChange[3] = false; + stateSequence[3] = "Fire"; + stateScript[3] = "onFire"; + stateSound[3] = ShockLanceDryFireSound; + + stateName[4] = "Reload"; + stateTransitionOnNoAmmo[4] = "NoAmmo"; + stateTransitionOnTimeout[4] = "Ready"; + stateTimeoutValue[4] = 2.0; + stateAllowImageChange[4] = false; + stateSequence[4] = "Reload"; + stateSound[4] = ShockLanceReloadSound; + + stateName[5] = "NoAmmo"; + stateTransitionOnAmmo[5] = "Ready"; + + stateName[6] = "DryFire"; + stateSound[6] = ShockLanceDryFireSound; + stateTimeoutValue[6] = 1.0; + stateTransitionOnTimeout[6] = "Ready"; + + stateName[7] = "CheckWet"; + stateTransitionOnWet[7] = "DryFire"; + stateTransitionOnNotWet[7] = "Fire"; +}; + diff --git a/scripts/weapons/targetingLaser.cs b/scripts/weapons/targetingLaser.cs index b3c6d52..70e8a72 100644 --- a/scripts/weapons/targetingLaser.cs +++ b/scripts/weapons/targetingLaser.cs @@ -1,216 +1,216 @@ -//-------------------------------------------------------------------------- -// Targeting laser -// -//-------------------------------------------------------------------------- -datablock EffectProfile(TargetingLaserSwitchEffect) -{ - effectname = "weapons/generic_switch"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(TargetingLaserPaintEffect) -{ - effectname = "weapons/targetinglaser_paint"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock AudioProfile(TargetingLaserSwitchSound) -{ - filename = "fx/weapons/generic_switch.wav"; - description = AudioClosest3d; - preload = true; - effect = TargetingLaserSwitchEffect; -}; - -datablock AudioProfile(TargetingLaserPaintSound) -{ - filename = "fx/weapons/targetinglaser_paint.wav"; - description = CloseLooping3d; - preload = true; - effect = TargetingLaserPaintEffect; -}; - - -//-------------------------------------- -// Projectile -//-------------------------------------- -datablock TargetProjectileData(BasicTargeter) -{ - directDamage = 0.0; - hasDamageRadius = false; - indirectDamage = 0.0; - damageRadius = 0.0; - velInheritFactor = 1.0; - - maxRifleRange = 1000; - beamColor = "0.1 1.0 0.1"; - - startBeamWidth = 0.20; - pulseBeamWidth = 0.15; - beamFlareAngle = 3.0; - minFlareSize = 0.0; - maxFlareSize = 400.0; - pulseSpeed = 6.0; - pulseLength = 0.150; - - textureName[0] = "special/nonlingradient"; - textureName[1] = "special/flare"; - textureName[2] = "special/pulse"; - textureName[3] = "special/expFlare"; - beacon = true; -}; - - -//-------------------------------------- -// Rifle and item... -//-------------------------------------- -datablock ItemData(TargetingLaser) -{ - className = Weapon; - catagory = "Spawn Items"; - shapeFile = "weapon_targeting.dts"; - image = TargetingLaserImage; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - pickUpName = "a targeting laser rifle"; - - computeCRC = true; - -}; - -datablock ItemData(Light) -{ - className = Pack; - catagory = "Packs"; - shapeFile = "turret_muzzlepoint.dts"; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - rotate = true; - image = "MiningToolImage"; - pickUpName = "a light"; //if this shows up, then something went wrong - - lightOnlyStatic = true; - lightType = "PulsingLight"; - lightColor = "0.1 1.0 0.1"; - lightTime = 1200; - lightRadius = 2.5; //It's just a mining tool folks.. - - computeCRC = true; - emap = true; -}; - -datablock ShapeBaseImageData(TargetingLaserImage) -{ - className = WeaponImage; - - shapeFile = "weapon_targeting.dts"; - item = TargetingLaser; - offset = "0 0 0"; - - projectile = BasicTargeter; - projectileType = TargetProjectile; - deleteLastProjectile = true; - - usesEnergy = true; - minEnergy = 3; - - stateName[0] = "Activate"; - stateSequence[0] = "Activate"; - stateSound[0] = TargetingLaserSwitchSound; - stateTimeoutValue[0] = 0.5; - stateTransitionOnTimeout[0] = "ActivateReady"; - - stateName[1] = "ActivateReady"; - stateTransitionOnAmmo[1] = "Ready"; - stateTransitionOnNoAmmo[1] = "NoAmmo"; - - stateName[2] = "Ready"; - stateTransitionOnNoAmmo[2] = "NoAmmo"; - stateTransitionOnTriggerDown[2] = "Fire"; - - stateName[3] = "Fire"; - stateEnergyDrain[3] = 3; - stateFire[3] = true; - stateAllowImageChange[3] = false; - stateScript[3] = "onFire"; - stateTransitionOnTriggerUp[3] = "Deconstruction"; - stateTransitionOnNoAmmo[3] = "Deconstruction"; - stateSound[3] = TargetingLaserPaintSound; - - stateName[4] = "NoAmmo"; - stateTransitionOnAmmo[4] = "Ready"; - - stateName[5] = "Deconstruction"; - stateScript[5] = "deconstruct"; - stateTransitionOnTimeout[5] = "Ready"; -}; - -package TGLaser{ -function TargetingLaserImage::OnFire(%this,%obj,%slot) -{ -%obj.isfiringlaser = true; -LaserLoop(%obj); -Parent::OnFire(%this,%obj,%slot); -} - -function TargetingLaserImage::Deconstruct(%this,%obj,%slot) -{ -%obj.isfiringlaser = false; - -Parent::Deconstruct(%This,%obj,%slot); -} - -function TargetingLaserImage::onUnMount(%data,%obj,%slot) -{ -%obj.isfiringlaser = false; -Parent::onUnmount(%data,%obj,%slot); -} - -function TargetingLaserImage::onMount(%data,%obj,%slot) -{ -%obj.isfiringlaser = false; -Parent::onMount(%data,%obj,%slot); -} -}; -ActivatePackage(TGLaser); - -function LaserLoop(%obj) -{ -if (!IsObject(%obj)) -return; - -cancel(%obj.laserloop); - -if (!%obj.isfiringlaser) -return; - -%pos = %obj.getMuzzlePoint($WeaponSlot); -%vec = %obj.getMuzzleVector($WeaponSlot); -%targetpos = vectoradd(%pos,vectorscale(%vec,100)); -%object = containerraycast(%pos,%targetpos,$TypeMasks::AllObjectType,%obj); - -%pos = GetWord(%object, 1) SPC GetWord(%object, 2) SPC GetWord(%object, 3); - -if (GetWord(%object, 1) !$= "") -{ -%wp = new Item() -{ -Datablock = Light; -Position = %pos; -}; -schedule(50,0,"killit",%wp); -} - -%obj.laserloop = schedule(50,0,"LaserLoop",%obj); -} - -function killit(%obj) -{ -%obj.delete(); -} +//-------------------------------------------------------------------------- +// Targeting laser +// +//-------------------------------------------------------------------------- +datablock EffectProfile(TargetingLaserSwitchEffect) +{ + effectname = "weapons/generic_switch"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock EffectProfile(TargetingLaserPaintEffect) +{ + effectname = "weapons/targetinglaser_paint"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock AudioProfile(TargetingLaserSwitchSound) +{ + filename = "fx/weapons/generic_switch.wav"; + description = AudioClosest3d; + preload = true; + effect = TargetingLaserSwitchEffect; +}; + +datablock AudioProfile(TargetingLaserPaintSound) +{ + filename = "fx/weapons/targetinglaser_paint.wav"; + description = CloseLooping3d; + preload = true; + effect = TargetingLaserPaintEffect; +}; + + +//-------------------------------------- +// Projectile +//-------------------------------------- +datablock TargetProjectileData(BasicTargeter) +{ + directDamage = 0.0; + hasDamageRadius = false; + indirectDamage = 0.0; + damageRadius = 0.0; + velInheritFactor = 1.0; + + maxRifleRange = 1000; + beamColor = "0.1 1.0 0.1"; + + startBeamWidth = 0.20; + pulseBeamWidth = 0.15; + beamFlareAngle = 3.0; + minFlareSize = 0.0; + maxFlareSize = 400.0; + pulseSpeed = 6.0; + pulseLength = 0.150; + + textureName[0] = "special/nonlingradient"; + textureName[1] = "special/flare"; + textureName[2] = "special/pulse"; + textureName[3] = "special/expFlare"; + beacon = true; +}; + + +//-------------------------------------- +// Rifle and item... +//-------------------------------------- +datablock ItemData(TargetingLaser) +{ + className = Weapon; + catagory = "Spawn Items"; + shapeFile = "weapon_targeting.dts"; + image = TargetingLaserImage; + mass = 1; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 2; + pickUpName = "a targeting laser rifle"; + + computeCRC = true; + +}; + +datablock ItemData(Light) +{ + className = Pack; + catagory = "Packs"; + shapeFile = "turret_muzzlepoint.dts"; + mass = 1; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 2; + rotate = true; + image = "MiningToolImage"; + pickUpName = "a light"; //if this shows up, then something went wrong + + lightOnlyStatic = true; + lightType = "PulsingLight"; + lightColor = "0.1 1.0 0.1"; + lightTime = 1200; + lightRadius = 2.5; //It's just a mining tool folks.. + + computeCRC = true; + emap = true; +}; + +datablock ShapeBaseImageData(TargetingLaserImage) +{ + className = WeaponImage; + + shapeFile = "weapon_targeting.dts"; + item = TargetingLaser; + offset = "0 0 0"; + + projectile = BasicTargeter; + projectileType = TargetProjectile; + deleteLastProjectile = true; + + usesEnergy = true; + minEnergy = 3; + + stateName[0] = "Activate"; + stateSequence[0] = "Activate"; + stateSound[0] = TargetingLaserSwitchSound; + stateTimeoutValue[0] = 0.5; + stateTransitionOnTimeout[0] = "ActivateReady"; + + stateName[1] = "ActivateReady"; + stateTransitionOnAmmo[1] = "Ready"; + stateTransitionOnNoAmmo[1] = "NoAmmo"; + + stateName[2] = "Ready"; + stateTransitionOnNoAmmo[2] = "NoAmmo"; + stateTransitionOnTriggerDown[2] = "Fire"; + + stateName[3] = "Fire"; + stateEnergyDrain[3] = 3; + stateFire[3] = true; + stateAllowImageChange[3] = false; + stateScript[3] = "onFire"; + stateTransitionOnTriggerUp[3] = "Deconstruction"; + stateTransitionOnNoAmmo[3] = "Deconstruction"; + stateSound[3] = TargetingLaserPaintSound; + + stateName[4] = "NoAmmo"; + stateTransitionOnAmmo[4] = "Ready"; + + stateName[5] = "Deconstruction"; + stateScript[5] = "deconstruct"; + stateTransitionOnTimeout[5] = "Ready"; +}; + +package TGLaser{ +function TargetingLaserImage::OnFire(%this,%obj,%slot) +{ +%obj.isfiringlaser = true; +LaserLoop(%obj); +Parent::OnFire(%this,%obj,%slot); +} + +function TargetingLaserImage::Deconstruct(%this,%obj,%slot) +{ +%obj.isfiringlaser = false; + +Parent::Deconstruct(%This,%obj,%slot); +} + +function TargetingLaserImage::onUnMount(%data,%obj,%slot) +{ +%obj.isfiringlaser = false; +Parent::onUnmount(%data,%obj,%slot); +} + +function TargetingLaserImage::onMount(%data,%obj,%slot) +{ +%obj.isfiringlaser = false; +Parent::onMount(%data,%obj,%slot); +} +}; +ActivatePackage(TGLaser); + +function LaserLoop(%obj) +{ +if (!IsObject(%obj)) +return; + +cancel(%obj.laserloop); + +if (!%obj.isfiringlaser) +return; + +%pos = %obj.getMuzzlePoint($WeaponSlot); +%vec = %obj.getMuzzleVector($WeaponSlot); +%targetpos = vectoradd(%pos,vectorscale(%vec,100)); +%object = containerraycast(%pos,%targetpos,$TypeMasks::AllObjectType,%obj); + +%pos = GetWord(%object, 1) SPC GetWord(%object, 2) SPC GetWord(%object, 3); + +if (GetWord(%object, 1) !$= "") +{ +%wp = new Item() +{ +Datablock = Light; +Position = %pos; +}; +schedule(50,0,"killit",%wp); +} + +%obj.laserloop = schedule(50,0,"LaserLoop",%obj); +} + +function killit(%obj) +{ +%obj.delete(); +} diff --git a/scripts/shapes/MoneyBagC.png b/shapes/MoneyBagC.png similarity index 100% rename from scripts/shapes/MoneyBagC.png rename to shapes/MoneyBagC.png diff --git a/scripts/shapes/PutBack/Drake_Poly.dts b/shapes/PutBack/Drake_Poly.dts similarity index 100% rename from scripts/shapes/PutBack/Drake_Poly.dts rename to shapes/PutBack/Drake_Poly.dts diff --git a/scripts/shapes/PutBack/Drake_Poly_Huge.dts b/shapes/PutBack/Drake_Poly_Huge.dts similarity index 100% rename from scripts/shapes/PutBack/Drake_Poly_Huge.dts rename to shapes/PutBack/Drake_Poly_Huge.dts diff --git a/textures/Bonus/Thumbs.db b/textures/Bonus/Thumbs.db deleted file mode 100644 index ecb6c205ade96b381f0fe1c8c0a97d09f38978bb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55296 zcmeF(2UrwYzBuegKtQr&5J57M1POu!1xX@Vf*_#eoDmQN1SJOn0RaKY8I+uJ&KV?U zBzKc+p=rL;Gwa^n`~7!!cJIBfoU2e<;@16P4d03mP<0J{K$7$5;y08)SqAO|P_N`MNW2510U;3jY#pabZE8vp~q z2rvQ604pE>umS7<2k-#k1h@chfCsn*@B)0mZGayT1k?Z_;0_=RhyZs1Q9uk32PA-d zzqo-_iJCtBniBQ<{Z|GIut)yPA2t3h%aQ|$&`~=m7^EQ2 zL8+fZtie`5ZS#M2Ao>^bN9ECmI@rK~+IRme11LWl8dv~oalf_vsQvxzpYs3ps6id! z5T{<<;My*<2ViSBLae|M=Ln|Ez;>|()7s#uvjBUk9V+E7YmKV?A%Sm%doX*zJgBtK z!CcQl>PNq9OS`|CgB~PC{q7J$ObflbE;M;?bp7QLQO7E(j)72Nvg1GOMtcNua{^0q z1VBLZeZO_Ag;EUxDu-7{r)YZ}8r~OrrW6i@|}E?{#DZv&#!tH}{u*Z{GR` z1O^31MZb@Ujr$Ovkd~g2nU$TBn^#g=R$ftARbA84+ScCD+11@MGCDRsF*)^hdTDuO zb!~m)+vXPR;PB}9&Yr5qJdXCG9vUMYvN*?X zx_u))*~92IZ#vsD3!VAteitq!kGG|tM+yq-zV37DJsH9N(3huc7*CaG*-5u=%-eYw z$}@eoh-ly)I%*^{7r`t)sn6)y%$?Pl#u_UsE46sxJ13YMWgNcl#$D$l&vI!vy^m2w z!kEtQ0Df0$TvVgjoP0v$r0^z7yn~B5iCXzcduAGq>uj2wn!*RxngbjRs#dum-bjiy z@!Z5$9_QQN?;?mB;dbytT^p`fia&A>5F)237hm7|qG8b4-!GOukAa_OHxPMGEu~*T zHmwEL`Fak!M&x#x!WB?8H}78^r>H9o)K$sP<5UHlqwT=4Y71%vx4%k>x@JMuNvJ)a z1@rfD{L(|{|2Tessh58D$M3m%aUhb-YdjhKJXQP}+)8rnNTKlxT%nCRHa>TYx-#5A zxpGup*& z%w0mTDu(t6fBf;#|BSc8U&tSM}lbP`7^sNeU z+=@4aT z4K*TqYaYvlRArC01(^aOP94$sN7Le$!_x69TpUTB_p$IG49W&a%dAiL;ZX4i#=_ zuc+-P5Cz}%;n?aq=9?uGt;AHoddSWu%|#X)qRS(cOA`I@V~YC4*N;Rp*b;`-#gB`* z#}Xxe)}Kt5|ENFzxc>PY7k2+M*FWd%8!dRyrC|8SbFA&LNRrYz|MPPCcRI8EE(J54(KgvXx-G+~q9!Q# zNUeex-}&D!HzGSI`U3U0ky)oILK0X{?Chn55yV}OzG`jdwwpG#UKYNX9-A!8Vs$lb z>W4W-7v{{#~SUt51|Jk`IN%U*DdYC=eI2#l^!A{OTSxZy0b)Se-yvbaWl&D zWMU9H+W&I)y8)Vav%V-7F&)r}K$6<*g73ebgiJpvnpR_b?S){C_XElc`TTpQ)pK^5J2Lp}LSYV6HyTiJNo zl+Tn`=i{JG3gZH)HtvfaXEq}12Ll%n4J!qF2IXCI*L(Tbt|lH)zf}5mz+UEgTfg5n zHL731;{vj?l;;-G&QrMg(r=p%-}C;8p5*$;I&z-PutZ_~i~wHPUzWQ1{#C4UtcHw6 z@{T-5H%6F*9ogfb^@lrXTKpc`Pb!dSe_Vh4dt84Z^3sCYAiqlP=~z*%(&kEaUlV4Wrq z<7`9rRaNg@kIZ#*l62L(BxFT%EFDGDJxM&!33v5kOo&@rj~7gEp-dhhRrP&ji;h3) zLzudeUGAtU&R<(m5W^|6cqT73)j_nW199|0w>8YL}s6z(3=^s1_Y62FwZk=lCybxqlh|Ma7L# zG2nkD{@V%CO92l6R18=KkOfe2!haP1Ma7Fz@n%%47#06TtwYv35FzIW@jfZAb%a2qToC*M(jclX32=dL9)Ku3 zADEH^-`@Y_TRsqXzw^t#dBG-Tx)$Ut{v9{SDF>-hVx%2Tc-0(jS3{+XGN? zClEh$25ohFuq91?X{%d;Y1EeZ^}YdWAN|>?mjqkJ4#eM35k8y0YSrHYiNML^FH)jn zyQs9%U~8L!t!VOB=}~(XX#D?GdKZvJ{+DQ{?O&xu?P=gb7Xm48_Wj#y&kZ8>Ki3;I z2Nr4$iSCwp^1oGHZjj#gPbEb~La|YEbf=*W{LMLjZlS-P@0SRC1VtpzUu;<=P!`w! zw0-|$4a2|g+hL~dJ)wm7gbQ~*ed*=0{v9b^UsYOFR_c$>H@_IoR<2ioYzr?ZP1k%p zrdD!omXV|W$!l-hin!92sDf^qn5#T8==Jxd$+kY;kS0|@`$KS6mlb3hl6RVWR$qw67l{;aC)92yM9piPax@m(zvPsaU<4amuE-Ty6UF$*U+l$`HO~ zp0ZcPm`}9&4y*C&#zd$h+AkpGbj`|mn=fN314NZSy~=Mh(yVu}6Y2aO`(4DQ3@eB= znU`Le_=91vJn`eyF!uzd5s%rE=j`h0>G%wbiH9$g_BYa|7havyos2@G5clAbOZ{{P zpGPvF#}#2>{XxmYYjt(*%tZ6;*L?LpWA|EwUwdF;YV#%by0wk$iP3ouLMk0`4_e$@ zOkLK%@k(`n_lSpr#%D5uw(R=LcF&Imp^WkY(`qu@np|CdgY2{LQ=?%dzm;HRLQF+^ z&h{xMg{J+3t7m;} zTe|jbf#H%v<(WXXz7C$!AITQ8y=!~(4_Akxw4&xOAd|-z5DZrK$13S!hM%SnUf6DL zq=S!L8a|(wG*I@M?A6^}@(B7AJSg)ZWmmBB9d0CTzn^Z!w!2ZRHq&8$ZJjA|DCLNh z73(HJcGi<^9h>=-9G&~#&s|AoW_4yen1aox$ef*@fo1z*H)8}NKErpR`+C*z<3+;P zUKHU2lWmdm#X1&7I<*buCDi;wRJ$inABcWc(UE0NJYUooR;|Rlt7tq@rmjTeu;+qP_#m2>S#QQ@k; z+nx>+AyeLrYTFMrY@Zl%*nQ$#4-6CSP6XgaJRK5Yrz!2a+ht!y#jjf>#0F)3)$KA# zI6YOck5;^$)Feq?t(aHPH^R%@^64tPvCYnZfy9eoYI}jOPA`A+3w(6h`c%emX-=|J zt**Yrox8XQIl8X!qQMkhY5!K3f!*|QAQwC9F-MaZ`j9v!TuK32`L?Wz-v;YZNOyTj z<-iyfQDo zauxpb`XLU~$NwAgkJn($eE~n<4S;G}_=9l(5C{YT!9WNQ3WNdSKm_m(hy&;#@Wt3W?6 z01N^{z%VcZi~?i8I4}WB0#g8L&zJ^gfLUM;myO1pb6H4xseeS(inV%R-POF$3u7gxdD@+6c}kv_We$mx!UMFR8?82s z1_{z*+(}Hn)40Ym?#$Ju@vZNt$?x=bMDR!M-SB5TFo{=#KQBm8l%RFidvZ$4eWi0- zi)hS3X1Ba=--e6Mbw1i_M{Vm&FQu4V=WS6YuA+q#{+I&OyRvt3v=1Vy<%uE@54U<` zRUZ3w<&*u;Sh;{qvv#DE$aY2qiA4ChaNTZipo3{_oE#UHJ=2>q=ybiypeOT1`9P8M z%dAeRd&oMjbq(6;59h24h;OB*Rz(zMHPqFgOVgD%y*{Jpc3CBKKFW=1Kp0K=(*3e< z69w&l9R=?}rOiUEcX?1v;hc%q?uYM3ENb)hs-|^3Np;kY_PPw6v&x^mqM8HU6G)yLG`n|eZ zeFJx;(oI#1Z^st12%{0iT~}C=0Nj~lSNzp&$hC{ylls5b{|odV>G!_w-Tct&#+FW88zG^aM9YbeYmg|b$Lb76)9D+XI&Zu1?)UV@ zZW%nH+^;>GWR67_CpV?Np7y6(#CeIr${T$c8b-?TZ5K2XHp{p~rWI{_&+q8=z8F<@ z+0c_QElaVf57mXyw{T`Lc(n%Pm>iQ?#=oIaT`Qf8@t8hz%)NUj+pGt9cJ27-`1{M7 zDNyyn;0p+$DC2oP46At}ZhChjmpk#YZ-ttLw~5@R%J}v8xujm9=_TyfkZIZwy7yY& z0-93-_hGtC4sc&x%u!?H$XMCLYvw~VLD$1+Dzv61@6!F5fw?ossabCx_0|&|WgpP= zQ4Xv)tw$!M>KK%Iw`eRalq$ab+-&E;)$oBSc|qm1p}(MXvUVG{0{b1}2NIGJhGR7$ zi}+~<{rLR{@Q^lN_rj%HolGe+m1prprSH`oC1VY-Xd-mBmLCZ|k%_qy@96qIZ(h^# zYN&BK7J+dMtA`#(X5ZY%TCJ`RjtuE+D4J_DVi|1X@{D!iW`47K|c@$wR@{UygFSay9+Esbr7a-6#IC z7~xh29xAZQNoV&vQ{l3Y#sebiUgbTtSUxbYnaiJa*G&aE0Uq{%UIq0laO5n)s#m;E9DeIanX9c*KTwhQH!-Q zls@}>uZ{h#G>kyppM&si>u}WhNO?MGY-ILztHP&Q%QLkNGx{x=SQIR$7m((^u91J% zzpB5J`uC6f$Nx6h&p+=UH-7r2)xbJoeN-q&S7tER#o*7??8^I%PYxaS=?bYJtlF;bi+T+$AS6zcjtYz{Sr=j#&8xPTxW{S$^?ua0R(1lCD-FDcp{ z%8k>X38tDOpAOsNm)G;*U=e3kA{2RiJQE>-?4uEqZ#eJcGj?6E`eTjk)Hp$Dnfn)bY(+L^y$WJE)3f)YXM+%nOL+Bc2htHwAh`&sYeQWQ$p%ys0dsr!F8CGuo|}Q#LTdYz;`BvN+W6 zp1xj4$WDbz?yKo$B|k0?*`-|ROola1cceI0UcdJ$5&F^$i!KJ@m9D8-?ZhvG zJuKmHgF*gMlvcQe&W|`GO#{y0J~7mzXb&__&?6858syQn zB;$07@R#fEOx16r1-}rl^*r`%+pz!MS#G1%O)gQ%Bq*4B1uizl?JnZ8=X3!P-ReXL zc^VwCG$Qe^E+917EQvK31rhk?sg0}U@LFV}GSatv!)4g>0n8q@5mp{SgllBVvvJ!U z^ZU*so*BBB7)MeLrK&V3)*p`T}zE z0Q(DSxby4iU;c~AAGIia0ED}K32XhMh4q01t$)g2_#Y+y2jBlIwgVL!W% z^-kJSWxNd4xr-k3Ch+;iAdDbeFf7$l=;Xw4>-O|a-SD*3_jMCBNkXSk&9|gzu)(+D zoQTIGM_` za0^HYMikc)*Ks$|e8q0Au9pq3-MayuVX0xif0R{1#x3#0Ww=~|#8RAL$mNw*^YnaL zqV4){7ICMecRhpAxbUz$vq=;+OPK*#QHv6 z%@evLe1&&&PD#Z{(R{$2oo&X+<3s|+fBg!qxLr*00@5aLx1`I?&CNs4gq@x^*iymU z8(HUBSJ@-n)G-;_!0V|7Bk*6KbY?3=++OS#bdFFQE)SX(K2FrM=AXG;$#w8v{qWYn zyky+r;G2{Z+j>~k_jZxYy|RXDLlPCHM3m3@3!|!WBhb1@s-B!beR0<33GpE1f;Ewn`$$>v%irI z0Du3(^$tD3<-IwUr~$i1+*=sAo1@>veaqR>>JC5sywX99Ioc#F@$ED#hRV(vC|Amd z?7oYg_UiHWu_?#IpaP{3%)7y zvoqm8Gxq+|*}03B&gR{)<-XemIGFCbUSqby4lv#w5@Fm@$BNq1~wGX|G6*u4w^Z;YuJ z)z74gzY)1b4O_n8$q9IxMiBI}n^ zLd7YgR+N2bnvs-mk3R@7*IZuSe;msZ!fUr?bN6}pyv5wqyC>^@7Hy9H>x&;JvT@AF zN4|UTY2SW!@VI>4VA9bT=?03tOVzS|Bd@^|7`s3kM`rgP5bdL&tKgz<=~?T zjBl>g9kn@9Sr!%WLvGePkf=*OSWHp(AjVPlY*YA_9IUO^Z;ptXWyt24$3eF=3HB)y z(BIK&=d;sFUBae6;MEz6ZpZ=6nXEte!qfJ;1H+trgPq&!M$OES-6dLRCjO!z zoYhK>#Z|eV@}a~*0;)n6L_tSXX9o3q44rQ{&GtE#Bi|ap)tXMRRtSqK4JUw>FxZIZ z;z2Mzo;$2GenpptVTBy?khv+hH!#EPingTAh3kY~e9_fwbd9}QWhw@hQIcPc@?tpu zbOABc^FDcrY=LoJXBKCL=2_aev+m*7RXFynaCcX~&nHuPO5{{VJW{t6nM)~9bC-UJ zo%PEsvR&e8Q5`N!eR(3YcxyimAu+Pc%~PCSWjI{ltA`mh?0z>GhZJ)ygspjzpmdp{ zjVIKL`-?%uG&ktSfGy#7WEhn0ruFzkhl`b|-MqZR^%u1gG+M$Q;a@jj^RPEdxq7yAf8etD1r z9=FU=oP~D61j8JuPbwvdxQ1qry~QVog+&Dk%%m>KN{fj*K6j51!UTOQx4jAL6kJz$ z(9K15k&zCc=C=e@^%S%8ybCK{s64W1S|yo9-$Glixx!Ygvh?Tc6x8*~55JQw*yVBx zU+cQNr1qOg%CYh6F@fA&lO#=Z7Jmh+d+LD+W|RaM5FW~F38!9FjiCm3yGS0y-7y5a ziw8>**>*F1b&xBmTXwkd4@W*B88j*?j4?%F>5RuZih^znJ6gq7T&b4G>*lGA(Ej(M zdefFrT?K4~Akam|Ly)JfkmkDH9f*(n=25#tBaS%D41yIZT^V4rZ#+iM5t0~N74st2 zJ=;AIH@Xb{2E^=BQBTaBs&*FPvj45#o1lNSjZ?>jmX1tP6`A^#E@;%j)fMw5CdQA? zOdEABAjXZ@`iNWbR}PC}%FPw?WDQWnwk^-jjnMnc*pk@kW4#Z4oqAca$ituY-|waW`#s3L zKc3(Fi|6-HuYI`$fY*vZFaS*8GJpkO1317H02jam@BspV5Fi4G0aQOT5-=tO$N+MH z0-yw_0BV2+xCYPy*8%W;76?6X17H9c0VaSMU;$VGHh>+t32*?M02jaw@Bp^}UVsm{ z4e$d3fFK|Q+yR6E5#TN$3Wx#XfCO+4xDQAIQosX18jt~G0aUqA9)f8F;1Qq*C;`fV z3ZM$80qVeGKm*VOv;b}337`Y$0#5-wKp!vwo&nDRR31iPYz&wHrhpk>4p;z|fE8d3 z*Z{VG9bgYQ0FHnY;0(9`F927-4R8lu0v>=T@Cxt(ya6BJcO3siz$!uniY@GF$&>~} zBio&ITq>6D6sCpFFqM57Ah>xp9pcs&%1g=UFTiC5dW%DASH@FY_t!Cd;@L7DOiPIbG^D4HR`}?`adYW>#ON{g~dV~^3VZ$ht@7Dc25$dZomv`)iUSvA* zYESYS2~2GXzLsCE?w$IQ&?8sY&B-_*ww*unshh0dqLta|^YA2Rx&4E#&7(xw9`^^F z)o9wGJHlsE`{9i$9Pgk6x%ru?{vE0{>+)P&Y7Qx-`l1;f2SQJ8xd@A1bJBmCF8f_> zJ7I&<`IVIF1VYyPQ`LxzBFi3!TZUp5N7XnQaTR^&>*2t~m638QQ{xmVwb7O#%W3<1 z4%X8LXlm1@hs2DGcg3GqAqs?9g{g!YG8(>UFKI|m2d6$ZqJ$V$7B-e!7Yt5+s;qh~ zyQhO8xJv)6MCR*M6P~@?_kygkXXA^J%km87Q|X<2yT*1>Q|Gdm%Sz-DE9_6pt1$E5 zjWI&XT@!jd`=9D(Rhc64lg+1@^~C&T1*X33`|B)oGIem|jbt~Irgbt7mzm9K+~aIp zL>n8WuN{64^XR=?7CRXivf6FwI5a49h1TgUPm_A+di9TT2cu_2gKKREoum;TZDgL| z4B9<9o0Q74n9w;6_-e;Uqx!_iM78Exs0kl77PN5Ri8j2(<68ouKxUXBM^%^Z>J{0i zr-pS0&5vC96w&ueW3Sy@btafshbm(_VtrE8u=Yg53{IQdrZ~;4p>4sLVh|EWt2k&C zUL+n1uBKN|F27^gFWT^Y;PMbe;~o|oc#vI0WybC?4pSNLaXgw4DC=yw^K{{W{CYL5 zpE5`-plJ&5fw0{J9>(oTOH=-W3NXEa`{mY6q$NZgaiE%4ZtqW7^%^rp0U z%O7iZ=?Z$myn=`kXY?V}(D4bCP!wflUsFaWg%jaIv zDzjeRBLTT#!6&Yo=FxIKPMZ+rQiO1Mh#s{U^EU+fmk|7# zA^(3v{-{L}{S)~o|HbzIzx@6@tdq|3Do^$^hD~alvJFX?^~2N0d5Y>^l8~0Ihtgzxqn0X67BXYa}JJg=SZjX1d#^?Jf{eCCeIy!NcVl0EBB;dl1X^im0S7o+5+Z{hr~ zojg$=mN1(G{a`v+dON9OGFyn3wCq?&Y}oA>o_z3?5-D1I~kQ|1@$dQ@&(iHB}F zyVK^?dNI-AT|gEql8Ing!Jj_EDqHKNnol`r)Xxl*$2xLXg`M?AT36dznALXr5*OCc zj0|UAZ9@ZAWPKaN+yo`a+;H2-kqkr07F=O%Y_KxN)F0_l!esh_&6?9&IGQq4nrhxm z4eZF7>qM~Kn2D6-Vjq3#3B$mh*iD`>rO+Q#;rFpk#Frbqp>aFkSLi}q=lNlDEqVgr zv9LfyP??8~bi)XJ_1m;qCMQ3JIy;7vkC%#i90>?tkkAC?G|rfNP$1d51?Qq_N^6f; zR3fHgkg{9rpr01zwP8^WSgj1)2&&w&4Rh6~vXIHnXUUp=5uc5{IyJaK*w9-8{E1rG4C-)bI=l?) zLLpeU&#riC!X(-j;A|hY}_Hx`i)0oFDMb%;`Kh?C2UOtbEZ*L)J>U7I~kh z)ZmRo>8s=z7g%vi$#yn1ZPHX-gW>H!qaQQj=NzXv=LO!Y6XJZ{Q}LjK+$P>Q0*M?j zz*S!cH>AyvsIomg9#=%|y$BFDVt8g_koz2NT8C({&wi7CGioh@qjooY-9pJTI<(M( z{}ub0l-DQ`!ad;va(10*v`)y$%*nYz@)k?{N=rsba)ysRmgO1i^5yW>lRNO|_OO5` zd=~5&Idne?4A^Ke;uHKiu3r0!px!zM*Y)Q_ws~3igb~}v`^!RKcP}7DglL_FeM&LL zU3zC9WbUCiyo9O8E#{g`nJ<0Im-Ys|zVr+76$f-vBIiW{Ois!S@Rqep92OEzBak@x zFmEL&MJKIU%gbnYVz=1&8&8|IH|TLFMQYeM3aKr zajR(_jbWL+xx-j$yY|J>_DBN~Jk%nN9Mqxn^}>h#0eG7V)f`mHHTeen{ngtaNhTU`yiFp4V;3$r2*b_VCchnQstm3!$OPk<)2-POVqK$aX>^w` zE5^0(5QoGsdmY>;%6nILE@}F(n@unYsic<;~CUGR{jWOiQAWp^>Kp^K4tc_z{ zd|OBeRP+J@O@6AoH7R17_$reg+)NJEd{7n2!S}{RWzqi`+F6^E{sb!_o(9!WF0`8; zX~xOi&CEP>Dsr}j`MpJXnx@l>O!~H)Rr{&*c}I|koqzb&Tq);W-Bb>r41$&U#(TvD zX)uW$>BTUa2`T#05w3{`fqP5^&u-nJ4UPHDp_&QaecQ(T63Q_Iae5YU$rO^75|W;JqjEX}x8K1YVY!=?Du zd4Sh7U7@x?B2Vo}<*%MRi{Bo7o)wZWYV_wH#6XHU=;OjJZ+F2Ix4P7rpY%q}k@++Y z4y_`|=FKl4v`4#MyFOjt#>3n55JOngTAn#(Vi->^O(d(CVB!)QR-E<4zq4d*^9h>ZBW<< zRoKV5fV8lmT}6l=I@|47oh$6t#0;DnFz6QZ?b)#`9iY9M*uFd|+-E3Cn`#AfI(d7Z z?5PU9ZQ!q{DLrw7|JeQ1AgEyAOi>jPml~x?EFRid1;T7rpY5MbRk$nRejy0OVWQq^TDsxWDuu6XUJUnc`zY;hc(bRV z<^m!IErzo{j+;k6ei`qd8e7u!2$?ybP?^aa zT=%oO#?wH4!%)kK;|q2ZsXUX+{;?gL#b9T+(6X}TZD%X4+aCA2N6^(#&BltiPd63R+kR3%v>ZG0AbE4WGT5NrUwGrN=q9^9j+)$5 zMxZMPd-LT+Pv=26v)Rt@b8DFLB2Ad|v_&S#)9uQo7=0O+P2-L3?UO+SY`K>Cv~Mod*L0eWac}sa}$MzpbC{udR*$|KIO6x$GPs6TvERd~=TN z(p%AX%KDG9uc;+b%J9$aMO$>{Jwy!1FSyGK*sOWTf`eFtuui}vUolT#Z%ZjzDKYnx;EToS zz_1f4y=Dt4eSz4^+CLW1+yXR)yv=#=wi;-mdxFX*aF$~QGjB`)S z>ei_}AhyP(G7inx&5-l#9>0d(R3{8eUoqHOTAnH_LI|_IFvd_3xkJM#) zcCSU&9H27=etQ^|k$bZ*gZGE`$yhKK*2;csNIz?fUmKDMCi6NMJcn!+*&8O-0%$U{$eE6xh*21FUo+TKvTBoRbMD@q0WAbF7mcWf(+XAIdsa?GHppIW44Nt!wukU#+o?c3Q9cxGr)?%jMn|xn!qG2fHT#26lAd6w75i;)iAsHGWKTXoR-L?`wOW95qn5xh{KmC|`Rz z|4pBB*pqJozi4@Qw@%qLwb$DtC$6vZrSX#8b9}4SM2Z{3NQ;>CNaFxUp4K&(SzDpB z8Faj;e)(KiGkDejAqUe>uy#JKoL`=GN2r&04jkhpc<$FYJobS9%uj>fhM3CXaQP*HlQ8o06Kv#pd07`dVxNm9~b}z zfgxZR7y(8BRM~dHcmkLNrhu=&G%y3q0&~DTumCIqOTaR)0;~dSz&fx2d;>OtEnpki z0Z@7Df$=^71z^Ada0na$$G{2j9e@KrfK%WMKmg|e61V_RFMj>M9RKxRQubMaO$Hp> zSgF8RgQM1!uUZYczi6PZ@h6olx2jTAC2PsSp$~cC$ny)bLOlL7Wr4 zi6x{(0*im;0&<%oB;dTyH3i|AKkG?8dP@(Xy23W*GP7*eBynWozTZ|W5h$W@5=viJ z1*2pyIj|~xu&FsD?5uV3#(^syuL~C=@fukdr;wMe*NAs1PluvbX9MdYc3Hv}Xi{ky zUCwt9y@YMz>Z4$ zN+aq3-nXHMDqC^i{+kAd^HNcElRS7xYr{C=r17cx+|}bV87&-quhjl=K|8VwlavgSu6psIi_Yq->?f!#;k*DEoQ^80z8eD z4|DH3Q1hJl*NV+b>)v#_7W(*jh0)JX+6BCE4tuagVes^aA87ohy(4clU(m+#8F9jQ`B70>*UXT#OPCI;uQssXzJOH`AL2Rj?5tftnD)VK)Gx(t z3#YFdidC|(dK-A5%B^!|Eh82>qDYp{Fk^fEiPHFEzngLdE9;`2KG@cxjayywmtvOV zTEdJG=CJL}nv-OD;`Z~>eDm9ZI(J6QA85|BEPY|QwiE5Za@7$H^P6|GqUKq1W66Bu z3L&1A7Lt6@xi;V6sE}c4cdaVe>NRO3uMB#M*bLKE@n^hM2|tXGIQVw?Pc6KuJ?*Kv zOjRZ%*JrdNS3Pn`20wI}HQy+?-z_67oN;+$r+0;p#w~wEtCQ}so0igOT$4U#ihAW} z0`jVJ9f0DySfvgr?o*uKiDU!o>+KsLw7fP5Z2-grZsoJ zez4vP-fuWG+)_7Ck`^5N0@U2DIY&SHxb!nqBaX&DbbSQPmQy~vCqP>PGp@2Qz zQuWaYr_e_Zk%z3R0lZl|iXH1ri;6Is_Uqu`;*~7;9Q2$Ymj{1~(BYF+f>N!G>2NQ` zh%{-Vd6dbmu98+{tzpMfAojhRO>~y3`nqRAp5~)S5zkwtlLfX*V=NU8*$aBpydD-s zBW!*BcyCGi6bHka?{z&7=NQX#tQ+S$vnJNMe(ts>|$#eCfEnoI$8Y_)KmQ ziT<_U8=9?C>ASL1D!-gUlGj_7)Cd!6*h0git)f3{#!A>og84CG2I*gp} znonHL9$CN4FQuGx*er|D$0djJoVbqhr+iImK2ZH?3-dl>E2InU9N==%EN@-2zV1%UO>#pob?_KcnI%cWZkK&j*OMQS4B_M zU&*wyVtb1Nsw@j{gnG23&=h7SE|JJXwc{y+=&^A)zgUQs*c+%o% zgaX_NR(g^E^M1?Oz^X0LN*CZ**fs1aVOTR?i zOow$8aotLStjL-hyyv5;w=9_f#vgL+Q2*VRJ*xQD*a)XPfwobaFPa}ej@W7p6c>bU zbZkptdMXW3PSxE>>;bIa|DkdH@W^THeC zH8?GFQVJ^jmTP`Na^yL0^LoP%CeHSGS!=w~+qX%4_}n1Rw9NFC&-f8m(1?x&f0#a8 zwvEWme?~6pC?w=V}fEf@x0ONswWTJ z?o8bi_nn)9LdmeFa#7DbYen#EhHGTEgEd~1(Y$;_Z@7QsW2;Va22UKQ)-IMq;aB)d z>q*U8nsDWpnn(w+PugSTzV{DhT4dthy$pB6q?Zu$Ui>6Mi@=ADE)@qMF*X|s?VS4+ zRCT3{d#x*UOjAtoo0I2u@2#79cIka?6fMGGemG|EMJRY@6-3_L5PDFvu;UOOe2bTj zC-3!XYA3nLr#Y&1hFv>xh0#tP zgeG+kAK3B~rk6c=UJ;oVE)e-Bu^Yp7hH7x0Eal7^aV4c~p(1W)C0lQEBHB~jii*sW z=b4X`9jzZt;<#MQy_+z~_s=fPTv~K^L>T407{5?9AAKh5>F7J7pRDaEyj;~0pYyb? z{aI<8o8Tdz83u=~rqOpzO-3JAFIadC0*;)cyL1Ge_FEZw;wCw;{|Gvfo7tRa-tQuj z#A*IDY)U@*&@ODs@nL{|K=!5`f+YInd)av!;z`wuxt|$ZCnr zyw`_0+uu8Be0@C3c0Zko;|zFjA{Ty?lM(KgwR>Up$)00yT|iDO+0cg@h(g_z;ND~2 zy5O23bNt14yC>rXBvS1=vh{QUnZ%u6{^`;ePredqi<`>my0bq@VE8lW+r&Gl#$I?pQJL{v5G%+@K@!0qR@>;9+Wkeet0o-E+G*8jZy_i2&C${O( zHij24`Wi>?)I_0K@H1jzt`bdm<+=Cr-jv}(!`iJsqt^8TFXAj4T^nZ@E^^Lt7ZuJM zq&pQz?`rC`aPAQ*AS@T;gHh2qgat1|OCw&LVIxO)yTy|-npY(7p9aMWKi2=+6(u{2 zvth*;Sw*zv*7I55oNOyDR*>3rbW43^MmrCAqLBSKkbQBFt3$jT+PHfg>e|#;c3hFT zRE+MX+1f@Oda8H+J)lm(18;cKLG-F@!vt;)Emh34;XRw7h!5E}d+yz4KL1>{FoSjS zXk6ffvphngU{j<%vnbPaf4zB~uarZIm%v?Z%(vj2(OL6A}BChKT2t|l%>fp3zeV-{# z^&m4T(q%=T^E^VF8s561p9nMkE>mkqv$;$9Wxg|K@R}q4Lvk({){GB$Z6zVh?Bg-} znKa^d&IU5U`#9&)N#SDl|JUAmM@6xvYrmBw0+MqQ z0a20?1eMSrl0-yu29azNL_(8Wkt{(#q5>*8HaX`YAR>|_XOJjOY^1ySHfPS6d(V7- z+?hGE&aAoDTI)wqO;zu%qPlADdY|`w23@s=1+4r=v|f-fn~oJMJUAD`sH-9Dp=h+6 zJfSO8D4*+nWhx&C8)@))0iR zTcznoW(ErzCRv*zV6FVf9U(XV<-ui|`$T{Hbc5>Tk^1yBtqE`h)dWriX23N7_B+o2 zey{@d$y&eqhH3%D&w1b@eBvHz_E-PGpZd3-`9ptl{?O4+{nJnV(@*`=PyN$R{nJnV z(@*`=PyN$R{nJnV)BiR7({J(TlOl5eO#Jz`?NR^a_Gd{+NzRgxke#EVAUj8Sj)a7Q zj)Ib!hL)C=l$@S{j)sAXhL+}d9OS3s;o}qF6A%*+5Yv#6kp2C2gMM4{Fa8aGo4<7J zUyy&o2nM$xEcwfHGSK~>rXdh}#De2>GKu~1_J8rBJQ-o1e1Kox^ndtql6qu>_m`E# z|9JcVu>TngXj=H!{lES%X#eCH1P$Qt-T#w}r>no_Kd}QB5Q0;`OyJdDrcf2seG z=c)Z{aI@j#>+rVF+q^eL_8?dVnFCHqtMo6T${59bgO!SY!}e>f_EeLfU&=Ayai=J9 zXv^S7t3h-JQizA`5!Ur2?M$v&!553_^y)f>K19NJrDLGs3t2=_;jrj4Vp4MmAzZ zt-kcBQhZdJ3QLB6v_i>gF~TI)k5{Rw*=UMr7c`r>^S9+h9ZCC&6(i(%KQ_(yk>4VJ z1hJ%1mmvT!HP8$SxI|Lh!ViiC+6yvTjJohhL;P5$^g$et*<(KGAY7yK5gn8Caz&Co z-FNjtvDL>ROd}7x{C7yw66X?LMa9X?`ehr5E+al`Z|+z2O@gZD-L4O}C-2^_3C#S~ zM?4>Q#zfwO@=M1v*F_!3C&=gfaGNaVdt{OmJ!D!&FVQ4&T|abKRmw> z%Kv%{2)xQ0a*$}~Y+Vg|s5jpnpL~s04ZZqkJ9WY^w;mU@3U!TLuu_Jm%_ZH~?)V+G zKsa3uA|xWsnaW5y)z-NrIiCz%1Dc3s?qyqqupdx%g^7yktW!8 z-gHw8jrEn)x+QhR4M#UeC$g0l9!97J-!V|6yR+*n zlmYBfapJJYtl!|KQJ%c$fzY$s6h`tJ#I?597Op*-)~YSn)^p$r*P=LGX+G#f?)2pg z;eP#00!GA|D}HP$R$%tLoLQy`_s*N0>V@F4J8!L_H|%EYKit{grH)oZX8cl1`7gTb zKl}duuhuXB)_*ww3B3PI|L4!%{|7()*ZkpjC?`&U=RYFy?|``p@y|5!dD zoQp@nro$5OnZ~GFwzSWnRx{eCy3sLRee|0}ZshgLX z@0QGN7bMk)beCbp6_&?JqFOWP%KSCo zhg6Rt#G5aUA@Ud5F{Hn|;@u;@Q8|}PGN&7~v6s0OTj}rG<7)`Bs3*@fYEKJ%iEV&| zY>M6LB9FQf%dgab_?m*x<%s79A&($IhHwt^r?!5##=cF;olvkh7`INiNVV)3U%E8? z#{A7(vAzj{Z=7a#=NPgPzIJp|koUep-iq}xq~gs3bV24fXY5<|N;MSiYqAmpsl7LF zUN6zRq&A9o^X4PuEZsy?x4xvXA45`Ypuk)@PdPt$E59=44JaXRlPot+~Ry zY_N znr9jpr{{V>x?Z3^DCdtkQa*+}R~0#iL<6D3-@df=r6>1Xe#Z!e#rIAB3;B*II~@D0 z+Ncvd1{;Yx-S|nWkQ(QM3qbq8 zf;=1lji4DWa^D+z ze+=nozJngwZ)hw-MQ#u~+a0-HlDv^II?gYCR^QGsF}>>52L>~vR)HA$dsVX0<{Z8q zU&h&lQ6LL1yA1k6-qw@~*XL>ZIrd22eapCGAz6OiRmG^te*eQq=Ew8+^TK0Bf&gGw)e=xG6iV=JJrav@Aljo|_(iTkLb>hAZ81`^2_+IGAp&~(-4tL_P$aZA$deC#lb@4~VWUdY1{A#I{X|RsL=DJL;_dP`{#*ay+ zq6vY=!=cLDa9aMDJN{_!cTS+7$Qjo|M;}8}i>qs^26o-3k~LPZUA}NxX$a>N)@{nk4RsZt7`sO2OEUxxIS`AZz z%&n=*H+P)uUuwjV??`gaaaC@-0|}=v6}zOW(h9@DBEgF88-m8>q{Q1_^Ij4k)}`}n zeR!`Xi4F1A6bGl|I8=Yj|3~cSsM$zLw5Nw?0pXM)oj6lyFzezrwNQG4YDVvOhSRsb z;NBm}o#yH_wTJ77-mfy1XO|2)l)YB|E?{t3voorqtZ)4WU-?H;wuD2R8JUOa`i{BN zTq^n!`SWwH0#_tO(o9SrOcP`D{ zoSaZsq=5_O=H^_a;N3d?tZB1Z^+^(ZgBqo=w8EJ>7f~*0cSgPvMYeNeWsP_xQa|4RyM?=g{uY0X2$BI?>Y6^AChdr)<0F5ILv<5o~G#yHL9$K9z5^;=7+ z`_-LM1@Ct>a1u9WtXw)RL|SHJjg9CSjnm-en9JzAcNmMUbMfkEvh3uZ+wzN z)7q~@vM+P{vmwR#L+#gyFj$HR>Y!OO#~q=Fip4!gm;o8&*z1*~{NZ6|W5e2J(Pr9s zH-icLhp!X0wZgp1)!2De@3`5nSoZB=&Y`!GSv>Pp$b0Bjo#ngq@9}|%siI&Kng!w|yl-VW|Djpv2tT7`sCnrv2t`e~*J`oWi?u2M%;2^uy;B}*o zcj)m8T#DQ=40h9UDLH#w4q@&}((GjGOc8xK?Xh;$mj&UMO6S8URNWSM_ncCH`Swfl->zmA z+g~(|hDz@t0yyV5N~=_Tyw8u3wHf3LULzqF>tSQIjb=>0Xwh8GC3NV=p+GIr#4=Qe zzOohBF3mP58ZJI>8l)Cpu0NVKNUc*ECzL(aL7VbUlJ42|G)#~1TX#{ga2JK~l-?rL z)`xI@Hqy^m1kIxz@nc%1C{?YduiWr!@x%@(;sxcJxw?uKqh3O z5p!OVXEGZdXL{*X-*;ry58g~qB^&0uVV^Rj`5E@~?5pi43u++=hPsd5AFQPpm5)C5 z?MVj_1^H+1s8FOKYYG-!af-v!3~7$fO-Zs|9wtqA+R=p&l=4K8)jgCwD^JPjL}T{# za#Z?Dk5JY{!TgktBT8J4&KM~r#$(7;*%GA|E_t&-AN99>uwwz@uLT3i6XBd+3p3kv5}*sGkkn&k^}PFT{2Si#w}+@ zOIW%e7k`*C_wW<5yDULOzC}Hogt6J04rRWFA`55?#zRtiOwD_YSW zD6NncanOlR=+h)@TOcQ2^ALWRhVJwzF7eGF$2f7s@2pXXd9GB7I@I4?=rl1JPaD+{B&h!kAbzTuqlYGo)60DYBD{uLZ}CuFRP>MoTm|aG^ZPZI-Kz$yMVH3la*y z`e)K`h#zX0bH1#zPQtdMVY5Asvky(2kn8%(f)fB7PrlEpWz*3M(lDGwbF1T>Y z@}3iFS}`e|H6^i0A^NgWW_s@1J{x;q0i3~QQg}$9V0NN?+|K57p?+cnq>JmIP*K-@ znxgLFO+;J&eB_aHHS&sN8k0yf@Lhs}N)8#fF{>T{MlG(^Qb{qD$qAEE3GPSjr<6!t zZLTWyLe0wy(XuW;u&NY%l<*q*gVh6<@)iAJ4yfYQy%1Q=a-@o+_JYgcnmKbL%CZ!; zA^mBm7#Szp*wV=5Zn`0Ibk$vVKWYnGp88_1UgcJ3$0u1tx{*MssBprkmyL-HVhZjL z9CSI}-#W7_MHe*#s&3n|pAiLJxF@itmv*vGqOk#b0 z$Haquy_^#_K>eYzf%0m{oXa3{v(<)t*MPy^!r3Cb?L^;CftqK$^DUpeEy=;Yk0Vw;yWUEiqVXU_nzY z&#Ao-a3N9YHY8qFwxFlaZ{a=@w#+Rn8PGJJgA9Kc_t5eVl^&=`_;o$m^U=NCJ}f?> z)dF*oeMj5-6i6YV%>qKYbnqYTM5{&~@-~2TsU;K)l_GWL!lsLnA@A#opSf-@Ik^eP zG%wf5xOJbYJ+i8bd;!JVBlmZ!@je*)9Gm;1%hF#knX@?L>{)R+M=NhrTwo)3yxGB2HH}1w=U+H!5tB1K5&7d`k{0`C9Cjt2S#HS zDn_OAe#H0`u)|X1HT1ZE_4`T&}8};qAUO#l!ATSh>*UB_6IKkX(f1RNGKXM*a-~}KZYPn zK#x8#PRgqc0lpW$FmGqnWQ?~L3gbx>#94$&2`{wubS)|xv=?1Q-5!y!HuQSkHDi93 z*Pv*8DLdxXX6SVw01h;$2%ldwB-cG*pFNi;!#2r8?+20+17zFVjvR~sLS3w21KQe*(Yk!SB{k`#z)8NBu z{@T9KzoC5w(7p`OU-nw~-_X7oX#cnP+etp*HL#2azy}Zj2mwTZGXP@1SpW%u6hH_Q18@@{0gwbp0i*#?fDAwua0?&@ zxDAj8C;$`zN&scR9e@hpETmH;b&HQ=NjKQMm;fC20P_5cTfBj7Q>3Gf8q3~&Ls0^9&_fIGkg z;0f>ocmsR@z5oQ^Dd1=P?)r_Ja<}Cb6qS_!i zS_8B#cU=lisuqge?_ou?$GW9u?V#v(pz;vCizD|0Ioq10Ov$|hJ|X&BbB`r8?0vl= zgBw_?nF@-xa4}hr3|_^14&Iua8(dGi%$cH;)l%N3f_=vmb={O#>56fMs>6Z#B6wPg z5fkXo3%HkpOcH+eT3I~ZC$(*3YsazFtA6nOysH2LDY8qib@GAF;S5<-zz0tCqLb`~ z<)Pn437=xrd7vOm^i5vg7A4+%aBzQY3|%T$U7a|5{auiHK#C&IDJ{Y-u9pzn!(&LE zw@Qj51-iDQX8A=yQ0r0cbpv)P`AbRSwZWY+6XUPW3tvz)qp+bgkF$AyKWZ|BiG}>E zJ8X`9BPM_1TPm3=bMG1NOJ1i(QYp*H1mz8LNQ&sjEadG!y<-x>tNfTN@Cx^>-JX@k z`K~VyU5-XehMHo}44V5il_Vpgkjw!aN zT^~yh9-XAAjkkuu{X!-7p+TSCc-(JIMg@jEbLOb1l>Z@Jj4_^NN0y1Pr);|QBbxYpzGdUUQ(HGMt1Eq}pd1Vc5_G9^?ph*8g9*&nc(CSHty$-?*_ zGF)TT<__`ggRx1kE5)?(r#*1n9yw@G+iZYitG%@|+@1H!&IT_ZifeD+L{GYHv%P8+S6&c1F-`QcYQ!TE~_n|G>{ zmkflciV;| z)TktlQR~pkY{^q`9q;Jg8atKleYDfu(ePmTBvZ3vS-s9|@}}c@Y}=Fk4L>F&#*L1o zPi)%BPZ;Op6wz7pL}3^YP>SFMum=-t5I_}{5*Ex$>9$tj*n`^XoeYh*#?pshjs+*p za_9wHM8eEY@6F}oT1|NS>lBX+ywAg!zjDW^duj|t068mIP2y8jOOUH#CxFy404q6?Txlw>T8UX3J0V5-P+h8#ONc8;ZQk@ z6>mSkesE7>+($yS1l@EXt{eX(|9&%-dqQdFW*dR_edUKT5GvSybR%J-4U%F-2Pcgl zG8fFUW?eyvhuk-m{KmyUa$u-1vCPBCu5LWqC>+ixZ!&ZNx0Wg}J6)3O{W1Je=-EuF zGEKLsdn9?fzKU;GZk9(h9_i>m^0eG&NXwkUJWzRU*sZLiXB~pM%gCjuA;)(a|0)-S zEbWo9>2uRkWUxzKB)d0l@e9q;=w0{MtxERMF2aO{N5-uV&QZ@(-yx?Agd?oa_D7em zDr5J_DWzWVEtc78X=-h~dN@{rayDiz-G=^ySMlGjzoK9~@}F@1mHFx4^1mkj|BHWb zA<4XWTPKbj{jj?|DJ*Ww{bBcgKLIyePLGSB!*)%Pr?aM9tKz;E-N1f{x3T`3Wjd$U zrb<7n_-xOS&OLB`eN5psgGc(uusF-xM#X1qlVjl$ykU!pT2xRTgiYi46+KjC7)CSK z2nL^G7|1W6k`nwhI%YDSc4mfJmJm(yi7U3RTX{ivQ7*uSN(_SKNAsbUTIUI)ve8NX z+r#Wca!!Pi);@6J(xmNUNRQ1zlzO^-QTNi=8TH_JXQjgGF}@MLE#$r=_N_}};52<% zBh|EI_)M)~a5~IKK}}fTA}ljd;^<{?nDV$|z0S3}sh8f^YdKDIlN{OWe3;t*ILFs5 zkuYo{C@>-UqqOfd6Gt=h=87~L7cZrY$!dR-7T+S;kVTQqlD9gNyCV(J#c7e(;5KG_ zHT(324utaCpt?Nd#BZ1Oa2!QF3-yyUJd#t%LDL&^yh=5p#O@#)Vud#|kC@D7VC_lTJ-jG8rs1r02t8iV=01(QPWnTuJ$1(s+C z?yembgr8fa;w$1|BzlT{k9cr}7^5?=At-r+pdlt_RGw5wPmQzL(y6SgMt{+tB!v5d zQK@KnV>e{ON*F@!gWAIdk+=95<2ae6uH3E}U>Y$9D?wu^$e+wVtGeW zT|^)GrO^U8W`nlY=-*4episoL*O0~<#+3Xj)Vqq5qRTGaDL9VVJ-k|uH(t4*X?!7( ze)T(==b(vIcLr1zHZ&Ts+uSvlYbPAm6J@TZO&`dg3rmRBrp!?Z1TsH*Zdty7u+96Y z_EdjWGO`eLAn?>s^s{aSX@>gatMJo?D(Kzua!uMJgGqT80i(u`dEzmP^bc+wz78#7 zR%?Y4L+#jue;h+TNEtSJss-UH9%6mT>VgIe@u1Jyz- zA$K8;5Nm)Scv@x-<|mUV;KW%7l7i0q@Anu-a9^?b>pkYT@!OAo^7)y_zajpl2I3Bc zzvdr_{u|o2{cr7`9N<4XfiTTqr$72$|IGG(Z5;gak8b~G>-T?--+#-i`;V``j`>mk z;(CFXirsu@mNlJ|FkJnsZ$50tr!N*6?<^&- zQW(c@u}~%|VMSXtB8+=Q{8EiBD?vG#Ub`6l_~UBZ^S2%`J>#OJ94CeBSfPyB92 zb%~bp*86P8sW9@pZUy%2_lMF3;E!rtl!%1tpIRzvTqoe-NHhDAx4RPUo@=dHK5U<2 zsB2yxD*1#%G5p#2yvva1FA==8e3WjFe-t#3I2pyIu@M)p>B+_zS!LFhn~B;}HN2S! zT^9{(6>z%gH50m8mb0ZOdg99I;sGJi(6i}KLHX>)jrmigf9s!E(Nqu*8UM&;ZN(fX z${=a|hGpc&#Z3ErX#6ezWRQyznFD?P|@Yi?uv#n zis&U)XqeOX*&bZyOj;K-3rqn>KBO=VFs=cxMBQN$Sw$L6Qd z02_Ce_K_ITFGI7!Rj8fi;trI!AHKoyG8u}ak&#G!~g1YJOQ!0|K39}{Uw(7U*p<8 z+W+`@|FM1K?BePMclYpo?jH~s6dV#79rG$SE3v#yMrKxaPHstQS$RceRdr2E zYg_w=j?S)+{R4wT!y{iu|7iX0XP_^1qBA++=k$N?2;k%W=RUvq+5h<2|M=Pe_|NWt z{H`lVM)M5;%w19TbL66`S;?35mG@6MRHB+VDLvj?iCeJ$ ze3SH)X}{<5=_qQ26VA+QJcOnEhkKK zb=oRzHwetiwH1Jwn-TfVm3`SL6tLqM9L9~U8Y&4)JF#hrJ)x`O54n&)d7oh%TISh} z+;`o!UZ&gpy34GDd^$I!HtP=n$-Es5SAD9OjBDFh_$gh9oWnp*fbm;;_GN0V#T7o<(nriYc~9jl%mq0pi4Kp z6~DR+cqz%9&c{1_rjyI}+BVvBMswFRs$MO^Bp-WaNR-5SaJ?yd^{P=ZCEN0i^Ls4Y zP6Ia%kSUE00@Bm>w!S~7I@1Q*fAMZa65s#SF5C0a!7#S-a>1!k1f{*W|2`b{G z^x3#j%OR5Hv~`~Q_1SAe<8d}RKUS6~<38NkW_6IiZo-dv6=Xu;)G4>zUo@ifAoFECV0VKTM3E8k*MHS%a4@HJJ zpePq_8R+U2;2oJBSH6Z<;9*kv-u;CVYAP#7@0$orEFOM;igVnknQgMDol#+jRmrYR z4H9;B`34>wM-8PthV)4_f)gh;6}W*G+7;F|>9*(YE>-6$=V`u)QLWbuGZ1Un+}~Zf z`6MDr`KZre6mEmb!={(3THnPM_zJd_j_RSE+eo}DIado{XCn4QVW3_=Qktu5hcRLKDq`s2JVgX zk_~AM#mA7QS)6s-G=;bP95i$+wY{EPq12Jm;1PUe3=znWk;rJ-UWK!dxxqCP;)bOT zxb5xyBZa1DZ#g`+P@S$}YUaGtc=XmM<(AA^a%O`LHW_!?eSDTa{F*7N`{!|8bjEcy^IuTkcTVJ=Rkn397XYm{lYNu)3OSV7GO}L-NN-kJTV$-ag zqQd5Tkcpq&LnAB}FZCxK*fqN9mQGLHw3%7Hr=ka*M)b1pKvT%a3{%G>=8)KMPb4l* z#l+FHZ+hSQ1>&1p1K6)xC=ROl`$bc7m0(oa$_Mt*JyB(QC{AXNJFf55n}%Xm?-Agf zg1G)lcNdOLoSXhZ{k?HZuovX~^!blM#s?L7Kw8<`VC)*mN`k(* zgWbo*e)eVX?d1gLEfk!$yQb^CbjOe{sXm~zyc+`Ji$t5YN?)i&MTB_yyz5CHTj}q9 zyge}?b95lfC99>#nLPTEO@={d`8v_3c5_r>0}lz&^EWh)x aG;^_KmhR;>>zL6$GI;*euh#$i2LB&AVY;#a diff --git a/textures/GUI/Thumbs.db b/textures/GUI/Thumbs.db deleted file mode 100644 index 8857997a37589537321b5d7af30efdf6f859a0a8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15872 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 diff --git a/textures/Keldrin/Thumbs.db b/textures/Keldrin/Thumbs.db deleted file mode 100644 index 89a25ad85ced6fbcce459d7e9be6d5d73ca2f88b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7680 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 GBJdw!L)sYt diff --git a/textures/LiquidTiles/Thumbs.db b/textures/LiquidTiles/Thumbs.db deleted file mode 100644 index ba865ccfe72977f29db57fc591c3028b7597fab5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7680 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 diff --git a/textures/Thumbs.db b/textures/Thumbs.db deleted file mode 100644 index 78ce96cf3664b9ea1e4c251040e8d19db179f184..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 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 diff --git a/textures/UrbanAssault/Thumbs.db b/textures/UrbanAssault/Thumbs.db deleted file mode 100644 index 407498cbae918a4f2eaa895b1bdd8a7bab7b02ec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 264192 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 z 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 TzN7P!|9@EM-;?G3wM+j6TE^R# diff --git a/textures/inttext/Thumbs.db b/textures/inttext/Thumbs.db deleted file mode 100644 index 24a1c2f754a45a951e95172fb7cb815e452aa8ed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 213504 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 diff --git a/textures/skins/Thumbs.db b/textures/skins/Thumbs.db deleted file mode 100644 index 2daec0c368581b91e9b22a63b8a12bc5c884f8a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 58880 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 Ozth8?P5&?Nz`p^CI145K diff --git a/textures/terrain/Thumbs.db b/textures/terrain/Thumbs.db deleted file mode 100644 index d057f8b08e2210f12b481f7ecf8275c14f9ae329..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32256 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

Cew59kC#2|0_JeN{aG3Y9TA4Nwxv!3v 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 EFFh|y6aWAK diff --git a/textures/texticons/Thumbs.db b/textures/texticons/Thumbs.db deleted file mode 100644 index 858ccd713282eb4ff9c72e6ed3cb0e0dedfccfe3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 61952 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�Xj@boFYd9I+>CwAFZ$ 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 diff --git a/textures/texticons/Trophies/Thumbs.db b/textures/texticons/Trophies/Thumbs.db deleted file mode 100644 index 0a8db47b144a6268fc6c74feac759015ef5f82e6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17408 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 yZV>

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